[drape, MAP-29] Remove BackendRendererImpl.

This commit is contained in:
Dmitry Kunin 2014-01-13 14:30:14 +03:00 committed by Alex Zolotarev
parent cea8e3a8f4
commit 403a2974b4
6 changed files with 299 additions and 362 deletions

View file

@ -1,35 +1,250 @@
#include "backend_renderer.hpp"
#include "threads_commutator.hpp"
#include "tile_info.hpp"
#include "memory_feature_index.hpp"
#include "read_mwm_task.hpp"
#include "message.hpp"
#include "message_subclasses.hpp"
#include "impl/backend_renderer_impl.hpp"
#include "map_shape.hpp"
#include "../geometry/screenbase.hpp"
#include "../base/buffer_vector.hpp"
#include "../base/object_tracker.hpp"
#include "../base/stl_add.hpp"
#include "../std/bind.hpp"
namespace
{
void PostFinishTask(RefPointer<df::ThreadsCommutator> commutator, threads::IRoutine * routine)
{
commutator->PostMessage(df::ThreadsCommutator::ResourceUploadThread, MovePointer<df::Message>(new df::TaskFinishMessage(routine)));
}
struct CoverageCellComparer
{
bool operator()(df::ReadMWMTask const * task, df::TileKey const & tileKey) const
{
return task->GetTileInfo().m_key < tileKey;
}
bool operator()(df::TileKey const & tileKey, df::ReadMWMTask const * task) const
{
return tileKey < task->GetTileInfo().m_key;
}
};
}
namespace df
{
BackendRenderer::BackendRenderer(RefPointer<ThreadsCommutator> commutator,
RefPointer<OGLContextFactory> oglcontextfactory,
double visualScale,
int surfaceWidth,
int surfaceHeight)
: m_commutator(commutator)
RefPointer<OGLContextFactory> oglcontextfactory,
double visualScale,
int surfaceWidth,
int surfaceHeight)
: m_engineContext(commutator)
, m_commutator(commutator)
, m_contextFactory(oglcontextfactory)
{
m_impl.Reset(new BackendRendererImpl(m_commutator, oglcontextfactory, visualScale, surfaceWidth, surfaceHeight));
m_scaleProcessor.SetParams(visualScale, ScalesProcessor::CalculateTileSize(surfaceWidth, surfaceHeight));
m_currentViewport.SetFromRect(m2::AnyRectD(m_scaleProcessor.GetWorldRect()));
m_commutator->RegisterThread(ThreadsCommutator::ResourceUploadThread, this);
int readerCount = max(1, GetPlatform().CpuCores() - 2);
m_threadPool.Reset(new threads::ThreadPool(readerCount, bind(&PostFinishTask, commutator, _1)));
m_batchersPool.Reset(new BatchersPool(readerCount, bind(&BackendRenderer::PostToRenderThreads, this, _1)));
StartThread();
}
BackendRenderer::~BackendRenderer()
{
m_impl.Destroy();
StopThread();
}
void BackendRenderer::OnResize(int x0, int y0, int w, int h)
{
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
MovePointer<Message>(new ResizeMessage(x0, y0, w, h)));
}
void BackendRenderer::UpdateCoverage(const ScreenBase & screen)
{
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, MovePointer<Message>(new UpdateCoverageMessage(screen)));
m_tiler.seed(screen, screen.GlobalRect().GlobalCenter(), m_scaleProcessor.GetTileSize());
vector<Tiler::RectInfo> tiles;
m_tiler.tiles(tiles, 1);
if (!m_currentViewport.GlobalRect().IsIntersect(screen.GlobalRect()) ||
m_scaleProcessor.GetTileScaleBase(m_currentViewport) != m_scaleProcessor.GetTileScaleBase(screen))
{
typedef set<ReadMWMTask *>::iterator index_iter;
for (index_iter it = m_taskIndex.begin(); it != m_taskIndex.end(); ++it)
CancelTask(*it, false, false);
m_taskIndex.clear();
PostToRenderThreads(MovePointer<Message>(new DropCoverageMessage()));
for (size_t i = 0; i < tiles.size(); ++i)
{
const Tiler::RectInfo & info = tiles[i];
CreateTask(TileKey(info.m_x, info.m_y, info.m_tileScale));
}
}
else
{
set<TileKey> rectInfoSet;
for (size_t i = 0 ; i < tiles.size(); ++i)
{
const Tiler::RectInfo & info = tiles[i];
rectInfoSet.insert(TileKey(info.m_x, info.m_y, info.m_tileScale));
}
// Find rects that go out from viewport
buffer_vector<ReadMWMTask *, 8> outdatedTasks;
set_difference(m_taskIndex.begin(), m_taskIndex.end(),
rectInfoSet.begin(), rectInfoSet.end(),
back_inserter(outdatedTasks), CoverageCellComparer());
// Find rects that go in into viewport
buffer_vector<TileKey, 8> inputRects;
set_difference(rectInfoSet.begin(), rectInfoSet.end(),
m_taskIndex.begin(), m_taskIndex.end(),
back_inserter(inputRects), CoverageCellComparer());
for (size_t i = 0; i < outdatedTasks.size(); ++i)
CancelTask(outdatedTasks[i], true, true);
RestartExistTasks();
for (size_t i = 0; i < inputRects.size(); ++i)
CreateTask(inputRects[i]);
}
m_currentViewport = screen;
}
void BackendRenderer::Resize(int x0, int y0, int w, int h)
void BackendRenderer::FinishTask(threads::IRoutine * routine)
{
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, MovePointer<Message>(new ResizeMessage(x0, y0, w, h)));
ReadMWMTask * readTask = static_cast<ReadMWMTask *>(routine);
readTask->Finish();
if (routine->IsCancelled())
{
ASSERT(m_taskIndex.find(readTask) == m_taskIndex.end(), ());
CancelTask(readTask, false, true);
}
}
void BackendRenderer::Resize(m2::RectI const & rect)
{
m_currentViewport.OnSize(rect);
UpdateCoverage(m_currentViewport);
}
void BackendRenderer::CreateTask(TileKey const & info)
{
ReadMWMTask * task = new ReadMWMTask(info, m_index, m_engineContext);
m_taskIndex.insert(task);
m_threadPool->AddTask(task);
}
void BackendRenderer::CancelTask(ReadMWMTask * task, bool removefromIndex, bool postToRenderer)
{
task->Cancel();
if (postToRenderer)
PostToRenderThreads(MovePointer<Message>(new DropTileMessage(task->GetTileInfo().m_key)));
if (removefromIndex)
m_taskIndex.erase(task);
m_index.RemoveFeatures(task->GetTileInfo().m_featureInfo);
if (task->IsFinished())
delete task;
}
void BackendRenderer::RestartExistTasks()
{
typedef set<ReadMWMTask *>::iterator index_iter;
for (index_iter it = m_taskIndex.begin(); it != m_taskIndex.end(); ++it)
{
(*it)->PrepareToRestart();
m_threadPool->AddTask(*it);
}
}
/////////////////////////////////////////
// MessageAcceptor //
/////////////////////////////////////////
void BackendRenderer::AcceptMessage(RefPointer<Message> message)
{
switch (message->GetType())
{
case Message::UpdateCoverage:
UpdateCoverage(static_cast<UpdateCoverageMessage *>(message.GetRaw())->GetScreen());
break;
case Message::Resize:
Resize(static_cast<ResizeMessage *>(message.GetRaw())->GetRect());
break;
case Message::TaskFinish:
FinishTask(static_cast<TaskFinishMessage *>(message.GetRaw())->GetRoutine());
break;
case Message::TileReadStarted:
case Message::TileReadEnded:
case Message::MapShapeReaded:
m_batchersPool->AcceptMessage(message);
break;
default:
ASSERT(false, ());
break;
}
}
/////////////////////////////////////////
// ThreadPart //
/////////////////////////////////////////
void BackendRenderer::StartThread()
{
m_selfThread.Create(this);
}
void BackendRenderer::StopThread()
{
IRoutine::Cancel();
CloseQueue();
m_selfThread.Join();
}
void BackendRenderer::ThreadMain()
{
m_contextFactory->getResourcesUploadContext()->makeCurrent();
while (!IsCancelled())
ProcessSingleMessage(true);
ReleaseResources();
}
void BackendRenderer::ReleaseResources()
{
m_threadPool->Stop();
m_threadPool.Destroy();
m_batchersPool.Destroy();
GetRangeDeletor(m_taskIndex, DeleteFunctor())();
}
void BackendRenderer::Do()
{
ThreadMain();
}
void BackendRenderer::PostToRenderThreads(TransferPointer<Message> message)
{
m_commutator->PostMessage(ThreadsCommutator::RenderThread, message);
}
}

