136 lines
5.4 KiB
C++
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
|