From 3820545dfe7ca44a4ce9b10239809751e40666f8 Mon Sep 17 00:00:00 2001 From: rachytski Date: Mon, 30 Jan 2012 14:57:22 +0400 Subject: [PATCH] drawing "empty model" message in TilingRenderPolicyST. --- map/events.cpp | 38 +++++++++++++++++++++++++++ map/events.hpp | 29 +++++---------------- map/framework.cpp | 2 ++ map/map.pro | 3 ++- map/render_queue_routine.cpp | 4 +-- map/screen_coverage.cpp | 24 +++++++++++++++++ map/screen_coverage.hpp | 46 +++++++++++++++++++++------------ map/tile.cpp | 12 +++++---- map/tile.hpp | 4 ++- map/tile_renderer.cpp | 7 ++++- map/tiling_render_policy_st.cpp | 14 +++++++++- map/tiling_render_policy_st.hpp | 2 ++ 12 files changed, 135 insertions(+), 50 deletions(-) create mode 100644 map/events.cpp diff --git a/map/events.cpp b/map/events.cpp new file mode 100644 index 0000000000..990506ee39 --- /dev/null +++ b/map/events.cpp @@ -0,0 +1,38 @@ +#include "events.hpp" + +PaintEvent::PaintEvent(DrawerYG * drawer, + core::CommandsQueue::Environment const * env) + : m_drawer(drawer), + m_env(env), + m_isCancelled(false), + m_isEmptyDrawing(true) +{} + +DrawerYG * PaintEvent::drawer() const +{ + return m_drawer; +} + +void PaintEvent::cancel() +{ + ASSERT(m_env == 0, ()); + m_isCancelled = true; +} + +bool PaintEvent::isCancelled() const +{ + if (m_env) + return m_env->isCancelled(); + else + return m_isCancelled; +} + +bool PaintEvent::isEmptyDrawing() const +{ + return m_isEmptyDrawing; +} + +void PaintEvent::setIsEmptyDrawing(bool flag) +{ + m_isEmptyDrawing = flag; +} diff --git a/map/events.hpp b/map/events.hpp index a05f37c579..da5a0237cc 100644 --- a/map/events.hpp +++ b/map/events.hpp @@ -56,29 +56,14 @@ class PaintEvent DrawerYG * m_drawer; core::CommandsQueue::Environment const * m_env; bool m_isCancelled; + bool m_isEmptyDrawing; public: - PaintEvent(DrawerYG * drawer, core::CommandsQueue::Environment const * env = 0) - : m_drawer(drawer), m_env(env), m_isCancelled(false) - {} - - DrawerYG * drawer() const - { - return m_drawer; - } - - void Cancel() - { - ASSERT(m_env == 0, ()); - m_isCancelled = true; - } - - bool isCancelled() const - { - if (m_env) - return m_env->isCancelled(); - else - return m_isCancelled; - } + PaintEvent(DrawerYG * drawer, core::CommandsQueue::Environment const * env = 0); + DrawerYG * drawer() const; + void cancel(); + bool isCancelled() const; + bool isEmptyDrawing() const; + void setIsEmptyDrawing(bool flag); }; diff --git a/map/framework.cpp b/map/framework.cpp index bca370dd54..245af68e78 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -339,6 +339,8 @@ void Framework::DrawModel(shared_ptr const & e, } } + e->setIsEmptyDrawing(doDraw.IsEmptyDrawing()); + if (m_navigator.Update(m_timer.ElapsedSeconds())) Invalidate(); } diff --git a/map/map.pro b/map/map.pro index 6ad8062bb2..39bd6d8d29 100644 --- a/map/map.pro +++ b/map/map.pro @@ -78,7 +78,8 @@ SOURCES += \ basic_render_policy.cpp \ proto_to_yg_styles.cpp \ test_render_policy.cpp \ - queued_render_policy.cpp + queued_render_policy.cpp \ + events.cpp !iphone*:!bada*:!android* { HEADERS += qgl_render_context.hpp diff --git a/map/render_queue_routine.cpp b/map/render_queue_routine.cpp index be6d876daf..83b876723e 100644 --- a/map/render_queue_routine.cpp +++ b/map/render_queue_routine.cpp @@ -61,7 +61,7 @@ void RenderQueueRoutine::Cancel() if (m_currentRenderCommand != 0) { LOG(LDEBUG, ("cancelling current renderCommand in progress")); - m_currentRenderCommand->m_paintEvent->Cancel(); + m_currentRenderCommand->m_paintEvent->cancel(); } LOG(LDEBUG, ("waking up the sleeping thread...")); @@ -557,7 +557,7 @@ void RenderQueueRoutine::addCommand(render_fn_t const & fn, ScreenBase const & f /// else, if we are not panning, we should cancel the render command in progress to start a new one if ((m_currentRenderCommand != 0) && (!IsPanningAndRotate(m_currentRenderCommand->m_frameScreen, frameScreen))) - m_currentRenderCommand->m_paintEvent->Cancel(); + m_currentRenderCommand->m_paintEvent->cancel(); if (needToSignal) guard.Signal(); diff --git a/map/screen_coverage.cpp b/map/screen_coverage.cpp index 9deeedbfe2..2bfdeb8aeb 100644 --- a/map/screen_coverage.cpp +++ b/map/screen_coverage.cpp @@ -16,6 +16,7 @@ ScreenCoverage::ScreenCoverage() : m_tiler(0, 0), m_infoLayer(new yg::InfoLayer()), m_drawScale(0), + m_isEmptyDrawingCoverage(true), m_stylesCache(0) { m_infoLayer->setCouldOverlap(false); @@ -29,6 +30,7 @@ ScreenCoverage::ScreenCoverage(TileRenderer * tileRenderer, m_tiler(tileSize, scaleEtalonSize), m_infoLayer(new yg::InfoLayer()), m_drawScale(0), + m_isEmptyDrawingCoverage(true), m_coverageGenerator(coverageGenerator), m_stylesCache(0) { @@ -44,7 +46,9 @@ ScreenCoverage * ScreenCoverage::Clone() res->m_screen = m_screen; res->m_coverageGenerator = m_coverageGenerator; res->m_tileRects = m_tileRects; + res->m_newTileRects = m_newTileRects; res->m_drawScale = m_drawScale; + res->m_isEmptyDrawingCoverage = m_isEmptyDrawingCoverage; TileCache * tileCache = &m_tileRenderer->GetTileCache(); @@ -104,6 +108,9 @@ void ScreenCoverage::Merge(Tiler::RectInfo const & ri) tileCache->lockTile(ri); m_tiles.insert(tile); m_tileRects.erase(ri); + m_newTileRects.erase(ri); + + m_isEmptyDrawingCoverage &= tile->m_isEmptyDrawing; } } @@ -149,6 +156,7 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen) { m_screen = screen; + m_newTileRects.clear(); m_tiler.seed(m_screen, m_screen.GlobalRect().GlobalCenter()); vector allRects; @@ -171,6 +179,8 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen) m_drawScale = drawScale == -1 ? 0 : drawScale; + m_isEmptyDrawingCoverage = true; + for (unsigned i = 0; i < allRects.size(); ++i) { m_tileRects.insert(allRects[i]); @@ -180,6 +190,9 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen) tileCache->touchTile(ri); Tile const * tile = &tileCache->getTile(ri); ASSERT(tiles.find(tile) == tiles.end(), ()); + + m_isEmptyDrawingCoverage &= tile->m_isEmptyDrawing; + tiles.insert(tile); } else @@ -226,6 +239,7 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen) delete tileInfoLayerCopy; } + copy(newRects.begin(), newRects.end(), inserter(m_newTileRects, m_newTileRects.end())); /// clearing all old commands m_tileRenderer->ClearCommands(); /// setting new sequenceID @@ -302,3 +316,13 @@ int ScreenCoverage::GetDrawScale() const { return m_drawScale; } + +bool ScreenCoverage::IsEmptyDrawingCoverage() const +{ + return m_isEmptyDrawingCoverage; +} + +bool ScreenCoverage::IsPartialCoverage() const +{ + return !m_newTileRects.empty(); +} diff --git a/map/screen_coverage.hpp b/map/screen_coverage.hpp index 3e4731ecc4..fe9b05c234 100644 --- a/map/screen_coverage.hpp +++ b/map/screen_coverage.hpp @@ -32,22 +32,31 @@ class ScreenCoverage { private: - 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 - - typedef set TileSet; - + /// Queue to put new rendering tasks in + TileRenderer * m_tileRenderer; + /// 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 TileRectSet; - TileRectSet m_tileRects; //< rects, that forms a set of tiles in current rect. - - TileSet m_tiles; //< set of tiles, that are visible for the m_screen - scoped_ptr m_infoLayer; //< composite infoLayers for visible tiles - - //< scales, which are used in the tiles, drawn in the current screen. + /// All rects, including rects which corresponds to a tiles in m_tiles + TileRectSet m_tileRects; + /// Only rects, that should be drawn + TileRectSet m_newTileRects; + /// Typedef for a set of tiles, that are visible for the m_screen + typedef set TileSet; + TileSet m_tiles; + /// InfoLayer composed of infoLayers for visible tiles + scoped_ptr m_infoLayer; + /// Primary scale, which is used to draw tiles in m_screen. + /// Not all tiles could correspond to this value, as there could be tiles from + /// lower and higher level in the coverage to provide a smooth + /// scale transition experience int m_drawScale; + bool m_isEmptyDrawingCoverage; + CoverageGenerator * m_coverageGenerator; yg::StylesCache * m_stylesCache; @@ -64,14 +73,17 @@ public: size_t scaleEtalonSize); ScreenCoverage * Clone(); - + /// Is this screen coverage partial, which means that it contains non-drawn rects + bool IsPartialCoverage() const; + /// Is this screen coverage contains only empty tiles + bool IsEmptyDrawingCoverage() const; + /// Setters/Getters for current stylesCache void SetStylesCache(yg::StylesCache * stylesCache); yg::StylesCache * GetStylesCache() const; - + /// Getter for InfoLayer yg::InfoLayer * GetInfoLayer() const; - + /// Cache info layer on current style cache void CacheInfoLayer(); - /// 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 diff --git a/map/tile.cpp b/map/tile.cpp index 84570316c9..9bdc1ae5cf 100644 --- a/map/tile.cpp +++ b/map/tile.cpp @@ -8,15 +8,17 @@ Tile::Tile() {} Tile::Tile(shared_ptr const & renderTarget, - shared_ptr const & infoLayer, - ScreenBase const & tileScreen, - Tiler::RectInfo const & rectInfo, - double duration) + shared_ptr const & infoLayer, + ScreenBase const & tileScreen, + Tiler::RectInfo const & rectInfo, + double duration, + bool isEmptyDrawing) : m_renderTarget(renderTarget), m_infoLayer(infoLayer), m_tileScreen(tileScreen), m_rectInfo(rectInfo), - m_duration(duration) + m_duration(duration), + m_isEmptyDrawing(isEmptyDrawing) {} Tile::~Tile() diff --git a/map/tile.hpp b/map/tile.hpp index dea290d71e..0fdb929a51 100644 --- a/map/tile.hpp +++ b/map/tile.hpp @@ -23,6 +23,7 @@ struct Tile //< is performed on GUI thread. Tiler::RectInfo m_rectInfo; //< taken from tiler double m_duration; //< how long does it take to render tile + bool m_isEmptyDrawing; //< does this tile contains only coasts and oceans Tile(); @@ -30,7 +31,8 @@ struct Tile shared_ptr const & infoLayer, ScreenBase const & tileScreen, Tiler::RectInfo const & rectInfo, - double duration); + double duration, + bool isEmptyDrawing); ~Tile(); }; diff --git a/map/tile_renderer.cpp b/map/tile_renderer.cpp index 994551d9d7..948c184a93 100644 --- a/map/tile_renderer.cpp +++ b/map/tile_renderer.cpp @@ -220,7 +220,12 @@ void TileRenderer::DrawTile(core::CommandsQueue::Environment const & env, m_resourceManager->renderTargetTextures()->Free(tileTarget); } else - AddTile(rectInfo, Tile(tileTarget, tileInfoLayer, frameScreen, rectInfo, duration)); + AddTile(rectInfo, Tile(tileTarget, + tileInfoLayer, + frameScreen, + rectInfo, + duration, + paintEvent->isEmptyDrawing())); } void TileRenderer::AddCommand(Tiler::RectInfo const & rectInfo, int sequenceID, core::CommandsQueue::Chain const & afterTileFns) diff --git a/map/tiling_render_policy_st.cpp b/map/tiling_render_policy_st.cpp index ff124b0008..89402d9526 100644 --- a/map/tiling_render_policy_st.cpp +++ b/map/tiling_render_policy_st.cpp @@ -35,7 +35,8 @@ TilingRenderPolicyST::TilingRenderPolicyST(VideoTimer * videoTimer, yg::ResourceManager::Params const & rmParams, shared_ptr const & primaryRC) : QueuedRenderPolicy(GetPlatform().CpuCores() + 1, primaryRC, false), - m_drawScale(0) + m_drawScale(0), + m_isEmptyModel(false) { yg::ResourceManager::Params rmp = rmParams; @@ -256,6 +257,12 @@ void TilingRenderPolicyST::DrawFrame(shared_ptr const & e, ScreenBas m_drawScale = curCvg->GetDrawScale(); + if (!curCvg->IsEmptyDrawingCoverage()) + m_isEmptyModel = curCvg->IsEmptyDrawingCoverage(); + else + if (!curCvg->IsPartialCoverage()) + m_isEmptyModel = curCvg->IsEmptyDrawingCoverage(); + pDrawer->endFrame(); // yg::gl::g_doLogOGLCalls = false; @@ -288,3 +295,8 @@ bool TilingRenderPolicyST::IsTiling() const return true; } +bool TilingRenderPolicyST::IsEmptyModel() const +{ + return m_isEmptyModel; +} + diff --git a/map/tiling_render_policy_st.hpp b/map/tiling_render_policy_st.hpp index c1c09576a4..baee5f2964 100644 --- a/map/tiling_render_policy_st.hpp +++ b/map/tiling_render_policy_st.hpp @@ -38,6 +38,7 @@ private: int m_maxTilesCount; int m_drawScale; + bool m_isEmptyModel; protected: @@ -59,6 +60,7 @@ public: virtual void StopScale(); bool IsTiling() const; + bool IsEmptyModel() const; int GetDrawScale(ScreenBase const & s) const; void SetRenderFn(TRenderFn renderFn);