#pragma once #include #include #include #include #include #include #include #include "Render_Data.h" namespace YSG { /// 可渲染对象的基础接口和每对象渲染管线。 struct Renderable { /// 后台渲染任务状态。 enum class JobState { /// 没有任务运行或排队。 Idle, /// 已经进入调度队列。 Queued, /// CPU 渲染任务正在执行。 Running }; /// Plot 级颜色三缓冲中的一个物理颜色缓冲。 struct Color_Buffer { std::atomic 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 colorBuffers; std::atomic 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 mBeRelyList; bool dect_cycle_rely(); private: bool has_cycle_rely(Renderable* node, QSet& visited, QSet& recursionStack, QVector& currentPath); }; } // namespace YSG