Files
Renderive/YSGraphic_Core/RenderAble.cpp
T
2026-07-23 11:39:46 +08:00

262 lines
9.5 KiB
C++

#include "RenderAble.h"
#include <QDir>
#include "base/Plot.h"
#include "Axis/AbsAxis.h"
#include "plottable/HoverInfo.h"
#include "psc_global_include/export.h"
#include "psc_global_include/Fail_Fast.h"
namespace YSG {
QDebug operator<<(QDebug debug, const Range& range) {
QDebugStateSaver saver(debug); // 保存当前的 qDebug 状态
debug.nospace() << "Range(" << range.lower << ", " << range.upper << ")";
return debug;
}
void SpinLock::lock() {
while (flag.test_and_set(std::memory_order_acquire)) {}
}
bool SpinLock::tryLock() {
return !flag.test_and_set(std::memory_order_acquire);
}
bool SpinLock::tryLock(int durationMillis) {
if (durationMillis == 0) {
return tryLock();
}
auto duration = std::chrono::milliseconds(durationMillis);
auto start = std::chrono::steady_clock::now();
while (std::chrono::steady_clock::now() - start < duration) {
if (tryLock()) {
return true;
}
}
return false;
}
void SpinLock::unlock() {
flag.clear(std::memory_order_release);
}
SpinLockGuard::~SpinLockGuard() {
if (mLock) mLock->unlock();
}
SpinLockGuard::SpinLockGuard(SpinLock *lock) : mLock(lock) {
if (mLock) mLock->lock();
}
RenderAble::RenderPipeline::RenderPipeline() {
colorControl.reset();
}
void RenderAble::RenderPipeline::markEditState() {
editStateVersion.fetch_add(1, std::memory_order_release);
}
bool RenderAble::RenderPipeline::hasNewState() const {
return RenderAble::version_newer(editStateVersion.load(std::memory_order_acquire), renderStateVersion);
}
RenderAble::ColorBuffer* RenderAble::RenderPipeline::colorByIndex(std::uint8_t index) {
return &colorBuffers[index];
}
RenderAble::ColorBuffer* RenderAble::RenderPipeline::colorByRole(std::uint8_t role) {
return colorByIndex(colorControl.read_view()[role]);
}
RenderAble::ColorBufferLease RenderAble::RenderPipeline::waitRenderColor() {
auto lease = colorControl.wait_mark_use_role(Color_Render);
return {colorByIndex(lease.index), lease};
}
RenderAble::ColorBufferLease RenderAble::RenderPipeline::tryFrontColor() {
auto record = colorControl.try_mark_use_role(Color_Front);
if(record.result != Triple_Buffer_Result::Success) {
return {};
}
return {colorByIndex(record.lease.index), record.lease};
}
void RenderAble::RenderPipeline::unmarkColor(ColorBufferLease lease) {
colorControl.unmark_use(lease.lease);
}
QRegion RenderAble::RenderPipeline::publishRenderColor() {
colorControl.wait_swap_role(Color_Ready, Color_Render, [this](const Triple_Buffer_View& view) {
auto render = colorByIndex(view[Color_Render]);
auto ready = colorByIndex(view[Color_Ready]);
return RenderAble::version_newer(render->version.load(std::memory_order_acquire), ready->version.load(std::memory_order_acquire));
});
auto view = colorControl.read_view();
auto ready = colorByIndex(view[Color_Ready]);
auto front = colorByIndex(view[Color_Front]);
if(RenderAble::version_newer(ready->version.load(std::memory_order_acquire), front->version.load(std::memory_order_acquire)) && !paintRequestPending.exchange(true, std::memory_order_acq_rel)) {
return ready->dirtyRegion;
}
return {};
}
RenderAble::ColorBufferLease RenderAble::RenderPipeline::consumeReadyColor() {
colorControl.try_swap_role(Color_Front, Color_Ready, [this](const Triple_Buffer_View& view) {
auto ready = colorByIndex(view[Color_Ready]);
auto front = colorByIndex(view[Color_Front]);
return RenderAble::version_newer(ready->version.load(std::memory_order_acquire), front->version.load(std::memory_order_acquire));
});
paintRequestPending.store(false, std::memory_order_release);
return tryFrontColor();
}
RenderEditGuard::RenderEditGuard(RenderData* data) : mData(data) {
}
RenderEditGuard::~RenderEditGuard() {
if(mData && mData->qPtr) mData->qPtr->markStateDirty();
}
RenderInputGuard::RenderInputGuard(RenderData* data) : mData(data) {
}
RenderInputGuard::~RenderInputGuard() {
if(mData) mData->markInputDirty();
}
void RenderData::markInputDirty() {
InputBufferSlot& slot = inputSlot(Input_Edit);
slot.version = ++mInputVersion;
slot.pending = true;
if(qPtr) qPtr->markRenderDirty();
}
void RenderAble::init(Plot* plot, QString layerName) {
if(layerName.isEmpty()) {
layerName = plot->mDefaultLayerName;
}
plot->mLayerMap[layerName]->mRenderAbles.append(this);
mPlot = plot;
if(!dPtr) dPtr = createRenderData();
dPtr->clearStateBuffers();
dPtr->clearInputBuffers();
dPtr->mStateBuffers[State_Edit] = createRenderState();
dPtr->mStateBuffers[State_Ready] = createRenderState();
dPtr->mStateBuffers[State_Render] = createRenderState();
dPtr->mInputBuffers[Input_Edit].data = createInputData();
dPtr->mInputBuffers[Input_Ready].data = createInputData();
dPtr->mInputBuffers[Input_Render].data = createInputData();
for(RenderState* state : dPtr->mStateBuffers) {
state->dPtr = dPtr;
}
dPtr->qPtr = this;
dPtr->mStateBuffers[State_Edit]->version = 1;
if(mPlot) mPlot->markRenderStateDirty();
}
void RenderAble::markStateDirty() {
if(dPtr) ++dPtr->state(State_Edit)->version;
markRenderDirty();
}
void RenderAble::markRenderDirty() {
if(mPlot) mPlot->markRenderStateDirty();
}
bool RenderAble::ok() const {
return dPtr->mRenderStart && mPlot && !mPlot->mFirstResize && !mPlot->mFirstPrepareData;
}
RenderAble::~RenderAble(){
}
bool RenderAble::dectCycleRely() {
QQueue<RenderAble*> queue;
queue.enqueue(this);
while (!queue.isEmpty()) {
RenderAble* current = queue.dequeue();
QSet<RenderAble*> visited;
QSet<RenderAble*> recursionStack;
QVector<RenderAble*> path;
bool has = hasCycleRely(current, visited, recursionStack, path);
if(has){
return true;
}
}
qDebug() << this << " 检测成功!";
return false;
}
bool RenderAble::hasCycleRely(RenderAble* node, QSet<RenderAble*>& visited, QSet<RenderAble*>& recursionStack,
QVector<RenderAble*>& currentPath) {
if (!node) return false;
if (recursionStack.contains(node)) {
// 节点已经在当前递归路径中,检测到循环
qDebug() << "Cycle detected in path:";
// 打印循环依赖链
for (RenderAble* n : currentPath) {
qDebug() << n->mObjectName << "(" << n << ")->";
}
qDebug() << node; // 打印形成循环的节点
return true;
}
if (visited.contains(node)) {
// 节点已经被处理过,无需再次处理
return false;
}
// 标记当前节点为已访问
visited.insert(node);
// 将当前节点标记为递归路径中的节点
recursionStack.insert(node);
// 记录当前节点在路径中
currentPath.append(node);
// 递归检查所有子节点
for (RenderAble* child : node->mBeRelyList) {
if (hasCycleRely(child, visited, recursionStack, currentPath)) {
return true;
}
}
// 从递归路径中移除当前节点
recursionStack.remove(node);
// 从路径中移除当前节点
currentPath.removeLast();
return false;
}
QVector<QRgb> getTurboColorGradient() {
QVector<QRgb> colors;
// std::cout << "11111111111111111111111111111111111111" << std::endl;
// for (auto s : QDir(":/").entryList())
// {
// std::cout << "QDir=============" << s.toStdString() << std::endl;
// }
//
// std::cout << "11111111111111111111111111111111111111" << std::endl;
//
QFile file(":/turbo.colorMap");
if (!file.open(QIODevice::ReadOnly)) {
std::ostringstream oss;
oss << file.errorString().toStdString() << " getTurboColorGradient2: Failed to open file" << LOG_POS_SIMPLE << std::endl;
Psc::fail_fast(oss.str());
return colors; // 返回一个空的 std::vector
}
QByteArray fileData = file.readAll();
file.close();
// 检查文件内容
if (fileData.size() != 768) {
qDebug() << "getTurboColorGradient2: File size is not as expected (768 bytes), got" << fileData.size();
return colors; // 返回一个空的 std::vector
}
// 确保每个颜色有 3 个字节 (RGB),总共有 256 个颜色
colors.reserve(256);
for (int i = 0; i < 256; ++i) {
uchar r = fileData[i * 3];
uchar g = fileData[i * 3 + 1];
uchar b = fileData[i * 3 + 2];
colors.push_back(qRgb(r, g, b));
}
return colors;
}
SRC RenderState::src() {
auto view = dPtr->mStateControl.read_view();
for(std::uint8_t role = State_Edit; role <= State_Render; ++role) {
if(dPtr->mStateBuffers[view[role]] == this) return static_cast<SRC>(role);
}
return SRC::Edit;
}
}