Files
Renderive/YSGraphic_Core/architecture/Render_Data.h
T
2026-07-28 17:55:29 +08:00

256 lines
8.4 KiB
C++

#pragma once
#include <QImage>
#include <QRect>
#include <QRegion>
#include <array>
#include <atomic>
#include <cstdint>
#include "Render_Config.h"
#include "Plot_Render_Context.h"
#include "global.h"
class QEvent;
class QKeyEvent;
class QMouseEvent;
class QPainter;
class QPointF;
class QResizeEvent;
class QWheelEvent;
namespace YSG {
struct Render_Data;
struct Renderable;
struct Input_Data {
virtual ~Input_Data() = default;
virtual void clear() {
}
virtual std::uint64_t pending_count() const {
return 0;
}
virtual std::uint64_t dropped_count() const {
return 0;
}
virtual std::uint64_t capacity_dropped_count() const {
return 0;
}
virtual std::uint64_t rebuild_dropped_count() const {
return 0;
}
virtual std::uint64_t consumer_dropped_count() const {
return 0;
}
virtual std::uint64_t pushed_count() const {
return 0;
}
};
struct Render_State {
virtual ~Render_State() = default;
std::uint64_t version = 0;
Render_Data* dPtr{};
SRC src();
};
struct Input_Buffer_Slot {
Input_Data* data{};
std::uint64_t version = 0;
bool pending = false;
};
struct Render_Data {
Render_Data() {
mStateControl.set_stats(&mStateBufferStats);
mInputControl.set_stats(&mInputBufferStats);
}
Renderable* qPtr{};
bool mRenderStart = false;
Triple_Role_Buffer_Control mStateControl;
Triple_Buffer_Stats mStateBufferStats;
std::array<Render_State*, 3> mStateBuffers{};
Triple_Role_Buffer_Control mInputControl;
Triple_Buffer_Stats mInputBufferStats;
std::array<Input_Buffer_Slot, 3> mInputBuffers{};
std::uint64_t mInputVersion = 0;
std::atomic<Plot_Buffer_Acquire_Mode> mBufferAcquireMode{Plot_Buffer_Acquire_Mode::Wait};
std::atomic<RenderAble_Render_Schedule_Mode> mRenderScheduleMode{RenderAble_Render_Schedule_Mode::Inherit};
std::atomic<double> mRenderScheduleMaxFps{0.0};
std::atomic<std::uint64_t> mNextRenderSubmitNs{0};
Render_State* state(std::uint8_t role) const {
return state_by_index(mStateControl.read_view()[role]);
}
Render_State* state(SRC src) const {
return state(static_cast<std::uint8_t>(src));
}
Render_State* state_by_index(std::uint8_t index) const {
return mStateBuffers[index];
}
Plot_Buffer_Acquire_Mode buffer_acquire_mode() const {
return mBufferAcquireMode.load(std::memory_order_acquire);
}
void set_buffer_acquire_mode(Plot_Buffer_Acquire_Mode mode) {
mBufferAcquireMode.store(mode, std::memory_order_release);
}
RenderAble_Render_Schedule_Mode render_schedule_mode() const {
return mRenderScheduleMode.load(std::memory_order_acquire);
}
void set_render_schedule_mode(RenderAble_Render_Schedule_Mode mode) {
mRenderScheduleMode.store(mode, std::memory_order_release);
}
double render_schedule_max_fps() const {
return mRenderScheduleMaxFps.load(std::memory_order_acquire);
}
void set_render_schedule_max_fps(double fps) {
mRenderScheduleMaxFps.store(fps, std::memory_order_release);
}
Triple_Buffer_Lease mark_state_role(std::uint8_t role) {
if (buffer_acquire_mode() == Plot_Buffer_Acquire_Mode::Wait) {
return mStateControl.wait_mark_use_role(role);
}
auto record = mStateControl.try_mark_use_role(role);
if (record.result != Triple_Buffer_Result::Success) {
return {};
}
return record.lease;
}
void unmark_state(Triple_Buffer_Lease lease) {
mStateControl.unmark_use(lease);
}
void clear_state_buffers() {
for (Render_State*& state : mStateBuffers) {
delete state;
state = nullptr;
}
mStateControl.reset();
}
Input_Data* input_data(std::uint8_t role) const {
return input_slot(role).data;
}
Input_Data* input_data_by_index(std::uint8_t index) const {
return mInputBuffers[index].data;
}
Input_Buffer_Slot& input_slot(std::uint8_t role) {
return input_slot_by_index(mInputControl.read_view()[role]);
}
const Input_Buffer_Slot& input_slot(std::uint8_t role) const {
return input_slot_by_index(mInputControl.read_view()[role]);
}
Input_Buffer_Slot& input_slot_by_index(std::uint8_t index) {
return mInputBuffers[index];
}
const Input_Buffer_Slot& input_slot_by_index(std::uint8_t index) const {
return mInputBuffers[index];
}
bool has_pending_state() const {
auto view = mStateControl.read_view();
return buffer_version_newer(mStateBuffers[view[State_Edit]]->version, mStateBuffers[view[State_Render]]->version);
}
bool has_pending_input() const {
auto view = mInputControl.read_view();
const Input_Buffer_Slot& edit = mInputBuffers[view[Input_Edit]];
const Input_Buffer_Slot& ready = mInputBuffers[view[Input_Ready]];
const Input_Buffer_Slot& render = mInputBuffers[view[Input_Render]];
return (edit.pending && buffer_version_newer(edit.version, render.version)) || (ready.pending && buffer_version_newer(ready.version, render.version));
}
bool has_pending_render_data() const {
return has_pending_state() || has_pending_input();
}
void mark_input_dirty(Triple_Buffer_Lease lease, bool notifyRender = true);
void clear_input_role(std::uint8_t role) {
Input_Buffer_Slot& slot = input_slot(role);
slot.data->clear();
slot.pending = false;
}
void clear_render_input() {
clear_input_role(Input_Render);
}
void clear_input_buffers() {
for (Input_Buffer_Slot& slot : mInputBuffers) {
delete slot.data;
slot.data = nullptr;
slot.version = 0;
slot.pending = false;
}
mInputVersion = 0;
mInputControl.reset();
}
public:
/// 同步 State/Input 的 ready 角色到 render 角色。
virtual void sync_state_pipeline() = 0;
/// 返回 render 角色 State。
virtual Render_State* render_state() = 0;
/// 返回 ready 角色 State。
virtual Render_State* ready_state() = 0;
/// 返回 edit 角色 State。
virtual Render_State* edit_state() = 0;
/// 返回 render 角色 Input。
virtual Input_Data* render_input_data() = 0;
/// 返回 edit 角色 Input。
virtual Input_Data* edit_input_data() = 0;
virtual ~Render_Data() {
clear_state_buffers();
clear_input_buffers();
}
/// 绘制当前已准备好的数据。
virtual void draw(QPainter* painter, const Plot_Render_Snapshot& snapshot) {
}
/// 准备当前帧数据,默认只同步三缓冲管线。
virtual void prepare_data(const Plot_Render_Snapshot& snapshot) {
sync_state_pipeline();
}
virtual QRect pixel_bounds(const QSize& plotSize) {
return QRect(QPoint(0, 0), plotSize);
}
/// 判断指定坐标是否命中对象。
virtual bool select_test(const QPointF& pos) {
return false;
}
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) {
}
};
struct Base_Render_Data : Render_Data {
Render_State* render_state() override {
return nullptr;
}
Render_State* ready_state() override {
return nullptr;
}
Render_State* edit_state() override {
return nullptr;
}
Input_Data* render_input_data() override {
return nullptr;
}
Input_Data* edit_input_data() override {
return nullptr;
}
void sync_state_pipeline() override {
}
};
class Abs_Plot;
struct LIB_DECL Render_Edit_Guard {
Render_Edit_Guard(Render_Data* data, Triple_Buffer_Lease lease);
~Render_Edit_Guard();
Render_Data* mData{};
Triple_Buffer_Lease mLease{};
};
struct LIB_DECL Render_Input_Guard {
Render_Input_Guard(Render_Data* data, Triple_Buffer_Lease lease);
~Render_Input_Guard();
Render_Data* mData{};
Triple_Buffer_Lease mLease{};
};
} // namespace YSG