#include "Plot_p.h" #include "PerformanceShower_p.h" #include "Global.h" namespace YSG { class PrePareMutiDataMutexGuard { public: QVector mLockList; PrePareMutiDataMutexGuard(RenderAble* renderAble, Plot* plot) { for(PrePareMutiDataMutex* curLock : plot->mMutiSpinLock) { if(curLock->mSet.contains(renderAble)) { mLockList.append(curLock); } } for(PrePareMutiDataMutex* curLock : mLockList) curLock->lock(renderAble); } ~PrePareMutiDataMutexGuard() { for(PrePareMutiDataMutex* curLock : mLockList) curLock->unlock(); } }; void startAllRenderThread() { Global::instance()->startAllTimeThread(); } void Plot::bindRenderThread(const QString& threadName) { auto g = Global::instance(); if (!g->mTimerThreadMap.contains(threadName)) { auto newThread = new TimerThread; g->mTimerThreadMap[threadName] = newThread; newThread->setObjectName(threadName); } g->mTimerThreadMap[threadName]->mPlots.append(this); } Plot::Plot(){ d = new PlotPrivate(this); setAttribute(Qt::WA_OpaquePaintEvent, true); setFocusPolicy(Qt::NoFocus); } bool Plot::usePerformanceShower() { return d->mShower; } void Plot::set_usePerformanceShower(bool use) { SpinLockGuard g(&d->mRenderLock); if(!use) { PerformanceShower* t = d->mShower; d->mShower = nullptr; delete t; } else { if(d->mShower) return; d->mShower = new PerformanceShower(this); d->mShower->show(); } } Plot::~Plot() { delete d->mRenderBuffer; } bool Plot::isRendering() { if(!d->mTimer) return false; return d->mTimer->isActive(); } void Plot::startRender(int refreshTimesPreSecond) { d->mRefreshTimesPreSecond = refreshTimesPreSecond; startRender(); } void Plot::startRender() const { if(d->mTimer) QMetaObject::invokeMethod(d->mTimer, "start", Qt::AutoConnection, Q_ARG(int, qRound(1000.0 / (double) d->mRefreshTimesPreSecond))); } void Plot::pauseRender() const { if(d->mTimer) QMetaObject::invokeMethod(d->mTimer, "stop", Qt::AutoConnection); } void Plot::paintEvent(QPaintEvent* event) { SpinLockGuard guard(&d->mBufferLock); QPainter painter(this); painter.drawPixmap(QPoint(0, 0), d->mPaintBuffer); //painter.drawImage(QPoint(0, 0), d->mPaintBuffer); 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; if(d->mShower) { d->mShower->counterIncrease("渲染帧率"); d->mShower->mInfos["interval"] = QString("渲染:%1, global:%2").arg(d->mTimer->interval()).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); for(Layer* layer : mLayerList) { for(RenderAble *cur : layer->mRenderAbles) { //qDebug() << "info: "<< layer->mLayerName << " " << cur->mObjectName; for(auto rely : cur->mBeRelyList) { if(!rely->mPrepared){ PrePareMutiDataMutexGuard _guard(rely, this); // qDebug() << cur->mObjectName << "rely: " << mObjectName; rely->prepareData(); rely->mPrepared = true; } } if(!cur->mPrepared){ PrePareMutiDataMutexGuard _guard(cur, this); cur->prepareData(); //qDebug() << cur->mObjectName << " prepareData"; cur->mPrepared = true; } } } if(mFirstPrepareData) mFirstPrepareData = false; } { Cacl prepareData("draw耗时: %1 avg: %2", d->mShower); for(Layer* layer : mLayerList) { for(RenderAble* cur : layer->mRenderAbles) { if(!cur->mVisable) continue; cur->draw(&painter); } } } { 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(); } } QColor Plot::backgroundColor() { return d->mBackground; } void Plot::setBackgroundColor(const QColor& color) const { d->mBackground = color; } bool Plot::event(QEvent* event) { bool ret = QWidget::event(event); switch (event->type()){ case QEvent::Resize: { auto e = reinterpret_cast(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); if(mFirstResize) { for(Layer* layer : mLayerList) { for(RenderAble* able : layer->mRenderAbles) { able->firstResizeEvent(e); } } } for(Layer* layer : mLayerList) { for(RenderAble* able : layer->mRenderAbles) { able->resizeEvent(e); } } if(mFirstResize) mFirstResize = false; } break; } case QEvent::Show: { startRender(); break; } case QEvent::Hide: { pauseRender(); break; } case QEvent::Enter: { break; } case QEvent::Leave: { break; } case QEvent::Wheel: { auto e = reinterpret_cast(event); for(Layer* layer : mLayerList) { for(RenderAble* able : layer->mRenderAbles) { able->wheelEvent(e); } } } case QEvent::MouseMove: { auto e = reinterpret_cast(event); for(Layer* layer : mLayerList) { for(RenderAble* able : layer->mRenderAbles) { if(able->selectTest(e->pos())) { able->mouseMoveEvent(e); } } } break; } case QEvent::MouseButtonPress: { auto e = reinterpret_cast(event); for(Layer* layer : mLayerList) { for(RenderAble* able : layer->mRenderAbles) { if(able->selectTest(e->pos())) { able->mousePressEvent(e); } } } break; } case QEvent::MouseButtonRelease: { auto e = reinterpret_cast(event); for(Layer* layer : mLayerList) { for(RenderAble* able : layer->mRenderAbles) { if(able->selectTest(e->pos())) { able->mouseReleaseEvent(e); } } } break; } case QEvent::KeyPress: { auto e = reinterpret_cast(event); for(Layer* layer : mLayerList) { for(RenderAble* able : layer->mRenderAbles) { able->keyPressEvent(e); } } break; } case QEvent::KeyRelease: { auto e = reinterpret_cast(event); for(Layer* layer : mLayerList) { for(RenderAble* able : layer->mRenderAbles) { able->keyReleaseEvent(e); } } break; } default: break; } for(Layer* layer : mLayerList) { for(RenderAble* able : layer->mRenderAbles) { able->plotEvent(event); } } return ret; } }