From 6c41378b9fdeec2f98d129ff8c118a70170f8e29 Mon Sep 17 00:00:00 2001 From: Renato Machado Date: Tue, 21 Nov 2023 20:56:21 -0300 Subject: [PATCH] fix crash with framebuffer inside another framebuffer --- src/framework/graphics/drawpool.cpp | 11 +++++------ src/framework/graphics/drawpool.h | 1 + src/framework/graphics/framebuffermanager.cpp | 18 +++++++++++------- src/framework/graphics/framebuffermanager.h | 4 +--- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/framework/graphics/drawpool.cpp b/src/framework/graphics/drawpool.cpp index f8a5c23816..d5ec1749dc 100644 --- a/src/framework/graphics/drawpool.cpp +++ b/src/framework/graphics/drawpool.cpp @@ -32,6 +32,7 @@ DrawPool* DrawPool::create(const DrawPoolType type) if (type == DrawPoolType::MAP) { pool->m_framebuffer->m_useAlphaWriting = false; pool->m_framebuffer->disableBlend(); + pool->m_bindedFramebuffers = 0; // forces to use only framebuffer without smoothing. } else if (type == DrawPoolType::FOREGROUND) { pool->setFPS(FPS10); } @@ -363,11 +364,10 @@ void DrawPool::addAction(const std::function& action) void DrawPool::bindFrameBuffer(const Size& size) { - const uint8_t frameIndex = m_type == DrawPoolType::MAP ? 0 : 1; - + ++m_bindedFramebuffers; m_oldState = std::move(m_state); m_state = {}; - addAction([size, frameIndex, drawState = m_state] { + addAction([size, frameIndex = m_bindedFramebuffers, drawState = m_state] { drawState.execute(); const auto& frame = g_framebuffers.getTemporaryFrameBuffer(frameIndex); frame->resize(size); @@ -376,14 +376,13 @@ void DrawPool::bindFrameBuffer(const Size& size) } void DrawPool::releaseFrameBuffer(const Rect& dest) { - const uint8_t frameIndex = m_type == DrawPoolType::MAP ? 0 : 1; - m_state = std::move(m_oldState); - addAction([dest, frameIndex, drawState = m_state] { + addAction([dest, frameIndex = m_bindedFramebuffers, drawState = m_state] { const auto& frame = g_framebuffers.getTemporaryFrameBuffer(frameIndex); frame->release(); drawState.execute(); frame->draw(dest); }); if (hasFrameBuffer() && !dest.isNull()) stdext::hash_union(m_status.second, dest.hash()); + --m_bindedFramebuffers; } \ No newline at end of file diff --git a/src/framework/graphics/drawpool.h b/src/framework/graphics/drawpool.h index 3de84471f2..4db27acebb 100644 --- a/src/framework/graphics/drawpool.h +++ b/src/framework/graphics/drawpool.h @@ -228,6 +228,7 @@ class DrawPool bool m_enabled{ true }; bool m_alwaysGroupDrawings{ false }; + int8_t m_bindedFramebuffers{ -1 }; uint8_t m_depthLevel{ 0 }; uint16_t m_refreshDelay{ 0 }, m_shaderRefreshDelay{ 0 }; diff --git a/src/framework/graphics/framebuffermanager.cpp b/src/framework/graphics/framebuffermanager.cpp index f63f96bce6..60555cd1ad 100644 --- a/src/framework/graphics/framebuffermanager.cpp +++ b/src/framework/graphics/framebuffermanager.cpp @@ -27,15 +27,19 @@ FrameBufferManager g_framebuffers; void FrameBufferManager::init() { - m_temporaryFramebuffer.reserve(2); - for (uint_fast8_t i = 0; i < 2; ++i) { - const auto& frame = m_temporaryFramebuffer.emplace_back(std::make_shared()); - if (i == 0) { - frame->setSmooth(false); - } - }; + m_temporaryFramebuffer.emplace_back(std::make_shared()); } void FrameBufferManager::terminate() { m_temporaryFramebuffer.clear(); +} + +const FrameBufferPtr& FrameBufferManager::getTemporaryFrameBuffer(const uint8_t index) { + if (index < m_temporaryFramebuffer.size()) { + return m_temporaryFramebuffer[index]; + } + + const auto& tempfb = m_temporaryFramebuffer.emplace_back(std::make_shared()); + tempfb->setSmooth(false); + return tempfb; } \ No newline at end of file diff --git a/src/framework/graphics/framebuffermanager.h b/src/framework/graphics/framebuffermanager.h index 0e710429b2..d49864b8c1 100644 --- a/src/framework/graphics/framebuffermanager.h +++ b/src/framework/graphics/framebuffermanager.h @@ -30,9 +30,7 @@ class FrameBufferManager void init(); void terminate(); - const FrameBufferPtr& getTemporaryFrameBuffer(const uint8_t index) const { - return m_temporaryFramebuffer[index]; - } + const FrameBufferPtr& getTemporaryFrameBuffer(const uint8_t index); protected: std::vector m_temporaryFramebuffer;