View file

@ -1,19 +1,31 @@
#pragma once
#include "message_acceptor.hpp"
#include "memory_feature_index.hpp"
#include "engine_context.hpp"
#include "batchers_pool.hpp"
#include "read_mwm_task.hpp"
#include "../drape/pointers.hpp"
#include "../drape/oglcontextfactory.hpp"
#include "../geometry/screenbase.hpp"
#include "../map/scales_processor.hpp"
#include "../map/tiler.hpp"
#include "../std/function.hpp"
#include "../platform/platform.hpp"
#include "../base/thread.hpp"
#include "../base/thread_pool.hpp"
#include "../std/set.hpp"
namespace df
{
class ThreadsCommutator;
class BackendRendererImpl;
class Message;
class ThreadsCommutator;
class BackendRenderer
class BackendRenderer : public MessageAcceptor,
public threads::IRoutine
{
public:
BackendRenderer(RefPointer<ThreadsCommutator> commutator,
@ -24,11 +36,61 @@ namespace df
~BackendRenderer();
void UpdateCoverage(const ScreenBase & screen);
void Resize(int x0, int y0, int w, int h);
void OnResize(int x0, int y0, int w, int h);
private:
MasterPointer<BackendRendererImpl> m_impl;
void UpdateCoverage(const ScreenBase & screen);
void Resize(m2::RectI const & rect);
void FinishTask(threads::IRoutine * routine);
void TileReadStarted(const TileKey & key);
void TileReadEnded(const TileKey & key);
void ShapeReaded(const TileKey & key, MapShape const * shape);
private:
void CreateTask(const TileKey & info);
void CancelTask(ReadMWMTask * task, bool removefromIndex, bool postToRenderer);
void RestartExistTasks();
private:
ScreenBase m_currentViewport;
set<ReadMWMTask *, ReadMWMTask::LessByTileKey> m_taskIndex;
/////////////////////////////////////////
/// Calculate rect for read from MWM
Tiler m_tiler;
ScalesProcessor m_scaleProcessor;
/////////////////////////////////////////
/////////////////////////////////////////
/// Read features and
/// transfer it to batchers
MemoryFeatureIndex m_index;
EngineContext m_engineContext;
MasterPointer<BatchersPool> m_batchersPool;
/////////////////////////////////////////
/////////////////////////////////////////
// MessageAcceptor //
/////////////////////////////////////////
private:
void AcceptMessage(RefPointer<Message> message);
/////////////////////////////////////////
// ThreadPart //
/////////////////////////////////////////
private:
void StartThread();
void StopThread();
void ThreadMain();
void ReleaseResources();
virtual void Do();
void PostToRenderThreads(TransferPointer<Message> message);
private:
threads::Thread m_selfThread;
MasterPointer<threads::ThreadPool> m_threadPool;
RefPointer<ThreadsCommutator> m_commutator;
RefPointer<OGLContextFactory> m_contextFactory;
};
}

View file

@ -27,7 +27,7 @@ DrapeEngine::~DrapeEngine()
void DrapeEngine::OnSizeChanged(int x0, int y0, int w, int h)
{
m_backend->Resize(x0, y0, w, h);
m_backend->OnResize(x0, y0, w, h);
m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread,
MovePointer<Message>(new ResizeMessage(x0, y0, w, h)));
}

