RenderPolicy implementation

introduced RenderPolicy interface to separate rendering code from FrameWork class. implemented single-threaded and multi-threaded tile rendering policies (TilingRenderPolicyST and TilingRenderPolicyMT classes). using TilingRenderPolicyMT as the default render policy.
This commit is contained in:
rachytski 2011-07-15 02:35:18 +03:00 committed by Alex Zolotarev
parent bc1f646c75
commit cec98bb6b9
13 changed files with 462 additions and 223 deletions

View file

@ -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 <typename TModel>
@ -76,23 +79,16 @@ using namespace feature;
// {
m_locationState.UpdateCompass(info);
UpdateNow();
// }
}
}
template <typename TModel>
FrameWork<TModel>::FrameWork(shared_ptr<WindowHandle> 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 <typename TModel>
void FrameWork<TModel>::InitBenchmark()
{
DoGetBenchmarks<Benchmark> doGet(m_benchmarks);
ForEachBenchmarkRecord(doGet);
// DoGetBenchmarks<Benchmark> 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<yg::gl::RenderContext> const & primaryContext,
shared_ptr<yg::ResourceManager> 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<yg::gl::FrameBuffer> frameBuffer(new yg::gl::FrameBuffer());
unsigned tileWidth = m_resourceManager->tileTextureWidth();
unsigned tileHeight = m_resourceManager->tileTextureHeight();
shared_ptr<yg::gl::RenderBuffer> depthBuffer(new yg::gl::RenderBuffer(tileWidth, tileHeight, true));
frameBuffer->setDepthBuffer(depthBuffer);
DrawerYG::params_t params;
shared_ptr<yg::InfoLayer> 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 <typename TModel>
@ -525,13 +487,6 @@ using namespace feature;
m_navigator.SetFromRect(m_model.GetWorldRect());
}
template <typename TModel>
void FrameWork<TModel>::UpdateNow()
{
// AddRedrawCommand();
Invalidate();
}
template <typename TModel>
void FrameWork<TModel>::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 <typename TModel>
void FrameWork<TModel>::SetRedrawEnabled(bool isRedrawEnabled)
{
m_isRedrawEnabled = isRedrawEnabled;
Invalidate();
// AddRedrawCommand();
}
/// respond to device orientation changes
template <typename TModel>
void FrameWork<TModel>::SetOrientation(EOrientation orientation)
{
m_navigator.SetOrientation(orientation);
m_locationState.SetOrientation(orientation);
UpdateNow();
Invalidate();
}
template <typename TModel>
@ -610,8 +558,6 @@ using namespace feature;
}
/// Actual rendering function.
/// Called, as the renderQueue processes RenderCommand
/// Usually it happens in the separate thread.
template <typename TModel>
void FrameWork<TModel>::PaintImpl(shared_ptr<PaintEvent> 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> paintEvent(new PaintEvent(m_tileDrawer));
shared_ptr<yg::gl::BaseTexture> tileTarget = m_resourceManager->renderTargets().Front(true);
shared_ptr<yg::InfoLayer> 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<double, 3>());
m_renderPolicy->drawFrame(e, m_navigator.Screen());
m_informationDisplay.doDraw(pDrawer);
@ -787,7 +630,7 @@ using namespace feature;
void FrameWork<TModel>::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 <typename TModel>
@ -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<TModel>::ShowAll()
{
SetMaxWorldRect();
UpdateNow();
}
template <typename TModel>
void FrameWork<TModel>::Repaint()
{
// AddRedrawCommandSure();
Invalidate();
}
template <typename TModel>
void FrameWork<TModel>::RepaintRect(m2::RectD const & rect)
void FrameWork<TModel>::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 <typename TModel>
@ -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 <typename TModel>
@ -960,7 +796,8 @@ using namespace feature;
{
m_navigator.Scale(scale);
//m_tiler.seed(m_navigator.Screen(), m_tileSize);
UpdateNow();
Invalidate();
}
template <typename TModel>
@ -1032,7 +869,7 @@ using namespace feature;
m_informationDisplay.setDebugPoint(0, m2::PointD(0, 0));
#endif
UpdateNow();
Invalidate();
}
template<typename TModel>

View file

@ -56,6 +56,7 @@ typedef function<void (search::Result const &)> SearchCallbackT;
typedef function<void (void)> LocationRetrievedCallbackT;
class DrawerYG;
class RenderPolicy;
template
<
@ -70,24 +71,16 @@ class FrameWork
scoped_ptr<search::Engine> m_pSearchEngine;
model_t m_model;
Navigator m_navigator;
shared_ptr<WindowHandle> m_windowHandle;
shared_ptr<RenderPolicy> m_renderPolicy;
bool m_isBenchmarking;
bool m_isBenchmarkInitialized;
yg::Color m_bgColor;
RenderQueue m_renderQueue;
shared_ptr<yg::ResourceManager> m_resourceManager;
InformationDisplay m_informationDisplay;
yg::InfoLayer m_infoLayer;
shared_ptr<DrawerYG> 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<PaintEvent> e,
ScreenBase const & screen,
m2::RectD const & selectRect,
int scaleLevel
);
int scaleLevel);
/// Function for calling from platform dependent-paint function.
void Paint(shared_ptr<PaintEvent> 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);

