Files
Renderive/YSGraphic_Core/architecture/Renderable_Core.h
T
2026-07-24 10:54:44 +08:00

136 lines
5.4 KiB
C++

#pragma once
#include <QDebug>
#include <QQueue>
#include <QSet>
#include <QVector>
#include <array>
#include <atomic>
#include <cstdint>
#include "Render_Data.h"
namespace YSG {
/// 可渲染对象的基础接口和每对象渲染管线。
struct Renderable {
/// 后台渲染任务状态。
enum class JobState {
/// 没有任务运行或排队。
Idle,
/// 已经进入调度队列。
Queued,
/// CPU 渲染任务正在执行。
Running
};
/// Plot 级颜色三缓冲中的一个物理颜色缓冲。
struct Color_Buffer {
std::atomic<std::uint64_t> version{0};
QImage image;
QRegion dirtyRegion;
};
/// 颜色缓冲占用租约,析构时自动释放底层 busy 标记。
struct Color_Buffer_Lease {
Color_Buffer_Lease() = default;
Color_Buffer_Lease(Color_Buffer* buffer, Triple_Role_Buffer_Control* control, Triple_Buffer_Lease lease);
Color_Buffer_Lease(const Color_Buffer_Lease&) = delete;
Color_Buffer_Lease& operator=(const Color_Buffer_Lease&) = delete;
Color_Buffer_Lease(Color_Buffer_Lease&& other) noexcept;
Color_Buffer_Lease& operator=(Color_Buffer_Lease&& other) noexcept;
~Color_Buffer_Lease();
/// 提前释放当前租约。
void reset();
Color_Buffer* buffer{};
Triple_Role_Buffer_Control* control{};
Triple_Buffer_Lease lease{};
/// 判断当前租约是否持有有效颜色缓冲。
explicit operator bool() const {
return buffer && lease;
}
};
/// 单个 Plot 的颜色三缓冲管线。
struct Render_Pipeline {
Triple_Role_Buffer_Control colorControl;
Triple_Buffer_Stats colorBufferStats;
std::array<Color_Buffer, 3> colorBuffers;
std::atomic<std::uint64_t> editStateVersion{1};
std::uint64_t renderStateVersion = 0;
JobState jobState = JobState::Idle;
std::atomic_bool paintRequestPending{false};
Render_Pipeline();
/// 标记 GUI/edit 状态已经变化。
void mark_edit_state();
/// 判断是否存在 render 未消费的新状态。
bool has_new_state() const;
Color_Buffer* color_by_index(std::uint8_t index);
Color_Buffer* color_by_role(std::uint8_t role);
Color_Buffer_Lease wait_render_color();
Color_Buffer_Lease wait_front_color();
Color_Buffer_Lease try_front_color();
QRegion publish_render_color();
Color_Buffer_Lease consume_ready_color(Triple_Buffer_Mode mode);
};
/// 创建派生对象的私有渲染数据。
virtual Render_Data* create_render_data() {
return new Base_Render_Data;
}
/// 创建派生对象的 State 缓冲实体。
virtual Render_State* create_render_state() {
return new Render_State;
}
/// 创建派生对象的 Input 缓冲实体。
virtual Input_Data* create_input_data() {
return new Input_Data;
}
/// 把对象挂接到 Plot 的指定层。
virtual void init(Plot* plot, QString layerName = "");
/// 绘制已准备好的 Render_Data。
virtual void draw(QPainter* painter);
/// 在 CPU render 阶段准备渲染数据。
virtual void prepare_data();
/// 判断指定 Plot 坐标是否命中当前对象。
virtual bool select_test(const QPointF& pos);
/// 转发 Qt 事件给私有渲染数据。
virtual void plot_event(QEvent* event);
virtual void mousePressEvent(QMouseEvent* event);
virtual void mouseMoveEvent(QMouseEvent* event);
virtual void mouseReleaseEvent(QMouseEvent* event);
virtual void set_hover_state(const QPoint& pos, bool active);
virtual void keyPressEvent(QKeyEvent* event);
virtual void keyReleaseEvent(QKeyEvent* event);
virtual void first_resize_event(QResizeEvent* event);
virtual void resizeEvent(QResizeEvent* event);
virtual void wheelEvent(QWheelEvent* event);
/// 按三缓冲版本号环绕语义判断 a 是否比 b 新。
static bool version_newer(std::uint64_t a, std::uint64_t b);
/// 当前对象三缓冲获取模式。
Plot_Buffer_Acquire_Mode buffer_acquire_mode() const;
void set_buffer_acquire_mode(Plot_Buffer_Acquire_Mode mode);
/// 当前对象渲染调度策略。
RenderAble_Render_Schedule_Mode render_schedule_mode() const;
void set_render_schedule_mode(RenderAble_Render_Schedule_Mode mode);
/// 当前对象自身最大提交帧率,0 表示继承或不限速。
double render_schedule_max_fps() const;
void set_render_schedule_max_fps(double fps);
/// 判断是否启用对象独立像素缓存。
bool independent_pixel_cache() const;
void set_independent_pixel_cache(bool enabled);
/// 标记 State 缓冲有新版本。
void mark_state_dirty();
/// 请求父 Plot 调度一次渲染。
void mark_render_dirty();
QString mObjectName;
Render_Data* dPtr{};
Plot* mPlot{};
[[nodiscard]] bool ok() const;
bool mPrepared = false;
// 这里面可以预先准备数据用来同步
virtual ~Renderable();
virtual bool select(QPointF pos) {
return false;
}
bool mVisable = true;
Renderable* mParent{};
QVector<Renderable*> mBeRelyList;
bool dect_cycle_rely();
private:
bool has_cycle_rely(Renderable* node, QSet<Renderable*>& visited, QSet<Renderable*>& recursionStack, QVector<Renderable*>& currentPath);
};
} // namespace YSG