Added enabling/disabling rendering on enter to foreground/background

This commit is contained in:
r.kuznetsov 2015-03-13 17:05:15 +03:00
parent bb5b8d39a3
commit 6896b7d19a
16 changed files with 163 additions and 37 deletions

View file

@ -138,10 +138,15 @@ BackendRenderer::Routine::Routine(BackendRenderer & renderer) : m_renderer(rende
void BackendRenderer::Routine::Do()
{
m_renderer.m_contextFactory->getResourcesUploadContext()->makeCurrent();
GLFunctions::Init();
m_renderer.InitGLDependentResource();
while (!IsCancelled())
{
m_renderer.ProcessSingleMessage();
m_renderer.CheckRenderingEnabled();
}
m_renderer.ReleaseResources();
}

View file

@ -1,6 +1,6 @@
#pragma once
#include "drape_frontend/message_acceptor.hpp"
#include "drape_frontend/base_renderer.hpp"
#include "drape_frontend/engine_context.hpp"
#include "drape_frontend/viewport.hpp"
#include "drape_frontend/map_data_provider.hpp"
@ -26,7 +26,7 @@ class ThreadsCommutator;
class BatchersPool;
class ReadManager;
class BackendRenderer : public MessageAcceptor
class BackendRenderer : public BaseRenderer
{
public:
BackendRenderer(dp::RefPointer<ThreadsCommutator> commutator,

View file

@ -0,0 +1,65 @@
#include "base_renderer.hpp"
#include "../std/utility.hpp"
namespace df
{
BaseRenderer::BaseRenderer()
: m_isEnabled(true)
, m_renderingEnablingCompletionHandler(nullptr)
, m_wasNotified(false)
{
}
void BaseRenderer::SetRenderingEnabled(bool const isEnabled, completion_handler_t completionHandler)
{
if (isEnabled == m_isEnabled)
{
if (completionHandler != nullptr) completionHandler();
return;
}
m_renderingEnablingCompletionHandler = move(completionHandler);
if (isEnabled)
{
// wake up rendering thread
unique_lock<mutex> lock(m_renderingEnablingMutex);
m_wasNotified = true;
m_renderingEnablingCondition.notify_one();
}
else
{
// here we set up value only if rendering disabled
m_isEnabled = false;
// if renderer thread is waiting for message let it go
CancelMessageWaiting();
}
}
void BaseRenderer::CheckRenderingEnabled()
{
if (!m_isEnabled)
{
// nofity initiator-thread about rendering disabling
if (m_renderingEnablingCompletionHandler != nullptr)
m_renderingEnablingCompletionHandler();
// wait for signal
unique_lock<mutex> lock(m_renderingEnablingMutex);
while(!m_wasNotified)
{
m_renderingEnablingCondition.wait(lock);
}
// here rendering is enabled again
m_wasNotified = false;
m_isEnabled = true;
// nofity initiator-thread about rendering enabling
if (m_renderingEnablingCompletionHandler != nullptr)
m_renderingEnablingCompletionHandler();
}
}
} // namespace df

View file

@ -0,0 +1,32 @@
#pragma once
#include "message_acceptor.hpp"
#include "../std/condition_variable.hpp"
#include "../std/mutex.hpp"
#include "../std/atomic.hpp"
#include "../std/function.hpp"
namespace df
{
class BaseRenderer : public MessageAcceptor
{
public:
using completion_handler_t = function<void()>;
BaseRenderer();
void SetRenderingEnabled(bool const isEnabled, completion_handler_t completionHandler);
protected:
void CheckRenderingEnabled();
private:
mutex m_renderingEnablingMutex;
condition_variable m_renderingEnablingCondition;
atomic<bool> m_isEnabled;
completion_handler_t m_renderingEnablingCompletionHandler;
bool m_wasNotified;
};
} // namespace df

View file

@ -8,6 +8,8 @@
#include "drape/texture_manager.hpp"
#include "std/bind.hpp"
#include "std/condition_variable.hpp"
#include "std/mutex.hpp"
namespace df
{
@ -94,8 +96,32 @@ void DrapeEngine::UpdateUserMarksLayer(TileKey const & tileKey, UserMarksProvide
void DrapeEngine::SetRenderingEnabled(bool const isEnabled)
{
m_threadCommutator->PostMessageBroadcast(dp::MovePointer<Message>(new RenderingEnabledMessage(isEnabled)),
MessagePriority::High);
SetRenderingEnabled(m_frontend.GetRefPointer(), isEnabled);
SetRenderingEnabled(m_backend.GetRefPointer(), isEnabled);
LOG(LDEBUG, (isEnabled ? "Rendering enabled" : "Rendering disabled"));
}
void DrapeEngine::SetRenderingEnabled(dp::RefPointer<BaseRenderer> renderer, bool const isEnabled)
{
// here we have to wait for finishing of message processing
mutex completionMutex;
condition_variable completionCondition;
bool notified = false;
auto completionHandler = [&]()
{
unique_lock<mutex> lock(completionMutex);
notified = true;
completionCondition.notify_one();
};
renderer->SetRenderingEnabled(isEnabled, completionHandler);
unique_lock<mutex> lock(completionMutex);
while (!notified) // loop to avoid spurious wakeups
{
completionCondition.wait(lock);
}
}
} // namespace df

View file

@ -43,6 +43,8 @@ private:
dp::MasterPointer<dp::TextureManager> m_textureManager;
Viewport m_viewport;
void SetRenderingEnabled(dp::RefPointer<BaseRenderer> renderer, bool const isEnabled);
};
} // namespace df

View file

@ -39,6 +39,7 @@ SOURCES += \
map_data_provider.cpp \
user_mark_shapes.cpp \
user_marks_provider.cpp \
base_renderer.cpp
HEADERS += \
engine_context.hpp \
@ -76,3 +77,4 @@ HEADERS += \
map_data_provider.hpp \
user_mark_shapes.hpp \
user_marks_provider.hpp \
base_renderer.hpp

View file

@ -41,7 +41,6 @@ FrontendRenderer::FrontendRenderer(dp::RefPointer<ThreadsCommutator> commutator,
, m_textureManager(textureManager)
, m_gpuProgramManager(new dp::GpuProgramManager())
, m_viewport(viewport)
, m_isEnabled(true)
{
#ifdef DRAW_INFO
m_tpf = 0,0;
@ -446,6 +445,8 @@ void FrontendRenderer::Routine::Do()
context->present();
timer.Reset();
CheckRenderingEnabled();
}
m_renderer.ReleaseResources();

View file

@ -3,12 +3,12 @@
#include "base/thread.hpp"
#ifdef DRAW_INFO
#include "../base/timer.hpp"
#include "../std/vector.hpp"
#include "../std/numeric.hpp"
#include "base/timer.hpp"
#include "std/vector.hpp"
#include "std/numeric.hpp"
#endif
#include "drape_frontend/message_acceptor.hpp"
#include "drape_frontend/base_renderer.hpp"
#include "drape_frontend/threads_commutator.hpp"
#include "drape_frontend/tile_info.hpp"
#include "drape_frontend/backend_renderer.hpp"
@ -33,7 +33,10 @@ namespace dp { class RenderBucket; }
namespace df
{
class FrontendRenderer : public MessageAcceptor
struct RenderingEnablingContext;
class FrontendRenderer : public BaseRenderer
{
public:
FrontendRenderer(dp::RefPointer<ThreadsCommutator> commutator,
@ -112,8 +115,6 @@ private:
set<TileKey> m_tiles;
dp::OverlayTree m_overlayTree;
bool m_isEnabled;
};
} // namespace df

View file

@ -27,4 +27,9 @@ void MessageAcceptor::CloseQueue()
m_messageQueue.ClearQuery();
}
void MessageAcceptor::CancelMessageWaiting()
{
m_messageQueue.CancelWait();
}
} // namespace df

View file

@ -15,10 +15,15 @@ public:
virtual ~MessageAcceptor() {}
protected:
virtual ~MessageAcceptor(){}
virtual void AcceptMessage(dp::RefPointer<Message> message) = 0;
/// Must be called by subclass on message target thread
void ProcessSingleMessage(unsigned maxTimeWait = -1);
void CancelMessageWaiting();
void CloseQueue();
private:

View file

@ -16,7 +16,7 @@ class MessageQueue
public:
~MessageQueue();
/// if queue is empty than return NULL
/// if queue is empty then return NULL
dp::TransferPointer<Message> PopMessage(unsigned maxTimeWait);
void PushMessage(dp::TransferPointer<Message> message, MessagePriority priority);
void CancelWait();

View file

@ -10,13 +10,13 @@
#include "geometry/rect2d.hpp"
#include "geometry/screenbase.hpp"
#include "drape/glstate.hpp"
#include "drape/pointers.hpp"
#include "drape/render_bucket.hpp"
#include "std/shared_ptr.hpp"
#include "std/set.hpp"
#include "std/function.hpp"
namespace df
{
@ -237,18 +237,4 @@ private:
dp::TransferPointer<gui::LayerRenderer> m_renderer;
};
class RenderingEnabledMessage : public Message
{
public:
RenderingEnabledMessage(bool const isEnabled)
: m_isEnabled(isEnabled) {}
Type GetType() const override { return Message::RenderingEnabled; }
bool isSuspended() const { return m_isEnabled; }
private:
bool m_isEnabled;
};
} // namespace df

View file

@ -20,13 +20,5 @@ void ThreadsCommutator::PostMessage(ThreadName name, dp::TransferPointer<Message
it->second->PostMessage(message, priority);
}
void ThreadsCommutator::PostMessageBroadcast(dp::TransferPointer<Message> message, MessagePriority priority)
{
for (auto it = m_acceptors.cbegin(); it != m_acceptors.cend(); ++it)
{
it->second->PostMessage(message, priority);
}
}
} // namespace df

View file

@ -21,7 +21,6 @@ public:
void RegisterThread(ThreadName name, MessageAcceptor *acceptor);
void PostMessage(ThreadName name, dp::TransferPointer<Message> message, MessagePriority priority);
void PostMessageBroadcast(dp::TransferPointer<Message> message, MessagePriority priority);
private:
typedef map<ThreadName, MessageAcceptor *> acceptors_map_t;

View file

@ -897,11 +897,16 @@ void Framework::EnterBackground()
#ifndef OMIM_OS_ANDROID
ClearAllCaches();
#endif
if (!m_drapeEngine.IsNull())
m_drapeEngine->SetRenderingEnabled(false);
}
void Framework::EnterForeground()
{
m_startForegroundTime = my::Timer::LocalTime();
if (!m_drapeEngine.IsNull())
m_drapeEngine->SetRenderingEnabled(true);
}
void Framework::ShowAll()