106 lines
3.4 KiB
C++
106 lines
3.4 KiB
C++
#pragma once
|
||
|
||
|
||
#include <QTime>
|
||
#include "../RenderAble.h"
|
||
|
||
|
||
|
||
|
||
namespace YSG {
|
||
void LIB_DECL startAllRenderThread();
|
||
class TimerThread;
|
||
struct PlotPrivate;
|
||
// 此锁用于锁住从mSet里第一个元素,到最后一个元素的渲染过程 用于时间同步
|
||
// mSet 里的元素修改前 加上此锁,可保证 所有的这个元素组数据同步
|
||
class LIB_DECL PrePareMutiDataMutex {
|
||
public:
|
||
SpinLock mRangeLock;
|
||
QSet<RenderAble*> mSet;
|
||
QVector<RenderAble*> mList;
|
||
// lock,unlock都只在Plot渲染函数render里调用 一个线程,所以不用加锁
|
||
std::chrono::system_clock::time_point start;
|
||
void lock(RenderAble* a) {
|
||
if(mList.empty()) {
|
||
mRangeLock.lock();
|
||
start = std::chrono::system_clock::now();
|
||
//qDebug() << "lock " << QTime::currentTime().toString("ss:zzz");
|
||
mList.reserve(mSet.size());
|
||
for(RenderAble* that : mSet) {
|
||
mList.append(that);
|
||
}
|
||
}
|
||
mList.removeOne(a);
|
||
}
|
||
void unlock() {
|
||
if(mList.empty()) {
|
||
//qDebug() << "unlock " << QTime::currentTime().toString("ss:zzz");
|
||
mRangeLock.unlock();
|
||
double duration = std::chrono::duration<double>(std::chrono::system_clock::now() - start).count() * 1000;
|
||
//qDebug() << "duration == " << duration;
|
||
}
|
||
}
|
||
};
|
||
|
||
class PerformanceShower;
|
||
class LIB_DECL Plot : public QWidget {
|
||
Q_OBJECT
|
||
public:
|
||
bool usePerformanceShower();
|
||
void set_usePerformanceShower(bool use);
|
||
|
||
void bindRenderThread(const QString& threadName);
|
||
virtual void init() {
|
||
initLayer();
|
||
}
|
||
void render();
|
||
QColor backgroundColor();
|
||
bool mFirstResize = true, mFirstPrepareData = true;
|
||
void setBackgroundColor(const QColor& color) const;
|
||
void markRenderStateDirty();
|
||
void requestRender();
|
||
struct Layer {
|
||
QString mLayerName;
|
||
QVector<RenderAble*> mRenderAbles;
|
||
};
|
||
QString mObjectName;
|
||
QList<Layer*> mLayerList;
|
||
QString mDefaultLayerName;
|
||
virtual void initLayer() {
|
||
auto addLayer = [this](QString&& name) {
|
||
auto layer = new Layer;
|
||
layer->mLayerName = name;
|
||
mLayerList.append(layer);
|
||
mLayerMap[name] = layer;
|
||
};
|
||
addLayer("background");
|
||
addLayer("plottable");
|
||
addLayer("axis");
|
||
addLayer("legend");
|
||
mDefaultLayerName = "plottable";
|
||
}
|
||
bool isRendering();
|
||
void startRender(int refreshTimesPreSecond);
|
||
void startRender() const;
|
||
void pauseRender() const;
|
||
QVector<PrePareMutiDataMutex*> mMutiSpinLock;
|
||
Plot();
|
||
~Plot() override;
|
||
PlotPrivate *d{};
|
||
private:
|
||
QHash<QString, Layer*> mLayerMap;
|
||
bool event(QEvent* event) final;
|
||
void paintEvent(QPaintEvent* event) final;
|
||
void scheduleRenderTimer();
|
||
void submitRender();
|
||
void finishRender();
|
||
void requestUpdate(const QRegion& region);
|
||
void renderColor(RenderAble::ColorBuffer* color, QSize size, QColor background, std::uint64_t version);
|
||
friend class TimerThread;
|
||
friend struct RenderAble;
|
||
};
|
||
|
||
|
||
|
||
}
|