diff --git a/map/framework.cpp b/map/framework.cpp index 774d50fb5b..83c42bc198 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -29,6 +29,9 @@ #include "../yg/internal/opengl.hpp" #include "../yg/info_layer.hpp" +#include "tiling_render_policy_st.hpp" +#include "tiling_render_policy_mt.hpp" + using namespace feature; @@ -66,7 +69,7 @@ using namespace feature; } else if (m_centeringMode == ECenterOnly) CenterViewport(m_locationState.Position()); - UpdateNow(); + Invalidate(); } template @@ -76,23 +79,16 @@ using namespace feature; // { m_locationState.UpdateCompass(info); UpdateNow(); -// } + } } template FrameWork::FrameWork(shared_ptr windowHandle, size_t bottomShift) : m_windowHandle(windowHandle), + m_renderPolicy(new TilingRenderPolicyMT(windowHandle, bind(&this_type::PaintImpl, this, _1, _2, _3, _4))), m_isBenchmarking(GetPlatform().IsBenchmarking()), m_isBenchmarkInitialized(false), - m_bgColor(0xEE, 0xEE, 0xDD, 0xFF), - m_renderQueue(GetPlatform().SkinName(), - GetPlatform().IsBenchmarking(), - GetPlatform().ScaleEtalonSize(), - GetPlatform().MaxTilesCount(), - GetPlatform().CpuCores(), - m_bgColor), - m_isRedrawEnabled(true), m_metresMinWidth(20), m_minRulerWidth(97), m_centeringMode(EDoNothing), @@ -125,7 +121,6 @@ using namespace feature; m_informationDisplay.enableBenchmarkInfo(m_isBenchmarking); m_informationDisplay.setVisualScale(GetPlatform().VisualScale()); - m_renderQueue.AddWindowHandle(m_windowHandle); // initialize gps and compass subsystem GetLocationManager().SetGpsObserver( @@ -418,15 +413,15 @@ using namespace feature; template void FrameWork::InitBenchmark() { - DoGetBenchmarks doGet(m_benchmarks); - ForEachBenchmarkRecord(doGet); +// DoGetBenchmarks doGet(m_benchmarks); +// ForEachBenchmarkRecord(doGet); - m_curBenchmark = 0; +// m_curBenchmark = 0; - m_renderQueue.AddRenderCommandFinishedFn(bind(&this_type::BenchmarkCommandFinished, this)); - m_benchmarksTimer.Reset(); +// m_renderQueue.AddRenderCommandFinishedFn(bind(&this_type::BenchmarkCommandFinished, this)); +// m_benchmarksTimer.Reset(); - MarkBenchmarkResultsStart(); +// MarkBenchmarkResultsStart(); // NextBenchmarkCommand(); Invalidate(); @@ -437,40 +432,7 @@ using namespace feature; shared_ptr const & primaryContext, shared_ptr const & resourceManager) { - m_resourceManager = resourceManager; - - if (GetPlatform().IsMultiThreadedRendering()) - m_renderQueue.InitializeGL(primaryContext, m_resourceManager, GetPlatform().VisualScale()); - else - { - /// render single tile on the same thread - shared_ptr frameBuffer(new yg::gl::FrameBuffer()); - - unsigned tileWidth = m_resourceManager->tileTextureWidth(); - unsigned tileHeight = m_resourceManager->tileTextureHeight(); - - shared_ptr depthBuffer(new yg::gl::RenderBuffer(tileWidth, tileHeight, true)); - frameBuffer->setDepthBuffer(depthBuffer); - - DrawerYG::params_t params; - - shared_ptr infoLayer(new yg::InfoLayer()); - - params.m_resourceManager = m_resourceManager; - params.m_frameBuffer = frameBuffer; - params.m_infoLayer = infoLayer; - params.m_glyphCacheID = m_resourceManager->guiThreadGlyphCacheID(); - params.m_useOverlay = true; - params.m_threadID = 0; - - m_tileDrawer = make_shared_ptr(new DrawerYG(GetPlatform().SkinName(), params)); - m_tileDrawer->onSize(tileWidth, tileHeight); - - m_tileDrawer->SetVisualScale(GetPlatform().VisualScale()); - - m2::RectI renderRect(1, 1, tileWidth - 1, tileWidth - 1); - m_tileScreen.OnSize(renderRect); - } + m_renderPolicy->initialize(primaryContext, resourceManager); } template @@ -525,13 +487,6 @@ using namespace feature; m_navigator.SetFromRect(m_model.GetWorldRect()); } - template - void FrameWork::UpdateNow() - { -// AddRedrawCommand(); - Invalidate(); - } - template void FrameWork::Invalidate() { @@ -565,6 +520,8 @@ using namespace feature; m_navigator.OnSize(0, 0, w, h); + m_renderPolicy->onSize(w, h); + if ((m_isBenchmarking) && (!m_isBenchmarkInitialized)) { m_isBenchmarkInitialized = true; @@ -578,22 +535,13 @@ using namespace feature; return m_windowHandle->setUpdatesEnabled(doEnable); } - /// enabling/disabling AddRedrawCommand - template - void FrameWork::SetRedrawEnabled(bool isRedrawEnabled) - { - m_isRedrawEnabled = isRedrawEnabled; - Invalidate(); -// AddRedrawCommand(); - } - /// respond to device orientation changes template void FrameWork::SetOrientation(EOrientation orientation) { m_navigator.SetOrientation(orientation); m_locationState.SetOrientation(orientation); - UpdateNow(); + Invalidate(); } template @@ -610,8 +558,6 @@ using namespace feature; } /// Actual rendering function. - /// Called, as the renderQueue processes RenderCommand - /// Usually it happens in the separate thread. template void FrameWork::PaintImpl(shared_ptr e, ScreenBase const & screen, @@ -670,111 +616,8 @@ using namespace feature; }*/ e->drawer()->screen()->beginFrame(); - e->drawer()->screen()->clear(m_bgColor); - ScreenBase currentScreen = m_navigator.Screen(); - -// m_informationDisplay.enableEmptyModelMessage(m_renderQueue.renderStatePtr()->m_isEmptyModelActual); - -/* if (m_isBenchmarking) - currentScreen = m_renderQueue.renderState().m_actualScreen;*/ - -/* pDrawer->screen()->blit(m_renderQueue.renderState().m_actualTarget, - m_renderQueue.renderState().m_actualScreen, - currentScreen);*/ - - m_infoLayer.clear(); - - m_tiler.seed(currentScreen, - currentScreen.GlobalRect().Center(), - m_tileSize, - GetPlatform().ScaleEtalonSize()); - - while (m_tiler.hasTile()) - { - yg::Tiler::RectInfo ri = m_tiler.nextTile(); - - m_renderQueue.TileCache().lock(); - - if (m_renderQueue.TileCache().hasTile(ri)) - { - m_renderQueue.TileCache().touchTile(ri); - yg::Tile tile = m_renderQueue.TileCache().getTile(ri); - m_renderQueue.TileCache().unlock(); - - 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 - { - if (GetPlatform().IsMultiThreadedRendering()) - { - m_renderQueue.TileCache().unlock(); - m_renderQueue.AddCommand(bind(&this_type::PaintImpl, this, _1, _2, _3, _4), ri, m_tiler.seqNum()); - } - else - { - m_renderQueue.TileCache().unlock(); - shared_ptr paintEvent(new PaintEvent(m_tileDrawer)); - shared_ptr tileTarget = m_resourceManager->renderTargets().Front(true); - - shared_ptr tileInfoLayer(new yg::InfoLayer()); - - m_tileDrawer->screen()->setRenderTarget(tileTarget); - m_tileDrawer->screen()->setInfoLayer(tileInfoLayer); - - m_tileDrawer->beginFrame(); - - m_tileDrawer->clear(yg::Color(m_bgColor.r, m_bgColor.g, m_bgColor.b, 0)); - m2::RectI renderRect(1, 1, m_resourceManager->tileTextureWidth() - 1, m_resourceManager->tileTextureHeight() - 1); - m_tileDrawer->screen()->setClipRect(renderRect); - m_tileDrawer->clear(m_bgColor); - - m_tileScreen.SetFromRect(ri.m_rect); - - m2::RectD selectionRect; - - double inflationSize = 24 * GetPlatform().VisualScale(); - - m_tileScreen.PtoG(m2::Inflate(m2::RectD(renderRect), inflationSize, inflationSize), selectionRect); - - PaintImpl(paintEvent, - m_tileScreen, - selectionRect, - ri.m_drawScale); - - m_tileDrawer->endFrame(); - m_tileDrawer->screen()->resetInfoLayer(); - - yg::Tile tile(tileTarget, tileInfoLayer, m_tileScreen, ri, 0); - m_renderQueue.TileCache().lock(); - m_renderQueue.TileCache().addTile(ri, yg::TileCache::Entry(tile, m_resourceManager)); - m_renderQueue.TileCache().unlock(); - - m_renderQueue.TileCache().touchTile(ri); - tile = m_renderQueue.TileCache().getTile(ri); - m_renderQueue.TileCache().unlock(); - - 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.draw(pDrawer->screen().get(), - math::Identity()); + m_renderPolicy->drawFrame(e, m_navigator.Screen()); m_informationDisplay.doDraw(pDrawer); @@ -787,7 +630,7 @@ using namespace feature; void FrameWork::CenterViewport(m2::PointD const & pt) { m_navigator.CenterViewport(pt); - UpdateNow(); + Invalidate(); } int const theMetersFactor = 6; @@ -801,7 +644,7 @@ using namespace feature; rect.SetSizes(minSizeX, minSizeY); m_navigator.SetFromRect(rect); - UpdateNow(); + Invalidate(); } template @@ -857,7 +700,7 @@ using namespace feature; m_navigator.SetFromRect(clipRect); } - UpdateNow(); + Invalidate(); } /// Show all model by it's world rect. @@ -865,21 +708,14 @@ using namespace feature; void FrameWork::ShowAll() { SetMaxWorldRect(); - UpdateNow(); - } - - template - void FrameWork::Repaint() - { -// AddRedrawCommandSure(); Invalidate(); } template - void FrameWork::RepaintRect(m2::RectD const & rect) + void FrameWork::InvalidateRect(m2::RectD const & rect) { if (m_navigator.Screen().GlobalRect().IsIntersect(rect)) - Repaint(); + Invalidate(); } /// @name Drag implementation. @@ -923,7 +759,7 @@ using namespace feature; m_informationDisplay.setDebugPoint(0, m2::PointD(0, 0)); #endif - UpdateNow(); + Invalidate(); } template @@ -931,7 +767,7 @@ using namespace feature; { m_navigator.Move(azDir, factor); //m_tiler.seed(m_navigator.Screen(), m_tileSize); - UpdateNow(); + Invalidate(); } //@} @@ -946,7 +782,7 @@ using namespace feature; m_navigator.ScaleToPoint(pt, e.ScaleFactor(), m_timer.ElapsedSeconds()); - UpdateNow(); + Invalidate(); } template @@ -960,7 +796,8 @@ using namespace feature; { m_navigator.Scale(scale); //m_tiler.seed(m_navigator.Screen(), m_tileSize); - UpdateNow(); + + Invalidate(); } template @@ -1032,7 +869,7 @@ using namespace feature; m_informationDisplay.setDebugPoint(0, m2::PointD(0, 0)); #endif - UpdateNow(); + Invalidate(); } template diff --git a/map/framework.hpp b/map/framework.hpp index 71e5ef0c9a..558c342bea 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -56,6 +56,7 @@ typedef function SearchCallbackT; typedef function LocationRetrievedCallbackT; class DrawerYG; +class RenderPolicy; template < @@ -70,24 +71,16 @@ class FrameWork scoped_ptr m_pSearchEngine; model_t m_model; Navigator m_navigator; + shared_ptr m_windowHandle; + shared_ptr m_renderPolicy; bool m_isBenchmarking; bool m_isBenchmarkInitialized; - yg::Color m_bgColor; - - RenderQueue m_renderQueue; shared_ptr m_resourceManager; InformationDisplay m_informationDisplay; - yg::InfoLayer m_infoLayer; - - shared_ptr m_tileDrawer; - ScreenBase m_tileScreen; - - /// is AddRedrawCommand enabled? - bool m_isRedrawEnabled; double const m_metresMinWidth; int const m_minRulerWidth; @@ -104,9 +97,6 @@ class FrameWork mutable threads::Mutex m_modelSyn; - void AddRedrawCommandSure(); - void AddRedrawCommand(); - double m_maxDuration; m2::RectD m_maxDurationRect; m2::RectD m_curBenchmarkRect; @@ -185,7 +175,7 @@ public: // initializes model with locally downloaded maps storage.Init(bind(&FrameWork::AddMap, this, _1), bind(&FrameWork::RemoveMap, this, _1), - bind(&FrameWork::RepaintRect, this, _1), + bind(&FrameWork::InvalidateRect, this, _1), enumMapsFn); LOG(LINFO, ("Storage initialized")); } @@ -205,8 +195,10 @@ public: void Search(string const & text, SearchCallbackT callback); void SetMaxWorldRect(); - void UpdateNow(); + void Invalidate(); + void InvalidateRect(m2::RectD const & rect); + void SaveState(); bool LoadState(); @@ -215,9 +207,6 @@ public: bool SetUpdatesEnabled(bool doEnable); - /// enabling/disabling AddRedrawCommand - void SetRedrawEnabled(bool isRedrawEnabled); - /// respond to device orientation changes void SetOrientation(EOrientation orientation); @@ -229,8 +218,7 @@ public: void PaintImpl(shared_ptr e, ScreenBase const & screen, m2::RectD const & selectRect, - int scaleLevel - ); + int scaleLevel); /// Function for calling from platform dependent-paint function. void Paint(shared_ptr e); @@ -251,10 +239,6 @@ public: /// Show all model by it's world rect. void ShowAll(); - void Repaint(); - - void RepaintRect(m2::RectD const & rect); - /// @name Drag implementation. //@{ void StartDrag(DragEvent const & e); diff --git a/map/map.pro b/map/map.pro index 74ee503184..22b2290602 100644 --- a/map/map.pro +++ b/map/map.pro @@ -24,6 +24,10 @@ HEADERS += \ location_state.hpp \ benchmark_provider.hpp \ languages.hpp \ + render_policy.hpp \ + tiling_render_policy_mt.hpp \ + tiling_render_policy_st.hpp \ + tiling_render_policy.hpp SOURCES += \ feature_vec_model.cpp \ @@ -37,6 +41,10 @@ SOURCES += \ location_state.cpp \ benchmark_provider.cpp \ languages.cpp \ + render_policy.cpp \ + tiling_render_policy_mt.cpp \ + tiling_render_policy_st.cpp \ + tiling_render_policy.cpp !iphone*:!bada*:!android* { HEADERS += qgl_render_context.hpp diff --git a/map/render_policy.cpp b/map/render_policy.cpp new file mode 100644 index 0000000000..036e3bf729 --- /dev/null +++ b/map/render_policy.cpp @@ -0,0 +1,35 @@ +#include "../base/SRC_FIRST.hpp" + +#include "render_policy.hpp" + +RenderPolicy::RenderPolicy(shared_ptr const & windowHandle, render_fn_t const & renderFn) + : m_bgColor(0xEE, 0xEE, 0xDD, 0xFF), + m_windowHandle(windowHandle), + m_renderFn(renderFn) +{} + +yg::Color const & RenderPolicy::bgColor() const +{ + return m_bgColor; +} + +shared_ptr const & RenderPolicy::resourceManager() const +{ + return m_resourceManager; +} + +shared_ptr const & RenderPolicy::windowHandle() const +{ + return m_windowHandle; +} + +RenderPolicy::render_fn_t RenderPolicy::renderFn() const +{ + return m_renderFn; +} + +void RenderPolicy::initialize(shared_ptr const &, + shared_ptr const & resourceManager) +{ + m_resourceManager = resourceManager; +} diff --git a/map/render_policy.hpp b/map/render_policy.hpp new file mode 100644 index 0000000000..cdc7ab24c9 --- /dev/null +++ b/map/render_policy.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include "../yg/color.hpp" + +#include "../std/function.hpp" +#include "../std/shared_ptr.hpp" + +#include "../geometry/rect2d.hpp" + +class PaintEvent; +class ScreenBase; + +namespace yg +{ + namespace gl + { + class RenderContext; + } + + class ResourceManager; +} + +class WindowHandle; + +class RenderPolicy +{ +public: + + typedef function, ScreenBase const &, m2::RectD const &, int)> render_fn_t; + +private: + + yg::Color m_bgColor; + shared_ptr m_resourceManager; + shared_ptr m_windowHandle; + render_fn_t m_renderFn; + +protected: + + yg::Color const & bgColor() const; + shared_ptr const & resourceManager() const; + shared_ptr const & windowHandle() const; + render_fn_t renderFn() const; + +public: + + /// constructor + RenderPolicy(shared_ptr const & windowHandle, render_fn_t const & renderFn); + /// drawing single frame + virtual void drawFrame(shared_ptr const & paintEvent, ScreenBase const & currentScreen) = 0; + /// processing resize request + virtual void onSize(int w, int h) = 0; + /// initialize render policy + virtual void initialize(shared_ptr const & primaryContext, + shared_ptr const & resourceManager) = 0; + +}; diff --git a/map/render_queue_routine.hpp b/map/render_queue_routine.hpp index c02c82a2d1..42a430a7bc 100644 --- a/map/render_queue_routine.hpp +++ b/map/render_queue_routine.hpp @@ -10,6 +10,7 @@ #include "../yg/color.hpp" #include "../yg/tile_cache.hpp" #include "../yg/tiler.hpp" +#include "render_policy.hpp" class DrawerYG; @@ -43,7 +44,7 @@ class RenderQueueRoutine : public threads::IRoutine { public: - typedef function, ScreenBase const &, m2::RectD const &, int)> render_fn_t; + typedef RenderPolicy::render_fn_t render_fn_t; typedef function renderCommandFinishedFn; /// Single tile rendering command diff --git a/map/tiling_render_policy.cpp b/map/tiling_render_policy.cpp new file mode 100644 index 0000000000..3834bfb9dc --- /dev/null +++ b/map/tiling_render_policy.cpp @@ -0,0 +1,2 @@ +#include "../base/SRC_FIRST.hpp" +#include "tiling_render_policy.hpp" diff --git a/map/tiling_render_policy.hpp b/map/tiling_render_policy.hpp new file mode 100644 index 0000000000..a7a3bcb927 --- /dev/null +++ b/map/tiling_render_policy.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "render_policy.hpp" + +class TilingRenderPolicy : public RenderPolicy +{ +public: + + virtual void renderTile() = 0; + + void drawFrame(shared_ptr const & e, ScreenBase const & s); +}; diff --git a/map/tiling_render_policy_mt.cpp b/map/tiling_render_policy_mt.cpp new file mode 100644 index 0000000000..606b452a6b --- /dev/null +++ b/map/tiling_render_policy_mt.cpp @@ -0,0 +1,79 @@ +#include "../base/SRC_FIRST.hpp" + +#include "drawer_yg.hpp" +#include "events.hpp" +#include "tiling_render_policy_mt.hpp" + +#include "../geometry/screenbase.hpp" + +#include "../platform/platform.hpp" + + +TilingRenderPolicyMT::TilingRenderPolicyMT(shared_ptr const & windowHandle, + RenderPolicy::render_fn_t const & renderFn) + : RenderPolicy(windowHandle, renderFn), + m_renderQueue(GetPlatform().SkinName(), + GetPlatform().IsBenchmarking(), + GetPlatform().ScaleEtalonSize(), + GetPlatform().MaxTilesCount(), + GetPlatform().CpuCores(), + bgColor()) +{ + m_renderQueue.AddWindowHandle(windowHandle); +} + +void TilingRenderPolicyMT::initialize(shared_ptr const & primaryContext, + shared_ptr const & resourceManager) +{ + RenderPolicy::initialize(primaryContext, resourceManager); + m_renderQueue.InitializeGL(primaryContext, resourceManager, GetPlatform().VisualScale()); +} + +void TilingRenderPolicyMT::onSize(int w, int h) +{ +} + +void TilingRenderPolicyMT::drawFrame(shared_ptr const & e, ScreenBase const & currentScreen) +{ + DrawerYG * pDrawer = e->drawer().get(); + pDrawer->screen()->clear(bgColor()); + + m_infoLayer.clear(); + + m_tiler.seed(currentScreen, + currentScreen.GlobalRect().Center(), + GetPlatform().TileSize(), + GetPlatform().ScaleEtalonSize()); + + while (m_tiler.hasTile()) + { + yg::Tiler::RectInfo ri = m_tiler.nextTile(); + + m_renderQueue.TileCache().lock(); + + if (m_renderQueue.TileCache().hasTile(ri)) + { + m_renderQueue.TileCache().touchTile(ri); + yg::Tile tile = m_renderQueue.TileCache().getTile(ri); + m_renderQueue.TileCache().unlock(); + + 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 + { + m_renderQueue.TileCache().unlock(); + m_renderQueue.AddCommand(renderFn(), ri, m_tiler.seqNum()); + } + } + + m_infoLayer.draw(pDrawer->screen().get(), + math::Identity()); +} diff --git a/map/tiling_render_policy_mt.hpp b/map/tiling_render_policy_mt.hpp new file mode 100644 index 0000000000..d5dcf1d8b3 --- /dev/null +++ b/map/tiling_render_policy_mt.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include "render_policy.hpp" +#include "render_queue.hpp" + +#include "../yg/info_layer.hpp" +#include "../yg/tiler.hpp" + +namespace yg +{ + namespace gl + { + class RenderContext; + } + class ResourceManager; +} + +class WindowHandle; + +class TilingRenderPolicyMT : public RenderPolicy +{ +private: + + RenderQueue m_renderQueue; + + yg::InfoLayer m_infoLayer; + + yg::Tiler m_tiler; + +public: + + TilingRenderPolicyMT(shared_ptr const & windowHandle, + RenderPolicy::render_fn_t const & renderFn); + + void initialize(shared_ptr const & renderContext, + shared_ptr const & resourceManager); + + void onSize(int w, int h); + + void drawFrame(shared_ptr const & ev, ScreenBase const & currentScreen); +}; diff --git a/map/tiling_render_policy_st.cpp b/map/tiling_render_policy_st.cpp new file mode 100644 index 0000000000..fe09084ae9 --- /dev/null +++ b/map/tiling_render_policy_st.cpp @@ -0,0 +1,148 @@ +#include "../base/SRC_FIRST.hpp" + +#include "tiling_render_policy_st.hpp" + +#include "drawer_yg.hpp" +#include "window_handle.hpp" +#include "events.hpp" + +#include "../yg/framebuffer.hpp" +#include "../yg/renderbuffer.hpp" +#include "../yg/resource_manager.hpp" + +#include "../platform/platform.hpp" + + +TilingRenderPolicyST::TilingRenderPolicyST(shared_ptr const & windowHandle, + RenderPolicy::render_fn_t const & renderFn) + : RenderPolicy(windowHandle, renderFn), + m_tileCache(GetPlatform().MaxTilesCount() - 1) +{} + +void TilingRenderPolicyST::initialize(shared_ptr const & primaryContext, + shared_ptr const & rm) +{ + RenderPolicy::initialize(primaryContext, rm); + + /// render single tile on the same thread + shared_ptr frameBuffer(new yg::gl::FrameBuffer()); + + unsigned tileWidth = resourceManager()->tileTextureWidth(); + unsigned tileHeight = resourceManager()->tileTextureHeight(); + + shared_ptr depthBuffer(new yg::gl::RenderBuffer(tileWidth, tileHeight, true)); + frameBuffer->setDepthBuffer(depthBuffer); + + DrawerYG::params_t params; + + params.m_resourceManager = resourceManager(); + params.m_frameBuffer = frameBuffer; + params.m_glyphCacheID = resourceManager()->guiThreadGlyphCacheID(); + params.m_useOverlay = true; + params.m_threadID = 0; + + m_tileDrawer = make_shared_ptr(new DrawerYG(GetPlatform().SkinName(), params)); + m_tileDrawer->onSize(tileWidth, tileHeight); + + m_tileDrawer->SetVisualScale(GetPlatform().VisualScale()); + + m2::RectI renderRect(1, 1, tileWidth - 1, tileWidth - 1); + m_tileScreen.OnSize(renderRect); +} + +void TilingRenderPolicyST::onSize(int w, int h) +{} + +void TilingRenderPolicyST::drawFrame(shared_ptr const & e, ScreenBase const & currentScreen) +{ + DrawerYG * pDrawer = e->drawer().get(); + + pDrawer->screen()->clear(bgColor()); + + m_infoLayer.clear(); + + m_tiler.seed(currentScreen, + currentScreen.GlobalRect().Center(), + GetPlatform().TileSize(), + GetPlatform().ScaleEtalonSize()); + + while (m_tiler.hasTile()) + { + yg::Tiler::RectInfo ri = m_tiler.nextTile(); + + m_tileCache.lock(); + + if (m_tileCache.hasTile(ri)) + { + m_tileCache.touchTile(ri); + yg::Tile tile = m_tileCache.getTile(ri); + m_tileCache.unlock(); + + 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 + { + m_tileCache.unlock(); + shared_ptr paintEvent(new PaintEvent(m_tileDrawer)); + shared_ptr tileTarget = resourceManager()->renderTargets().Front(true); + + shared_ptr tileInfoLayer(new yg::InfoLayer()); + + m_tileDrawer->screen()->setRenderTarget(tileTarget); + m_tileDrawer->screen()->setInfoLayer(tileInfoLayer); + + m_tileDrawer->beginFrame(); + + yg::Color c = bgColor(); + + m_tileDrawer->clear(yg::Color(c.r, c.g, c.b, 0)); + m2::RectI renderRect(1, 1, resourceManager()->tileTextureWidth() - 1, resourceManager()->tileTextureHeight() - 1); + m_tileDrawer->screen()->setClipRect(renderRect); + m_tileDrawer->clear(c); + + m_tileScreen.SetFromRect(ri.m_rect); + + m2::RectD selectionRect; + + double inflationSize = 24 * GetPlatform().VisualScale(); + + m_tileScreen.PtoG(m2::Inflate(m2::RectD(renderRect), inflationSize, inflationSize), selectionRect); + + renderFn()(paintEvent, + m_tileScreen, + selectionRect, + ri.m_drawScale); + + m_tileDrawer->endFrame(); + m_tileDrawer->screen()->resetInfoLayer(); + + yg::Tile tile(tileTarget, tileInfoLayer, m_tileScreen, ri, 0); + m_tileCache.lock(); + m_tileCache.addTile(ri, yg::TileCache::Entry(tile, resourceManager())); + m_tileCache.unlock(); + + m_tileCache.lock(); + m_tileCache.touchTile(ri); + tile = m_tileCache.getTile(ri); + m_tileCache.unlock(); + + 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)); + + windowHandle()->invalidate(); + } + } +} diff --git a/map/tiling_render_policy_st.hpp b/map/tiling_render_policy_st.hpp new file mode 100644 index 0000000000..29716982f1 --- /dev/null +++ b/map/tiling_render_policy_st.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include "render_policy.hpp" + +#include "../yg/info_layer.hpp" +#include "../yg/tiler.hpp" +#include "../yg/tile_cache.hpp" + +#include "../std/shared_ptr.hpp" + +#include "../geometry/screenbase.hpp" + +class DrawerYG; +class WindowHandle; + +class TilingRenderPolicyST : public RenderPolicy +{ +private: + + shared_ptr m_tileDrawer; + ScreenBase m_tileScreen; + + yg::InfoLayer m_infoLayer; + yg::TileCache m_tileCache; + + yg::Tiler m_tiler; + +public: + + TilingRenderPolicyST(shared_ptr const & windowHandle, + RenderPolicy::render_fn_t const & renderFn); + + void initialize(shared_ptr const & renderContext, + shared_ptr const & resourceManager); + + void drawFrame(shared_ptr const & paintEvent, ScreenBase const & screenBase); + + void onSize(int w, int h); +}; diff --git a/qt/draw_widget.cpp b/qt/draw_widget.cpp index cba361c7a1..58b1ddf220 100644 --- a/qt/draw_widget.cpp +++ b/qt/draw_widget.cpp @@ -42,7 +42,7 @@ namespace qt void DrawWidget::UpdateNow() { - m_framework.UpdateNow(); + m_framework.Invalidate(); } bool DrawWidget::LoadState() @@ -145,7 +145,7 @@ namespace qt void DrawWidget::Repaint() { - m_framework.Repaint(); + m_framework.Invalidate(); } void DrawWidget::ScaleChanged(int action) @@ -178,7 +178,7 @@ namespace qt void DrawWidget::DoResize(int w, int h) { m_framework.OnSize(w, h); - m_framework.UpdateNow(); + m_framework.Invalidate(); UpdateScaleControl(); emit ViewportChanged(); } @@ -198,7 +198,6 @@ namespace qt if (e->button() == Qt::LeftButton) { - m_framework.SetRedrawEnabled(false); m_framework.StartDrag(get_drag_event(e)); setCursor(Qt::CrossCursor); @@ -241,7 +240,6 @@ namespace qt { if (m_isDrag && e->button() == Qt::LeftButton) { - m_framework.SetRedrawEnabled(true); m_framework.StopDrag(get_drag_event(e)); setCursor(Qt::ArrowCursor); @@ -251,7 +249,6 @@ namespace qt void DrawWidget::ScaleTimerElapsed() { - m_framework.SetRedrawEnabled(true); m_timer->stop(); } @@ -263,7 +260,6 @@ namespace qt if (m_timer->isActive()) m_timer->stop(); - m_framework.SetRedrawEnabled(false); m_timer->start(m_redrawInterval); //m_framework.Scale(exp(e->delta() / 360.0)); m_framework.ScaleToPoint(ScaleToPointEvent(e->pos().x(), e->pos().y(), exp(e->delta() / 360.0)));