View file

@ -7,14 +7,13 @@ ROOT_DIR = ..
include($$ROOT_DIR/common.pri)
SOURCES += \
backend_renderer.cpp \
engine_context.cpp \
memory_feature_index.cpp \
message_queue.cpp \
message.cpp \
threads_commutator.cpp \
message_acceptor.cpp \
impl/backend_renderer_impl.cpp \
backend_renderer.cpp \
read_mwm_task.cpp \
batchers_pool.cpp \
frontend_renderer.cpp \
@ -22,7 +21,6 @@ SOURCES += \
area_shape.cpp
HEADERS += \
backend_renderer.hpp \
engine_context.hpp \
memory_feature_index.hpp \
tile_info.hpp \
@ -30,7 +28,7 @@ HEADERS += \
message.hpp \
threads_commutator.hpp \
message_acceptor.hpp \
impl/backend_renderer_impl.hpp \
backend_renderer.hpp \
read_mwm_task.hpp \
message_subclasses.hpp \
map_shape.hpp \

View file

@ -1,244 +0,0 @@
#include "backend_renderer_impl.hpp"
#include "threads_commutator.hpp"
#include "tile_info.hpp"
#include "memory_feature_index.hpp"
#include "read_mwm_task.hpp"
#include "message.hpp"
#include "message_subclasses.hpp"
#include "map_shape.hpp"
#include "../geometry/screenbase.hpp"
#include "../base/buffer_vector.hpp"
#include "../base/object_tracker.hpp"
#include "../base/stl_add.hpp"
#include "../std/bind.hpp"
namespace
{
void PostFinishTask(RefPointer<df::ThreadsCommutator> commutator, threads::IRoutine * routine)
{
commutator->PostMessage(df::ThreadsCommutator::ResourceUploadThread, MovePointer<df::Message>(new df::TaskFinishMessage(routine)));
}
struct CoverageCellComparer
{
bool operator()(df::ReadMWMTask const * task, df::TileKey const & tileKey) const
{
return task->GetTileInfo().m_key < tileKey;
}
bool operator()(df::TileKey const & tileKey, df::ReadMWMTask const * task) const
{
return tileKey < task->GetTileInfo().m_key;
}
};
}
namespace df
{
BackendRendererImpl::BackendRendererImpl(RefPointer<ThreadsCommutator> commutator,
RefPointer<OGLContextFactory> oglcontextfactory,
double visualScale,
int surfaceWidth,
int surfaceHeight)
: m_engineContext(commutator)
, m_commutator(commutator)
, m_contextFactory(oglcontextfactory)
{
m_scaleProcessor.SetParams(visualScale, ScalesProcessor::CalculateTileSize(surfaceWidth, surfaceHeight));
m_currentViewport.SetFromRect(m2::AnyRectD(m_scaleProcessor.GetWorldRect()));
m_commutator->RegisterThread(ThreadsCommutator::ResourceUploadThread, this);
int readerCount = max(1, GetPlatform().CpuCores() - 2);
m_threadPool.Reset(new threads::ThreadPool(readerCount, bind(&PostFinishTask, commutator, _1)));
m_batchersPool.Reset(new BatchersPool(readerCount, bind(&BackendRendererImpl::PostToRenderThreads, this, _1)));
StartThread();
}
BackendRendererImpl::~BackendRendererImpl()
{
StopThread();
}
void BackendRendererImpl::UpdateCoverage(const ScreenBase & screen)
{
m_tiler.seed(screen, screen.GlobalRect().GlobalCenter(), m_scaleProcessor.GetTileSize());
vector<Tiler::RectInfo> tiles;
m_tiler.tiles(tiles, 1);
if (!m_currentViewport.GlobalRect().IsIntersect(screen.GlobalRect()) ||
m_scaleProcessor.GetTileScaleBase(m_currentViewport) != m_scaleProcessor.GetTileScaleBase(screen))
{
typedef set<ReadMWMTask *>::iterator index_iter;
for (index_iter it = m_taskIndex.begin(); it != m_taskIndex.end(); ++it)
CancelTask(*it, false, false);
m_taskIndex.clear();
PostToRenderThreads(MovePointer<Message>(new DropCoverageMessage()));
for (size_t i = 0; i < tiles.size(); ++i)
{
const Tiler::RectInfo & info = tiles[i];
CreateTask(TileKey(info.m_x, info.m_y, info.m_tileScale));
}
}
else
{
set<TileKey> rectInfoSet;
for (size_t i = 0 ; i < tiles.size(); ++i)
{
const Tiler::RectInfo & info = tiles[i];
rectInfoSet.insert(TileKey(info.m_x, info.m_y, info.m_tileScale));
}
// Find rects that go out from viewport
buffer_vector<ReadMWMTask *, 8> outdatedTasks;
set_difference(m_taskIndex.begin(), m_taskIndex.end(),
rectInfoSet.begin(), rectInfoSet.end(),
back_inserter(outdatedTasks), CoverageCellComparer());
// Find rects that go in into viewport
buffer_vector<TileKey, 8> inputRects;
set_difference(rectInfoSet.begin(), rectInfoSet.end(),
m_taskIndex.begin(), m_taskIndex.end(),
back_inserter(inputRects), CoverageCellComparer());
for (size_t i = 0; i < outdatedTasks.size(); ++i)
CancelTask(outdatedTasks[i], true, true);
RestartExistTasks();
for (size_t i = 0; i < inputRects.size(); ++i)
CreateTask(inputRects[i]);
}
m_currentViewport = screen;
}
void BackendRendererImpl::FinishTask(threads::IRoutine * routine)
{
ReadMWMTask * readTask = static_cast<ReadMWMTask *>(routine);
readTask->Finish();
if (routine->IsCancelled())
{
ASSERT(m_taskIndex.find(readTask) == m_taskIndex.end(), ());
CancelTask(readTask, false, true);
}
}
void BackendRendererImpl::Resize(m2::RectI const & rect)
{
m_currentViewport.OnSize(rect);
UpdateCoverage(m_currentViewport);
}
void BackendRendererImpl::CreateTask(TileKey const & info)
{
ReadMWMTask * task = new ReadMWMTask(info, m_index, m_engineContext);
m_taskIndex.insert(task);
m_threadPool->AddTask(task);
}
void BackendRendererImpl::CancelTask(ReadMWMTask * task, bool removefromIndex, bool postToRenderer)
{
task->Cancel();
if (postToRenderer)
PostToRenderThreads(MovePointer<Message>(new DropTileMessage(task->GetTileInfo().m_key)));
if (removefromIndex)
m_taskIndex.erase(task);
m_index.RemoveFeatures(task->GetTileInfo().m_featureInfo);
if (task->IsFinished())
delete task;
}
void BackendRendererImpl::RestartExistTasks()
{
typedef set<ReadMWMTask *>::iterator index_iter;
for (index_iter it = m_taskIndex.begin(); it != m_taskIndex.end(); ++it)
{
(*it)->PrepareToRestart();
m_threadPool->AddTask(*it);
}
}
/////////////////////////////////////////
// MessageAcceptor //
/////////////////////////////////////////
void BackendRendererImpl::AcceptMessage(RefPointer<Message> message)
{
switch (message->GetType())
{
case Message::UpdateCoverage:
UpdateCoverage(static_cast<UpdateCoverageMessage *>(message.GetRaw())->GetScreen());
break;
case Message::Resize:
Resize(static_cast<ResizeMessage *>(message.GetRaw())->GetRect());
break;
case Message::TaskFinish:
FinishTask(static_cast<TaskFinishMessage *>(message.GetRaw())->GetRoutine());
break;
case Message::TileReadStarted:
case Message::TileReadEnded:
case Message::MapShapeReaded:
m_batchersPool->AcceptMessage(message);
break;
default:
ASSERT(false, ());
break;
}
}
/////////////////////////////////////////
// ThreadPart //
/////////////////////////////////////////
void BackendRendererImpl::StartThread()
{
m_selfThread.Create(this);
}
void BackendRendererImpl::StopThread()
{
IRoutine::Cancel();
CloseQueue();
m_selfThread.Join();
}
void BackendRendererImpl::ThreadMain()
{
m_contextFactory->getResourcesUploadContext()->makeCurrent();
while (!IsCancelled())
ProcessSingleMessage(true);
ReleaseResources();
}
void BackendRendererImpl::ReleaseResources()
{
m_threadPool->Stop();
m_threadPool.Destroy();
m_batchersPool.Destroy();
GetRangeDeletor(m_taskIndex, DeleteFunctor())();
}
void BackendRendererImpl::Do()
{
ThreadMain();
}
void BackendRendererImpl::PostToRenderThreads(TransferPointer<Message> message)
{
m_commutator->PostMessage(ThreadsCommutator::RenderThread, message);
}
}

