Files
Renderive/YSGraphic_Core/base/Plot.cpp
T
2026-06-16 13:33:27 +08:00

280 lines
9.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "Plot_p.h"
#include "PerformanceShower_p.h"
#include "Global.h"
namespace YSG {
class PrePareMutiDataMutexGuard {
public:
QVector<PrePareMutiDataMutex*> 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<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);
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<QWheelEvent*>(event);
for(Layer* layer : mLayerList) {
for(RenderAble* able : layer->mRenderAbles) {
able->wheelEvent(e);
}
}
}
case QEvent::MouseMove: {
auto e = reinterpret_cast<QMouseEvent*>(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<QMouseEvent*>(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<QMouseEvent*>(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<QKeyEvent*>(event);
for(Layer* layer : mLayerList) {
for(RenderAble* able : layer->mRenderAbles) {
able->keyPressEvent(e);
}
}
break;
}
case QEvent::KeyRelease: {
auto e = reinterpret_cast<QKeyEvent*>(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;
}
}