diff --git a/map/basic_tiling_render_policy.cpp b/map/basic_tiling_render_policy.cpp index 18546a1119..bd6e195fab 100644 --- a/map/basic_tiling_render_policy.cpp +++ b/map/basic_tiling_render_policy.cpp @@ -75,11 +75,6 @@ void BasicTilingRenderPolicy::DrawFrame(shared_ptr const & e, Screen void BasicTilingRenderPolicy::EndFrame(shared_ptr const & e, ScreenBase const & s) { - ScreenCoverage * curCvg = &m_CoverageGenerator->CurrentCoverage(); - - DrawerYG * pDrawer = e->drawer(); - - curCvg->EndFrame(pDrawer->screen().get()); m_CoverageGenerator->Mutex().Unlock(); if (m_QueuedRenderer) diff --git a/map/coverage_generator.cpp b/map/coverage_generator.cpp index 7ddc244be0..d25116a2fe 100644 --- a/map/coverage_generator.cpp +++ b/map/coverage_generator.cpp @@ -24,54 +24,51 @@ CoverageGenerator::CoverageGenerator( RenderPolicy::TEmptyModelFn emptyModelFn) : m_queue(1), m_tileRenderer(tileRenderer), - m_workCoverage(0), - m_currentCoverage(new ScreenCoverage(tileRenderer, this)), m_sequenceID(0), m_windowHandle(windowHandle), - m_emptyModelFn(emptyModelFn) + m_emptyModelFn(emptyModelFn), + m_glQueue(glQueue), + m_skinName(skinName) { g_coverageGeneratorDestroyed = false; m_resourceManager = rm; - if (!glQueue) + + if (!m_glQueue) m_renderContext = primaryRC->createShared(); - m_currentStylesCache.reset(new yg::ResourceStyleCache(rm, - rm->cacheThreadGlyphCacheID(), - glQueue)); - - m_workStylesCache.reset(new yg::ResourceStyleCache(rm, - rm->cacheThreadGlyphCacheID(), - glQueue)); - - m_params.m_resourceManager = m_resourceManager; - m_params.m_frameBuffer = make_shared_ptr(new yg::gl::FrameBuffer()); - - if (glQueue) - m_params.m_renderQueue = glQueue; - - m_params.m_doUnbindRT = false; - m_params.m_isSynchronized = false; - m_params.m_glyphCacheID = m_resourceManager->cacheThreadGlyphCacheID(); - - m_cacheSkin.reset(loadSkin(m_resourceManager, - skinName, - 2, - 2)); - m_queue.AddInitCommand(bind(&CoverageGenerator::InitializeThreadGL, this)); m_queue.AddFinCommand(bind(&CoverageGenerator::FinalizeThreadGL, this)); m_queue.Start(); } +ScreenCoverage * CoverageGenerator::CreateCoverage() +{ + yg::gl::Screen::Params params; + + params.m_resourceManager = m_resourceManager; + params.m_renderQueue = m_glQueue; + + params.m_doUnbindRT = false; + params.m_isSynchronized = false; + params.m_glyphCacheID = m_resourceManager->cacheThreadGlyphCacheID(); + + shared_ptr screen(new yg::gl::Screen(params)); + shared_ptr skin(loadSkin(m_resourceManager, m_skinName, 2, 2)); + + screen->setSkin(skin); + + return new ScreenCoverage(m_tileRenderer, this, screen); +} + void CoverageGenerator::InitializeThreadGL() { if (m_renderContext) m_renderContext->makeCurrent(); - m_cacheScreen.reset(new yg::gl::Screen(m_params)); - m_cacheScreen->setSkin(m_cacheSkin); + m_workCoverage = CreateCoverage(); + m_currentCoverage = CreateCoverage(); } void CoverageGenerator::FinalizeThreadGL() @@ -85,14 +82,13 @@ CoverageGenerator::~CoverageGenerator() LOG(LINFO, ("cancelling coverage thread")); Cancel(); - LOG(LINFO, ("deleting cacheScreen")); - m_cacheScreen.reset(); - LOG(LINFO, ("deleting workCoverage")); delete m_workCoverage; + m_workCoverage = 0; LOG(LINFO, ("deleting currentCoverage")); delete m_currentCoverage; + m_currentCoverage = 0; g_coverageGeneratorDestroyed = true; } @@ -159,34 +155,22 @@ void CoverageGenerator::CoverScreen(ScreenBase const & screen, int sequenceID) if (sequenceID < m_sequenceID) return; - ASSERT(m_workCoverage == 0, ()); + m_currentCoverage->CopyInto(*m_workCoverage); - m_workCoverage = m_currentCoverage->Clone(); m_workCoverage->SetSequenceID(sequenceID); - m_workCoverage->SetResourceStyleCache(m_workStylesCache.get()); m_workCoverage->SetScreen(screen); if (!m_workCoverage->IsPartialCoverage() && m_workCoverage->IsEmptyDrawingCoverage()) AddCheckEmptyModelTask(sequenceID); - m_workCoverage->Cache(m_cacheScreen.get()); + m_workCoverage->Cache(); { threads::MutexGuard g(m_mutex); - - /// test that m_workCoverage->InfoLayer doesn't have - /// the same elements as m_currentCoverage->InfoLayer - ASSERT(!m_workCoverage->GetInfoLayer()->checkHasEquals(m_currentCoverage->GetInfoLayer()), ()); - ASSERT(m_workCoverage->GetInfoLayer()->checkCached(m_workStylesCache.get()), ()); - swap(m_currentCoverage, m_workCoverage); - swap(m_currentStylesCache, m_workStylesCache); - - ASSERT(m_currentCoverage->GetResourceStyleCache() == m_currentStylesCache.get(), ()); } - delete m_workCoverage; - m_workCoverage = 0; + m_workCoverage->Clear(); m_windowHandle->invalidate(); } @@ -208,35 +192,21 @@ void CoverageGenerator::MergeTile(Tiler::RectInfo const & rectInfo, int sequence return; } - ASSERT(m_workCoverage == 0, ()); - - m_workCoverage = m_currentCoverage->Clone(); + m_currentCoverage->CopyInto(*m_workCoverage); m_workCoverage->SetSequenceID(sequenceID); - m_workCoverage->SetResourceStyleCache(m_workStylesCache.get()); m_workCoverage->Merge(rectInfo); if (!m_workCoverage->IsPartialCoverage() && m_workCoverage->IsEmptyDrawingCoverage()) AddCheckEmptyModelTask(sequenceID); - m_workCoverage->Cache(m_cacheScreen.get()); + m_workCoverage->Cache(); { threads::MutexGuard g(m_mutex); - - /// test that m_workCoverage->InfoLayer doesn't have - /// the same elements as m_currentCoverage->InfoLayer - ASSERT(!m_workCoverage->GetInfoLayer()->checkHasEquals(m_currentCoverage->GetInfoLayer()), ()); - ASSERT(m_workCoverage->GetInfoLayer()->checkCached(m_workStylesCache.get()), ()); - swap(m_currentCoverage, m_workCoverage); - swap(m_currentStylesCache, m_workStylesCache); - - ASSERT(m_currentCoverage->GetResourceStyleCache() == m_currentStylesCache.get(), ()); } - /// we should delete workCoverage - delete m_workCoverage; - m_workCoverage = 0; + m_workCoverage->Clear(); m_windowHandle->invalidate(); } diff --git a/map/coverage_generator.hpp b/map/coverage_generator.hpp index 2960d2078b..0377994ce0 100644 --- a/map/coverage_generator.hpp +++ b/map/coverage_generator.hpp @@ -46,9 +46,6 @@ private: ScreenCoverage * m_workCoverage; ScreenCoverage * m_currentCoverage; - shared_ptr m_workStylesCache; - shared_ptr m_currentStylesCache; - ScreenBase m_currentScreen; int m_sequenceID; @@ -58,10 +55,10 @@ private: RenderPolicy::TEmptyModelFn m_emptyModelFn; - /// screen for caching ScreenCoverage - yg::gl::Screen::Params m_cacheParams; - shared_ptr m_cacheScreen; - shared_ptr m_cacheSkin; + yg::gl::PacketsQueue * m_glQueue; + string m_skinName; + + ScreenCoverage * CreateCoverage(); public: diff --git a/map/screen_coverage.cpp b/map/screen_coverage.cpp index 964de2759c..1af4fa9047 100644 --- a/map/screen_coverage.cpp +++ b/map/screen_coverage.cpp @@ -22,47 +22,45 @@ ScreenCoverage::ScreenCoverage() m_infoLayer(new yg::InfoLayer()), m_isEmptyDrawingCoverage(false), m_isEmptyModelAtCoverageCenter(true), - m_leafTilesToRender(0), - m_stylesCache(0) + m_leafTilesToRender(0) { m_infoLayer->setCouldOverlap(false); } ScreenCoverage::ScreenCoverage(TileRenderer * tileRenderer, - CoverageGenerator * coverageGenerator) + CoverageGenerator * coverageGenerator, + shared_ptr const & cacheScreen) : m_tileRenderer(tileRenderer), + m_coverageGenerator(coverageGenerator), m_infoLayer(new yg::InfoLayer()), m_isEmptyDrawingCoverage(false), m_isEmptyModelAtCoverageCenter(true), m_leafTilesToRender(0), - m_coverageGenerator(coverageGenerator), - m_stylesCache(0) + m_cacheScreen(cacheScreen) { m_infoLayer->setCouldOverlap(false); } -ScreenCoverage * ScreenCoverage::Clone() +void ScreenCoverage::CopyInto(ScreenCoverage & cvg) { - ScreenCoverage * res = new ScreenCoverage(); - - res->m_tileRenderer = m_tileRenderer; - res->m_tiler = m_tiler; - res->m_screen = m_screen; - res->m_coverageGenerator = m_coverageGenerator; - res->m_tileRects = m_tileRects; - res->m_newTileRects = m_newTileRects; - res->m_newLeafTileRects = m_newLeafTileRects; - res->m_isEmptyDrawingCoverage = m_isEmptyDrawingCoverage; - res->m_isEmptyModelAtCoverageCenter = m_isEmptyModelAtCoverageCenter; - res->m_leafTilesToRender = m_leafTilesToRender; + cvg.m_tileRenderer = m_tileRenderer; + cvg.m_tiler = m_tiler; + cvg.m_screen = m_screen; + cvg.m_coverageGenerator = m_coverageGenerator; + cvg.m_tileRects = m_tileRects; + cvg.m_newTileRects = m_newTileRects; + cvg.m_newLeafTileRects = m_newLeafTileRects; + cvg.m_isEmptyDrawingCoverage = m_isEmptyDrawingCoverage; + cvg.m_isEmptyModelAtCoverageCenter = m_isEmptyModelAtCoverageCenter; + cvg.m_leafTilesToRender = m_leafTilesToRender; TileCache * tileCache = &m_tileRenderer->GetTileCache(); tileCache->Lock(); - res->m_tiles = m_tiles; + cvg.m_tiles = m_tiles; - for (TTileSet::const_iterator it = res->m_tiles.begin(); it != res->m_tiles.end(); ++it) + for (TTileSet::const_iterator it = cvg.m_tiles.begin(); it != cvg.m_tiles.end(); ++it) { Tiler::RectInfo const & ri = (*it)->m_rectInfo; tileCache->LockTile(ri); @@ -70,22 +68,32 @@ ScreenCoverage * ScreenCoverage::Clone() tileCache->Unlock(); - res->m_infoLayer.reset(); - res->m_infoLayer.reset(m_infoLayer->clone()); - res->m_stylesCache = 0; - res->m_displayList.reset(); - - return res; + cvg.m_infoLayer.reset(m_infoLayer->clone()); } -void ScreenCoverage::SetResourceStyleCache(yg::ResourceStyleCache * stylesCache) +void ScreenCoverage::Clear() { - m_stylesCache = stylesCache; -} + m_tileRects.clear(); + m_newTileRects.clear(); + m_newLeafTileRects.clear(); + m_infoLayer->clear(); + m_isEmptyDrawingCoverage = false; + m_isEmptyModelAtCoverageCenter = true; + m_leafTilesToRender = 0; -yg::ResourceStyleCache * ScreenCoverage::GetResourceStyleCache() const -{ - return m_stylesCache; + TileCache * tileCache = &m_tileRenderer->GetTileCache(); + + tileCache->Lock(); + + for (TTileSet::const_iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) + { + Tiler::RectInfo const & ri = (*it)->m_rectInfo; + tileCache->UnlockTile(ri); + } + + tileCache->Unlock(); + + m_tiles.clear(); } void ScreenCoverage::Merge(Tiler::RectInfo const & ri) @@ -145,15 +153,15 @@ void ScreenCoverage::Merge(Tiler::RectInfo const & ri) } } -void ScreenCoverage::Cache(yg::gl::Screen *screen) +void ScreenCoverage::Cache() { /// caching tiles blitting commands. m_displayList.reset(); - m_displayList.reset(screen->createDisplayList()); + m_displayList.reset(m_cacheScreen->createDisplayList()); - screen->beginFrame(); - screen->setDisplayList(m_displayList.get()); + m_cacheScreen->beginFrame(); + m_cacheScreen->setDisplayList(m_displayList.get()); vector infos; @@ -175,46 +183,17 @@ void ScreenCoverage::Cache(yg::gl::Screen *screen) } if (!infos.empty()) - screen->blit(&infos[0], infos.size(), true); + m_cacheScreen->blit(&infos[0], infos.size(), true); - screen->setDisplayList(0); - screen->endFrame(); + m_infoLayer->draw(m_cacheScreen.get(), math::Identity()); - /// caching InfoLayer into texture - - if (!m_stylesCache) - { - LOG(LWARNING, ("no styles cache")); - return; - } - - m_infoLayer->cache(m_stylesCache); - - /// asserting, that all visible elements is cached - ASSERT(m_infoLayer->checkCached(m_stylesCache), ()); - - m_stylesCache->upload(); - - /// and then into display list - - screen->beginFrame(); - screen->setAdditionalSkinPage(m_stylesCache->cachePage()); - screen->setDisplayList(m_displayList.get()); - - m_infoLayer->draw(screen, math::Identity()); - - screen->setDisplayList(0); - screen->clearAdditionalSkinPage(); - screen->endFrame(); + m_cacheScreen->setDisplayList(0); + m_cacheScreen->endFrame(); /// completing commands that was immediately executed /// while recording of displayList(for example UnlockStorage) - screen->completeCommands(); -} - -void ScreenCoverage::Remove(Tile const *) -{ + m_cacheScreen->completeCommands(); } void ScreenCoverage::SetScreen(ScreenBase const & screen) @@ -376,17 +355,7 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen) ScreenCoverage::~ScreenCoverage() { - TileCache * tileCache = &m_tileRenderer->GetTileCache(); - - tileCache->Lock(); - - for (TTileSet::const_iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) - { - Tiler::RectInfo const & ri = (*it)->m_rectInfo; - tileCache->UnlockTile(ri); - } - - tileCache->Unlock(); + Clear(); } void ScreenCoverage::Draw(yg::gl::Screen * s, ScreenBase const & screen) @@ -400,11 +369,6 @@ yg::InfoLayer * ScreenCoverage::GetInfoLayer() const return m_infoLayer.get(); } -void ScreenCoverage::EndFrame(yg::gl::Screen *s) -{ - s->clearAdditionalSkinPage(); -} - int ScreenCoverage::GetDrawScale() const { return min(m_tiler.tileScale(), scales::GetUpperScale()); diff --git a/map/screen_coverage.hpp b/map/screen_coverage.hpp index a223e618c7..30a2eeb5c0 100644 --- a/map/screen_coverage.hpp +++ b/map/screen_coverage.hpp @@ -26,54 +26,71 @@ class CoverageGenerator; class ScreenCoverage { private: - /// Unique ID of this screen coverage int m_sequenceID; /// Queue to put new rendering tasks in TileRenderer * m_tileRenderer; + /// Coverage generator + CoverageGenerator * m_coverageGenerator; /// Tiler to compute visible and predicted tiles Tiler m_tiler; /// Last covered screen ScreenBase m_screen; /// Container for a rects, that forms a set of tiles in the m_screen typedef set TTileRectSet; - /// All rects, including rects which corresponds to a tiles in m_tiles + /// This set contains all rects that was returned by Tiler. + /// This includes already drawn rects, and rects which is not drawn yet. TTileRectSet m_tileRects; - /// Only rects, that should be drawn + /// This set contains rects, which was send to TileRenderer to draw TTileRectSet m_newTileRects; - /// Only leaf rects, that should be drawn + /// Subset of newTileRects, only leaf rects that should be drawn + /// For quick check for Partial/NonPartial coverage TTileRectSet m_newLeafTileRects; /// Typedef for a set of tiles, that are visible for the m_screen typedef set TTileSet; + /// This set contains all tiles that are found in the TileCache. + /// Tiles in this set are locked to prevent their deletion + /// from TileCache while drawing them TTileSet m_tiles; /// InfoLayer composed of infoLayers for visible tiles scoped_ptr m_infoLayer; - /// Does this coverage holds only tiles that are empty + + /// State flags + + /// Does the all leaf tiles in this coverage are empty? bool m_isEmptyDrawingCoverage; - /// Does the model empty at the screen center? + /// If the map model empty at the screen center? bool m_isEmptyModelAtCoverageCenter; - /// How many "leaf" tiles we should render to cover the screen + /// How many "leaf" tiles we should render to cover the screen. + /// This is efficiently the size of newLeafTileRects and is cached for + /// quick check. int m_leafTilesToRender; - - CoverageGenerator * m_coverageGenerator; - yg::ResourceStyleCache * m_stylesCache; - + /// Screen, which is used for caching of this ScreenCoverage into DisplayList + shared_ptr m_cacheScreen; + /// DisplayList which holds cached ScreenCoverage shared_ptr m_displayList; + /// Direct copying is prohibited. ScreenCoverage(ScreenCoverage const & src); ScreenCoverage const & operator=(ScreenCoverage const & src); + /// For each tile in m_tiles merge it's infoLayer into the big one. void MergeInfoLayer(); public: + /// Default Constructor ScreenCoverage(); - ~ScreenCoverage(); + /// Constructor ScreenCoverage(TileRenderer * tileRenderer, - CoverageGenerator * coverageGenerator); - - ScreenCoverage * Clone(); - + CoverageGenerator * coverageGenerator, + shared_ptr const & cacheScreen); + /// Destructor + ~ScreenCoverage(); + /// Copy all needed information into specified ScreenCoverage + void CopyInto(ScreenCoverage & cvg); + /// Make screen coverage empty + void Clear(); /// set unique ID for all actions, used to compute this coverage void SetSequenceID(int id); /// get unique ID for all actions, used to compute this coverage @@ -86,23 +103,16 @@ public: bool IsEmptyModelAtCoverageCenter() const; /// Check, whether the model is empty at the center of the coverage. void CheckEmptyModelAtCoverageCenter(); - /// Setters/Getters for current stylesCache - void SetResourceStyleCache(yg::ResourceStyleCache * stylesCache); - yg::ResourceStyleCache * GetResourceStyleCache() const; /// Getter for InfoLayer yg::InfoLayer * GetInfoLayer() const; - /// Cache entire coverage in display list - void Cache(yg::gl::Screen * screen); + /// Cache coverage in display list + void Cache(); /// 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); /// draw screen coverage void Draw(yg::gl::Screen * s, ScreenBase const & currentScreen); - /// perform end frame - void EndFrame(yg::gl::Screen * s); /// get draw scale for the tiles in the current coverage /// Not all tiles in coverage could correspond to this value, /// as there could be tiles from lower and higher level in the diff --git a/map/tiling_render_policy_mt.cpp b/map/tiling_render_policy_mt.cpp index 83ee70e368..78b75cb710 100644 --- a/map/tiling_render_policy_mt.cpp +++ b/map/tiling_render_policy_mt.cpp @@ -32,6 +32,18 @@ TilingRenderPolicyMT::TilingRenderPolicyMT(VideoTimer * videoTimer, false, true); + rmp.m_fontTexturesParams = yg::ResourceManager::TexturePoolParams(256, + 256, + 1, + rmp.m_texFormat, + true, + true, + true, + 1, + "primaryTexture", + true, + true); + rmp.m_primaryStoragesParams = yg::ResourceManager::StoragePoolParams(50000 * sizeof(yg::gl::Vertex), sizeof(yg::gl::Vertex), 100000 * sizeof(unsigned short), diff --git a/map/tiling_render_policy_st.cpp b/map/tiling_render_policy_st.cpp index eb7af9ed38..efee871763 100644 --- a/map/tiling_render_policy_st.cpp +++ b/map/tiling_render_policy_st.cpp @@ -35,6 +35,18 @@ TilingRenderPolicyST::TilingRenderPolicyST(VideoTimer * videoTimer, true, true); + rmp.m_fontTexturesParams = yg::ResourceManager::TexturePoolParams(256, + 256, + 1, + rmp.m_texFormat, + true, + true, + true, + 1, + "primaryTexture", + true, + true); + rmp.m_primaryStoragesParams = yg::ResourceManager::StoragePoolParams(6000 * sizeof(yg::gl::Vertex), sizeof(yg::gl::Vertex), 9000 * sizeof(unsigned short), diff --git a/yg/renderer.cpp b/yg/renderer.cpp index 31c80032b0..995b0e8dfc 100644 --- a/yg/renderer.cpp +++ b/yg/renderer.cpp @@ -53,10 +53,13 @@ namespace yg { m_isRendering = true; - m_frameBuffer->setRenderTarget(m_renderTarget); - m_frameBuffer->setDepthBuffer(m_depthBuffer); + if (m_frameBuffer) + { + m_frameBuffer->setRenderTarget(m_renderTarget); + m_frameBuffer->setDepthBuffer(m_depthBuffer); - processCommand(make_shared_ptr(new ChangeFrameBuffer(m_frameBuffer))); + processCommand(make_shared_ptr(new ChangeFrameBuffer(m_frameBuffer))); + } // checkStatus(); }