View file

@ -1,94 +0,0 @@
#pragma once
#include "message_acceptor.hpp"
#include "memory_feature_index.hpp"
#include "engine_context.hpp"
#include "batchers_pool.hpp"
#include "read_mwm_task.hpp"
#include "../drape/pointers.hpp"
#include "../drape/oglcontextfactory.hpp"
#include "../map/scales_processor.hpp"
#include "../map/tiler.hpp"
#include "../platform/platform.hpp"
#include "../base/thread.hpp"
#include "../base/thread_pool.hpp"
#include "../std/set.hpp"
namespace df
{
class Message;
class ThreadsCommutator;
class BackendRendererImpl : public MessageAcceptor,
public threads::IRoutine
{
public:
BackendRendererImpl(RefPointer<ThreadsCommutator> commutator,
RefPointer<OGLContextFactory> oglcontextfactory,
double visualScale,
int surfaceWidth,
int surfaceHeight);
~BackendRendererImpl();
private:
void UpdateCoverage(const ScreenBase & screen);
void Resize(m2::RectI const & rect);
void FinishTask(threads::IRoutine * routine);
void TileReadStarted(const TileKey & key);
void TileReadEnded(const TileKey & key);
void ShapeReaded(const TileKey & key, MapShape const * shape);
private:
void CreateTask(const TileKey & info);
void CancelTask(ReadMWMTask * task, bool removefromIndex, bool postToRenderer);
void RestartExistTasks();
private:
ScreenBase m_currentViewport;
set<ReadMWMTask *, ReadMWMTask::LessByTileKey> m_taskIndex;
/////////////////////////////////////////
/// Calculate rect for read from MWM
Tiler m_tiler;
ScalesProcessor m_scaleProcessor;
/////////////////////////////////////////
/////////////////////////////////////////
/// Read features and
/// transfer it to batchers
MemoryFeatureIndex m_index;
EngineContext m_engineContext;
MasterPointer<BatchersPool> m_batchersPool;
/////////////////////////////////////////
/////////////////////////////////////////
// MessageAcceptor //
/////////////////////////////////////////
private:
void AcceptMessage(RefPointer<Message> message);
/////////////////////////////////////////
// ThreadPart //
/////////////////////////////////////////
private:
void StartThread();
void StopThread();
void ThreadMain();
void ReleaseResources();
virtual void Do();
void PostToRenderThreads(TransferPointer<Message> message);
private:
threads::Thread m_selfThread;
MasterPointer<threads::ThreadPool> m_threadPool;
RefPointer<ThreadsCommutator> m_commutator;
RefPointer<OGLContextFactory> m_contextFactory;
};
}