diff --git a/base/mru_cache.hpp b/base/mru_cache.hpp index 46ba80ed0c..5535daf649 100644 --- a/base/mru_cache.hpp +++ b/base/mru_cache.hpp @@ -32,7 +32,7 @@ namespace my typename list_t::iterator m_it; }; - typedef unordered_map map_t; + typedef map map_t; map_t m_map; list_t m_list; diff --git a/base/threaded_list.hpp b/base/threaded_list.hpp index a4bf46a2e8..35d83ab83a 100644 --- a/base/threaded_list.hpp +++ b/base/threaded_list.hpp @@ -14,6 +14,21 @@ private: public: + template + void ProcessList(Fn const & fn) + { + threads::ConditionGuard g(m_Cond); + + bool hadElements = !m_list.empty(); + + fn(m_list); + + bool hasElements = !m_list.empty(); + + if (!hadElements && hasElements) + m_Cond.Signal(); + } + void PushBack(T const & t) { threads::ConditionGuard g(m_Cond); diff --git a/map/benchmark_tiling_render_policy_mt.cpp b/map/benchmark_tiling_render_policy_mt.cpp index e6bd616376..b2c5793b9d 100644 --- a/map/benchmark_tiling_render_policy_mt.cpp +++ b/map/benchmark_tiling_render_policy_mt.cpp @@ -23,7 +23,7 @@ void BenchmarkTilingRenderPolicyMT::DrawFrame(shared_ptr const & e, { TilingRenderPolicyMT::DrawFrame(e, s); /// waiting for render queue to empty - GetRenderQueue().WaitForEmptyAndFinished(); + GetTileRenderer().WaitForEmptyAndFinished(); /// current screen should be fully covered, so the following call will only blit results TilingRenderPolicyMT::DrawFrame(e, s); } diff --git a/map/coverage_generator.cpp b/map/coverage_generator.cpp index 14a2754d22..379f4e08ef 100644 --- a/map/coverage_generator.cpp +++ b/map/coverage_generator.cpp @@ -1,149 +1,31 @@ #include "../base/SRC_FIRST.hpp" #include "coverage_generator.hpp" -#include "render_queue.hpp" +#include "screen_coverage.hpp" +#include "tile_renderer.hpp" #include "../base/logging.hpp" #include "../std/bind.hpp" -ScreenCoverage::ScreenCoverage() -{} - -struct unlock_synchronized -{ - TileCache * m_c; - - unlock_synchronized(TileCache * c) : m_c(c) - {} - - void operator()(Tile const * t) - { - m_c->readLock(); - m_c->unlockTile(t->m_rectInfo); - m_c->readUnlock(); - } -}; - -void ScreenCoverage::Clear() -{ - m_tileCache->writeLock(); - - for (unsigned i = 0; i < m_tiles.size(); ++i) - m_tileCache->unlockTile(m_tiles[i]->m_rectInfo); - - m_tileCache->writeUnlock(); - - m_tiles.clear(); - m_infoLayer.clear(); -} - -CoverageGenerator::CoverageTask::CoverageTask(ScreenBase const & screen) - : m_screen(screen) -{} - -void CoverageGenerator::CoverageTask::execute(CoverageGenerator * generator) -{ - unsigned tilesCount = 0; - generator->m_tiler.seed(m_screen, m_screen.GlobalRect().Center()); - generator->m_sequenceID++; - - { - threads::MutexGuard g(generator->m_mutex); - LOG(LINFO, ("clearing workCoverage")); - generator->m_workCoverage->Clear(); - } - - generator->m_workCoverage->m_screen = m_screen; - - while (generator->m_tiler.hasTile()) - { - ++tilesCount; - Tiler::RectInfo rectInfo = generator->m_tiler.nextTile(); - - TileCache & tileCache = generator->m_renderQueue->GetTileCache(); - - tileCache.readLock(); - - if (tileCache.hasTile(rectInfo)) - { - tileCache.lockTile(rectInfo); - - Tile const * tile = &tileCache.getTile(rectInfo); - - shared_ptr lockedTile = make_shared_ptr(tile, unlock_synchronized(&tileCache)); - - generator->m_workCoverage->m_tiles.push_back(lockedTile); - generator->m_workCoverage->m_infoLayer.merge(*tile->m_infoLayer.get(), - tile->m_tileScreen.PtoGMatrix() * generator->m_workCoverage->m_screen.GtoPMatrix()); - - tileCache.readUnlock(); - } - else - { - tileCache.readUnlock(); - generator->m_renderQueue->AddCommand( - generator->m_renderFn, - rectInfo, - generator->m_sequenceID, - bind(&CoverageGenerator::AddMergeTileTask, generator, _1, _2)); - } - } - - { - threads::MutexGuard g(generator->Mutex()); - swap(generator->m_currentCoverage, generator->m_workCoverage); - } -} - -CoverageGenerator::MergeTileTask::MergeTileTask(shared_ptr const & tile) - : m_tile(tile) -{} - -void CoverageGenerator::MergeTileTask::execute(CoverageGenerator * generator) -{ - { - threads::MutexGuard g(generator->m_mutex); - LOG(LINFO, ("making a working copy of currentCoverage")); - *generator->m_mergeCoverage = *generator->m_currentCoverage; - } - - LOG(LINFO, (generator->m_mergeCoverage->m_tiles.size())); - - generator->m_mergeCoverage->m_tiles.push_back(m_tile); - generator->m_mergeCoverage->m_infoLayer.merge(*m_tile->m_infoLayer.get(), - m_tile->m_tileScreen.PtoGMatrix() * generator->m_mergeCoverage->m_screen.GtoPMatrix()); - - { - threads::MutexGuard g(generator->m_mutex); - LOG(LINFO, ("saving merged coverage into workCoverage")); - *generator->m_workCoverage = *generator->m_mergeCoverage; - LOG(LINFO, ("saving merged coverage into currentCoverage")); - *generator->m_currentCoverage = *generator->m_mergeCoverage; - } - - generator->m_renderQueue->Invalidate(); -} - CoverageGenerator::CoverageGenerator( size_t tileSize, size_t scaleEtalonSize, - RenderPolicy::TRenderFn renderFn, - RenderQueue * renderQueue) - : m_tiler(tileSize, scaleEtalonSize), + TileRenderer * tileRenderer, + shared_ptr const & windowHandle) + : m_queue(1), + m_tileRenderer(tileRenderer), + m_workCoverage(new ScreenCoverage(tileRenderer, this, tileSize, scaleEtalonSize)), + m_mergeCoverage(new ScreenCoverage(tileRenderer, this, tileSize, scaleEtalonSize)), + m_currentCoverage(new ScreenCoverage(tileRenderer, this, tileSize, scaleEtalonSize)), m_sequenceID(0), - m_renderFn(renderFn), - m_renderQueue(renderQueue), - m_workCoverage(new ScreenCoverage()), - m_mergeCoverage(new ScreenCoverage()), - m_currentCoverage(new ScreenCoverage()) + m_windowHandle(windowHandle) { - m_routine = new Routine(this); } void CoverageGenerator::Initialize() { - m_thread.Create(m_routine); + m_queue.Start(); } CoverageGenerator::~CoverageGenerator() @@ -155,61 +37,64 @@ CoverageGenerator::~CoverageGenerator() void CoverageGenerator::Cancel() { - m_thread.Cancel(); + m_queue.Cancel(); } -void CoverageGenerator::AddCoverageTask(ScreenBase const & screen) +void CoverageGenerator::AddCoverScreenTask(ScreenBase const & screen) { if (screen == m_currentScreen) return; + m_currentScreen = screen; - m_tasks.PushBack(make_shared_ptr(new CoverageTask(screen))); + m_sequenceID++; + + m_queue.AddCommand(bind(&CoverageGenerator::CoverScreen, this, screen, m_sequenceID)); } -void CoverageGenerator::AddMergeTileTask(Tiler::RectInfo const & rectInfo, Tile const &) +void CoverageGenerator::CoverScreen(ScreenBase const & screen, int sequenceID) { - TileCache & tileCache = m_renderQueue->GetTileCache(); - tileCache.readLock(); + if (sequenceID < m_sequenceID) + return; - if (tileCache.hasTile(rectInfo)) { - tileCache.lockTile(rectInfo); - - Tile const * tile = &tileCache.getTile(rectInfo); - - shared_ptr lockedTile = make_shared_ptr(tile, unlock_synchronized(&tileCache)); - - tileCache.readUnlock(); - - m_tasks.PushBack(make_shared_ptr(new MergeTileTask(lockedTile))); + threads::MutexGuard g(m_mutex); + *m_workCoverage = *m_currentCoverage; } - else - tileCache.readUnlock(); -} -CoverageGenerator::Routine::Routine(CoverageGenerator * parent) - : m_parent(parent) -{} + m_workCoverage->SetScreen(screen); -void CoverageGenerator::Routine::Do() -{ - while (!IsCancelled()) { - shared_ptr task = m_parent->m_tasks.Front(true); - - if (m_parent->m_tasks.IsCancelled()) - break; - - task->execute(m_parent); + threads::MutexGuard g(m_mutex); + *m_currentCoverage = *m_workCoverage; + m_workCoverage->Clear(); } } -threads::Mutex & CoverageGenerator::Mutex() +void CoverageGenerator::AddMergeTileTask(Tiler::RectInfo const & rectInfo) { - return m_mutex; + m_queue.AddCommand(bind(&CoverageGenerator::MergeTile, this, rectInfo)); } -ScreenCoverage * CoverageGenerator::CurrentCoverage() +void CoverageGenerator::MergeTile(Tiler::RectInfo const & rectInfo) { - return m_currentCoverage; + { + threads::MutexGuard g(m_mutex); + *m_workCoverage = *m_currentCoverage; + } + + m_workCoverage->Merge(rectInfo); + + { + threads::MutexGuard g(m_mutex); + *m_currentCoverage = *m_workCoverage; + m_workCoverage->Clear(); + } + + m_windowHandle->invalidate(); +} + +void CoverageGenerator::CopyCurrentCoverage(ScreenCoverage & dst) +{ + threads::MutexGuard g(m_mutex); + dst = *m_currentCoverage; } diff --git a/map/coverage_generator.hpp b/map/coverage_generator.hpp index 5d0bbf2830..2744cb0d8b 100644 --- a/map/coverage_generator.hpp +++ b/map/coverage_generator.hpp @@ -3,6 +3,7 @@ #include "render_policy.hpp" #include "tiler.hpp" #include "tile.hpp" +#include "window_handle.hpp" #include "../geometry/screenbase.hpp" @@ -11,100 +12,52 @@ #include "../base/thread.hpp" #include "../base/threaded_list.hpp" #include "../base/mutex.hpp" +#include "../base/commands_queue.hpp" #include "../std/vector.hpp" #include "../std/shared_ptr.hpp" -class RenderQueue; +class TileRenderer; class TileCache; - -/// holds the tile coverage for a specific screen -struct ScreenCoverage -{ - TileCache * m_tileCache; - ScreenBase m_screen; - vector > m_tiles; - yg::InfoLayer m_infoLayer; - - bool m_IsRendering; //< while this flag is set - the object shouldn't - //be altered, 'cause GUI thread is rendering from it - - ScreenCoverage(); - - void Merge(Tiler::RectInfo const & rectInfo, Tile const & tile); - void Compute(ScreenBase const & screen); - void Clear(); -}; +class ScreenCoverage; class CoverageGenerator { private: - struct Task - { - virtual void execute(CoverageGenerator * generator) = 0; - }; + core::CommandsQueue m_queue; - struct CoverageTask : Task - { - ScreenBase m_screen; - CoverageTask(ScreenBase const & screen); - void execute(CoverageGenerator * generator); - }; - - struct MergeTileTask : Task - { - shared_ptr m_tile; - MergeTileTask(shared_ptr const & tile); - void execute(CoverageGenerator * generator); - }; - - ThreadedList > m_tasks; - - struct Routine : public threads::IRoutine - { - CoverageGenerator * m_parent; - void Do(); - Routine(CoverageGenerator * parent); - }; - - friend struct Routine; - - Routine * m_routine; - threads::Thread m_thread; - - threads::Mutex m_mutex; - - Tiler m_tiler; - - RenderPolicy::TRenderFn m_renderFn; - RenderQueue * m_renderQueue; + TileRenderer * m_tileRenderer; ScreenCoverage * m_workCoverage; ScreenCoverage * m_mergeCoverage; ScreenCoverage * m_currentCoverage; ScreenBase m_currentScreen; - size_t m_sequenceID; + int m_sequenceID; + + shared_ptr m_windowHandle; + + threads::Mutex m_mutex; public: CoverageGenerator(size_t tileSize, size_t scaleEtalonSize, - RenderPolicy::TRenderFn renderFn, - RenderQueue * renderQueue); + TileRenderer * tileRenderer, + shared_ptr const & windowHandle); ~CoverageGenerator(); - void AddCoverageTask(ScreenBase const & screen); + void AddCoverScreenTask(ScreenBase const & screen); + void AddMergeTileTask(Tiler::RectInfo const & rectInfo); - void AddMergeTileTask(Tiler::RectInfo const & rectInfo, Tile const &); + void CoverScreen(ScreenBase const & screen, int sequenceID); + void MergeTile(Tiler::RectInfo const & rectInfo); void Cancel(); void Initialize(); - threads::Mutex & Mutex(); - - ScreenCoverage * CurrentCoverage(); + void CopyCurrentCoverage(ScreenCoverage & dst); }; diff --git a/map/draw_processor.cpp b/map/draw_processor.cpp index 8a2dda8c62..988863415a 100644 --- a/map/draw_processor.cpp +++ b/map/draw_processor.cpp @@ -208,14 +208,13 @@ namespace fwork DrawProcessor::DrawProcessor( m2::RectD const & r, ScreenBase const & convertor, - shared_ptr const & paintEvent, - int scaleLevel, - yg::GlyphCache * glyphCache) + shared_ptr const & e, + int scaleLevel) : m_rect(r), m_convertor(convertor), - m_paintEvent(paintEvent), + m_paintEvent(e), m_zoom(scaleLevel), - m_glyphCache(glyphCache) + m_glyphCache(e->drawer()->screen()->glyphCache()) #ifdef PROFILER_DRAWING , m_drawCount(0) #endif diff --git a/map/draw_processor.hpp b/map/draw_processor.hpp index 1821446c23..7419ff9e71 100644 --- a/map/draw_processor.hpp +++ b/map/draw_processor.hpp @@ -329,7 +329,7 @@ namespace fwork size_t m_drawCount; #endif - inline DrawerYG * GetDrawer() const { return m_paintEvent->drawer().get(); } + inline DrawerYG * GetDrawer() const { return m_paintEvent->drawer(); } void PreProcessKeys(vector & keys) const; @@ -340,8 +340,7 @@ namespace fwork DrawProcessor(m2::RectD const & r, ScreenBase const & convertor, shared_ptr const & paintEvent, - int scaleLevel, - yg::GlyphCache * glyphCache); + int scaleLevel); bool operator() (FeatureType const & f) const; }; diff --git a/map/drawer_yg.cpp b/map/drawer_yg.cpp index b42918ba92..7325222f17 100644 --- a/map/drawer_yg.cpp +++ b/map/drawer_yg.cpp @@ -21,7 +21,8 @@ DrawerYG::Params::Params() : m_dynamicPagesCount(2), m_textPagesCount(2), - m_threadID(0) + m_threadID(0), + m_visualScale(1) { } @@ -35,12 +36,12 @@ void di::DrawRule::SetID(size_t threadID, uint32_t id) const m_transparent ? m_rule->SetID2(threadID, id) : m_rule->SetID(threadID, id); } -DrawerYG::DrawerYG(string const & skinName, params_t const & params) - : m_threadID(params.m_threadID) +DrawerYG::DrawerYG(params_t const & params) + : m_visualScale(params.m_visualScale), m_threadID(params.m_threadID) { m_pScreen = shared_ptr(new yg::gl::Screen(params)); m_pSkin = shared_ptr(loadSkin(params.m_resourceManager, - skinName, + params.m_skinName, params.m_dynamicPagesCount, params.m_textPagesCount)); m_pScreen->setSkin(m_pSkin); @@ -313,9 +314,9 @@ shared_ptr DrawerYG::screen() const return m_pScreen; } -void DrawerYG::SetVisualScale(double visualScale) +int DrawerYG::VisualScale() const { - m_visualScale = visualScale; + return m_visualScale; } void DrawerYG::SetScale(int level) diff --git a/map/drawer_yg.hpp b/map/drawer_yg.hpp index 81cb70d288..085a570e8f 100644 --- a/map/drawer_yg.hpp +++ b/map/drawer_yg.hpp @@ -94,12 +94,14 @@ public: size_t m_dynamicPagesCount; size_t m_textPagesCount; size_t m_threadID; + string m_skinName; + double m_visualScale; Params(); }; typedef Params params_t; - DrawerYG(string const & skinName, params_t const & params = params_t()); + DrawerYG(params_t const & params = params_t()); void drawSymbol(m2::PointD const & pt, string const & symbolName, yg::EPosition pos, int depth); @@ -112,7 +114,7 @@ public: shared_ptr screen() const; - void SetVisualScale(double visualScale); + int VisualScale() const; void SetScale(int level); void Draw(di::DrawInfo const * pInfo, di::DrawRule const * rules, size_t count); diff --git a/map/events.hpp b/map/events.hpp index b364716dd8..16f0cdd3b7 100644 --- a/map/events.hpp +++ b/map/events.hpp @@ -3,6 +3,8 @@ #include "../std/shared_ptr.hpp" +#include "../base/commands_queue.hpp" + #include "../base/start_mem_debug.hpp" @@ -43,25 +45,24 @@ class DrawerYG; class PaintEvent : public Event { - shared_ptr m_drawer; - bool m_isCancelled; + + DrawerYG * m_drawer; + core::CommandsQueue::Environment const * m_env; public: - PaintEvent(shared_ptr drawer) - : m_drawer(drawer), m_isCancelled(false) {} - shared_ptr drawer() const + PaintEvent(DrawerYG * drawer, core::CommandsQueue::Environment const * env = 0) + : m_drawer(drawer), m_env(env) + {} + + DrawerYG * drawer() const { return m_drawer; } - void setIsCancelled(bool isCancelled) - { - m_isCancelled = isCancelled; - } bool isCancelled() const { - return m_isCancelled; + return (m_env && m_env->IsCancelled()); } }; diff --git a/map/framework.cpp b/map/framework.cpp index f3048b15ae..5e5e0ca515 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -287,12 +287,12 @@ double Framework::GetCurrentScale() const /// Actual rendering function. template -void Framework::DrawModel(shared_ptr e, - ScreenBase const & screen, - m2::RectD const & selectRect, - int scaleLevel) +void Framework::DrawModel(shared_ptr const & e, + ScreenBase const & screen, + m2::RectD const & selectRect, + int scaleLevel) { - fwork::DrawProcessor doDraw(selectRect, screen, e, scaleLevel, e->drawer()->screen()->glyphCache()); + fwork::DrawProcessor doDraw(selectRect, screen, e, scaleLevel); try { @@ -313,8 +313,7 @@ void Framework::DrawModel(shared_ptr e, template void Framework::Paint(shared_ptr e) { - DrawerYG * pDrawer = e->drawer().get(); - pDrawer->SetVisualScale(GetPlatform().VisualScale()); + DrawerYG * pDrawer = e->drawer(); m_informationDisplay.setScreen(m_navigator.Screen()); diff --git a/map/framework.hpp b/map/framework.hpp index 93753ab8ce..1ffce84ee5 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -2,7 +2,7 @@ #include "events.hpp" #include "drawer_yg.hpp" -#include "render_queue.hpp" +#include "tile_renderer.hpp" #include "information_display.hpp" #include "window_handle.hpp" #include "location_state.hpp" @@ -181,7 +181,7 @@ public: public: - void DrawModel(shared_ptr e, + void DrawModel(shared_ptr const & e, ScreenBase const & screen, m2::RectD const & selectRect, int scaleLevel); diff --git a/map/map.pro b/map/map.pro index 7f5057cc54..31e81a749a 100644 --- a/map/map.pro +++ b/map/map.pro @@ -18,8 +18,7 @@ HEADERS += \ draw_processor.hpp \ draw_info.hpp \ window_handle.hpp \ - render_queue.hpp \ - render_queue_routine.hpp \ + tile_renderer.hpp \ information_display.hpp \ location_state.hpp \ benchmark_provider.hpp \ @@ -34,7 +33,8 @@ HEADERS += \ coverage_generator.hpp \ tiler.hpp \ tile.hpp \ - tile_cache.hpp + tile_cache.hpp \ + screen_coverage.hpp SOURCES += \ feature_vec_model.cpp \ @@ -42,8 +42,7 @@ SOURCES += \ navigator.cpp \ drawer_yg.cpp \ draw_processor.cpp \ - render_queue.cpp \ - render_queue_routine.cpp \ + tile_renderer.cpp \ information_display.cpp \ location_state.cpp \ benchmark_provider.cpp \ @@ -58,7 +57,8 @@ SOURCES += \ coverage_generator.cpp \ tiler.cpp \ tile_cache.cpp \ - tile.cpp + tile.cpp \ + screen_coverage.cpp !iphone*:!bada*:!android* { HEADERS += qgl_render_context.hpp diff --git a/map/render_policy_st.cpp b/map/render_policy_st.cpp index ef2390a947..7734d2d4b8 100644 --- a/map/render_policy_st.cpp +++ b/map/render_policy_st.cpp @@ -36,8 +36,6 @@ void RenderPolicyST::DrawFrame(shared_ptr const & e, e->drawer()->screen()->setInfoLayer(infoLayer); - e->drawer()->SetVisualScale(GetPlatform().VisualScale()); - e->drawer()->screen()->clear(bgColor()); renderFn()(e, s, s.GlobalRect(), scales::GetScaleLevel(glbRect)); diff --git a/map/screen_coverage.cpp b/map/screen_coverage.cpp new file mode 100644 index 0000000000..d63a44b150 --- /dev/null +++ b/map/screen_coverage.cpp @@ -0,0 +1,229 @@ +#include "../base/SRC_FIRST.hpp" + +#include "../std/bind.hpp" +#include "../std/set.hpp" +#include "../std/algorithm.hpp" + +#include "../yg/screen.hpp" +#include "../yg/base_texture.hpp" + +#include "screen_coverage.hpp" +#include "tile_renderer.hpp" +#include "window_handle.hpp" +#include "coverage_generator.hpp" + +ScreenCoverage::ScreenCoverage() + : m_tiler(0, 0) +{} + +ScreenCoverage::ScreenCoverage(TileRenderer * tileRenderer, + CoverageGenerator * coverageGenerator, + size_t tileSize, + size_t scaleEtalonSize) + : m_tileRenderer(tileRenderer), + m_tiler(tileSize, scaleEtalonSize), + m_coverageGenerator(coverageGenerator) +{} + +ScreenCoverage::ScreenCoverage(ScreenCoverage const & src) + : m_tileRenderer(src.m_tileRenderer), + m_tiler(src.m_tiler), + m_screen(src.m_screen), + m_tiles(src.m_tiles), + m_infoLayer(src.m_infoLayer) +{ + TileCache * tileCache = &m_tileRenderer->GetTileCache(); + tileCache->readLock(); + + for (size_t i = 0; i < m_tiles.size(); ++i) + tileCache->lockTile(m_tiles[i]->m_rectInfo); + + tileCache->readUnlock(); +} + +ScreenCoverage const & ScreenCoverage::operator=(ScreenCoverage const & src) +{ + if (&src != this) + { + m_tileRenderer = src.m_tileRenderer; + m_tiler = src.m_tiler; + m_screen = src.m_screen; + m_tiles = src.m_tiles; + + TileCache * tileCache = &m_tileRenderer->GetTileCache(); + + tileCache->readLock(); + + for (size_t i = 0; i < m_tiles.size(); ++i) + tileCache->lockTile(m_tiles[i]->m_rectInfo); + + tileCache->readUnlock(); + + m_infoLayer = src.m_infoLayer; + } + return *this; +} + +void ScreenCoverage::Merge(Tiler::RectInfo const & ri) +{ + threads::MutexGuard g(m_mutex); + TileCache * tileCache = &m_tileRenderer->GetTileCache(); + + Tile const * tile = 0; + bool hasTile = false; + + tileCache->readLock(); + hasTile = tileCache->hasTile(ri); + if (hasTile) + tile = &tileCache->getTile(ri); + tileCache->readUnlock(); + + if (hasTile) + { + m_tiles.push_back(tile); + m_infoLayer.merge(*tile->m_infoLayer.get(), + tile->m_tileScreen.PtoGMatrix() * m_screen.GtoPMatrix()); + } +} + +void ScreenCoverage::Remove(Tile const * tile) +{ + threads::MutexGuard g(m_mutex); +} + +struct lessRectInfo +{ + bool operator()(Tile const * l, Tile const * r) + { + return l->m_rectInfo.toUInt64Cell() < r->m_rectInfo.toUInt64Cell(); + } +}; + +void ScreenCoverage::SetScreen(ScreenBase const & screen, bool mergePathNames) +{ + threads::MutexGuard g(m_mutex); + + m_screen = screen; + + m_tiler.seed(m_screen, m_screen.GlobalRect().Center()); + + vector allRects; + vector newRects; + vector tiles; + + m_tiler.visibleTiles(allRects); + + TileCache * tileCache = &m_tileRenderer->GetTileCache(); + + tileCache->readLock(); + + for (unsigned i = 0; i < allRects.size(); ++i) + { + Tiler::RectInfo ri = allRects[i]; + if (tileCache->hasTile(ri)) + { + tiles.push_back(&tileCache->getTile(ri)); + tileCache->touchTile(ri); + } + else + newRects.push_back(ri); + } + + /// computing difference between current and previous coverage + /// tiles, that aren't in current coverage are unlocked to allow their deletion from TileCache + /// tiles, that are new to the current coverage are added into m_tiles and locked in TileCache + + typedef set TileSet; + + LOG(LINFO, ("prevSet size: ", m_tiles.size())); + + TileSet prevSet; + copy(m_tiles.begin(), m_tiles.end(), inserter(prevSet, prevSet.end())); + + LOG(LINFO, ("curSet size: ", tiles.size())); + + TileSet curSet; + copy(tiles.begin(), tiles.end(), inserter(curSet, curSet.end())); + + TileSet erasedTiles; + TileSet addedTiles; + + set_difference(prevSet.begin(), prevSet.end(), curSet.begin(), curSet.end(), inserter(erasedTiles, erasedTiles.end())); + set_difference(curSet.begin(), curSet.end(), prevSet.begin(), prevSet.end(), inserter(addedTiles, addedTiles.end())); + + LOG(LINFO, ("erased tiles size: ", erasedTiles.size())); + + for (TileSet::const_iterator it = erasedTiles.begin(); it != erasedTiles.end(); ++it) + { + Tiler::RectInfo ri = (*it)->m_rectInfo; +// LOG(LINFO, ("erasing tile: ", ri.m_tileScale, ri.m_drawScale, ri.m_y, ri.m_x)); + tileCache->unlockTile((*it)->m_rectInfo); + /// here we should "unmerge" erasedTiles[i].m_infoLayer from m_infoLayer + } + + LOG(LINFO, ("added tiles size: ", addedTiles.size())); + + for (TileSet::const_iterator it = addedTiles.begin(); it != addedTiles.end(); ++it) + { + Tiler::RectInfo ri = (*it)->m_rectInfo; +// LOG(LINFO, ("adding tile: ", ri.m_tileScale, ri.m_drawScale, ri.m_y, ri.m_x)); + tileCache->lockTile((*it)->m_rectInfo); +// m_infoLayer.merge(*((*it)->m_infoLayer.get()), (*it)->m_tileScreen.PtoGMatrix() * screen.GtoPMatrix()); + } + + m_infoLayer.clear(); + for (size_t i = 0; i < tiles.size(); ++i) + m_infoLayer.merge(*tiles[i]->m_infoLayer.get(), tiles[i]->m_tileScreen.PtoGMatrix() * screen.GtoPMatrix()); + + tileCache->readUnlock(); + + m_tiles = tiles; + + /// adding commands for tiles which aren't in cache + for (size_t i = 0; i < newRects.size(); ++i) + { + m_tileRenderer->AddCommand(newRects[i], m_tiler.sequenceID(), + bind(&CoverageGenerator::AddMergeTileTask, m_coverageGenerator, newRects[i])); + } +} + +ScreenCoverage::~ScreenCoverage() +{ + Clear(); +} + +void ScreenCoverage::Clear() +{ + threads::MutexGuard g(m_mutex); + + TileCache * tileCache = &m_tileRenderer->GetTileCache(); + + tileCache->readLock(); + for (unsigned i = 0; i < m_tiles.size(); ++i) + tileCache->unlockTile(m_tiles[i]->m_rectInfo); + + tileCache->readUnlock(); + + m_tiles.clear(); + m_infoLayer.clear(); +} + +void ScreenCoverage::Draw(yg::gl::Screen * s, ScreenBase const & screen) +{ + threads::MutexGuard g(m_mutex); + + for (size_t i = 0; i < m_tiles.size(); ++i) + { + Tile const * tile = m_tiles[i]; + size_t tileWidth = tile->m_renderTarget->width(); + size_t tileHeight = tile->m_renderTarget->height(); + + s->blit(tile->m_renderTarget, tile->m_tileScreen, screen, true, + yg::Color(), + m2::RectI(0, 0, tileWidth - 2, tileHeight - 2), + m2::RectU(1, 1, tileWidth - 1, tileHeight - 1)); + + } + + m_infoLayer.draw(s, m_screen.PtoGMatrix() * screen.GtoPMatrix()); +} diff --git a/map/screen_coverage.hpp b/map/screen_coverage.hpp new file mode 100644 index 0000000000..2db7fb698d --- /dev/null +++ b/map/screen_coverage.hpp @@ -0,0 +1,59 @@ +#pragma once + +#include "../base/mutex.hpp" + +#include "../geometry/screenbase.hpp" + +#include "../yg/info_layer.hpp" + +#include "tile.hpp" +#include "tiler.hpp" +#include "render_policy.hpp" + +class TileRenderer; + +namespace yg +{ + namespace gl + { + class Screen; + } +} + +class CoverageGenerator; + +class ScreenCoverage +{ +private: + + threads::Mutex m_mutex; + + TileRenderer * m_tileRenderer; //< queue to put new rendering tasks in + Tiler m_tiler; //< tiler to compute visible and predicted tiles + + ScreenBase m_screen; //< last covered screen + vector m_tiles; //< vector of visible tiles for m_screen + yg::InfoLayer m_infoLayer; //< composite infoLayers for visible tiles + + CoverageGenerator * m_coverageGenerator; + +public: + + ScreenCoverage(); + ScreenCoverage(TileRenderer * tileRenderer, CoverageGenerator * coverageGenerator, size_t tileSize, size_t scaleEtalonSize); + ~ScreenCoverage(); + + ScreenCoverage(ScreenCoverage const & src); + ScreenCoverage const & operator=(ScreenCoverage const & src); + + /// add rendered tile to coverage. Tile is locked, so make sure to unlock it in case it's not needed. + void Merge(Tiler::RectInfo const & ri); + /// remove tile from coverage + void Remove(Tile const * tile); + /// recalculate screen coverage, using as much info from prev coverage as possible + void SetScreen(ScreenBase const & screen, bool mergePathNames = true); + /// clear screen coverage and associated info layer + void Clear(); + /// draw screen coverage + void Draw(yg::gl::Screen * s, ScreenBase const & currentScreen); +}; diff --git a/map/tile_cache.hpp b/map/tile_cache.hpp index 26c489994b..cd3cf33d58 100644 --- a/map/tile_cache.hpp +++ b/map/tile_cache.hpp @@ -39,12 +39,13 @@ private: public: TileCache(size_t maxCacheSize); - /// lock for multithreaded access + /// lock for multithreaded READ access void readLock(); - /// unlock for multithreaded access + /// unlock for multithreaded READ access void readUnlock(); - + /// lock for multithreaded WRITE access void writeLock(); + /// unlock for multithreaded WRITE access void writeUnlock(); /// add tile to cache void addTile(Tiler::RectInfo const & key, Entry const & entry); diff --git a/map/tile_renderer.cpp b/map/tile_renderer.cpp index def099d14c..620ec0aafe 100644 --- a/map/tile_renderer.cpp +++ b/map/tile_renderer.cpp @@ -1,128 +1,198 @@ #include "../base/SRC_FIRST.hpp" -#include "render_queue.hpp" +#include "tile_renderer.hpp" #include "window_handle.hpp" #include "../yg/render_state.hpp" #include "../yg/rendercontext.hpp" +#include "../yg/base_texture.hpp" #include "../std/bind.hpp" #include "../base/logging.hpp" #include "../base/condition.hpp" -RenderQueue::RenderQueue( +TileRenderer::TileRenderer( string const & skinName, unsigned scaleEtalonSize, unsigned maxTilesCount, - unsigned tasksCount, - yg::Color const & bgColor - ) : m_sequenceID(0), m_tileCache(maxTilesCount - 1), m_activeCommands(0) + unsigned executorsCount, + yg::Color const & bgColor, + RenderPolicy::TRenderFn const & renderFn + ) : m_queue(executorsCount), + m_tileCache(maxTilesCount - executorsCount - 1), + m_renderFn(renderFn), + m_skinName(skinName), + m_bgColor(bgColor), + m_sequenceID(0) { - m_tasksCount = tasksCount; //< calculate from the CPU Cores Number - LOG(LINFO, ("initializing ", tasksCount, " rendering threads")); - m_tasks = new Task[m_tasksCount]; - for (unsigned i = 0; i < m_tasksCount; ++i) - m_tasks[i].m_routine = new RenderQueueRoutine( - skinName, - scaleEtalonSize, - bgColor, - i, - this); } -void RenderQueue::Initialize(shared_ptr const & primaryContext, +void TileRenderer::Initialize(shared_ptr const & primaryContext, shared_ptr const & resourceManager, double visualScale) { m_resourceManager = resourceManager; - for (unsigned i = 0; i < m_tasksCount; ++i) + + LOG(LINFO, ("initializing ", m_queue.ExecutorsCount(), " rendering threads")); + + int tileWidth = m_resourceManager->tileTextureWidth(); + int tileHeight = m_resourceManager->tileTextureHeight(); + + for (unsigned i = 0; i < m_queue.ExecutorsCount(); ++i) { - m_tasks[i].m_routine->InitializeGL(primaryContext->createShared(), - m_resourceManager, - visualScale); - m_tasks[i].m_thread.Create(m_tasks[i].m_routine); + DrawerYG::params_t params; + + params.m_resourceManager = m_resourceManager; + params.m_frameBuffer = make_shared_ptr(new yg::gl::FrameBuffer()); + + shared_ptr depthBuffer(new yg::gl::RenderBuffer(tileWidth, tileHeight, true)); + params.m_frameBuffer->setDepthBuffer(depthBuffer); + + params.m_glyphCacheID = m_resourceManager->renderThreadGlyphCacheID(i); + params.m_useOverlay = true; + params.m_threadID = i; + params.m_visualScale = visualScale; + params.m_skinName = m_skinName; + /* params.m_isDebugging = true; + params.m_drawPathes = false; + params.m_drawAreas = false; + params.m_drawTexts = false; */ + + m_drawerParams.push_back(params); + m_drawers.push_back(0); + m_renderContexts.push_back(primaryContext->createShared()); } + + m_queue.AddInitCommand(bind(&TileRenderer::InitializeThreadGL, this, _1)); + m_queue.AddFinCommand(bind(&TileRenderer::FinalizeThreadGL, this, _1)); + + m_queue.Start(); } -RenderQueue::~RenderQueue() +TileRenderer::~TileRenderer() { - m_renderCommands.Cancel(); - for (unsigned i = 0; i < m_tasksCount; ++i) - m_tasks[i].m_thread.Cancel(); - delete [] m_tasks; + m_queue.Cancel(); } -void RenderQueue::AddCommand( - RenderQueueRoutine::TRenderFn const & renderFn, - Tiler::RectInfo const & rectInfo, - size_t sequenceID, - RenderQueueRoutine::TCommandFinishedFn const & commandFinishedFn) +void TileRenderer::InitializeThreadGL(core::CommandsQueue::Environment const & env) +{ + m_renderContexts[env.GetThreadNum()]->makeCurrent(); + + m_drawers[env.GetThreadNum()] = new DrawerYG(m_drawerParams[env.GetThreadNum()]); +} + +void TileRenderer::FinalizeThreadGL(core::CommandsQueue::Environment const & env) +{ + m_renderContexts[env.GetThreadNum()]->endThreadDrawing(); + if (m_drawers[env.GetThreadNum()] != 0) + delete m_drawers[env.GetThreadNum()]; +} + +void TileRenderer::DrawTile(core::CommandsQueue::Environment const & env, + Tiler::RectInfo const & rectInfo, + int sequenceID) +{ + DrawerYG * drawer = m_drawers[env.GetThreadNum()]; + + ScreenBase frameScreen; + + unsigned tileWidth = m_resourceManager->tileTextureWidth(); + unsigned tileHeight = m_resourceManager->tileTextureHeight(); + + m2::RectI renderRect(1, 1, tileWidth - 1, tileHeight - 1); + + frameScreen.OnSize(renderRect); + + /// commands from the previous sequence are ignored + if (sequenceID < m_sequenceID) + return; + + if (HasTile(rectInfo)) + return; + + shared_ptr paintEvent = make_shared_ptr(new PaintEvent(drawer, &env)); + + my::Timer timer; + + shared_ptr tileTarget = m_resourceManager->renderTargets().Front(true); + + if (m_resourceManager->renderTargets().IsCancelled()) + return; + + drawer->screen()->setRenderTarget(tileTarget); + + shared_ptr tileInfoLayer(new yg::InfoLayer()); + + drawer->screen()->setInfoLayer(tileInfoLayer); + + drawer->beginFrame(); + drawer->clear(yg::Color(m_bgColor.r, m_bgColor.g, m_bgColor.b, 0)); + drawer->screen()->setClipRect(renderRect); + drawer->clear(m_bgColor); + + frameScreen.SetFromRect(rectInfo.m_rect); + + m2::RectD selectionRect; + + double const inflationSize = 24 * drawer->VisualScale(); + //frameScreen.PtoG(m2::Inflate(m2::RectD(renderRect), inflationSize, inflationSize), selectionRect); + frameScreen.PtoG(m2::RectD(renderRect), selectionRect); + + m_renderFn( + paintEvent, + frameScreen, + selectionRect, + rectInfo.m_drawScale + ); + + drawer->endFrame(); + drawer->screen()->resetInfoLayer(); + + double duration = timer.ElapsedSeconds(); + + if (env.IsCancelled()) + m_resourceManager->renderTargets().PushBack(tileTarget); + else + AddTile(rectInfo, Tile(tileTarget, tileInfoLayer, frameScreen, rectInfo, duration)); +} + +void TileRenderer::AddCommand(Tiler::RectInfo const & rectInfo, int sequenceID, core::CommandsQueue::Chain const & afterTileFns) { m_sequenceID = sequenceID; - m_renderCommands.PushBack(make_shared_ptr(new RenderQueueRoutine::Command(renderFn, rectInfo, sequenceID, commandFinishedFn))); - { - threads::ConditionGuard g(m_emptyAndFinished); - m_activeCommands++; - } + + core::CommandsQueue::Chain chain; + chain.addCommand(bind(&TileRenderer::DrawTile, this, _1, rectInfo, sequenceID)); + chain.addCommand(afterTileFns); + + m_queue.AddCommand(chain); } -void RenderQueue::AddWindowHandle(shared_ptr const & window) -{ - m_windowHandles.push_back(window); -} - -void RenderQueue::Invalidate() -{ - for_each(m_windowHandles.begin(), - m_windowHandles.end(), - bind(&WindowHandle::invalidate, _1)); -} - -void RenderQueue::MemoryWarning() -{ - for (unsigned i = 0; i < m_tasksCount; ++i) - m_tasks[i].m_routine->MemoryWarning(); -} - -void RenderQueue::EnterBackground() -{ - for (unsigned i = 0; i < m_tasksCount; ++i) - m_tasks[i].m_routine->EnterBackground(); -} - -void RenderQueue::EnterForeground() -{ - for (unsigned i = 0; i < m_tasksCount; ++i) - m_tasks[i].m_routine->EnterForeground(); -} - -TileCache & RenderQueue::GetTileCache() +TileCache & TileRenderer::GetTileCache() { return m_tileCache; } -size_t RenderQueue::CurrentSequence() const +void TileRenderer::WaitForEmptyAndFinished() { - return m_sequenceID; + m_queue.Join(); } -ThreadedList > & RenderQueue::RenderCommands() +bool TileRenderer::HasTile(Tiler::RectInfo const & rectInfo) { - return m_renderCommands; + m_tileCache.readLock(); + bool res = m_tileCache.hasTile(rectInfo); + m_tileCache.readUnlock(); + return res; } -void RenderQueue::WaitForEmptyAndFinished() +void TileRenderer::AddTile(Tiler::RectInfo const & rectInfo, Tile const & tile) { - threads::ConditionGuard g(m_emptyAndFinished); - if (m_activeCommands != 0) - m_emptyAndFinished.Wait(); + m_tileCache.writeLock(); + if (m_tileCache.hasTile(rectInfo)) + m_tileCache.touchTile(rectInfo); + else + m_tileCache.addTile(rectInfo, TileCache::Entry(tile, m_resourceManager)); + m_tileCache.writeUnlock(); } -void RenderQueue::FinishCommand() -{ - threads::ConditionGuard g(m_emptyAndFinished); - --m_activeCommands; - if (m_activeCommands == 0) - m_emptyAndFinished.Signal(); -} diff --git a/map/tile_renderer.hpp b/map/tile_renderer.hpp index 4430af7017..93077c5fbb 100644 --- a/map/tile_renderer.hpp +++ b/map/tile_renderer.hpp @@ -1,15 +1,18 @@ #pragma once -#include "render_queue_routine.hpp" +#include "render_policy.hpp" #include "tiler.hpp" #include "tile_cache.hpp" +#include "drawer_yg.hpp" #include "../geometry/screenbase.hpp" #include "../base/thread.hpp" #include "../base/threaded_list.hpp" +#include "../base/commands_queue.hpp" #include "../std/shared_ptr.hpp" +#include "../std/vector.hpp" namespace yg { @@ -22,77 +25,58 @@ namespace yg } class WindowHandle; +class DrawerYG; -class RenderQueue +class TileRenderer { private: - /// Single rendering task. Engine allocates tasks by number of cores - struct Task - { - threads::Thread m_thread; - RenderQueueRoutine * m_routine; - }; - - Task * m_tasks; - size_t m_tasksCount; - - size_t m_sequenceID; - - friend class RenderQueueRoutine; + core::CommandsQueue m_queue; shared_ptr m_resourceManager; - ThreadedList > m_renderCommands; + vector m_drawers; + vector m_drawerParams; + vector > m_renderContexts; TileCache m_tileCache; - /// A list of window handles to notify about ending rendering operations. - list > m_windowHandles; + RenderPolicy::TRenderFn m_renderFn; + string m_skinName; + yg::Color m_bgColor; + int m_sequenceID; - threads::Condition m_emptyAndFinished; + void InitializeThreadGL(core::CommandsQueue::Environment const & env); + void FinalizeThreadGL(core::CommandsQueue::Environment const & env); - /// number of currently active render commands - int m_activeCommands; + void DrawTile(core::CommandsQueue::Environment const & env, + Tiler::RectInfo const & rectInfo, + int sequenceID); public: /// constructor. - RenderQueue(string const & skinName, - unsigned scaleEtalonSize, - unsigned maxTilesCount, - unsigned tasksCount, - yg::Color const & bgColor); + TileRenderer(string const & skinName, + unsigned scaleEtalonSize, + unsigned maxTilesCount, + unsigned tasksCount, + yg::Color const & bgColor, + RenderPolicy::TRenderFn const & renderFn); /// destructor. - ~RenderQueue(); + ~TileRenderer(); /// set the primary context. it starts the rendering thread. void Initialize(shared_ptr const & primaryContext, shared_ptr const & resourceManager, double visualScale); /// add command to the commands queue. - void AddCommand(RenderQueueRoutine::TRenderFn const & renderFn, - Tiler::RectInfo const & rectInfo, - size_t sequenceID, - RenderQueueRoutine::TCommandFinishedFn const & commandFinishedFn); - /// add window handle to notify when rendering operation finishes - void AddWindowHandle(shared_ptr const & windowHandle); - /// free all possible memory caches. - void MemoryWarning(); - /// free all possible memory caches, opengl resources, - /// and make sure no opengl call will be made in background - void EnterBackground(); - /// load all necessary memory caches and opengl resources. - void EnterForeground(); + void AddCommand(Tiler::RectInfo const & rectInfo, + int sequenceID, + core::CommandsQueue::Chain const & afterTileFns = core::CommandsQueue::Chain()); /// get tile cache. TileCache & GetTileCache(); - /// number of the current tiler sequence to skip the old commands upon rendering. - size_t CurrentSequence() const; - /// common render commands queue for all rendering threads. - ThreadedList > & RenderCommands(); - /// invalidate all connected windows - void Invalidate(); /// wait on a condition variable for an empty queue. void WaitForEmptyAndFinished(); - void FinishCommand(); + bool HasTile(Tiler::RectInfo const & rectInfo); + void AddTile(Tiler::RectInfo const & rectInfo, Tile const & tile); }; diff --git a/map/tiler.cpp b/map/tiler.cpp index 580a1d70bb..333c18a0bc 100644 --- a/map/tiler.cpp +++ b/map/tiler.cpp @@ -123,23 +123,16 @@ void Tiler::seed(ScreenBase const & screen, m2::PointD const & centerPt) m_coverage.push_back(RectInfo(m_drawScale, m_tileScale, tileX, tileY, screenRect, centerPt)); /// sorting coverage elements - sort(m_coverage.begin(), m_coverage.end(), greater()); + sort(m_coverage.begin(), m_coverage.end(), less()); } Tiler::Tiler(size_t tileSize, size_t scaleEtalonSize) : m_sequenceID(0), m_tileSize(tileSize), m_scaleEtalonSize(scaleEtalonSize) {} -bool Tiler::hasTile() +void Tiler::visibleTiles(vector & tiles) { - return !m_coverage.empty(); -} - -Tiler::RectInfo const Tiler::nextTile() -{ - RectInfo r = m_coverage.back(); - m_coverage.pop_back(); - return r; + tiles = m_coverage; } size_t Tiler::sequenceID() const diff --git a/map/tiler.hpp b/map/tiler.hpp index 546d62e65e..c9740b354b 100644 --- a/map/tiler.hpp +++ b/map/tiler.hpp @@ -51,10 +51,7 @@ public: /// seed tiler with new screenBase. void seed(ScreenBase const & screenBase, m2::PointD const & centerPt); - /// check whether the sequence has next tile - bool hasTile(); - /// pop tile from the sequence and return it - RectInfo const nextTile(); + void visibleTiles(vector & tiles); size_t sequenceID() const; }; diff --git a/map/tiling_render_policy_mt.cpp b/map/tiling_render_policy_mt.cpp index a068aa7907..205653c651 100644 --- a/map/tiling_render_policy_mt.cpp +++ b/map/tiling_render_policy_mt.cpp @@ -11,31 +11,33 @@ #include "events.hpp" #include "tiling_render_policy_mt.hpp" #include "window_handle.hpp" +#include "screen_coverage.hpp" TilingRenderPolicyMT::TilingRenderPolicyMT(shared_ptr const & windowHandle, RenderPolicy::TRenderFn const & renderFn) : RenderPolicy(windowHandle, renderFn), - m_renderQueue(GetPlatform().SkinName(), + m_tileRenderer(GetPlatform().SkinName(), GetPlatform().ScaleEtalonSize(), GetPlatform().MaxTilesCount(), - 1/*GetPlatform().CpuCores()*/, - bgColor()), - m_tiler(GetPlatform().TileSize(), - GetPlatform().ScaleEtalonSize()) -// m_coverageGenerator(GetPlatform().TileSize(), -// GetPlatform().ScaleEtalonSize(), -// renderFn, -// &m_renderQueue) + 2/*GetPlatform().CpuCores()*/, + bgColor(), + renderFn), + m_coverageGenerator(GetPlatform().TileSize(), + GetPlatform().ScaleEtalonSize(), + &m_tileRenderer, + windowHandle) +/* m_screenCoverage(&m_tileRenderer, + GetPlatform().TileSize(), + GetPlatform().ScaleEtalonSize())*/ { - m_renderQueue.AddWindowHandle(windowHandle); } void TilingRenderPolicyMT::Initialize(shared_ptr const & primaryContext, shared_ptr const & resourceManager) { RenderPolicy::Initialize(primaryContext, resourceManager); - m_renderQueue.Initialize(primaryContext, resourceManager, GetPlatform().VisualScale()); -// m_coverageGenerator.Initialize(); + m_tileRenderer.Initialize(primaryContext, resourceManager, GetPlatform().VisualScale()); + m_coverageGenerator.Initialize(); } void TilingRenderPolicyMT::OnSize(int /*w*/, int /*h*/) @@ -44,84 +46,24 @@ void TilingRenderPolicyMT::OnSize(int /*w*/, int /*h*/) void TilingRenderPolicyMT::DrawFrame(shared_ptr const & e, ScreenBase const & currentScreen) { - DrawerYG * pDrawer = e->drawer().get(); + DrawerYG * pDrawer = e->drawer(); pDrawer->screen()->clear(bgColor()); -/* m_coverageGenerator.AddCoverageTask(currentScreen); + m_coverageGenerator.AddCoverScreenTask(currentScreen); ScreenCoverage coverage; - { - /// copying full coverage - threads::MutexGuard(m_coverageGenerator.Mutex()); - coverage = *m_coverageGenerator.CurrentCoverage(); - } + m_coverageGenerator.CopyCurrentCoverage(coverage); - /// drawing from full coverage - for (unsigned i = 0; i < coverage.m_tiles.size(); ++i) - { - shared_ptr tile = coverage.m_tiles[i]; + coverage.Draw(pDrawer->screen().get(), currentScreen); - size_t tileWidth = tile->m_renderTarget->width(); - size_t tileHeight = tile->m_renderTarget->height(); +/* m_screenCoverage.SetScreen(currentScreen); - pDrawer->screen()->blit(tile->m_renderTarget, tile->m_tileScreen, currentScreen, true, - yg::Color(), - m2::RectI(0, 0, tileWidth - 2, tileHeight - 2), - m2::RectU(1, 1, tileWidth - 1, tileHeight - 1)); - } - - coverage.m_infoLayer.draw(pDrawer->screen().get(), - coverage.m_screen.PtoGMatrix() * currentScreen.GtoPMatrix()); - - coverage.Clear();*/ - - m_infoLayer.clear(); - - m_tiler.seed(currentScreen, - currentScreen.GlobalRect().Center()); - - while (m_tiler.hasTile()) - { - Tiler::RectInfo ri = m_tiler.nextTile(); - - TileCache & tileCache = m_renderQueue.GetTileCache(); - - tileCache.readLock(); - - if (tileCache.hasTile(ri)) - { - tileCache.touchTile(ri); - Tile tile = tileCache.getTile(ri); - tileCache.readUnlock(); - - size_t tileWidth = tile.m_renderTarget->width(); - size_t tileHeight = tile.m_renderTarget->height(); - - pDrawer->screen()->blit(tile.m_renderTarget, tile.m_tileScreen, currentScreen, true, - yg::Color(), - m2::RectI(0, 0, tileWidth - 2, tileHeight - 2), - m2::RectU(1, 1, tileWidth - 1, tileHeight - 1)); - - m_infoLayer.merge(*tile.m_infoLayer.get(), - tile.m_tileScreen.PtoGMatrix() * currentScreen.GtoPMatrix()); - } - else - { - tileCache.readUnlock(); - m_renderQueue.AddCommand( - renderFn(), - ri, - m_tiler.sequenceID(), - bind(&WindowHandle::invalidate, windowHandle())); - } - } - - m_infoLayer.draw(pDrawer->screen().get(), - math::Identity()); + m_screenCoverage.Draw(pDrawer->screen().get(), currentScreen); + m_currentScreen = currentScreen;*/ } -RenderQueue & TilingRenderPolicyMT::GetRenderQueue() +TileRenderer & TilingRenderPolicyMT::GetTileRenderer() { - return m_renderQueue; + return m_tileRenderer; } diff --git a/map/tiling_render_policy_mt.hpp b/map/tiling_render_policy_mt.hpp index 91c0645488..edef1bf89e 100644 --- a/map/tiling_render_policy_mt.hpp +++ b/map/tiling_render_policy_mt.hpp @@ -1,9 +1,10 @@ #pragma once #include "render_policy.hpp" -#include "render_queue.hpp" +#include "tile_renderer.hpp" #include "coverage_generator.hpp" #include "tiler.hpp" +#include "screen_coverage.hpp" #include "../yg/info_layer.hpp" @@ -22,16 +23,17 @@ class TilingRenderPolicyMT : public RenderPolicy { private: - RenderQueue m_renderQueue; -// CoverageGenerator m_coverageGenerator; + TileRenderer m_tileRenderer; - yg::InfoLayer m_infoLayer; + CoverageGenerator m_coverageGenerator; - Tiler m_tiler; + ScreenBase m_currentScreen; + +// ScreenCoverage m_screenCoverage; protected: - RenderQueue & GetRenderQueue(); + TileRenderer & GetTileRenderer(); public: diff --git a/map/tiling_render_policy_st.cpp b/map/tiling_render_policy_st.cpp index 685deb0db2..e0f8c8158d 100644 --- a/map/tiling_render_policy_st.cpp +++ b/map/tiling_render_policy_st.cpp @@ -42,12 +42,12 @@ void TilingRenderPolicyST::Initialize(shared_ptr const & params.m_glyphCacheID = resourceManager()->guiThreadGlyphCacheID(); params.m_useOverlay = true; params.m_threadID = 0; + params.m_skinName = GetPlatform().SkinName(); + params.m_visualScale = GetPlatform().VisualScale(); - m_tileDrawer = make_shared_ptr(new DrawerYG(GetPlatform().SkinName(), params)); + m_tileDrawer = make_shared_ptr(new DrawerYG(params)); m_tileDrawer->onSize(tileWidth, tileHeight); - m_tileDrawer->SetVisualScale(GetPlatform().VisualScale()); - m2::RectI renderRect(1, 1, tileWidth - 1, tileWidth - 1); m_tileScreen.OnSize(renderRect); } @@ -57,7 +57,7 @@ void TilingRenderPolicyST::OnSize(int /*w*/, int /*h*/) void TilingRenderPolicyST::DrawFrame(shared_ptr const & e, ScreenBase const & currentScreen) { - DrawerYG * pDrawer = e->drawer().get(); + DrawerYG * pDrawer = e->drawer(); pDrawer->screen()->clear(bgColor()); @@ -66,9 +66,12 @@ void TilingRenderPolicyST::DrawFrame(shared_ptr const & e, ScreenBas m_tiler.seed(currentScreen, currentScreen.GlobalRect().Center()); - while (m_tiler.hasTile()) + vector visibleTiles; + m_tiler.visibleTiles(visibleTiles); + + for (unsigned i = 0; i < visibleTiles.size(); ++i) { - Tiler::RectInfo ri = m_tiler.nextTile(); + Tiler::RectInfo ri = visibleTiles[i]; m_tileCache.readLock(); @@ -91,7 +94,7 @@ void TilingRenderPolicyST::DrawFrame(shared_ptr const & e, ScreenBas else { m_tileCache.readUnlock(); - shared_ptr paintEvent(new PaintEvent(m_tileDrawer)); + shared_ptr paintEvent(new PaintEvent(m_tileDrawer.get())); shared_ptr tileTarget = resourceManager()->renderTargets().Front(true); shared_ptr tileInfoLayer(new yg::InfoLayer()); diff --git a/qt/draw_widget.cpp b/qt/draw_widget.cpp index e3d65d5c50..a549a2d6c3 100644 --- a/qt/draw_widget.cpp +++ b/qt/draw_widget.cpp @@ -171,7 +171,7 @@ namespace qt void DrawWidget::DoDraw(shared_ptr p) { - shared_ptr paintEvent(new PaintEvent(p)); + shared_ptr paintEvent(new PaintEvent(p.get())); m_framework->Paint(paintEvent); } diff --git a/qt/widgets.cpp b/qt/widgets.cpp index 38e9b55c34..ce285f7798 100644 --- a/qt/widgets.cpp +++ b/qt/widgets.cpp @@ -72,8 +72,10 @@ namespace qt p.m_dynamicPagesCount = 2; p.m_textPagesCount = 2; p.m_glyphCacheID = m_resourceManager->guiThreadGlyphCacheID(); + p.m_skinName = GetPlatform().SkinName(); + p.m_visualScale = GetPlatform().VisualScale(); - m_p = shared_ptr(new DrawerYG(GetPlatform().SkinName(), p)); + m_p = shared_ptr(new DrawerYG(p)); } }