From 3b009921ae5de2e8047904c25e671dee33deafa4 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Wed, 22 Apr 2015 14:21:12 +0300 Subject: [PATCH] Added stop rendering on FR while user is inactive --- drape_frontend/frontend_renderer.cpp | 43 +++++++++++++++++++--------- drape_frontend/frontend_renderer.hpp | 2 +- drape_frontend/message_acceptor.cpp | 18 ++++++++++++ drape_frontend/message_acceptor.hpp | 7 +++++ drape_frontend/message_queue.cpp | 6 ++++ drape_frontend/message_queue.hpp | 1 + 6 files changed, 62 insertions(+), 15 deletions(-) diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 5184793150..9a4b34787d 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -458,23 +458,31 @@ void FrontendRenderer::Routine::Do() context->setDefaultFramebuffer(); m_renderer.m_textureManager->UpdateDynamicTextures(); m_renderer.RenderScene(); - m_renderer.UpdateScene(); + bool const viewChanged = m_renderer.UpdateScene(); + context->present(); - double availableTime = VSyncInterval - (timer.ElapsedSeconds() /*+ avarageMessageTime*/); - - if (availableTime < 0.0) - availableTime = 0.01; - - while (availableTime > 0) + if (!viewChanged && m_renderer.IsQueueEmpty()) { - m_renderer.ProcessSingleMessage(availableTime * 1000.0); - availableTime = VSyncInterval - (timer.ElapsedSeconds() /*+ avarageMessageTime*/); - //messageCount++; + // process a message or wait for a message + m_renderer.ProcessSingleMessage(); + } + else + { + double availableTime = VSyncInterval - (timer.ElapsedSeconds() /*+ avarageMessageTime*/); + + if (availableTime < 0.0) + availableTime = 0.01; + + while (availableTime > 0) + { + m_renderer.ProcessSingleMessage(availableTime * 1000.0); + availableTime = VSyncInterval - (timer.ElapsedSeconds() /*+ avarageMessageTime*/); + //messageCount++; + } + + //processingTime = (timer.ElapsedSeconds() - processingTime) / messageCount; } - //processingTime = (timer.ElapsedSeconds() - processingTime) / messageCount; - - context->present(); timer.Reset(); m_renderer.CheckRenderingEnabled(); @@ -499,9 +507,14 @@ void FrontendRenderer::SetModelView(ScreenBase const & screen) { lock_guard lock(m_modelViewMutex); m_newView = screen; + + // check if view changed and cancel endless message waiting + bool const viewChanged = (m_view != m_newView); + if (viewChanged && IsInInfinityWaiting()) + CancelMessageWaiting(); } -void FrontendRenderer::UpdateScene() +bool FrontendRenderer::UpdateScene() { lock_guard lock(m_modelViewMutex); if (m_view != m_newView) @@ -516,7 +529,9 @@ void FrontendRenderer::UpdateScene() m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(m_view, move(tiles)), MessagePriority::Normal); + return true; } + return false; } } // namespace df diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 74f9ff4c72..4c76a18cd9 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -89,7 +89,7 @@ private: private: // it applies new model-view matrix to the scene (this matrix will be used on next frame) - void UpdateScene(); + bool UpdateScene(); void AddToRenderGroup(vector> & groups, dp::GLState const & state, diff --git a/drape_frontend/message_acceptor.cpp b/drape_frontend/message_acceptor.cpp index 09996d8aa1..adc5df902d 100644 --- a/drape_frontend/message_acceptor.cpp +++ b/drape_frontend/message_acceptor.cpp @@ -5,9 +5,17 @@ namespace df { +MessageAcceptor::MessageAcceptor() + : m_infinityWaiting(false) +{ +} + void MessageAcceptor::ProcessSingleMessage(unsigned maxTimeWait) { + m_infinityWaiting = (maxTimeWait == -1); drape_ptr message = m_messageQueue.PopMessage(maxTimeWait); + m_infinityWaiting = false; + if (message == nullptr) return; @@ -31,4 +39,14 @@ void MessageAcceptor::CancelMessageWaiting() m_messageQueue.CancelWait(); } +bool MessageAcceptor::IsInInfinityWaiting() const +{ + return m_infinityWaiting; +} + +bool MessageAcceptor::IsQueueEmpty() +{ + return m_messageQueue.IsEmpty(); +} + } // namespace df diff --git a/drape_frontend/message_acceptor.hpp b/drape_frontend/message_acceptor.hpp index 621055e0d3..06b10f551e 100644 --- a/drape_frontend/message_acceptor.hpp +++ b/drape_frontend/message_acceptor.hpp @@ -4,6 +4,8 @@ #include "drape/pointers.hpp" +#include "std/atomic.hpp" + namespace df { @@ -12,6 +14,7 @@ class Message; class MessageAcceptor { protected: + MessageAcceptor(); virtual ~MessageAcceptor(){} virtual void AcceptMessage(ref_ptr message) = 0; @@ -24,6 +27,9 @@ protected: void CloseQueue(); + bool IsInInfinityWaiting() const; + bool IsQueueEmpty(); + private: friend class ThreadsCommutator; @@ -31,6 +37,7 @@ private: private: MessageQueue m_messageQueue; + atomic m_infinityWaiting; }; } // namespace df diff --git a/drape_frontend/message_queue.cpp b/drape_frontend/message_queue.cpp index 8f68a2bc0f..b1033c695b 100644 --- a/drape_frontend/message_queue.cpp +++ b/drape_frontend/message_queue.cpp @@ -53,6 +53,12 @@ void MessageQueue::PushMessage(drape_ptr && message, MessagePriority pr guard.Signal(); } +bool MessageQueue::IsEmpty() +{ + threads::ConditionGuard guard(m_condition); + return m_messages.empty(); +} + void MessageQueue::WaitMessage(unsigned maxTimeWait) { if (m_messages.empty()) diff --git a/drape_frontend/message_queue.hpp b/drape_frontend/message_queue.hpp index e6029ed655..2c8884f529 100644 --- a/drape_frontend/message_queue.hpp +++ b/drape_frontend/message_queue.hpp @@ -21,6 +21,7 @@ public: void PushMessage(drape_ptr && message, MessagePriority priority); void CancelWait(); void ClearQuery(); + bool IsEmpty(); private: void WaitMessage(unsigned maxTimeWait);