From 404c904f48473df7d55084795e9348b0b375b155 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Mon, 16 Mar 2015 17:18:51 +0300 Subject: [PATCH] Added synchronous stopping of render threads --- drape_frontend/backend_renderer.cpp | 8 ++++++-- drape_frontend/base_renderer.cpp | 25 ++++++++++++++++++------- drape_frontend/base_renderer.hpp | 9 ++++++--- drape_frontend/frontend_renderer.cpp | 10 +++++++--- drape_frontend/message.hpp | 3 ++- drape_frontend/message_subclasses.hpp | 7 +++++++ 6 files changed, 46 insertions(+), 16 deletions(-) diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index 86fe0f9730..222fbf17d1 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -22,13 +22,12 @@ BackendRenderer::BackendRenderer(dp::RefPointer commutator, dp::RefPointer oglcontextfactory, dp::RefPointer textureManager, MapDataProvider const & model) - : BaseRenderer(commutator, oglcontextfactory) + : BaseRenderer(ThreadsCommutator::ResourceUploadThread, commutator, oglcontextfactory) , m_model(model) , m_engineContext(commutator) , m_texturesManager(textureManager) , m_guiCacher("default") { - m_commutator->RegisterThread(ThreadsCommutator::ResourceUploadThread, this); m_batchersPool.Reset(new BatchersPool(ReadManager::ReadCount(), bind(&BackendRenderer::FlushGeometry, this, _1))); m_readManager.Reset(new ReadManager(m_engineContext, m_model)); @@ -99,6 +98,11 @@ void BackendRenderer::AcceptMessage(dp::RefPointer message) m_batchersPool->ReleaseBatcher(key); break; } + case Message::StopRendering: + { + ProcessStopRenderingMessage(); + break; + } default: ASSERT(false, ()); break; diff --git a/drape_frontend/base_renderer.cpp b/drape_frontend/base_renderer.cpp index 2d1517f590..771f065c7b 100644 --- a/drape_frontend/base_renderer.cpp +++ b/drape_frontend/base_renderer.cpp @@ -1,21 +1,21 @@ #include "base_renderer.hpp" -#include "threads_commutator.hpp" +#include "message_subclasses.hpp" #include "../std/utility.hpp" -#include "../base/logging.hpp" - - namespace df { -BaseRenderer::BaseRenderer(dp::RefPointer commutator, +BaseRenderer::BaseRenderer(ThreadsCommutator::ThreadName name, + dp::RefPointer commutator, dp::RefPointer oglcontextfactory) : m_commutator(commutator) , m_contextFactory(oglcontextfactory) + , m_threadName(name) , m_isEnabled(true) , m_renderingEnablingCompletionHandler(nullptr) , m_wasNotified(false) { + m_commutator->RegisterThread(m_threadName, this); } void BaseRenderer::StartThread() @@ -25,13 +25,18 @@ void BaseRenderer::StartThread() void BaseRenderer::StopThread() { - IRoutine::Cancel(); + // send message to stop rendering in render thread + m_commutator->PostMessage(m_threadName, + dp::MovePointer(new StopRenderingMessage()), + MessagePriority::High); + // wake up render thread if necessary if (!m_isEnabled) { WakeUp(); } - CloseQueue(); + + // wait for render thread completion m_selfThread.Join(); } @@ -116,4 +121,10 @@ void BaseRenderer::WakeUp() m_renderingEnablingCondition.notify_one(); } +void BaseRenderer::ProcessStopRenderingMessage() +{ + CloseQueue(); + IRoutine::Cancel(); +} + } // namespace df diff --git a/drape_frontend/base_renderer.hpp b/drape_frontend/base_renderer.hpp index 94b3fc8cb1..f2079f2c73 100644 --- a/drape_frontend/base_renderer.hpp +++ b/drape_frontend/base_renderer.hpp @@ -1,6 +1,7 @@ #pragma once #include "message_acceptor.hpp" +#include "threads_commutator.hpp" #include "../base/thread.hpp" #include "../drape/oglcontextfactory.hpp" @@ -12,15 +13,14 @@ namespace df { -class ThreadsCommutator; - class BaseRenderer : public MessageAcceptor, public threads::IRoutine { public: using TCompletionHandler = function; - BaseRenderer(dp::RefPointer commutator, + BaseRenderer(ThreadsCommutator::ThreadName name, + dp::RefPointer commutator, dp::RefPointer oglcontextfactory); void SetRenderingEnabled(bool const isEnabled); @@ -32,10 +32,13 @@ protected: void StartThread(); void StopThread(); + void CheckRenderingEnabled(); + void ProcessStopRenderingMessage(); private: threads::Thread m_selfThread; + ThreadsCommutator::ThreadName m_threadName; mutex m_renderingEnablingMutex; condition_variable m_renderingEnablingCondition; diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 215674bdce..aaf04967de 100644 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -36,7 +36,7 @@ FrontendRenderer::FrontendRenderer(dp::RefPointer commutator, dp::RefPointer oglcontextfactory, dp::RefPointer textureManager, Viewport viewport) - : BaseRenderer(commutator, oglcontextfactory) + : BaseRenderer(ThreadsCommutator::RenderThread, commutator, oglcontextfactory) , m_textureManager(textureManager) , m_gpuProgramManager(new dp::GpuProgramManager()) , m_viewport(viewport) @@ -46,10 +46,9 @@ FrontendRenderer::FrontendRenderer(dp::RefPointer commutator, m_fps = 0.0; #endif - m_commutator->RegisterThread(ThreadsCommutator::RenderThread, this); - RefreshProjection(); RefreshModelView(); + StartThread(); } @@ -221,6 +220,11 @@ void FrontendRenderer::AcceptMessage(dp::RefPointer message) m_guiRenderer->Build(m_gpuProgramManager.GetRefPointer()); break; } + case Message::StopRendering: + { + ProcessStopRenderingMessage(); + break; + } default: ASSERT(false, ()); } diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp index cbd3744ca8..b4e8c20d66 100644 --- a/drape_frontend/message.hpp +++ b/drape_frontend/message.hpp @@ -21,7 +21,8 @@ public: ClearUserMarkLayer, ChangeUserMarkLayerVisibility, UpdateUserMarkLayer, - GuiLayerRecached + GuiLayerRecached, + StopRendering }; virtual ~Message() {} diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index 63d83fc35b..a754ca2c74 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -242,4 +242,11 @@ private: dp::TransferPointer m_renderer; }; +class StopRenderingMessage : public Message +{ +public: + StopRenderingMessage(){} + Type GetType() const override { return Message::StopRendering; } +}; + } // namespace df