diff --git a/drape_frontend/drape_frontend.pro b/drape_frontend/drape_frontend.pro index 6e400125df..c9aa75cd93 100644 --- a/drape_frontend/drape_frontend.pro +++ b/drape_frontend/drape_frontend.pro @@ -16,7 +16,8 @@ SOURCES += \ message_acceptor.cpp \ impl/backend_renderer_impl.cpp \ read_mwm_task.cpp \ - batchers_pool.cpp + batchers_pool.cpp \ + frontend_renderer.cpp HEADERS += \ backend_renderer.hpp \ @@ -32,4 +33,5 @@ HEADERS += \ read_mwm_task.hpp \ message_subclasses.hpp \ map_shape.hpp \ - batchers_pool.hpp + batchers_pool.hpp \ + frontend_renderer.hpp diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp new file mode 100644 index 0000000000..26da40129e --- /dev/null +++ b/drape_frontend/frontend_renderer.cpp @@ -0,0 +1,115 @@ +#include "frontend_renderer.hpp" + +#include "../base/assert.hpp" +#include "../base/stl_add.hpp" + +#include "message_subclasses.hpp" +#include "render_thread.hpp" + +#include "../std/bind.hpp" + +namespace df +{ + FrontendRenderer::FrontendRenderer(RefPointer commutator) + : m_commutator(commutator) + , m_gpuProgramManager(new GpuProgramManager()) + { + StartThread(); + } + + FrontendRenderer::~FrontendRenderer() + { + StopThread(); + } + + void FrontendRenderer::AcceptMessage(RefPointer message) + { + switch (message->GetType()) + { + case Message::FlushTile: + { + FlushTileMessage * msg = static_cast(message.GetRaw()); + const GLState & state = msg->GetState(); + const TileKey & key = msg->GetKey(); + MasterPointer buffer(msg->GetBuffer()); + render_data_t::iterator renderIterator = m_renderData.insert(make_pair(state, buffer)); + m_tileData.insert(make_pair(key, renderIterator)); + break; + } + case Message::DropTile: + { + DropTileMessage * msg = static_cast(message.GetRaw()); + const TileKey & key = msg->GetKey(); + tile_data_range_t range = m_tileData.equal_range(key); + for (tile_data_iter eraseIter = range.first; eraseIter != range.second; ++eraseIter) + { + eraseIter->second->second.Destroy(); + m_renderData.erase(eraseIter->second); + } + m_tileData.erase(range.first, range.second); + break; + } + case Message::DropCoverage: + DeleteRenderData(); + break; + default: + ASSERT(false, ()); + } + } + + namespace + { + void render_part(RefPointer manager , pair > & node) + { + ApplyState(node.first, manager->GetProgram(node.first.GetProgramIndex())); + node.second->Render(); + } + } + + void FrontendRenderer::RenderScene() + { + for_each(m_renderData.begin(), m_renderData.end(), bind(&render_part, m_gpuProgramManager.GetRefPointer(), _1)); + } + + void FrontendRenderer::StartThread() + { + m_selfThread.Create(this); + } + + void FrontendRenderer::StopThread() + { + IRoutine::Cancel(); + CloseQueue(); + m_selfThread.Join(); + } + + void FrontendRenderer::ThreadMain() + { + InitRenderThread(); + + while (!IsCancelled()) + { + ProcessSingleMessage(false); + RenderScene(); + } + + ReleaseResources(); + } + + void FrontendRenderer::ReleaseResources() + { + DeleteRenderData(); + m_gpuProgramManager.Destroy(); + } + + void FrontendRenderer::Do() + { + ThreadMain(); + } + + void FrontendRenderer::DeleteRenderData() + { + m_tileData.clear(); + GetRangeDeletor(m_renderData, MasterPointerDeleter())(); + } +} diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp new file mode 100644 index 0000000000..a89f7516cb --- /dev/null +++ b/drape_frontend/frontend_renderer.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include "../base/thread.hpp" + +#include "message_acceptor.hpp" +#include "threads_commutator.hpp" +#include "tile_info.hpp" +#include "backend_renderer.hpp" + +#include "../drape/pointers.hpp" +#include "../drape/glstate.hpp" +#include "../drape/vertex_array_buffer.hpp" +#include "../drape/gpu_program_manager.hpp" + +#include "../std/map.hpp" + +namespace df +{ + class FrontendRenderer : public MessageAcceptor, + public threads::IRoutine + { + public: + FrontendRenderer(RefPointer commutator); + ~FrontendRenderer(); + + protected: + virtual void AcceptMessage(RefPointer message); + + private: + void RenderScene(); + + private: + void StartThread(); + void StopThread(); + void ThreadMain(); + void ReleaseResources(); + + virtual void Do(); + + private: + void DeleteRenderData(); + + private: + RefPointer m_commutator; + MasterPointer m_gpuProgramManager; + threads::Thread m_selfThread; + + private: + typedef multimap > render_data_t; + typedef render_data_t render_data_iter; + typedef multimap tile_data_t; + typedef tile_data_t::iterator tile_data_iter; + typedef pair tile_data_range_t; + render_data_t m_renderData; + tile_data_t m_tileData; + }; +} diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index 4b22bcd3b5..6da06a3d70 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -69,7 +69,6 @@ namespace df const GLState & GetState() const { return m_state; } TransferPointer & GetBuffer(); - private: GLState m_state; TransferPointer m_buffer;