View file

@ -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

35
map/render_policy.cpp Normal file
View file

@ -0,0 +1,35 @@
#include "../base/SRC_FIRST.hpp"
#include "render_policy.hpp"
RenderPolicy::RenderPolicy(shared_ptr<WindowHandle> 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<yg::ResourceManager> const & RenderPolicy::resourceManager() const
{
return m_resourceManager;
}
shared_ptr<WindowHandle> const & RenderPolicy::windowHandle() const
{
return m_windowHandle;
}
RenderPolicy::render_fn_t RenderPolicy::renderFn() const
{
return m_renderFn;
}
void RenderPolicy::initialize(shared_ptr<yg::gl::RenderContext> const &,
shared_ptr<yg::ResourceManager> const & resourceManager)
{
m_resourceManager = resourceManager;
}

57
map/render_policy.hpp Normal file
View file

@ -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<void(shared_ptr<PaintEvent>, ScreenBase const &, m2::RectD const &, int)> render_fn_t;
private:
yg::Color m_bgColor;
shared_ptr<yg::ResourceManager> m_resourceManager;
shared_ptr<WindowHandle> m_windowHandle;
render_fn_t m_renderFn;
protected:
yg::Color const & bgColor() const;
shared_ptr<yg::ResourceManager> const & resourceManager() const;
shared_ptr<WindowHandle> const & windowHandle() const;
render_fn_t renderFn() const;
public:
/// constructor
RenderPolicy(shared_ptr<WindowHandle> const & windowHandle, render_fn_t const & renderFn);
/// drawing single frame
virtual void drawFrame(shared_ptr<PaintEvent> 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<yg::gl::RenderContext> const & primaryContext,
shared_ptr<yg::ResourceManager> const & resourceManager) = 0;
};

View file

@ -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<void(shared_ptr<PaintEvent>, ScreenBase const &, m2::RectD const &, int)> render_fn_t;
typedef RenderPolicy::render_fn_t render_fn_t;
typedef function<void()> renderCommandFinishedFn;
/// Single tile rendering command

View file

@ -0,0 +1,2 @@
#include "../base/SRC_FIRST.hpp"
#include "tiling_render_policy.hpp"

View file

@ -0,0 +1,12 @@
#pragma once
#include "render_policy.hpp"
class TilingRenderPolicy : public RenderPolicy
{
public:
virtual void renderTile() = 0;
void drawFrame(shared_ptr<PaintEvent> const & e, ScreenBase const & s);
};

View file

@ -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<WindowHandle> 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<yg::gl::RenderContext> const & primaryContext,
shared_ptr<yg::ResourceManager> 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<PaintEvent> 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<double, 3>());
}

View file

@ -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<WindowHandle> const & windowHandle,
RenderPolicy::render_fn_t const & renderFn);
void initialize(shared_ptr<yg::gl::RenderContext> const & renderContext,
shared_ptr<yg::ResourceManager> const & resourceManager);
void onSize(int w, int h);
void drawFrame(shared_ptr<PaintEvent> const & ev, ScreenBase const & currentScreen);
};

View file

@ -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<WindowHandle> const & windowHandle,
RenderPolicy::render_fn_t const & renderFn)
: RenderPolicy(windowHandle, renderFn),
m_tileCache(GetPlatform().MaxTilesCount() - 1)
{}
void TilingRenderPolicyST::initialize(shared_ptr<yg::gl::RenderContext> const & primaryContext,
shared_ptr<yg::ResourceManager> const & rm)
{
RenderPolicy::initialize(primaryContext, rm);
/// render single tile on the same thread
shared_ptr<yg::gl::FrameBuffer> frameBuffer(new yg::gl::FrameBuffer());
unsigned tileWidth = resourceManager()->tileTextureWidth();
unsigned tileHeight = resourceManager()->tileTextureHeight();
shared_ptr<yg::gl::RenderBuffer> 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<PaintEvent> 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> paintEvent(new PaintEvent(m_tileDrawer));
shared_ptr<yg::gl::BaseTexture> tileTarget = resourceManager()->renderTargets().Front(true);
shared_ptr<yg::InfoLayer> 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();
}
}
}

View file

@ -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<DrawerYG> m_tileDrawer;
ScreenBase m_tileScreen;
yg::InfoLayer m_infoLayer;
yg::TileCache m_tileCache;
yg::Tiler m_tiler;
public:
TilingRenderPolicyST(shared_ptr<WindowHandle> const & windowHandle,
RenderPolicy::render_fn_t const & renderFn);
void initialize(shared_ptr<yg::gl::RenderContext> const & renderContext,
shared_ptr<yg::ResourceManager> const & resourceManager);
void drawFrame(shared_ptr<PaintEvent> const & paintEvent, ScreenBase const & screenBase);
void onSize(int w, int h);
};

View file

@ -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)));