#include "Renderable.h" #include #include "base/Plot.h" #include "Axis/Abs_Axis.h" #include "plottable/Hover_Info.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; } Renderable::Render_Pipeline::Render_Pipeline() { colorControl.set_stats(&colorBufferStats); colorControl.reset(); } void Renderable::Render_Pipeline::mark_edit_state() { editStateVersion.fetch_add(1, std::memory_order_release); } bool Renderable::Render_Pipeline::has_new_state() const { return Renderable::version_newer(editStateVersion.load(std::memory_order_acquire), renderStateVersion); } Renderable::Color_Buffer* Renderable::Render_Pipeline::color_by_index(std::uint8_t index) { return &colorBuffers[index]; } Renderable::Color_Buffer* Renderable::Render_Pipeline::color_by_role(std::uint8_t role) { return color_by_index(colorControl.read_view()[role]); } Renderable::Color_Buffer_Lease Renderable::Render_Pipeline::wait_render_color() { auto lease = colorControl.wait_mark_use_role(Color_Render); return {color_by_index(lease.index), lease}; } Renderable::Color_Buffer_Lease Renderable::Render_Pipeline::wait_front_color() { auto lease = colorControl.wait_mark_use_role(Color_Front); return {color_by_index(lease.index), lease}; } Renderable::Color_Buffer_Lease Renderable::Render_Pipeline::try_front_color() { auto record = colorControl.try_mark_use_role(Color_Front); if (record.result != Triple_Buffer_Result::Success) { return {}; } return {color_by_index(record.lease.index), record.lease}; } void Renderable::Render_Pipeline::unmark_color(Color_Buffer_Lease lease) { colorControl.unmark_use(lease.lease); } Plot_Buffer_Acquire_Mode Renderable::buffer_acquire_mode() const { return dPtr->buffer_acquire_mode(); } void Renderable::set_buffer_acquire_mode(Plot_Buffer_Acquire_Mode mode) { dPtr->set_buffer_acquire_mode(mode); } RenderAble_Render_Schedule_Mode Renderable::render_schedule_mode() const { return dPtr->render_schedule_mode(); } void Renderable::set_render_schedule_mode(RenderAble_Render_Schedule_Mode mode) { dPtr->set_render_schedule_mode(mode); } double Renderable::render_schedule_max_fps() const { return dPtr->render_schedule_max_fps(); } void Renderable::set_render_schedule_max_fps(double fps) { dPtr->set_render_schedule_max_fps(fps); } bool Renderable::independent_pixel_cache() const { return dPtr->independent_pixel_cache(); } void Renderable::set_independent_pixel_cache(bool enabled) { dPtr->set_independent_pixel_cache(enabled); } QRegion Renderable::Render_Pipeline::publish_render_color() { colorControl.wait_swap_role(Color_Ready, Color_Render, [this](const Triple_Buffer_View& view) { auto render = color_by_index(view[Color_Render]); auto ready = color_by_index(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 = color_by_index(view[Color_Ready]); auto front = color_by_index(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::Color_Buffer_Lease Renderable::Render_Pipeline::consume_ready_color(Triple_Buffer_Mode mode) { auto canSwap = [this](const Triple_Buffer_View& view) { auto ready = color_by_index(view[Color_Ready]); auto front = color_by_index(view[Color_Front]); return Renderable::version_newer(ready->version.load(std::memory_order_acquire), front->version.load(std::memory_order_acquire)); }; if (mode == Triple_Buffer_Mode::Wait) { colorControl.wait_swap_role(Color_Front, Color_Ready, canSwap); } else { colorControl.try_swap_role(Color_Front, Color_Ready, canSwap); } paintRequestPending.store(false, std::memory_order_release); if (mode == Triple_Buffer_Mode::Wait) { return wait_front_color(); } return try_front_color(); } Render_Edit_Guard::Render_Edit_Guard(Render_Data* data, Triple_Buffer_Lease lease) : mData(data), mLease(lease) {} Render_Edit_Guard::~Render_Edit_Guard() { if (!mData) return; ++mData->state_by_index(mLease.index)->version; if (mData->qPtr) mData->qPtr->mark_render_dirty(); mData->unmark_state(mLease); } Render_Input_Guard::Render_Input_Guard(Render_Data* data, Triple_Buffer_Lease lease) : mData(data), mLease(lease) {} Render_Input_Guard::~Render_Input_Guard() { if (!mData) return; mData->mark_input_dirty(mLease); mData->mInputControl.unmark_use(mLease); } void Render_Data::mark_input_dirty(Triple_Buffer_Lease lease, bool notifyRender) { Input_Buffer_Slot& slot = input_slot_by_index(lease.index); slot.version = ++mInputVersion; slot.pending = true; if (notifyRender && qPtr) qPtr->mark_render_dirty(); } void Renderable::init(Plot* plot, QString layerName) { if (layerName.isEmpty()) { layerName = plot->default_layer_name; } plot->mLayerMap[layerName]->renderable_list.append(this); mPlot = plot; if (!dPtr) dPtr = create_render_data(); dPtr->set_buffer_acquire_mode(plot->render_able_buffer_acquire_mode()); dPtr->clear_state_buffers(); dPtr->clear_input_buffers(); dPtr->mStateBuffers[State_Edit] = create_render_state(); dPtr->mStateBuffers[State_Ready] = create_render_state(); dPtr->mStateBuffers[State_Render] = create_render_state(); dPtr->mInputBuffers[Input_Edit].data = create_input_data(); dPtr->mInputBuffers[Input_Ready].data = create_input_data(); dPtr->mInputBuffers[Input_Render].data = create_input_data(); for (Render_State* state : dPtr->mStateBuffers) { state->dPtr = dPtr; } dPtr->qPtr = this; dPtr->mStateBuffers[State_Edit]->version = 1; if (mPlot) mPlot->mark_render_state_dirty(); } void Renderable::mark_state_dirty() { if (dPtr) { auto lease = dPtr->mStateControl.wait_mark_use_role(State_Edit); ++dPtr->state_by_index(lease.index)->version; dPtr->mStateControl.unmark_use(lease); } mark_render_dirty(); } void Renderable::mark_render_dirty() { if (!mPlot) return; if (dPtr&& dPtr->independent_pixel_cache()) { dPtr->mark_pixel_dirty(); mPlot->mark_independent_render_dirty(this); return; } mPlot->mark_render_state_dirty(); } bool Renderable::ok() const { return dPtr->mRenderStart && mPlot && !mPlot->first_resize && !mPlot->first_prepare_data; } Renderable::~Renderable() {} bool Renderable::dect_cycle_rely() { QQueue queue; queue.enqueue(this); while (!queue.isEmpty()) { Renderable* current = queue.dequeue(); QSet visited; QSet recursionStack; QVector path; bool has = has_cycle_rely(current, visited, recursionStack, path); if (has) { return true; } } qDebug() << this << " 检测成功!"; return false; } bool Renderable::has_cycle_rely(Renderable* node, QSet& visited, QSet& recursionStack, QVector& 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 (has_cycle_rely(child, visited, recursionStack, currentPath)) { return true; } } // 从递归路径中移除当前节点 recursionStack.remove(node); // 从路径中移除当前节点 currentPath.removeLast(); return false; } QVector get_turbo_color_gradient() { QVector 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 Render_State::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(role); } return SRC::Edit; } }