初步重构

This commit is contained in:
2026-07-23 17:06:07 +08:00
parent 92bc5c9907
commit aa243e3d97
77 changed files with 2195 additions and 2195 deletions
+204 -204
View File
@@ -5,13 +5,13 @@
#include <chrono>
namespace YSG {
static std::uint64_t steadyNowNs() {
static std::uint64_t steady_now_ns() {
return static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count());
}
static double elapsedMs(std::uint64_t startNs, std::uint64_t endNs) {
static double elapsed_ms(std::uint64_t startNs, std::uint64_t endNs) {
return static_cast<double>(endNs - startNs) / 1000000.0;
}
static QString jobStateText(RenderAble::JobState state) {
static QString job_state_text(RenderAble::JobState state) {
switch(state) {
case RenderAble::JobState::Idle:
return "Idle";
@@ -22,14 +22,14 @@ namespace YSG {
}
return {};
}
static QString renderAbleName(RenderAble* able) {
static QString render_able_name(RenderAble* able) {
if(!able->mObjectName.isEmpty()) return able->mObjectName;
return QString::number(reinterpret_cast<std::uintptr_t>(able), 16);
}
static QString acquireModeText(Plot_Buffer_Acquire_Mode mode) {
static QString acquire_mode_text(Plot_Buffer_Acquire_Mode mode) {
return mode == Plot_Buffer_Acquire_Mode::Wait ? "Wait" : "Try";
}
static QString plotScheduleModeText(Plot_Render_Schedule_Mode mode) {
static QString plot_schedule_mode_text(Plot_Render_Schedule_Mode mode) {
switch(mode) {
case Plot_Render_Schedule_Mode::Timer_Check:
return "Timer_Check";
@@ -42,7 +42,7 @@ namespace YSG {
}
return {};
}
static QString renderAbleScheduleModeText(RenderAble_Render_Schedule_Mode mode) {
static QString render_able_schedule_mode_text(RenderAble_Render_Schedule_Mode mode) {
switch(mode) {
case RenderAble_Render_Schedule_Mode::Inherit:
return "Inherit";
@@ -57,50 +57,50 @@ namespace YSG {
}
return {};
}
static void publishTripleBufferStats(PerformanceShower* shower, const QString& name, const Triple_Buffer_Stats& stats) {
static void publish_triple_buffer_stats(PerformanceShower* shower, const QString& name, const Triple_Buffer_Stats& stats) {
if(!shower || !shower->enabled()) return;
shower->setGauge("Buffer", name + ".markSuccess", static_cast<double>(stats.mark_success.load(std::memory_order_relaxed)));
shower->setGauge("Buffer", name + ".markBusy", static_cast<double>(stats.mark_busy.load(std::memory_order_relaxed)));
shower->setGauge("Buffer", name + ".markStateChanged", static_cast<double>(stats.mark_state_changed.load(std::memory_order_relaxed)));
shower->setGauge("Buffer", name + ".swapSuccess", static_cast<double>(stats.swap_success.load(std::memory_order_relaxed)));
shower->setGauge("Buffer", name + ".swapBusy", static_cast<double>(stats.swap_busy.load(std::memory_order_relaxed)));
shower->setGauge("Buffer", name + ".swapStateChanged", static_cast<double>(stats.swap_state_changed.load(std::memory_order_relaxed)));
shower->setGauge("Buffer", name + ".swapNoNeed", static_cast<double>(stats.swap_condition_failed.load(std::memory_order_relaxed)));
shower->setGauge("Buffer", name + ".wait", static_cast<double>(stats.wait_count.load(std::memory_order_relaxed)));
shower->set_gauge("Buffer", name + ".markSuccess", static_cast<double>(stats.mark_success.load(std::memory_order_relaxed)));
shower->set_gauge("Buffer", name + ".markBusy", static_cast<double>(stats.mark_busy.load(std::memory_order_relaxed)));
shower->set_gauge("Buffer", name + ".markStateChanged", static_cast<double>(stats.mark_state_changed.load(std::memory_order_relaxed)));
shower->set_gauge("Buffer", name + ".swapSuccess", static_cast<double>(stats.swap_success.load(std::memory_order_relaxed)));
shower->set_gauge("Buffer", name + ".swapBusy", static_cast<double>(stats.swap_busy.load(std::memory_order_relaxed)));
shower->set_gauge("Buffer", name + ".swapStateChanged", static_cast<double>(stats.swap_state_changed.load(std::memory_order_relaxed)));
shower->set_gauge("Buffer", name + ".swapNoNeed", static_cast<double>(stats.swap_condition_failed.load(std::memory_order_relaxed)));
shower->set_gauge("Buffer", name + ".wait", static_cast<double>(stats.wait_count.load(std::memory_order_relaxed)));
}
static void publishRenderAbleBufferStats(PerformanceShower* shower, RenderAble* able) {
static void publish_render_able_buffer_stats(PerformanceShower* shower, RenderAble* able) {
if(!shower || !shower->enabled()) return;
if(able == shower) return;
QString name = renderAbleName(able);
shower->setState("RenderAble", name + ".bufferAcquireMode", acquireModeText(able->bufferAcquireMode()));
shower->setState("RenderAble", name + ".renderScheduleMode", renderAbleScheduleModeText(able->renderScheduleMode()));
shower->setGauge("RenderAble", name + ".renderScheduleMaxFps", able->renderScheduleMaxFps());
publishTripleBufferStats(shower, name + ".State", able->dPtr->mStateBufferStats);
publishTripleBufferStats(shower, name + ".Input", able->dPtr->mInputBufferStats);
QString name = render_able_name(able);
shower->set_state("RenderAble", name + ".buffer_acquire_mode", acquire_mode_text(able->buffer_acquire_mode()));
shower->set_state("RenderAble", name + ".render_schedule_mode", render_able_schedule_mode_text(able->render_schedule_mode()));
shower->set_gauge("RenderAble", name + ".render_schedule_max_fps", able->render_schedule_max_fps());
publish_triple_buffer_stats(shower, name + ".State", able->dPtr->mStateBufferStats);
publish_triple_buffer_stats(shower, name + ".Input", able->dPtr->mInputBufferStats);
}
static void publishPipelineStats(PlotPrivate* data) {
static void publish_pipeline_stats(PlotPrivate* data) {
PerformanceShower* shower = data->mShower;
if(!shower || !shower->enabled()) return;
RenderAble::RenderPipeline& pipeline = data->mPipeline;
shower->setState("Pipeline", "jobState", jobStateText(pipeline.jobState));
shower->setState("Pipeline", "renderScheduleMode", plotScheduleModeText(data->mRenderScheduleMode.load(std::memory_order_acquire)));
shower->setState("Pipeline", "paintBufferAcquireMode", acquireModeText(data->mPaintBufferAcquireMode.load(std::memory_order_acquire)));
shower->setState("Pipeline", "renderAbleDefaultAcquireMode", acquireModeText(data->mRenderAbleBufferAcquireMode.load(std::memory_order_acquire)));
shower->setGauge("Pipeline", "renderCheckFps", static_cast<double>(data->mRefreshTimesPreSecond));
shower->setGauge("Pipeline", "maxRenderFps", data->mMaxRenderFps.load(std::memory_order_acquire));
shower->setGauge("Pipeline", "activeRenderTasks", data->mActiveRenderTasks.load(std::memory_order_acquire));
shower->setGauge("Pipeline", "renderEnabled", data->mRenderEnabled.load(std::memory_order_acquire) ? 1.0 : 0.0);
shower->setGauge("Pipeline", "renderSubmitPending", data->mRenderSubmitPending.load(std::memory_order_acquire) ? 1.0 : 0.0);
shower->setGauge("Pipeline", "paintRequestPending", pipeline.paintRequestPending.load(std::memory_order_acquire) ? 1.0 : 0.0);
shower->setGauge("Pipeline", "editStateVersion", static_cast<double>(pipeline.editStateVersion.load(std::memory_order_acquire)));
shower->setGauge("Pipeline", "renderStateVersion", static_cast<double>(pipeline.renderStateVersion));
publishTripleBufferStats(shower, "Color", pipeline.colorBufferStats);
shower->set_state("Pipeline", "jobState", job_state_text(pipeline.jobState));
shower->set_state("Pipeline", "render_schedule_mode", plot_schedule_mode_text(data->mRenderScheduleMode.load(std::memory_order_acquire)));
shower->set_state("Pipeline", "paint_buffer_acquire_mode", acquire_mode_text(data->mPaintBufferAcquireMode.load(std::memory_order_acquire)));
shower->set_state("Pipeline", "renderAbleDefaultAcquireMode", acquire_mode_text(data->mRenderAbleBufferAcquireMode.load(std::memory_order_acquire)));
shower->set_gauge("Pipeline", "render_check_fps", static_cast<double>(data->mRefreshTimesPreSecond));
shower->set_gauge("Pipeline", "max_render_fps", data->mMaxRenderFps.load(std::memory_order_acquire));
shower->set_gauge("Pipeline", "activeRenderTasks", data->mActiveRenderTasks.load(std::memory_order_acquire));
shower->set_gauge("Pipeline", "renderEnabled", data->mRenderEnabled.load(std::memory_order_acquire) ? 1.0 : 0.0);
shower->set_gauge("Pipeline", "renderSubmitPending", data->mRenderSubmitPending.load(std::memory_order_acquire) ? 1.0 : 0.0);
shower->set_gauge("Pipeline", "paintRequestPending", pipeline.paintRequestPending.load(std::memory_order_acquire) ? 1.0 : 0.0);
shower->set_gauge("Pipeline", "editStateVersion", static_cast<double>(pipeline.editStateVersion.load(std::memory_order_acquire)));
shower->set_gauge("Pipeline", "renderStateVersion", static_cast<double>(pipeline.renderStateVersion));
publish_triple_buffer_stats(shower, "Color", pipeline.colorBufferStats);
}
static void notifyRenderTaskDone(PlotPrivate* data) {
static void notify_render_task_done(PlotPrivate* data) {
if(data->mActiveRenderTasks.fetch_sub(1, std::memory_order_acq_rel) == 1) data->mRenderTaskDone.notify_all();
}
void startRenderScheduler() {
Global::instance()->startRenderScheduler();
void start_render_scheduler() {
Global::instance()->start_render_scheduler();
}
Plot::Plot() {
@@ -110,10 +110,10 @@ namespace YSG {
setFocusPolicy(Qt::NoFocus);
Global::instance()->renderScheduler().registerPlot(this);
}
bool Plot::usePerformanceShower() {
bool Plot::use_performance_shower() {
return d->mShower && d->mShower->enabled();
}
void Plot::set_usePerformanceShower(bool use) {
void Plot::set_use_performance_shower(bool use) {
if(!d->mShower) {
d->mShower = new PerformanceShower;
d->mShower->init(this, "legend");
@@ -136,16 +136,16 @@ namespace YSG {
delete d;
}
bool Plot::isRendering() {
bool Plot::is_rendering() {
return d->mRenderEnabled.load(std::memory_order_acquire);
}
void Plot::startRender(int refreshTimesPreSecond) {
setRenderCheckFps(refreshTimesPreSecond);
startRender();
void Plot::start_render(int refreshTimesPreSecond) {
set_render_check_fps(refreshTimesPreSecond);
start_render();
}
void Plot::startRender() const {
void Plot::start_render() const {
if(d->mDestroying.load(std::memory_order_acquire)) return;
d->mRenderEnabled.store(true, std::memory_order_release);
Plot* self = const_cast<Plot*>(this);
@@ -156,15 +156,15 @@ namespace YSG {
if(!d->mDestroying.load(std::memory_order_acquire)) {
if(d->mRenderTimer) {
d->mRenderTimer->cancel();
self->scheduleRenderTimer();
self->schedule_render_timer();
}
self->onRenderRequest(Render_Request_Source::Dirty);
self->on_render_request(Render_Request_Source::Dirty);
}
notifyRenderTaskDone(privateData);
notify_render_task_done(privateData);
});
}
void Plot::pauseRender() const {
void Plot::pause_render() const {
d->mRenderEnabled.store(false, std::memory_order_release);
if(d->mDestroying.load(std::memory_order_acquire)) return;
Plot* self = const_cast<Plot*>(this);
@@ -182,136 +182,136 @@ namespace YSG {
d->mRenderSubmitPending.store(false, std::memory_order_release);
}
}
notifyRenderTaskDone(privateData);
notify_render_task_done(privateData);
});
}
void Plot::paintEvent(QPaintEvent* event) {
Q_UNUSED(event)
Cacl paintData("Pipeline", "paintEvent", d->mShower);
std::uint64_t paintNs = steadyNowNs();
std::uint64_t paintNs = steady_now_ns();
std::uint64_t updateRequestNs = d->mLastUpdateRequestNs.exchange(0, std::memory_order_acq_rel);
if(updateRequestNs && d->mShower) d->mShower->recordDuration("Pipeline", "updateToPaint", elapsedMs(updateRequestNs, paintNs));
if(updateRequestNs && d->mShower) d->mShower->record_duration("Pipeline", "updateToPaint", elapsed_ms(updateRequestNs, paintNs));
QPainter painter(this);
auto mode = to_triple_buffer_mode(d->mPaintBufferAcquireMode.load(std::memory_order_acquire));
RenderAble::ColorBufferLease colorLease;
{
Cacl consumeData("Buffer", "Color.consumeReady", d->mShower);
colorLease = d->mPipeline.consumeReadyColor(mode);
colorLease = d->mPipeline.consume_ready_color(mode);
}
RenderAble::ColorBuffer* color = colorLease.buffer;
if(color && !color->image.isNull()) painter.drawImage(QPoint(0, 0), color->image);
else painter.fillRect(rect(), d->mBackground);
if(colorLease) d->mPipeline.unmarkColor(colorLease);
if(colorLease) d->mPipeline.unmark_color(colorLease);
for(Layer* layer : mLayerList) {
for(RenderAble* able : layer->mRenderAbles) {
if(!able->mVisable || !able->dPtr->independentPixelCache()) continue;
auto pixelLease = able->dPtr->consumeReadyPixel(Triple_Buffer_Mode::Try);
if(!able->mVisable || !able->dPtr->independent_pixel_cache()) continue;
auto pixelLease = able->dPtr->consume_ready_pixel(Triple_Buffer_Mode::Try);
if(pixelLease && !pixelLease.buffer->image.isNull()) painter.drawImage(QPoint(0, 0), pixelLease.buffer->image);
if(pixelLease) able->dPtr->unmarkPixel(pixelLease);
if(pixelLease) able->dPtr->unmark_pixel(pixelLease);
}
}
painter.end();
if(d->mShower) {
if(colorLease) d->mShower->incrementCounter("Buffer", "Color.frontLeaseSuccess");
else d->mShower->incrementCounter("Buffer", "Color.frontLeaseMiss");
d->mShower->incrementCounter("Pipeline", "paint");
publishPipelineStats(d);
if(colorLease) d->mShower->increment_counter("Buffer", "Color.frontLeaseSuccess");
else d->mShower->increment_counter("Buffer", "Color.frontLeaseMiss");
d->mShower->increment_counter("Pipeline", "paint");
publish_pipeline_stats(d);
}
}
void Plot::render() {
requestRender(Render_Request_Source::Manual);
request_render(Render_Request_Source::Manual);
}
Plot_Buffer_Acquire_Mode Plot::paintBufferAcquireMode() const {
Plot_Buffer_Acquire_Mode Plot::paint_buffer_acquire_mode() const {
return d->mPaintBufferAcquireMode.load(std::memory_order_acquire);
}
void Plot::setPaintBufferAcquireMode(Plot_Buffer_Acquire_Mode mode) {
void Plot::set_paint_buffer_acquire_mode(Plot_Buffer_Acquire_Mode mode) {
d->mPaintBufferAcquireMode.store(mode, std::memory_order_release);
}
Plot_Buffer_Acquire_Mode Plot::renderAbleBufferAcquireMode() const {
Plot_Buffer_Acquire_Mode Plot::render_able_buffer_acquire_mode() const {
return d->mRenderAbleBufferAcquireMode.load(std::memory_order_acquire);
}
void Plot::setRenderAbleBufferAcquireMode(Plot_Buffer_Acquire_Mode mode) {
void Plot::set_render_able_buffer_acquire_mode(Plot_Buffer_Acquire_Mode mode) {
d->mRenderAbleBufferAcquireMode.store(mode, std::memory_order_release);
}
Plot_Render_Schedule_Mode Plot::renderScheduleMode() const {
Plot_Render_Schedule_Mode Plot::render_schedule_mode() const {
return d->mRenderScheduleMode.load(std::memory_order_acquire);
}
void Plot::setRenderScheduleMode(Plot_Render_Schedule_Mode mode) {
void Plot::set_render_schedule_mode(Plot_Render_Schedule_Mode mode) {
d->mRenderScheduleMode.store(mode, std::memory_order_release);
if(mode == Plot_Render_Schedule_Mode::Max_Fps && d->mMaxRenderFps.load(std::memory_order_acquire) <= 0.0) d->mMaxRenderFps.store(renderCheckFps(), std::memory_order_release);
requestRender(Render_Request_Source::Dirty);
if(mode == Plot_Render_Schedule_Mode::Max_Fps && d->mMaxRenderFps.load(std::memory_order_acquire) <= 0.0) d->mMaxRenderFps.store(render_check_fps(), std::memory_order_release);
request_render(Render_Request_Source::Dirty);
}
double Plot::renderCheckFps() const {
double Plot::render_check_fps() const {
return static_cast<double>(d->mRefreshTimesPreSecond);
}
void Plot::setRenderCheckFps(double fps) {
void Plot::set_render_check_fps(double fps) {
d->mRefreshTimesPreSecond = qMax(1, qRound(fps));
}
double Plot::maxRenderFps() const {
double Plot::max_render_fps() const {
return d->mMaxRenderFps.load(std::memory_order_acquire);
}
void Plot::setMaxRenderFps(double fps) {
void Plot::set_max_render_fps(double fps) {
d->mMaxRenderFps.store(fps, std::memory_order_release);
}
bool Plot::submitRenderOnce() {
bool Plot::submit_render_once() {
RenderScheduler& scheduler = Global::instance()->renderScheduler();
if(!scheduler.isSchedulerThread()) {
PlotPrivate* privateData = d;
std::uint64_t postNs = steadyNowNs();
std::uint64_t postNs = steady_now_ns();
privateData->mActiveRenderTasks.fetch_add(1, std::memory_order_acq_rel);
scheduler.post([this, privateData, postNs]() {
if(privateData->mShower) privateData->mShower->recordDuration("Pipeline", "schedulerQueueWait", elapsedMs(postNs, steadyNowNs()));
if(!privateData->mDestroying.load(std::memory_order_acquire)) submitRenderOnce();
notifyRenderTaskDone(privateData);
if(privateData->mShower) privateData->mShower->record_duration("Pipeline", "schedulerQueueWait", elapsed_ms(postNs, steady_now_ns()));
if(!privateData->mDestroying.load(std::memory_order_acquire)) submit_render_once();
notify_render_task_done(privateData);
});
return false;
}
if(d->mDestroying.load(std::memory_order_acquire)) return false;
std::uint64_t submitNs = steadyNowNs();
std::uint64_t submitNs = steady_now_ns();
Render_Request_Source source = d->mSubmitSource;
std::uint64_t requestNs = d->mLastRequestNs.exchange(0, std::memory_order_acq_rel);
if(requestNs && d->mShower) d->mShower->recordDuration("Pipeline", "requestToSubmit", elapsedMs(requestNs, submitNs));
if(requestNs && d->mShower) d->mShower->record_duration("Pipeline", "requestToSubmit", elapsed_ms(requestNs, submitNs));
if(mFirstResize) return false;
if(!d->mRenderEnabled.load(std::memory_order_acquire)) return false;
QSize renderSize = d->mRenderSize;
if(renderSize.width() <= 0 || renderSize.height() <= 0) return false;
RenderAble::RenderPipeline& pipeline = d->mPipeline;
if(pipeline.jobState != RenderAble::JobState::Idle) return false;
if(!hasSubmitCandidate(source, submitNs)) return false;
if(!has_submit_candidate(source, submitNs)) return false;
pipeline.jobState = RenderAble::JobState::Queued;
pipeline.renderStateVersion = pipeline.editStateVersion.load(std::memory_order_acquire);
if(d->mShower) {
d->mShower->incrementCounter("Pipeline", "renderFrame");
d->mShower->setInfo("interval", QString("渲染:%1, global%2").arg(qRound(1000.0 / (double)d->mRefreshTimesPreSecond)).arg(Global::instance()->mInterval));
publishPipelineStats(d);
d->mShower->increment_counter("Pipeline", "renderFrame");
d->mShower->set_info("interval", QString("渲染:%1, global%2").arg(qRound(1000.0 / (double)d->mRefreshTimesPreSecond)).arg(Global::instance()->mInterval));
publish_pipeline_stats(d);
}
{
Cacl prepareData("Pipeline", "prepareData", d->mShower);
Cacl prepare_data("Pipeline", "prepare_data", d->mShower);
for(Layer* layer : mLayerList) {
for(RenderAble *cur : layer->mRenderAbles) {
for(auto rely : cur->mBeRelyList) {
if(rely->dPtr->independentPixelCache()) continue;
if(!renderAbleReadyForSubmit(rely, source, submitNs, false)) continue;
if(rely->dPtr->independent_pixel_cache()) continue;
if(!render_able_ready_for_submit(rely, source, submitNs, false)) continue;
if(!rely->mPrepared){
{
Cacl renderAblePrepare("RenderAble", renderAbleName(rely) + ".prepareData", d->mShower);
rely->prepareData();
Cacl renderAblePrepare("RenderAble", render_able_name(rely) + ".prepare_data", d->mShower);
rely->prepare_data();
}
markRenderAbleSubmitted(rely, submitNs);
publishRenderAbleBufferStats(d->mShower, rely);
mark_render_able_submitted(rely, submitNs);
publish_render_able_buffer_stats(d->mShower, rely);
rely->mPrepared = true;
}
}
if(cur->dPtr->independentPixelCache()) continue;
if(!renderAbleReadyForSubmit(cur, source, submitNs, false)) continue;
if(cur->dPtr->independent_pixel_cache()) continue;
if(!render_able_ready_for_submit(cur, source, submitNs, false)) continue;
if(!cur->mPrepared){
{
Cacl renderAblePrepare("RenderAble", renderAbleName(cur) + ".prepareData", d->mShower);
cur->prepareData();
Cacl renderAblePrepare("RenderAble", render_able_name(cur) + ".prepare_data", d->mShower);
cur->prepare_data();
}
markRenderAbleSubmitted(cur, submitNs);
publishRenderAbleBufferStats(d->mShower, cur);
mark_render_able_submitted(cur, submitNs);
publish_render_able_buffer_stats(d->mShower, cur);
cur->mPrepared = true;
}
}
@@ -325,86 +325,86 @@ namespace YSG {
}
RenderAble::ColorBufferLease colorLease;
{
Cacl waitRenderColor("Buffer", "Color.waitRenderLease", d->mShower);
colorLease = pipeline.waitRenderColor();
Cacl wait_render_color("Buffer", "Color.waitRenderLease", d->mShower);
colorLease = pipeline.wait_render_color();
}
RenderAble::ColorBuffer* color = colorLease.buffer;
QColor background = d->mBackground;
std::uint64_t version = pipeline.renderStateVersion;
pipeline.jobState = RenderAble::JobState::Running;
if(d->mShower) publishPipelineStats(d);
if(d->mShower) publish_pipeline_stats(d);
PlotPrivate* privateData = d;
std::uint64_t cpuPostNs = steadyNowNs();
std::uint64_t cpuPostNs = steady_now_ns();
privateData->mActiveRenderTasks.fetch_add(1, std::memory_order_acq_rel);
scheduler.postCpu([this, privateData, colorLease, color, renderSize, background, version, cpuPostNs]() {
if(privateData->mShower) privateData->mShower->recordDuration("Pipeline", "cpuQueueWait", elapsedMs(cpuPostNs, steadyNowNs()));
if(privateData->mShower) privateData->mShower->record_duration("Pipeline", "cpuQueueWait", elapsed_ms(cpuPostNs, steady_now_ns()));
if(privateData->mDestroying.load(std::memory_order_acquire)) {
privateData->mPipeline.unmarkColor(colorLease);
notifyRenderTaskDone(privateData);
privateData->mPipeline.unmark_color(colorLease);
notify_render_task_done(privateData);
return;
}
renderColor(color, renderSize, background, version);
privateData->mPipeline.unmarkColor(colorLease);
render_color(color, renderSize, background, version);
privateData->mPipeline.unmark_color(colorLease);
if(privateData->mDestroying.load(std::memory_order_acquire)) {
notifyRenderTaskDone(privateData);
notify_render_task_done(privateData);
return;
}
Global::instance()->renderScheduler().post([this, privateData]() {
if(!privateData->mDestroying.load(std::memory_order_acquire)) finishRender();
notifyRenderTaskDone(privateData);
if(!privateData->mDestroying.load(std::memory_order_acquire)) finish_render();
notify_render_task_done(privateData);
});
});
return true;
}
void Plot::onRenderRequest(Render_Request_Source source) {
void Plot::on_render_request(Render_Request_Source source) {
if(d->mDestroying.load(std::memory_order_acquire)) return;
Plot_Render_Schedule_Mode mode = d->mRenderScheduleMode.load(std::memory_order_acquire);
d->mSubmitSource = source;
switch(mode) {
case Plot_Render_Schedule_Mode::Timer_Check:
if(source == Render_Request_Source::Timer) submitRenderOnce();
if(source == Render_Request_Source::Timer) submit_render_once();
break;
case Plot_Render_Schedule_Mode::Chase_Latest:
submitRenderOnce();
submit_render_once();
break;
case Plot_Render_Schedule_Mode::Max_Fps:
submitRenderWithFpsLimit();
submit_render_with_fps_limit();
break;
case Plot_Render_Schedule_Mode::Manual:
if(source == Render_Request_Source::Manual) submitRenderOnce();
if(source == Render_Request_Source::Manual) submit_render_once();
break;
}
for(Layer* layer : mLayerList) {
for(RenderAble* able : layer->mRenderAbles) {
if(able->mVisable && able->dPtr->independentPixelCache() && able->dPtr->hasNewPixelState()) submitIndependentRender(able, source);
if(able->mVisable && able->dPtr->independent_pixel_cache() && able->dPtr->has_new_pixel_state()) submit_independent_render(able, source);
}
}
if(d->mShower) publishPipelineStats(d);
if(d->mShower) publish_pipeline_stats(d);
}
bool Plot::submitRenderWithFpsLimit() {
bool Plot::submit_render_with_fps_limit() {
double fps = d->mMaxRenderFps.load(std::memory_order_acquire);
if(fps <= 0.0) return submitRenderOnce();
std::uint64_t now = steadyNowNs();
if(fps <= 0.0) return submit_render_once();
std::uint64_t now = steady_now_ns();
std::uint64_t intervalNs = static_cast<std::uint64_t>(1000000000.0 / fps);
if(now < d->mNextSubmitNs) {
d->mRenderSubmitPending.store(true, std::memory_order_release);
scheduleMaxFpsSubmit(d->mNextSubmitNs);
schedule_max_fps_submit(d->mNextSubmitNs);
return false;
}
bool submitted = submitRenderOnce();
bool submitted = submit_render_once();
if(submitted) {
d->mNextSubmitNs = now + intervalNs;
d->mRenderSubmitPending.store(false, std::memory_order_release);
} else if(!d->mPipeline.hasNewState()) {
} else if(!d->mPipeline.has_new_state()) {
d->mRenderSubmitPending.store(false, std::memory_order_release);
}
return submitted;
}
void Plot::scheduleMaxFpsSubmit(std::uint64_t targetNs) {
void Plot::schedule_max_fps_submit(std::uint64_t targetNs) {
if(!d->mSubmitTimer || !d->mRenderEnabled.load(std::memory_order_acquire)) return;
if(d->mSubmitTimerTargetNs && d->mSubmitTimerTargetNs <= targetNs) return;
d->mSubmitTimerTargetNs = targetNs;
std::uint64_t now = steadyNowNs();
std::uint64_t now = steady_now_ns();
std::uint64_t delayNs = targetNs > now ? targetNs - now : 0;
d->mSubmitTimer->expires_after(std::chrono::nanoseconds(delayNs));
PlotPrivate* privateData = d;
@@ -412,24 +412,24 @@ namespace YSG {
d->mSubmitTimer->async_wait([this, privateData, targetNs](const asio::error_code& error) {
if(!error && !privateData->mDestroying.load(std::memory_order_acquire) && privateData->mSubmitTimerTargetNs == targetNs) {
privateData->mSubmitTimerTargetNs = 0;
if(privateData->mRenderSubmitPending.load(std::memory_order_acquire)) onRenderRequest(privateData->mSubmitSource);
if(privateData->mRenderSubmitPending.load(std::memory_order_acquire)) on_render_request(privateData->mSubmitSource);
}
notifyRenderTaskDone(privateData);
notify_render_task_done(privateData);
});
}
bool Plot::hasSubmitCandidate(Render_Request_Source source, std::uint64_t nowNs) {
bool Plot::has_submit_candidate(Render_Request_Source source, std::uint64_t nowNs) {
if(mFirstPrepareData) return true;
for(Layer* layer : mLayerList) {
for(RenderAble* able : layer->mRenderAbles) {
if(!able->mVisable || able->dPtr->independentPixelCache()) continue;
if(able->dPtr->hasPendingRenderData() && renderAbleReadyForSubmit(able, source, nowNs, false)) return true;
if(!able->mVisable || able->dPtr->independent_pixel_cache()) continue;
if(able->dPtr->has_pending_render_data() && render_able_ready_for_submit(able, source, nowNs, false)) return true;
}
}
return false;
}
bool Plot::renderAbleReadyForSubmit(RenderAble* able, Render_Request_Source source, std::uint64_t nowNs, bool independent) {
bool Plot::render_able_ready_for_submit(RenderAble* able, Render_Request_Source source, std::uint64_t nowNs, bool independent) {
Q_UNUSED(independent)
RenderAble_Render_Schedule_Mode mode = able->renderScheduleMode();
RenderAble_Render_Schedule_Mode mode = able->render_schedule_mode();
if(mode == RenderAble_Render_Schedule_Mode::Inherit) {
switch(d->mRenderScheduleMode.load(std::memory_order_acquire)) {
case Plot_Render_Schedule_Mode::Timer_Check:
@@ -448,12 +448,12 @@ namespace YSG {
case RenderAble_Render_Schedule_Mode::Chase_Latest:
return true;
case RenderAble_Render_Schedule_Mode::Max_Fps: {
double fps = able->renderScheduleMaxFps();
double fps = able->render_schedule_max_fps();
if(fps <= 0.0) return true;
std::uint64_t nextNs = able->dPtr->mNextRenderSubmitNs.load(std::memory_order_acquire);
if(nowNs >= nextNs) return true;
d->mRenderSubmitPending.store(true, std::memory_order_release);
scheduleMaxFpsSubmit(nextNs);
schedule_max_fps_submit(nextNs);
return false;
}
case RenderAble_Render_Schedule_Mode::On_Dirty:
@@ -463,27 +463,27 @@ namespace YSG {
}
return true;
}
void Plot::markRenderAbleSubmitted(RenderAble* able, std::uint64_t nowNs) {
if(able->renderScheduleMode() != RenderAble_Render_Schedule_Mode::Max_Fps) return;
double fps = able->renderScheduleMaxFps();
void Plot::mark_render_able_submitted(RenderAble* able, std::uint64_t nowNs) {
if(able->render_schedule_mode() != RenderAble_Render_Schedule_Mode::Max_Fps) return;
double fps = able->render_schedule_max_fps();
if(fps <= 0.0) return;
able->dPtr->mNextRenderSubmitNs.store(nowNs + static_cast<std::uint64_t>(1000000000.0 / fps), std::memory_order_release);
}
void Plot::finishRender() {
void Plot::finish_render() {
if(d->mDestroying.load(std::memory_order_acquire)) return;
RenderAble::RenderPipeline& pipeline = d->mPipeline;
QRegion updateRegion;
{
Cacl publishData("Pipeline", "publishRenderColor", d->mShower);
updateRegion = pipeline.publishRenderColor();
Cacl publishData("Pipeline", "publish_render_color", d->mShower);
updateRegion = pipeline.publish_render_color();
}
pipeline.jobState = RenderAble::JobState::Idle;
if(d->mShower) publishPipelineStats(d);
if(!updateRegion.isEmpty()) requestUpdate(updateRegion);
onRenderRequest(Render_Request_Source::Finish);
if(d->mShower) publish_pipeline_stats(d);
if(!updateRegion.isEmpty()) request_update(updateRegion);
on_render_request(Render_Request_Source::Finish);
}
void Plot::renderColor(RenderAble::ColorBuffer* color, QSize size, QColor background, std::uint64_t version) {
Cacl renderData("Pipeline", "renderColor", d->mShower);
void Plot::render_color(RenderAble::ColorBuffer* color, QSize size, QColor background, std::uint64_t version) {
Cacl renderData("Pipeline", "render_color", d->mShower);
if(color->image.size() != size || color->image.format() != QImage::Format_ARGB32) {
color->image = QImage(size, QImage::Format_ARGB32);
}
@@ -496,10 +496,10 @@ namespace YSG {
Cacl drawData("Pipeline", "draw", d->mShower);
for(Layer* layer : mLayerList) {
for(RenderAble* cur : layer->mRenderAbles) {
if(!cur->mVisable || cur->dPtr->independentPixelCache()) continue;
auto lease = cur->dPtr->markStateRole(State_Render);
if(!cur->mVisable || cur->dPtr->independent_pixel_cache()) continue;
auto lease = cur->dPtr->mark_state_role(State_Render);
if(!lease) {
if(d->mShower) d->mShower->incrementCounter("RenderAble", renderAbleName(cur) + ".stateLeaseMiss");
if(d->mShower) d->mShower->increment_counter("RenderAble", render_able_name(cur) + ".stateLeaseMiss");
continue;
}
leasedAbles.append(cur);
@@ -507,37 +507,37 @@ namespace YSG {
}
}
for(RenderAble* able : leasedAbles) {
Cacl renderAbleDraw("RenderAble", renderAbleName(able) + ".draw", d->mShower);
Cacl renderAbleDraw("RenderAble", render_able_name(able) + ".draw", d->mShower);
able->draw(&painter);
}
}
for(int i = 0; i < leasedAbles.size(); ++i) {
leasedAbles[i]->dPtr->unmarkState(stateLeases[i]);
leasedAbles[i]->dPtr->unmark_state(stateLeases[i]);
}
painter.end();
color->version.store(version, std::memory_order_release);
color->dirtyRegion = QRegion(QRect(QPoint(0, 0), size));
}
void Plot::markIndependentRenderDirty(RenderAble* able, Render_Request_Source source) {
void Plot::mark_independent_render_dirty(RenderAble* able, Render_Request_Source source) {
if(d->mDestroying.load(std::memory_order_acquire)) return;
PlotPrivate* privateData = d;
privateData->mActiveRenderTasks.fetch_add(1, std::memory_order_acq_rel);
Global::instance()->renderScheduler().post([this, privateData, able, source]() {
if(!privateData->mDestroying.load(std::memory_order_acquire)) submitIndependentRender(able, source);
notifyRenderTaskDone(privateData);
if(!privateData->mDestroying.load(std::memory_order_acquire)) submit_independent_render(able, source);
notify_render_task_done(privateData);
});
}
void Plot::submitIndependentRender(RenderAble* able, Render_Request_Source source) {
void Plot::submit_independent_render(RenderAble* able, Render_Request_Source source) {
RenderScheduler& scheduler = Global::instance()->renderScheduler();
if(!scheduler.isSchedulerThread()) {
markIndependentRenderDirty(able, source);
mark_independent_render_dirty(able, source);
return;
}
if(d->mDestroying.load(std::memory_order_acquire)) return;
if(!able || !able->mVisable || !able->dPtr->independentPixelCache()) return;
if(!able || !able->mVisable || !able->dPtr->independent_pixel_cache()) return;
if(able->dPtr->mIndependentRenderQueued.exchange(true, std::memory_order_acq_rel)) return;
std::uint64_t now = steadyNowNs();
if(!renderAbleReadyForSubmit(able, source, now, true)) {
std::uint64_t now = steady_now_ns();
if(!render_able_ready_for_submit(able, source, now, true)) {
able->dPtr->mIndependentRenderQueued.store(false, std::memory_order_release);
return;
}
@@ -546,55 +546,55 @@ namespace YSG {
able->dPtr->mIndependentRenderQueued.store(false, std::memory_order_release);
return;
}
if(!able->dPtr->hasNewPixelState()) {
if(!able->dPtr->has_new_pixel_state()) {
able->dPtr->mIndependentRenderQueued.store(false, std::memory_order_release);
return;
}
able->prepareData();
markRenderAbleSubmitted(able, now);
auto pixelLease = able->dPtr->waitRenderPixel();
able->prepare_data();
mark_render_able_submitted(able, now);
auto pixelLease = able->dPtr->wait_render_pixel();
PixelBufferSlot* pixel = pixelLease.buffer;
std::uint64_t version = able->dPtr->mPixelEditVersion.load(std::memory_order_acquire);
PlotPrivate* privateData = d;
privateData->mActiveRenderTasks.fetch_add(1, std::memory_order_acq_rel);
scheduler.postCpu([this, privateData, able, pixelLease, pixel, renderSize, version]() {
if(privateData->mDestroying.load(std::memory_order_acquire)) {
able->dPtr->unmarkPixel(pixelLease);
notifyRenderTaskDone(privateData);
able->dPtr->unmark_pixel(pixelLease);
notify_render_task_done(privateData);
return;
}
renderIndependentColor(able, pixel, renderSize, version);
able->dPtr->unmarkPixel(pixelLease);
render_independent_color(able, pixel, renderSize, version);
able->dPtr->unmark_pixel(pixelLease);
Global::instance()->renderScheduler().post([this, privateData, able]() {
if(!privateData->mDestroying.load(std::memory_order_acquire)) finishIndependentRender(able);
notifyRenderTaskDone(privateData);
if(!privateData->mDestroying.load(std::memory_order_acquire)) finish_independent_render(able);
notify_render_task_done(privateData);
});
});
}
void Plot::renderIndependentColor(RenderAble* able, PixelBufferSlot* pixel, QSize size, std::uint64_t version) {
void Plot::render_independent_color(RenderAble* able, PixelBufferSlot* pixel, QSize size, std::uint64_t version) {
if(pixel->image.size() != size || pixel->image.format() != QImage::Format_ARGB32) {
pixel->image = QImage(size, QImage::Format_ARGB32);
}
pixel->image.detach();
pixel->image.fill(Qt::transparent);
QPainter painter(&pixel->image);
auto lease = able->dPtr->markStateRole(State_Render);
auto lease = able->dPtr->mark_state_role(State_Render);
if(lease) {
able->draw(&painter);
able->dPtr->unmarkState(lease);
able->dPtr->unmark_state(lease);
}
painter.end();
pixel->version.store(version, std::memory_order_release);
pixel->dirtyRegion = QRegion(QRect(QPoint(0, 0), size));
able->dPtr->mPixelRenderVersion = version;
}
void Plot::finishIndependentRender(RenderAble* able) {
QRegion updateRegion = able->dPtr->publishRenderPixel();
void Plot::finish_independent_render(RenderAble* able) {
QRegion updateRegion = able->dPtr->publish_render_pixel();
able->dPtr->mIndependentRenderQueued.store(false, std::memory_order_release);
if(!updateRegion.isEmpty()) requestUpdate(updateRegion);
if(able->dPtr->hasNewPixelState()) submitIndependentRender(able, Render_Request_Source::Finish);
if(!updateRegion.isEmpty()) request_update(updateRegion);
if(able->dPtr->has_new_pixel_state()) submit_independent_render(able, Render_Request_Source::Finish);
}
void Plot::scheduleRenderTimer() {
void Plot::schedule_render_timer() {
if(d->mDestroying.load(std::memory_order_acquire) || !d->mRenderTimer || !d->mRenderEnabled.load(std::memory_order_acquire)) return;
int interval = std::max(1, qRound(1000.0 / (double)d->mRefreshTimesPreSecond));
d->mRenderTimer->expires_after(std::chrono::milliseconds(interval));
@@ -602,30 +602,30 @@ namespace YSG {
privateData->mActiveRenderTasks.fetch_add(1, std::memory_order_acq_rel);
d->mRenderTimer->async_wait([this, privateData](const asio::error_code& error) {
if(!error && !d->mDestroying.load(std::memory_order_acquire)) {
if(d->mShower) d->mShower->incrementCounter("Pipeline", "timerTick");
onRenderRequest(Render_Request_Source::Timer);
scheduleRenderTimer();
if(d->mShower) d->mShower->increment_counter("Pipeline", "timerTick");
on_render_request(Render_Request_Source::Timer);
schedule_render_timer();
}
notifyRenderTaskDone(privateData);
notify_render_task_done(privateData);
});
}
void Plot::markRenderStateDirty() {
void Plot::mark_render_state_dirty() {
if(d->mDestroying.load(std::memory_order_acquire)) return;
d->mPipeline.markEditState();
requestRender();
d->mPipeline.mark_edit_state();
request_render();
}
void Plot::requestRender(Render_Request_Source source) {
void Plot::request_render(Render_Request_Source source) {
if(d->mDestroying.load(std::memory_order_acquire)) return;
d->mLastRequestNs.store(steadyNowNs(), std::memory_order_release);
d->mLastRequestNs.store(steady_now_ns(), std::memory_order_release);
PlotPrivate* privateData = d;
privateData->mActiveRenderTasks.fetch_add(1, std::memory_order_acq_rel);
Global::instance()->renderScheduler().post([this, privateData, source]() {
if(!d->mDestroying.load(std::memory_order_acquire)) onRenderRequest(source);
notifyRenderTaskDone(privateData);
if(!d->mDestroying.load(std::memory_order_acquire)) on_render_request(source);
notify_render_task_done(privateData);
});
}
void Plot::requestUpdate(const QRegion& region) {
d->mLastUpdateRequestNs.store(steadyNowNs(), std::memory_order_release);
void Plot::request_update(const QRegion& region) {
d->mLastUpdateRequestNs.store(steady_now_ns(), std::memory_order_release);
QTimer::singleShot(0, this, [this, region]() {
if(d->mDestroying.load(std::memory_order_acquire)) return;
if(region.isEmpty()) update();
@@ -633,11 +633,11 @@ namespace YSG {
});
}
QColor Plot::backgroundColor() {
QColor Plot::background_color() {
return d->mBackground;
}
void Plot::setBackgroundColor(const QColor& color) const {
void Plot::set_background_color(const QColor& color) const {
d->mBackground = color;
}
@@ -653,12 +653,12 @@ namespace YSG {
privateData->mActiveRenderTasks.fetch_add(1, std::memory_order_acq_rel);
Global::instance()->renderScheduler().post([privateData, renderSize]() {
if(!privateData->mDestroying.load(std::memory_order_acquire)) privateData->mRenderSize = renderSize;
notifyRenderTaskDone(privateData);
notify_render_task_done(privateData);
});
if(mFirstResize) {
for(Layer* layer : mLayerList) {
for(RenderAble* able : layer->mRenderAbles) {
able->firstResizeEvent(e);
able->first_resize_event(e);
}
}
}
@@ -668,15 +668,15 @@ namespace YSG {
}
}
if(mFirstResize) mFirstResize = false;
markRenderStateDirty();
mark_render_state_dirty();
break;
}
case QEvent::Show: {
startRender();
start_render();
break;
}
case QEvent::Hide: {
pauseRender();
pause_render();
break;
}
case QEvent::Enter: {
@@ -685,7 +685,7 @@ namespace YSG {
case QEvent::Leave: {
for(Layer* layer : mLayerList) {
for(RenderAble* able : layer->mRenderAbles) {
able->setHoverState(QPoint(), false);
able->set_hover_state(QPoint(), false);
}
}
break;
@@ -703,8 +703,8 @@ namespace YSG {
auto e = reinterpret_cast<QMouseEvent*>(event);
for(Layer* layer : mLayerList) {
for(RenderAble* able : layer->mRenderAbles) {
bool selected = able->selectTest(e->pos());
able->setHoverState(e->pos(), selected);
bool selected = able->select_test(e->pos());
able->set_hover_state(e->pos(), selected);
if(selected) {
able->mouseMoveEvent(e);
}
@@ -716,7 +716,7 @@ namespace YSG {
auto e = reinterpret_cast<QMouseEvent*>(event);
for(Layer* layer : mLayerList) {
for(RenderAble* able : layer->mRenderAbles) {
if(able->selectTest(e->pos())) {
if(able->select_test(e->pos())) {
able->mousePressEvent(e);
}
}
@@ -727,7 +727,7 @@ namespace YSG {
auto e = reinterpret_cast<QMouseEvent*>(event);
for(Layer* layer : mLayerList) {
for(RenderAble* able : layer->mRenderAbles) {
if(able->selectTest(e->pos())) {
if(able->select_test(e->pos())) {
able->mouseReleaseEvent(e);
}
}
@@ -756,7 +756,7 @@ namespace YSG {
}
for(Layer* layer : mLayerList) {
for(RenderAble* able : layer->mRenderAbles) {
able->plotEvent(event);
able->plot_event(event);
}
}
return ret;