协程架构重构成功, 下一步准备指针交换 无锁化重构

This commit is contained in:
2026-07-23 08:51:05 +08:00
parent 8c8cc8707b
commit c3e96d2f86
13 changed files with 475 additions and 230 deletions
+115 -45
View File
@@ -1,6 +1,8 @@
#include "Plot_p.h"
#include "PerformanceShower_p.h"
#include "Global.h"
#include <algorithm>
#include <chrono>
namespace YSG {
class PrePareMutiDataMutexGuard {
@@ -31,7 +33,9 @@ namespace YSG {
g->mTimerThreadMap[threadName] = newThread;
newThread->setObjectName(threadName);
}
g->mTimerThreadMap[threadName]->mPlots.append(this);
TimerThread* thread = g->mTimerThreadMap[threadName];
thread->mPlots.append(this);
d->mTimerThread = thread;
}
Plot::Plot(){
@@ -57,12 +61,12 @@ namespace YSG {
}
Plot::~Plot() {
delete d->mRenderBuffer;
pauseRender();
delete d;
}
bool Plot::isRendering() {
if(!d->mTimer) return false;
return d->mTimer->isActive();
return d->mRenderEnabled;
}
void Plot::startRender(int refreshTimesPreSecond) {
@@ -71,36 +75,57 @@ namespace YSG {
}
void Plot::startRender() const {
if(d->mTimer) QMetaObject::invokeMethod(d->mTimer, "start", Qt::AutoConnection, Q_ARG(int, qRound(1000.0 / (double) d->mRefreshTimesPreSecond)));
d->mRenderEnabled = true;
if(!d->mTimerThread) return;
Plot* self = const_cast<Plot*>(this);
d->mTimerThread->post([self]() {
PlotPrivate* d = self->d;
if(d->mRenderTimer) {
d->mRenderTimer->cancel();
self->scheduleRenderTimer();
}
self->submitRender();
});
}
void Plot::pauseRender() const {
if(d->mTimer) QMetaObject::invokeMethod(d->mTimer, "stop", Qt::AutoConnection);
d->mRenderEnabled = false;
if(!d->mTimerThread) return;
Plot* self = const_cast<Plot*>(this);
d->mTimerThread->post([self]() {
PlotPrivate* d = self->d;
if(d->mRenderTimer) {
d->mRenderTimer->cancel();
}
});
}
void Plot::paintEvent(QPaintEvent* event) {
SpinLockGuard guard(&d->mBufferLock);
Q_UNUSED(event)
QPainter painter(this);
painter.drawPixmap(QPoint(0, 0), d->mPaintBuffer);
//painter.drawImage(QPoint(0, 0), d->mPaintBuffer);
RenderAble::ColorBuffer* color = d->mPipeline.consumeReadyColor();
if(color && !color->image.isNull()) painter.drawImage(QPoint(0, 0), color->image);
else painter.fillRect(rect(), d->mBackground);
painter.end();
if(d->mShower) d->mShower->counterIncrease("plot paint");
d->mPlotState.storeRelease(PlotPrivate::NeedToRender);
}
void Plot::render() {
if (mFirstResize) return;
if (d->mPlotState.loadAcquire() != PlotPrivate::NeedToRender) return;
if(!d->mRenderBuffer) return;
SpinLockGuard renderGuard(&d->mRenderLock);
if(d->mRenderBuffer->isNull()) return;
submitRender();
}
void Plot::submitRender() {
if(mFirstResize) return;
if(!d->mRenderEnabled) return;
QSize renderSize = d->mRenderSize;
if(renderSize.width() <= 0 || renderSize.height() <= 0) return;
RenderAble::RenderPipeline& pipeline = d->mPipeline;
if(pipeline.jobState != RenderAble::JobState::Idle) return;
if(!pipeline.hasNewState()) return;
pipeline.jobState = RenderAble::JobState::Queued;
pipeline.renderStateVersion = pipeline.editStateVersion.load(std::memory_order_acquire);
if(d->mShower) {
d->mShower->counterIncrease("渲染帧率");
d->mShower->mInfos["interval"] = QString("渲染:%1, global%2").arg(d->mTimer->interval()).arg(Global::instance()->mInterval);
d->mShower->mInfos["interval"] = QString("渲染:%1, global%2").arg(qRound(1000.0 / (double)d->mRefreshTimesPreSecond)).arg(Global::instance()->mInterval);
}
Cacl renderData("整体渲染耗时: %1 avg: %2", d->mShower);
QPainter painter(d->mRenderBuffer);
painter.fillRect(rect(), d->mBackground);
{
Cacl prepareData("准备数据耗时: %1 avg: %2", d->mShower);
SpinLockGuard prepareDataLock(&d->mPrepareDataLock);
@@ -125,10 +150,46 @@ namespace YSG {
}
if(mFirstPrepareData) mFirstPrepareData = false;
}
for(Layer* layer : mLayerList) {
for(RenderAble* able : layer->mRenderAbles) {
able->mPrepared = false;
}
}
RenderAble::ColorBuffer* color = pipeline.currentRenderColor();
QColor background = d->mBackground;
std::uint64_t version = pipeline.renderStateVersion;
TimerThread* thread = d->mTimerThread;
pipeline.jobState = RenderAble::JobState::Running;
if(thread) {
thread->postCpu([this, color, renderSize, background, version, thread]() {
renderColor(color, renderSize, background, version);
thread->post([this]() {
finishRender();
});
});
} else {
renderColor(color, renderSize, background, version);
finishRender();
}
}
void Plot::finishRender() {
RenderAble::RenderPipeline& pipeline = d->mPipeline;
QRegion updateRegion = pipeline.publishRenderColor();
pipeline.jobState = RenderAble::JobState::Idle;
if(!updateRegion.isEmpty()) requestUpdate(updateRegion);
if(d->mShower) d->mShower->refresh();
if(pipeline.hasNewState()) submitRender();
}
void Plot::renderColor(RenderAble::ColorBuffer* color, QSize size, QColor background, std::uint64_t version) {
Cacl renderData("整体渲染耗时: %1 avg: %2", d->mShower);
if(color->image.size() != size || color->image.format() != QImage::Format_ARGB32) {
color->image = QImage(size, QImage::Format_ARGB32);
}
color->image.detach();
color->image.fill(background);
QPainter painter(&color->image);
{
Cacl prepareData("draw耗时: %1 avg: %2", d->mShower);
Cacl drawData("draw耗时: %1 avg: %2", d->mShower);
for(Layer* layer : mLayerList) {
for(RenderAble* cur : layer->mRenderAbles) {
if(!cur->mVisable) continue;
@@ -136,23 +197,35 @@ namespace YSG {
}
}
}
{
SpinLockGuard bufferGuard(&d->mBufferLock);
// d->mPaintBuffer = *d->mRenderBuffer;
d->mPaintBuffer = QPixmap::fromImage(*d->mRenderBuffer);
d->mPlotState.storeRelease(PlotPrivate::NeedToPaint);
}
for(Layer* layer : mLayerList) {
for(RenderAble* able : layer->mRenderAbles) {
able->mPrepared = false;
}
}
if(d->mShower) {
d->mShower->refresh();
}
painter.end();
color->version = version;
color->dirtyRegion = QRegion(QRect(QPoint(0, 0), size));
}
void Plot::scheduleRenderTimer() {
if(!d->mRenderTimer || !d->mRenderEnabled) return;
int interval = std::max(1, qRound(1000.0 / (double)d->mRefreshTimesPreSecond));
d->mRenderTimer->expires_after(std::chrono::milliseconds(interval));
d->mRenderTimer->async_wait([this](const asio::error_code& error) {
if(error) return;
submitRender();
scheduleRenderTimer();
});
}
void Plot::markRenderStateDirty() {
d->mPipeline.markEditState();
requestRender();
}
void Plot::requestRender() {
if(!d->mTimerThread) return;
d->mTimerThread->post([this]() {
submitRender();
});
}
void Plot::requestUpdate(const QRegion& region) {
QTimer::singleShot(0, this, [this, region]() {
if(region.isEmpty()) update();
else update(region);
});
}
QColor Plot::backgroundColor() {
@@ -169,12 +242,8 @@ namespace YSG {
case QEvent::Resize: {
auto e = reinterpret_cast<QResizeEvent*>(event);
{
//qDebug() << resizeEvent->size();
SpinLockGuard guard(&d->mRenderLock);
delete d->mRenderBuffer;
//d->mRenderBuffer = new QPixmap(e->size());
d->mRenderBuffer = new QImage(e->size().width(), e->size().height(), QImage::Format_ARGB32);
d->mRenderSize = e->size();
if(mFirstResize) {
for(Layer* layer : mLayerList) {
for(RenderAble* able : layer->mRenderAbles) {
@@ -189,6 +258,7 @@ namespace YSG {
}
if(mFirstResize) mFirstResize = false;
}
markRenderStateDirty();
break;
}
case QEvent::Show: {