Added RenderPolicyMT from the old rendering code.

This commit is contained in:
rachytski 2011-08-30 14:12:32 +03:00 committed by Alex Zolotarev
parent dfaa348527
commit b409579c6f
28 changed files with 1275 additions and 68 deletions

View file

@ -13,11 +13,6 @@ void BenchmarkTilingRenderPolicyMT::Initialize(shared_ptr<yg::gl::RenderContext>
TilingRenderPolicyMT::Initialize(renderContext, resourceManager);
}
void BenchmarkTilingRenderPolicyMT::OnSize(int w, int h)
{
TilingRenderPolicyMT::OnSize(w, h);
}
void BenchmarkTilingRenderPolicyMT::DrawFrame(shared_ptr<PaintEvent> const & e,
ScreenBase const & s)
{

View file

@ -13,6 +13,4 @@ public:
shared_ptr<yg::ResourceManager> const & resourceManager);
void DrawFrame(shared_ptr<PaintEvent> const & e, ScreenBase const & s);
void OnSize(int w, int h);
};

View file

@ -48,11 +48,12 @@ class PaintEvent : public Event
DrawerYG * m_drawer;
core::CommandsQueue::Environment const * m_env;
bool m_isCancelled;
public:
PaintEvent(DrawerYG * drawer, core::CommandsQueue::Environment const * env = 0)
: m_drawer(drawer), m_env(env)
: m_drawer(drawer), m_env(env), m_isCancelled(false)
{}
DrawerYG * drawer() const
@ -60,9 +61,18 @@ public:
return m_drawer;
}
void Cancel()
{
ASSERT(m_env == 0, ());
m_isCancelled = true;
}
bool isCancelled() const
{
return (m_env && m_env->IsCancelled());
if (m_env)
return m_env->IsCancelled();
else
return m_isCancelled;
}
};

View file

@ -26,6 +26,7 @@
#include "../std/fstream.hpp"
#include "render_policy_st.hpp"
#include "render_policy_mt.hpp"
#include "tiling_render_policy_st.hpp"
#include "tiling_render_policy_mt.hpp"
@ -86,7 +87,8 @@ Framework<TModel>::Framework(shared_ptr<WindowHandle> windowHandle,
// on Android policy is created in AndroidFramework
#ifndef OMIM_OS_ANDROID
// SetRenderPolicy(make_shared_ptr(new RenderPolicyST(windowHandle, bind(&this_type::DrawModel, this, _1, _2, _3, _4, _5))));
SetRenderPolicy(make_shared_ptr(new TilingRenderPolicyMT(windowHandle, bind(&this_type::DrawModel, this, _1, _2, _3, _4, _5))));
// SetRenderPolicy(make_shared_ptr(new TilingRenderPolicyMT(windowHandle, bind(&this_type::DrawModel, this, _1, _2, _3, _4, _5))));
SetRenderPolicy(make_shared_ptr(new RenderPolicyMT(windowHandle, bind(&this_type::DrawModel, this, _1, _2, _3, _4, _5))));
#endif
m_informationDisplay.setBottomShift(bottomShift);
#ifdef DRAW_TOUCH_POINTS
@ -252,9 +254,13 @@ void Framework<TModel>::OnSize(int w, int h)
m_informationDisplay.setDisplayRect(m2::RectI(m2::PointI(0, 0), m2::PointU(w, h)));
m_navigator.OnSize(0, 0, w, h);
m2::RectI const & viewPort = m_renderPolicy->OnSize(w, h);
m_renderPolicy->OnSize(w, h);
m_navigator.OnSize(
viewPort.minX(),
viewPort.minY(),
viewPort.SizeX(),
viewPort.SizeY());
}
template <typename TModel>
@ -298,7 +304,8 @@ void Framework<TModel>::DrawModel(shared_ptr<PaintEvent> const & e,
try
{
//threads::MutexGuard lock(m_modelSyn);
m_model.ForEachFeature_TileDrawing(selectRect, doDraw, scaleLevel);
// m_model.ForEachFeature_TileDrawing(selectRect, doDraw, scaleLevel);
m_model.ForEachFeature(selectRect, doDraw, scaleLevel);
}
catch (redraw_operation_cancelled const &)
{
@ -436,13 +443,13 @@ template <typename TModel>
void Framework<TModel>::StartDrag(DragEvent const & e)
{
m2::PointD pos = m_navigator.OrientPoint(e.Pos());
m_navigator.StartDrag(pos, m_timer.ElapsedSeconds());
#ifdef DRAW_TOUCH_POINTS
m_informationDisplay.setDebugPoint(0, pos);
#endif
Invalidate();
m_navigator.StartDrag(pos, m_timer.ElapsedSeconds());
m_renderPolicy->StartDrag(pos, m_timer.ElapsedSeconds());
}
template <typename TModel>
@ -451,13 +458,14 @@ void Framework<TModel>::DoDrag(DragEvent const & e)
m_centeringMode = EDoNothing;
m2::PointD pos = m_navigator.OrientPoint(e.Pos());
m_navigator.DoDrag(pos, m_timer.ElapsedSeconds());
#ifdef DRAW_TOUCH_POINTS
m_informationDisplay.setDebugPoint(0, pos);
#endif
Invalidate();
m_navigator.DoDrag(pos, m_timer.ElapsedSeconds());
m_renderPolicy->DoDrag(pos, m_timer.ElapsedSeconds());
}
template <typename TModel>
@ -471,14 +479,14 @@ void Framework<TModel>::StopDrag(DragEvent const & e)
m_informationDisplay.setDebugPoint(0, m2::PointD(0, 0));
#endif
Invalidate();
m_renderPolicy->StopDrag(pos, m_timer.ElapsedSeconds());
}
template <typename TModel>
void Framework<TModel>::Move(double azDir, double factor)
{
m_navigator.Move(azDir, factor);
//m_tiler.seed(m_navigator.Screen(), m_tileSize);
Invalidate();
}
//@}
@ -526,14 +534,13 @@ void Framework<TModel>::StartScale(ScaleEvent const & e)
pt2 += ptDiff;
}
m_navigator.StartScale(pt1, pt2, m_timer.ElapsedSeconds());
#ifdef DRAW_TOUCH_POINTS
m_informationDisplay.setDebugPoint(0, pt1);
m_informationDisplay.setDebugPoint(1, pt2);
#endif
Invalidate();
m_navigator.StartScale(pt1, pt2, m_timer.ElapsedSeconds());
m_renderPolicy->StartScale(pt1, pt2, m_timer.ElapsedSeconds());
}
template <typename TModel>
@ -550,14 +557,13 @@ void Framework<TModel>::DoScale(ScaleEvent const & e)
pt2 += ptDiff;
}
m_navigator.DoScale(pt1, pt2, m_timer.ElapsedSeconds());
#ifdef DRAW_TOUCH_POINTS
m_informationDisplay.setDebugPoint(0, pt1);
m_informationDisplay.setDebugPoint(1, pt2);
#endif
Invalidate();
m_navigator.DoScale(pt1, pt2, m_timer.ElapsedSeconds());
m_renderPolicy->DoScale(pt1, pt2, m_timer.ElapsedSeconds());
}
template <typename TModel>
@ -574,14 +580,13 @@ void Framework<TModel>::StopScale(ScaleEvent const & e)
pt2 += ptDiff;
}
m_navigator.StopScale(pt1, pt2, m_timer.ElapsedSeconds());
#ifdef DRAW_TOUCH_POINTS
m_informationDisplay.setDebugPoint(0, m2::PointD(0, 0));
m_informationDisplay.setDebugPoint(0, m2::PointD(0, 0));
#endif
Invalidate();
m_navigator.StopScale(pt1, pt2, m_timer.ElapsedSeconds());
m_renderPolicy->StopScale(pt1, pt2, m_timer.ElapsedSeconds());
}
template<typename TModel>

View file

@ -34,7 +34,10 @@ HEADERS += \
tiler.hpp \
tile.hpp \
tile_cache.hpp \
screen_coverage.hpp
screen_coverage.hpp \
render_policy_mt.hpp \
render_queue.hpp \
render_queue_routine.hpp
SOURCES += \
feature_vec_model.cpp \
@ -58,7 +61,10 @@ SOURCES += \
tiler.cpp \
tile_cache.cpp \
tile.cpp \
screen_coverage.cpp
screen_coverage.cpp \
render_policy_mt.cpp \
render_queue_routine.cpp \
render_queue.cpp
!iphone*:!bada*:!android* {
HEADERS += qgl_render_context.hpp

View file

@ -403,17 +403,19 @@ EOrientation Navigator::Orientation() const
m2::PointD const Navigator::OrientPoint(m2::PointD const & pt) const
{
m2::PointD ptShift(m_Screen.PixelRect().minX(), m_Screen.PixelRect().minY());
switch (m_orientation)
{
case EOrientation90:
return m2::PointD(m_Screen.GetWidth() - pt.y, pt.x);
return m2::PointD(m_Screen.GetWidth() - pt.y, pt.x) + ptShift;
case EOrientation180:
return m2::PointD(m_Screen.GetWidth() - pt.x, m_Screen.GetHeight() - pt.y);
return m2::PointD(m_Screen.GetWidth() - pt.x, m_Screen.GetHeight() - pt.y) + ptShift;
case EOrientation270:
return m2::PointD(pt.y, m_Screen.GetHeight() - pt.x);
return m2::PointD(pt.y, m_Screen.GetHeight() - pt.x) + ptShift;
case EOrientation0:
return pt;
return pt + ptShift;
};
return m2::PointD(0, 0);
return ptShift;
}

View file

@ -1,6 +1,7 @@
#include "../base/SRC_FIRST.hpp"
#include "render_policy.hpp"
#include "window_handle.hpp"
RenderPolicy::RenderPolicy(shared_ptr<WindowHandle> const & windowHandle, TRenderFn const & renderFn)
: m_bgColor(0xEE, 0xEE, 0xDD, 0xFF),
@ -33,3 +34,38 @@ void RenderPolicy::Initialize(shared_ptr<yg::gl::RenderContext> const &,
{
m_resourceManager = resourceManager;
}
m2::RectI const RenderPolicy::OnSize(int w, int h)
{
return m2::RectI(0, 0, w, h);
}
void RenderPolicy::StartDrag(m2::PointD const & pt, double timeInSec)
{
m_windowHandle->invalidate();
}
void RenderPolicy::DoDrag(m2::PointD const & pt, double timeInSec)
{
m_windowHandle->invalidate();
}
void RenderPolicy::StopDrag(m2::PointD const & pt, double timeInSec)
{
m_windowHandle->invalidate();
}
void RenderPolicy::StartScale(m2::PointD const & pt1, m2::PointD const & pt2, double timeInSec)
{
m_windowHandle->invalidate();
}
void RenderPolicy::DoScale(m2::PointD const & pt1, m2::PointD const & pt2, double timeInSec)
{
m_windowHandle->invalidate();
}
void RenderPolicy::StopScale(m2::PointD const & pt1, m2::PointD const & pt2, double timeInSec)
{
m_windowHandle->invalidate();
}

View file

@ -50,8 +50,19 @@ public:
/// 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;
virtual m2::RectI const OnSize(int w, int h);
/// initialize render policy
virtual void Initialize(shared_ptr<yg::gl::RenderContext> const & primaryContext,
shared_ptr<yg::ResourceManager> const & resourceManager) = 0;
/// reacting on navigation actions
/// @{
virtual void StartDrag(m2::PointD const & pt, double timeInSec);
virtual void DoDrag(m2::PointD const & pt, double timeInSec);
virtual void StopDrag(m2::PointD const & pt, double timeInSec);
virtual void StartScale(m2::PointD const & pt1, m2::PointD const & pt2, double timeInSec);
virtual void DoScale(m2::PointD const & pt1, m2::PointD const & pt2, double timeInSec);
virtual void StopScale(m2::PointD const & pt1, m2::PointD const & pt2, double timeInSec);
/// @}
};

96
map/render_policy_mt.cpp Normal file
View file

@ -0,0 +1,96 @@
#include "../base/SRC_FIRST.hpp"
#include "render_policy_mt.hpp"
#include "events.hpp"
#include "drawer_yg.hpp"
#include "../yg/render_state.hpp"
#include "../geometry/transformations.hpp"
#include "../base/mutex.hpp"
#include "../platform/platform.hpp"
RenderPolicyMT::RenderPolicyMT(shared_ptr<WindowHandle> const & wh,
RenderPolicy::TRenderFn const & renderFn)
: RenderPolicy(wh, renderFn),
m_renderQueue(GetPlatform().SkinName(),
false,
true,
0.1,
false,
GetPlatform().ScaleEtalonSize(),
GetPlatform().VisualScale(),
bgColor()),
m_DoAddCommand(true)
{
m_renderQueue.AddWindowHandle(wh);
}
void RenderPolicyMT::Initialize(shared_ptr<yg::gl::RenderContext> const & rc,
shared_ptr<yg::ResourceManager> const & rm)
{
m_renderQueue.initializeGL(rc, rm);
RenderPolicy::Initialize(rc, rm);
}
m2::RectI const RenderPolicyMT::OnSize(int w, int h)
{
m_renderQueue.OnSize(w, h);
m2::PointU pt = m_renderQueue.renderState().coordSystemShift();
return m2::RectI(pt.x, pt.y, pt.x + w, pt.y + h);
}
void RenderPolicyMT::DrawFrame(shared_ptr<PaintEvent> const & e,
ScreenBase const & s)
{
if (m_DoAddCommand && (s != m_renderQueue.renderState().m_actualScreen))
m_renderQueue.AddCommand(renderFn(), s);
DrawerYG * pDrawer = e->drawer();
threads::MutexGuard g(*m_renderQueue.renderState().m_mutex.get());
e->drawer()->screen()->clear(bgColor());
if (m_renderQueue.renderState().m_actualTarget.get() != 0)
{
m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(false);
// OGLCHECK(glMatrixMode(GL_MODELVIEW));
// OGLCHECK(glPushMatrix());
// OGLCHECK(glTranslatef(-ptShift.x, -ptShift.y, 0));
math::Matrix<double, 3, 3> m = m_renderQueue.renderState().m_actualScreen.PtoGMatrix() * s.GtoPMatrix();
m = math::Shift(m, -ptShift);
pDrawer->screen()->blit(m_renderQueue.renderState().m_actualTarget,
m);
}
}
void RenderPolicyMT::StartDrag(m2::PointD const & pt, double timeInSec)
{
m_DoAddCommand = false;
RenderPolicy::StartDrag(pt, timeInSec);
}
void RenderPolicyMT::StopDrag(m2::PointD const & pt, double timeInSec)
{
m_DoAddCommand = true;
RenderPolicy::StopDrag(pt, timeInSec);
}
void RenderPolicyMT::StartScale(m2::PointD const & pt1, m2::PointD const & pt2, double timeInSec)
{
m_DoAddCommand = false;
RenderPolicy::StartScale(pt1, pt2, timeInSec);
}
void RenderPolicyMT::StopScale(m2::PointD const & pt1, m2::PointD const & pt2, double timeInSec)
{
m_DoAddCommand = true;
RenderPolicy::StartScale(pt1, pt2, timeInSec);
}

33
map/render_policy_mt.hpp Normal file
View file

@ -0,0 +1,33 @@
#pragma once
#include "render_policy.hpp"
#include "render_queue.hpp"
#include "../geometry/point2d.hpp"
class WindowHandle;
class RenderPolicyMT : public RenderPolicy
{
private:
RenderQueue m_renderQueue;
bool m_DoAddCommand;
public:
RenderPolicyMT(shared_ptr<WindowHandle> const & wh,
RenderPolicy::TRenderFn const & renderFn);
void Initialize(shared_ptr<yg::gl::RenderContext> const & rc,
shared_ptr<yg::ResourceManager> const & rm);
void DrawFrame(shared_ptr<PaintEvent> const & paintEvent,
ScreenBase const & screenBase);
m2::RectI const OnSize(int w, int h);
void StartDrag(m2::PointD const & pt, double timeInSec);
void StopDrag(m2::PointD const & pt, double timeInSec);
void StartScale(m2::PointD const & pt1, m2::PointD const & pt2, double timeInSec);
void StopScale(m2::PointD const & pt1, m2::PointD const & pt2, double timeInSec);
};

View file

@ -43,7 +43,3 @@ void RenderPolicyST::DrawFrame(shared_ptr<PaintEvent> const & e,
infoLayer->draw(e->drawer()->screen().get(), math::Identity<double, 3>());
e->drawer()->screen()->resetInfoLayer();
}
void RenderPolicyST::OnSize(int w, int h)
{
}

View file

@ -16,6 +16,4 @@ public:
void DrawFrame(shared_ptr<PaintEvent> const & paintEvent,
ScreenBase const & screenBase);
void OnSize(int w, int h);
};

109
map/render_queue.cpp Normal file
View file

@ -0,0 +1,109 @@
#include "../base/SRC_FIRST.hpp"
#include "render_queue.hpp"
#include "../yg/render_state.hpp"
#include "../yg/rendercontext.hpp"
RenderQueue::RenderQueue(
string const & skinName,
bool isMultiSampled,
bool doPeriodicalUpdate,
double updateInterval,
bool isBenchmarking,
unsigned scaleEtalonSize,
double visualScale,
yg::Color const & bgColor
)
: m_renderState(new yg::gl::RenderState())
{
m_renderState->m_surfaceWidth = 100;
m_renderState->m_surfaceHeight = 100;
m_renderState->m_textureWidth = 256;
m_renderState->m_textureHeight = 256;
m_renderState->m_duration = 0;
m_routine = new RenderQueueRoutine(
m_renderState,
skinName,
isMultiSampled,
doPeriodicalUpdate,
updateInterval,
isBenchmarking,
scaleEtalonSize,
visualScale,
bgColor);
}
void RenderQueue::initializeGL(shared_ptr<yg::gl::RenderContext> const & primaryContext,
shared_ptr<yg::ResourceManager> const & resourceManager)
{
m_resourceManager = resourceManager;
m_routine->initializeGL(primaryContext->createShared(),
m_resourceManager);
m_renderQueueThread.Create(m_routine);
}
RenderQueue::~RenderQueue()
{
m_renderQueueThread.Cancel();
}
void RenderQueue::AddCommand(RenderQueueRoutine::render_fn_t const & fn, ScreenBase const & frameScreen)
{
m_routine->addCommand(fn, frameScreen);
}
void RenderQueue::AddBenchmarkCommand(RenderQueueRoutine::render_fn_t const & fn, ScreenBase const & frameScreen)
{
m_routine->addBenchmarkCommand(fn, frameScreen);
}
void RenderQueue::SetRedrawAll()
{
m_renderState->m_doRepaintAll = true;
}
void RenderQueue::AddWindowHandle(shared_ptr<WindowHandle> const & windowHandle)
{
m_routine->addWindowHandle(windowHandle);
}
void RenderQueue::OnSize(size_t w, size_t h)
{
m_renderState->onSize(w, h);
}
yg::gl::RenderState const RenderQueue::CopyState() const
{
yg::gl::RenderState state;
m_renderState->copyTo(state);
return state;
}
yg::gl::RenderState const & RenderQueue::renderState() const
{
return *m_renderState.get();
}
shared_ptr<yg::gl::RenderState> const & RenderQueue::renderStatePtr() const
{
return m_renderState;
}
void RenderQueue::memoryWarning()
{
m_routine->memoryWarning();
}
void RenderQueue::enterBackground()
{
m_routine->enterBackground();
}
void RenderQueue::enterForeground()
{
m_routine->enterForeground();
}

73
map/render_queue.hpp Normal file
View file

@ -0,0 +1,73 @@
#pragma once
#include "../base/thread.hpp"
#include "../geometry/screenbase.hpp"
#include "../std/shared_ptr.hpp"
#include "render_queue_routine.hpp"
namespace yg
{
class ResourceManager;
namespace gl
{
class RenderState;
class RenderContext;
}
}
class WindowHandle;
class RenderQueue
{
private:
friend class RenderQueueRoutine;
threads::Thread m_renderQueueThread;
shared_ptr<yg::gl::RenderState> m_renderState;
shared_ptr<yg::ResourceManager> m_resourceManager;
RenderQueueRoutine * m_routine;
public:
/// constructor.
RenderQueue(string const & skinName,
bool isMultiSampled,
bool doPeriodicalUpdate,
double updateInterval,
bool isBenchmarking,
unsigned scaleEtalonSize,
double visualScale,
yg::Color const & bgColor);
/// destructor.
~RenderQueue();
/// set the primary context. it starts the rendering thread.
void initializeGL(shared_ptr<yg::gl::RenderContext> const & primaryContext,
shared_ptr<yg::ResourceManager> const & resourceManager);
/// add command to the commands queue.
void AddCommand(RenderQueueRoutine::render_fn_t const & fn, ScreenBase const & frameScreen);
void AddBenchmarkCommand(RenderQueueRoutine::render_fn_t const & fn, ScreenBase const & frameScreen);
void SetRedrawAll();
void SetVisualScale(double visualScale);
/// add window handle to notify when rendering operation finishes
void AddWindowHandle(shared_ptr<WindowHandle> const & windowHandle);
/// process resize request
void OnSize(size_t w, size_t h);
/// copy primary render state
yg::gl::RenderState const CopyState() const;
shared_ptr<yg::gl::RenderState> const & renderStatePtr() const;
yg::gl::RenderState const & renderState() const;
/// 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();
};

View file

@ -0,0 +1,514 @@
#include "../base/SRC_FIRST.hpp"
#include "../base/mutex.hpp"
#include "../base/timer.hpp"
#include "../base/logging.hpp"
#include "../std/bind.hpp"
#include "../yg/internal/opengl.hpp"
#include "../yg/render_state.hpp"
#include "../yg/rendercontext.hpp"
#include "../yg/framebuffer.hpp"
#include "../yg/renderbuffer.hpp"
#include "../yg/texture.hpp"
#include "../yg/resource_manager.hpp"
#include "../yg/screen.hpp"
#include "../yg/pen_info.hpp"
#include "../yg/skin.hpp"
#include "../indexer/scales.hpp"
#include "events.hpp"
#include "drawer_yg.hpp"
#include "window_handle.hpp"
#include "render_queue_routine.hpp"
RenderQueueRoutine::RenderModelCommand::RenderModelCommand(ScreenBase const & frameScreen,
render_fn_t renderFn)
: m_frameScreen(frameScreen),
m_renderFn(renderFn)
{}
RenderQueueRoutine::RenderQueueRoutine(shared_ptr<yg::gl::RenderState> const & renderState,
string const & skinName,
bool isMultiSampled,
bool doPeriodicalUpdate,
double updateInterval,
bool isBenchmarking,
unsigned scaleEtalonSize,
double visualScale,
yg::Color const & bgColor)
{
m_skinName = skinName;
m_visualScale = visualScale;
m_renderState = renderState;
m_renderState->addInvalidateFn(bind(&RenderQueueRoutine::invalidate, this));
m_isMultiSampled = isMultiSampled;
m_doPeriodicalUpdate = doPeriodicalUpdate;
m_updateInterval = updateInterval;
m_isBenchmarking = isBenchmarking;
m_scaleEtalonSize = scaleEtalonSize;
m_bgColor = bgColor;
}
void RenderQueueRoutine::Cancel()
{
IRoutine::Cancel();
/// Waking up the sleeping thread...
m_hasRenderCommands.Signal();
/// ...Or cancelling the current rendering command in progress.
if (m_currentRenderCommand != 0)
m_currentRenderCommand->m_paintEvent->Cancel();
}
void RenderQueueRoutine::processResize(ScreenBase const & frameScreen)
{
if (m_renderState->m_isResized)
{
size_t texW = m_renderState->m_textureWidth;
size_t texH = m_renderState->m_textureHeight;
m_renderState->m_depthBuffer.reset();
if (!m_isMultiSampled)
{
m_renderState->m_depthBuffer = make_shared_ptr(new yg::gl::RenderBuffer(texW, texH, true));
m_threadDrawer->screen()->frameBuffer()->setDepthBuffer(m_renderState->m_depthBuffer);
}
m_threadDrawer->onSize(texW, texH);
m_threadDrawer->screen()->frameBuffer()->onSize(texW, texH);
shared_ptr<yg::gl::BaseTexture> oldActualTarget = m_renderState->m_actualTarget;
m_renderState->m_actualTarget.reset();
m_renderState->m_actualTarget = m_resourceManager->createRenderTarget(texW, texH);
m_auxScreen->onSize(texW, texH);
m_auxScreen->setRenderTarget(m_renderState->m_actualTarget);
m_auxScreen->beginFrame();
m_auxScreen->clear(m_bgColor);
if (oldActualTarget != 0)
{
m_auxScreen->blit(oldActualTarget,
m_renderState->m_actualScreen,
frameScreen);
oldActualTarget.reset();
}
m_auxScreen->endFrame();
for (size_t i = 0; i < m_renderState->m_backBufferLayers.size(); ++i)
{
shared_ptr<yg::gl::BaseTexture> oldBackBuffer = m_renderState->m_backBufferLayers[i];
m_renderState->m_backBufferLayers[i].reset();
m_renderState->m_backBufferLayers[i] = m_resourceManager->createRenderTarget(texW, texH);
m_auxScreen->setRenderTarget(m_renderState->m_backBufferLayers[i]);
m_auxScreen->beginFrame();
m_auxScreen->clear(m_bgColor);
if (oldBackBuffer != 0)
{
m_auxScreen->blit(oldBackBuffer,
m_renderState->m_actualScreen,
frameScreen);
oldBackBuffer.reset();
}
m_auxScreen->endFrame();
m_renderState->m_actualScreen = frameScreen;
}
m_renderState->m_isResized = false;
}
}
void RenderQueueRoutine::getUpdateAreas(
ScreenBase const & oldScreen,
m2::RectI const & oldRect,
ScreenBase const & newScreen,
m2::RectI const & newRect,
vector<m2::RectI> & areas)
{
areas.clear();
if (IsPanning(oldScreen, newScreen))
{
m2::RectD o(newScreen.GtoP(oldScreen.PtoG(m2::PointD(oldRect.minX(), oldRect.minY()))),
newScreen.GtoP(oldScreen.PtoG(m2::PointD(oldRect.maxX(), oldRect.maxY()))));
m2::RectD n(newRect);
/// checking two corner cases
if (o.IsRectInside(n))
return;
if (!o.IsIntersect(n))
{
areas.push_back(m2::RectI(n));
return;
}
double leftBarMinX = 0;
double leftBarMaxX = 0;
double rightBarMinX = n.maxX();
double rightBarMaxX = n.maxX();
double topBarMinY = 0;
double topBarMaxY = 0;
double bottomBarMinY = n.maxY();
double bottomBarMaxY = n.maxY();
if (o.minX() > n.minX())
leftBarMaxX = ceil(o.minX());
if (o.maxX() < n.maxX())
rightBarMinX = floor(o.maxX());
if (o.minY() > n.minY())
topBarMaxY = ceil(o.minY());
if (o.maxY() < n.maxY())
bottomBarMinY = floor(o.maxY());
if (leftBarMinX != leftBarMaxX)
areas.push_back(m2::RectI(leftBarMinX, topBarMinY, leftBarMaxX, bottomBarMinY));
if (topBarMinY != topBarMaxY)
areas.push_back(m2::RectI(leftBarMaxX, topBarMinY, rightBarMaxX, topBarMaxY));
if (rightBarMinX != rightBarMaxX)
areas.push_back(m2::RectI(rightBarMinX, topBarMaxY, rightBarMaxX, bottomBarMaxY));
if (bottomBarMinY != bottomBarMaxY)
areas.push_back(m2::RectI(leftBarMinX, bottomBarMinY, rightBarMinX, bottomBarMaxY));
}
else
{
areas.push_back(newRect);
/* int rectW = (w + 9) / 5;
int rectH = (h + 9) / 5;
m2::RectI r( 2 * rectW, 2 * rectH, 3 * rectW, 3 * rectH);
areas.push_back(r);
areas.push_back(m2::Offset(r, -rectW, 0));
areas.push_back(m2::Offset(r, -rectW, -rectH));
areas.push_back(m2::Offset(r, 0, -rectH));
areas.push_back(m2::Offset(r, rectW, -rectH));
areas.push_back(m2::Offset(r, rectW, 0));
areas.push_back(m2::Offset(r, rectW, rectH));
areas.push_back(m2::Offset(r, 0, rectH));
areas.push_back(m2::Offset(r, -rectW, rectH));
areas.push_back(m2::Offset(r, -2 * rectW, rectH));
areas.push_back(m2::Offset(r, -2 * rectW, 0));
areas.push_back(m2::Offset(r, -2 * rectW, -rectH));
areas.push_back(m2::Offset(r, -2 * rectW, -2*rectH));
areas.push_back(m2::Offset(r, -rectW, -2*rectH));
areas.push_back(m2::Offset(r, 0, -2*rectH));
areas.push_back(m2::Offset(r, rectW, -2*rectH));
areas.push_back(m2::Offset(r, 2 * rectW, -2*rectH));
areas.push_back(m2::Offset(r, 2 * rectW, -rectH));
areas.push_back(m2::Offset(r, 2 * rectW, 0));
areas.push_back(m2::Offset(r, 2 * rectW, rectH));
areas.push_back(m2::Offset(r, 2 * rectW, 2*rectH));
areas.push_back(m2::Offset(r, rectW, 2*rectH));
areas.push_back(m2::Offset(r, 0, 2*rectH));
areas.push_back(m2::Offset(r, -rectW, 2*rectH));
areas.push_back(m2::Offset(r, -2*rectW, 2*rectH));
*/
}
}
void RenderQueueRoutine::setVisualScale(double visualScale)
{
m_visualScale = visualScale;
}
void RenderQueueRoutine::waitForRenderCommand(list<shared_ptr<RenderModelCommand> > & cmdList,
threads::ConditionGuard & guard)
{
while (cmdList.empty())
{
guard.Wait();
if (IsCancelled())
break;
}
}
void RenderQueueRoutine::Do()
{
m_renderContext->makeCurrent();
m_frameBuffer = make_shared_ptr(new yg::gl::FrameBuffer());
DrawerYG::params_t params;
params.m_resourceManager = m_resourceManager;
params.m_frameBuffer = m_frameBuffer;
params.m_renderState = m_renderState;
params.m_doPeriodicalUpdate = m_doPeriodicalUpdate;
params.m_updateInterval = m_updateInterval;
params.m_skinName = m_skinName;
params.m_visualScale = m_visualScale;
params.m_threadID = 0;
params.m_glyphCacheID = m_resourceManager->renderThreadGlyphCacheID(0);
params.m_useOverlay = true;
/* params.m_isDebugging = true;
params.m_drawPathes = false;
params.m_drawAreas = false;
params.m_drawTexts = false;*/
m_threadDrawer = make_shared_ptr(new DrawerYG(params));
yg::gl::Screen::Params auxParams;
auxParams.m_frameBuffer = make_shared_ptr(new yg::gl::FrameBuffer());
auxParams.m_resourceManager = m_resourceManager;
m_auxScreen = make_shared_ptr(new yg::gl::Screen(auxParams));
bool isPanning = false;
bool doRedrawAll = false;
bool fullRectRepaint = false;
/// update areas in pixel coordinates.
vector<m2::RectI> areas;
m2::RectI surfaceRect;
m2::RectI textureRect;
shared_ptr<yg::InfoLayer> infoLayer(new yg::InfoLayer());
m_threadDrawer->screen()->setInfoLayer(infoLayer);
while (!IsCancelled())
{
{
threads::ConditionGuard guard(m_hasRenderCommands);
waitForRenderCommand(m_renderCommands, guard);
if (IsCancelled())
break;
m_currentRenderCommand = m_renderCommands.front();
m_renderCommands.erase(m_renderCommands.begin());
m_currentRenderCommand->m_paintEvent = make_shared_ptr(new PaintEvent(m_threadDrawer.get()));
/// this prevents the framework from flooding us with a bunch of RenderCommands with the same screen.
{
threads::MutexGuard guard(*m_renderState->m_mutex.get());
m_renderState->m_currentScreen = m_currentRenderCommand->m_frameScreen;
m2::RectI prevRect(0, 0, 0, 0);
ScreenBase prevScreen = m_renderState->m_actualScreen;
if (m_renderState->m_actualTarget != 0)
prevRect = m2::RectI(0, 0,
m_renderState->m_actualTarget->width(),
m_renderState->m_actualTarget->height());
processResize(m_currentRenderCommand->m_frameScreen);
/// saving parameters, which might be changed from the GUI thread for later use.
surfaceRect = m2::RectI(0, 0, m_renderState->m_surfaceWidth, m_renderState->m_surfaceHeight);
textureRect = m2::RectI(0, 0, m_renderState->m_textureWidth, m_renderState->m_textureHeight);
m2::RectI curRect = textureRect;
doRedrawAll = m_renderState->m_doRepaintAll;
fullRectRepaint = false;
if (m_renderState->m_doRepaintAll)
{
areas.clear();
areas.push_back(curRect);
fullRectRepaint = true;
m_threadDrawer->screen()->infoLayer()->clear();
m_renderState->m_doRepaintAll = false;
}
else
{
getUpdateAreas(prevScreen,
prevRect,
m_currentRenderCommand->m_frameScreen,
curRect,
areas);
if ((areas.size() == 1) && (areas[0] == curRect))
fullRectRepaint = true;
}
isPanning = IsPanning(prevScreen, m_renderState->m_currentScreen);
if (isPanning)
{
m2::RectD oldRect = m2::RectD(m_renderState->m_currentScreen.GtoP(prevScreen.PtoG(m2::PointD(prevRect.minX(), prevRect.minY()))),
m_renderState->m_currentScreen.GtoP(prevScreen.PtoG(m2::PointD(prevRect.maxX(), prevRect.maxY()))));
m2::RectD redrawTextRect(curRect);
if (!redrawTextRect.Intersect(oldRect))
redrawTextRect = m2::RectD(0, 0, 0, 0);
shared_ptr<yg::InfoLayer> infoLayer(new yg::InfoLayer());
infoLayer->merge(*m_threadDrawer->screen()->infoLayer().get(),
prevScreen.PtoGMatrix() * m_renderState->m_currentScreen.GtoPMatrix());
m_threadDrawer->screen()->setInfoLayer(infoLayer);
}
else
m_threadDrawer->screen()->infoLayer()->clear();
}
}
my::Timer timer;
/// At this point renderQueue->mutex is released to allow
/// main thread to add new rendering tasks and blit already
/// rendered model while the current command is actually rendering.
if (m_currentRenderCommand != 0)
{
/// this fixes some strange issue with multisampled framebuffer.
/// setRenderTarget should be made here.
m_threadDrawer->screen()->setRenderTarget(m_renderState->m_backBufferLayers.front());
m_threadDrawer->beginFrame();
m_threadDrawer->screen()->enableClipRect(true);
m_threadDrawer->screen()->setClipRect(textureRect);
m_threadDrawer->clear(m_bgColor);
if ((isPanning) && (!doRedrawAll))
{
m_threadDrawer->screen()->blit(
m_renderState->m_actualTarget,
m_renderState->m_actualScreen,
m_renderState->m_currentScreen);
}
//m_threadDrawer->screen()->setNeedTextRedraw(isPanning);
ScreenBase const & frameScreen = m_currentRenderCommand->m_frameScreen;
m2::RectD glbRect;
frameScreen.PtoG(m2::RectD(textureRect.Center() - m2::PointD(m_scaleEtalonSize / 2, m_scaleEtalonSize / 2),
textureRect.Center() + m2::PointD(m_scaleEtalonSize / 2, m_scaleEtalonSize / 2)),
glbRect);
// frameScreen.PtoG(m2::RectD(surfaceRect), glbRect);
int scaleLevel = scales::GetScaleLevel(glbRect);
for (size_t i = 0; i < areas.size(); ++i)
{
if ((areas[i].SizeX() != 0) && (areas[i].SizeY() != 0))
{
frameScreen.PtoG(m2::Inflate<double>(m2::RectD(areas[i]), 30 * m_visualScale, 30 * m_visualScale), glbRect);
if ((glbRect.SizeX() == 0) || (glbRect.SizeY() == 0))
continue;
m_threadDrawer->screen()->setClipRect(areas[i]);
m_currentRenderCommand->m_renderFn(
m_currentRenderCommand->m_paintEvent,
m_currentRenderCommand->m_frameScreen,
glbRect,
glbRect,
scaleLevel);
}
}
/// if something were actually drawn, or (exclusive or) we are repainting the whole rect
if ((!m_renderState->m_isEmptyModelCurrent) || (fullRectRepaint))
m_renderState->m_isEmptyModelActual = m_renderState->m_isEmptyModelCurrent;
/// setting the "whole texture" clip rect to render texts opened by panning.
m_threadDrawer->screen()->setClipRect(textureRect);
m_threadDrawer->screen()->infoLayer()->draw(m_threadDrawer->screen().get(), math::Identity<double, 3>());
m_threadDrawer->endFrame();
}
double duration = timer.ElapsedSeconds();
if (!IsCancelled())
{
/// We shouldn't update the actual target as it's already happened (through callback function)
/// in the endFrame function
/// updateActualTarget();
m_currentRenderCommand.reset();
{
threads::MutexGuard guard(*m_renderState->m_mutex.get());
m_renderState->m_duration = duration;
}
invalidate();
}
}
// By VNG: We can't destroy render context in drawing thread.
// Notify render context instead.
m_renderContext->endThreadDrawing();
}
void RenderQueueRoutine::addWindowHandle(shared_ptr<WindowHandle> window)
{
m_windowHandles.push_back(window);
}
void RenderQueueRoutine::invalidate()
{
for_each(m_windowHandles.begin(),
m_windowHandles.end(),
bind(&WindowHandle::invalidate, _1));
}
void RenderQueueRoutine::addCommand(render_fn_t const & fn, ScreenBase const & frameScreen)
{
/// Command queue modification is syncronized by mutex
threads::ConditionGuard guard(m_hasRenderCommands);
bool needToSignal = m_renderCommands.empty();
/// Clearing a list of commands.
m_renderCommands.clear();
/// pushing back new RenderCommand.
m_renderCommands.push_back(make_shared_ptr(new RenderModelCommand(frameScreen, fn)));
/// if we are in benchmarking mode, we shouldn't cancel any render command
/// else, if we are not panning, we should cancel the render command in progress to start a new one
if ((m_currentRenderCommand != 0)
&& (!IsPanning(m_currentRenderCommand->m_frameScreen, frameScreen)))
m_currentRenderCommand->m_paintEvent->Cancel();
if (needToSignal)
guard.Signal();
}
void RenderQueueRoutine::addBenchmarkCommand(render_fn_t const & fn, ScreenBase const & frameScreen)
{
/// Command queue modification is syncronized by mutex
threads::ConditionGuard guard(m_hasRenderCommands);
bool needToSignal = m_renderCommands.empty();
m_benchmarkRenderCommands.push_back(make_shared_ptr(new RenderModelCommand(frameScreen, fn)));
if (needToSignal)
guard.Signal();
}
void RenderQueueRoutine::initializeGL(shared_ptr<yg::gl::RenderContext> const & renderContext,
shared_ptr<yg::ResourceManager> const & resourceManager)
{
m_renderContext = renderContext;
m_resourceManager = resourceManager;
}
void RenderQueueRoutine::memoryWarning()
{
m_threadDrawer->screen()->memoryWarning();
}
void RenderQueueRoutine::enterBackground()
{
m_threadDrawer->screen()->enterBackground();
}
void RenderQueueRoutine::enterForeground()
{
m_threadDrawer->screen()->enterForeground();
}

View file

@ -0,0 +1,124 @@
#pragma once
#include "../base/thread.hpp"
#include "../base/condition.hpp"
#include "../base/commands_queue.hpp"
#include "../geometry/rect2d.hpp"
#include "../geometry/screenbase.hpp"
#include "../std/list.hpp"
#include "../std/function.hpp"
#include "../yg/color.hpp"
class DrawerYG;
namespace threads
{
class Condition;
}
class PaintEvent;
class WindowHandle;
namespace yg
{
class ResourceManager;
namespace gl
{
class RenderContext;
class FrameBuffer;
class RenderBuffer;
class BaseTexture;
class RenderState;
class RenderState;
class Screen;
}
}
class RenderQueueRoutine : public threads::IRoutine
{
public:
typedef function<void(shared_ptr<PaintEvent>, ScreenBase const &, m2::RectD const &, m2::RectD const &, int)> render_fn_t;
private:
struct RenderModelCommand
{
ScreenBase m_frameScreen;
shared_ptr<PaintEvent> m_paintEvent;
render_fn_t m_renderFn;
RenderModelCommand(ScreenBase const & frameScreen,
render_fn_t renderFn);
};
shared_ptr<yg::gl::RenderContext> m_renderContext;
shared_ptr<yg::gl::FrameBuffer> m_frameBuffer;
shared_ptr<DrawerYG> m_threadDrawer;
shared_ptr<yg::gl::Screen> m_auxScreen;
threads::Condition m_hasRenderCommands;
shared_ptr<RenderModelCommand> m_currentRenderCommand;
list<shared_ptr<RenderModelCommand> > m_renderCommands;
list<shared_ptr<RenderModelCommand> > m_benchmarkRenderCommands;
shared_ptr<yg::gl::RenderState> m_renderState;
shared_ptr<yg::ResourceManager> m_resourceManager;
/// A list of window handles to notify about ending rendering operations.
list<shared_ptr<WindowHandle> > m_windowHandles;
bool m_isMultiSampled;
bool m_doPeriodicalUpdate;
double m_updateInterval;
double m_visualScale;
string m_skinName;
bool m_isBenchmarking;
unsigned m_scaleEtalonSize;
yg::Color m_bgColor;
void waitForRenderCommand(list<shared_ptr<RenderModelCommand> > & cmdList,
threads::ConditionGuard & guard);
public:
RenderQueueRoutine(shared_ptr<yg::gl::RenderState> const & renderState,
string const & skinName,
bool isMultiSampled,
bool doPeriodicalUpdate,
double updateInterval,
bool isBenchmarking,
unsigned scaleEtalonSize,
double visualScale,
yg::Color const & bgColor);
/// initialize GL rendering
/// this function is called just before the thread starts.
void initializeGL(shared_ptr<yg::gl::RenderContext> const & renderContext,
shared_ptr<yg::ResourceManager> const & resourceManager);
/// This function should always be called from the main thread.
void Cancel();
/// Check, whether the resize command is queued, and resize accordingly.
void processResize(ScreenBase const & frameScreen);
/// Get update areas for the current render state
void getUpdateAreas(ScreenBase const & oldScreen, m2::RectI const & oldRect,
ScreenBase const & newScreen, m2::RectI const & newRect,
vector<m2::RectI> & areas);
/// Thread procedure
void Do();
/// invalidate all connected window handles
void invalidate();
/// add monitoring window
void addWindowHandle(shared_ptr<WindowHandle> window);
/// add model rendering command to rendering queue
void addCommand(render_fn_t const & fn, ScreenBase const & frameScreen);
/// add benchmark rendering command
void addBenchmarkCommand(render_fn_t const & fn, ScreenBase const & frameScreen);
/// set the resolution scale factor to the main thread drawer;
void setVisualScale(double visualScale);
/// free all available memory
void memoryWarning();
/// free all easily recreatable opengl resources and make sure that no opengl call will be made.
void enterBackground();
/// recreate all necessary opengl resources and prepare to run in foreground.
void enterForeground();
};

View file

@ -92,7 +92,7 @@ void ScreenCoverage::Merge(Tiler::RectInfo const & ri)
}
void ScreenCoverage::Remove(Tile const * tile)
void ScreenCoverage::Remove(Tile const *)
{
}

View file

@ -19,7 +19,7 @@ TilingRenderPolicyMT::TilingRenderPolicyMT(shared_ptr<WindowHandle> const & wind
m_tileRenderer(GetPlatform().SkinName(),
GetPlatform().ScaleEtalonSize(),
GetPlatform().MaxTilesCount(),
GetPlatform().CpuCores(),
1, //GetPlatform().CpuCores(),
bgColor(),
renderFn),
m_coverageGenerator(GetPlatform().TileSize(),
@ -37,10 +37,6 @@ void TilingRenderPolicyMT::Initialize(shared_ptr<yg::gl::RenderContext> const &
m_coverageGenerator.Initialize();
}
void TilingRenderPolicyMT::OnSize(int /*w*/, int /*h*/)
{
}
void TilingRenderPolicyMT::DrawFrame(shared_ptr<PaintEvent> const & e, ScreenBase const & currentScreen)
{
DrawerYG * pDrawer = e->drawer();

View file

@ -43,7 +43,5 @@ public:
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

@ -52,9 +52,6 @@ void TilingRenderPolicyST::Initialize(shared_ptr<yg::gl::RenderContext> const &
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();

View file

@ -34,6 +34,4 @@ public:
shared_ptr<yg::ResourceManager> const & resourceManager);
void DrawFrame(shared_ptr<PaintEvent> const & paintEvent, ScreenBase const & screenBase);
void OnSize(int w, int h);
};

View file

@ -45,7 +45,34 @@ namespace yg
m2::RectI const & srcRect,
m2::RectU const & texRect)
{
m2::PointF pt = to.GtoP(from.PtoG(m2::PointF(srcRect.minX(), srcRect.minY())));
blit(srcSurface,
from.PtoGMatrix() * to.GtoPMatrix(),
isSubPixel,
color,
srcRect,
texRect);
}
void Blitter::blit(shared_ptr<yg::gl::BaseTexture> const & srcSurface,
math::Matrix<double, 3, 3> const & m,
bool isSubPixel)
{
blit(srcSurface,
m,
isSubPixel,
yg::Color(),
m2::RectI(0, 0, srcSurface->width(), srcSurface->height()),
m2::RectU(0, 0, srcSurface->width(), srcSurface->height()));
}
void Blitter::blit(shared_ptr<yg::gl::BaseTexture> const & srcSurface,
math::Matrix<double, 3, 3> const & m,
bool isSubPixel,
yg::Color const & color,
m2::RectI const & srcRect,
m2::RectU const & texRect)
{
m2::PointF pt = m2::PointF(m2::PointD(srcRect.minX(), srcRect.minY()) * m);
if (!isSubPixel)
{
@ -57,10 +84,10 @@ namespace yg
m2::PointF pts[4] =
{
to.GtoP(from.PtoG(m2::PointF(srcRect.minX(), srcRect.minY()))) + pt,
to.GtoP(from.PtoG(m2::PointF(srcRect.maxX(), srcRect.minY()))) + pt,
to.GtoP(from.PtoG(m2::PointF(srcRect.maxX(), srcRect.maxY()))) + pt,
to.GtoP(from.PtoG(m2::PointF(srcRect.minX(), srcRect.maxY()))) + pt
m2::PointF(m2::PointD(srcRect.minX(), srcRect.minY()) * m) + pt,
m2::PointF(m2::PointD(srcRect.maxX(), srcRect.minY()) * m) + pt,
m2::PointF(m2::PointD(srcRect.maxX(), srcRect.maxY()) * m) + pt,
m2::PointF(m2::PointD(srcRect.minX(), srcRect.maxY()) * m) + pt
};
m2::PointF texPts[4] =

View file

@ -55,6 +55,17 @@ namespace yg
ScreenBase const & to,
bool isSubPixel = false);
void blit(shared_ptr<BaseTexture> const & srcSurface,
math::Matrix<double, 3, 3> const & m,
bool isSubPixel = false);
void blit(shared_ptr<BaseTexture> const & srcSurface,
math::Matrix<double, 3, 3> const & m,
bool isSubPixel,
yg::Color const & color,
m2::RectI const & srcRect,
m2::RectU const & texRect);
void immDrawSolidRect(m2::RectF const & rect,
yg::Color const & color);

View file

@ -5,7 +5,7 @@
#include "indexbuffer.hpp"
#include "renderbuffer.hpp"
#include "framebuffer.hpp"
#include "geometry_renderer.hpp"
#include "render_state_updater.hpp"
#include "storage.hpp"
#include "skin_page.hpp"
@ -30,7 +30,7 @@ namespace yg
namespace gl
{
class GeometryBatcher : public GeometryRenderer
class GeometryBatcher : public RenderStateUpdater
{
public:
@ -38,7 +38,7 @@ namespace yg
private:
typedef GeometryRenderer base_t;
typedef RenderStateUpdater base_t;
shared_ptr<yg::Skin> m_skin;

View file

@ -300,12 +300,12 @@ namespace yg
strings::UniString GlyphCache::log2vis(strings::UniString const & str)
{
// FriBidiEnv e;
/* size_t const count = str.size();
size_t const count = str.size();
strings::UniString res(count);
FriBidiParType dir = FRIBIDI_PAR_LTR; // requested base direction
fribidi_log2vis(&str[0], count, &dir, &res[0], 0, 0, 0);
return res;*/
return str;
return res;
// return str;
}
}

119
yg/render_state_updater.cpp Normal file
View file

@ -0,0 +1,119 @@
#include "../base/SRC_FIRST.hpp"
#include "render_state_updater.hpp"
#include "render_state.hpp"
#include "framebuffer.hpp"
#include "base_texture.hpp"
#include "internal/opengl.hpp"
#include "../base/logging.hpp"
namespace yg
{
namespace gl
{
RenderStateUpdater::Params::Params()
: m_doPeriodicalUpdate(false), m_updateInterval(0.0)
{}
RenderStateUpdater::RenderStateUpdater(Params const & params)
: base_t(params),
m_renderState(params.m_renderState),
m_doPeriodicalUpdate(params.m_doPeriodicalUpdate),
m_updateInterval(params.m_updateInterval)
{
}
shared_ptr<RenderState> const & RenderStateUpdater::renderState() const
{
return m_renderState;
}
void RenderStateUpdater::drawGeometry(shared_ptr<BaseTexture> const & texture,
shared_ptr<VertexBuffer> const & vertices,
shared_ptr<IndexBuffer> const & indices,
size_t indicesCount)
{
base_t::drawGeometry(texture, vertices, indices, indicesCount);
m_indicesCount += indicesCount;
if (m_doPeriodicalUpdate
&& m_renderState
&& (m_indicesCount > 20000)
&& (m_updateTimer.ElapsedSeconds() > m_updateInterval))
{
updateActualTarget();
m_indicesCount %= 20000;
m_updateTimer.Reset();
}
}
void RenderStateUpdater::updateActualTarget()
{
/// Carefully synchronizing the access to the m_renderState to minimize wait time.
OGLCHECK(glFinish());
{
threads::MutexGuard guard(*m_renderState->m_mutex.get());
swap(m_renderState->m_actualTarget, m_renderState->m_backBufferLayers.front());
m_renderState->m_actualScreen = m_renderState->m_currentScreen;
}
/// blitting will be performed through
/// non-multisampled framebuffer for the sake of speed
frameBuffer()->setRenderTarget(m_renderState->m_backBufferLayers.front());
frameBuffer()->makeCurrent();
OGLCHECK(glFinish());
OGLCHECK(glDisable(GL_SCISSOR_TEST));
OGLCHECK(glClearColor(192 / 255.0, 192 / 255.0, 192 / 255.0, 1.0));
OGLCHECK(glClear(GL_COLOR_BUFFER_BIT));
shared_ptr<BaseTexture> actualTarget = m_renderState->m_actualTarget;
immDrawTexturedRect(
m2::RectF(0, 0, actualTarget->width(), actualTarget->height()),
m2::RectF(0, 0, 1, 1),
actualTarget
);
if (clipRectEnabled())
OGLCHECK(glEnable(GL_SCISSOR_TEST));
OGLCHECK(glFinish());
m_renderState->invalidate();
}
void RenderStateUpdater::beginFrame()
{
base_t::beginFrame();
m_indicesCount = 0;
m_updateTimer.Reset();
}
void RenderStateUpdater::setClipRect(m2::RectI const & rect)
{
if ((m_renderState) && (m_indicesCount))
{
updateActualTarget();
m_indicesCount = 0;
m_updateTimer.Reset();
}
base_t::setClipRect(rect);
}
void RenderStateUpdater::endFrame()
{
if (m_renderState)
updateActualTarget();
m_indicesCount = 0;
m_updateTimer.Reset();
base_t::endFrame();
}
}
}

View file

@ -0,0 +1,53 @@
#pragma once
#include "../std/shared_ptr.hpp"
#include "../geometry/screenbase.hpp"
#include "../base/timer.hpp"
#include "geometry_renderer.hpp"
namespace yg
{
namespace gl
{
class RenderState;
class RenderStateUpdater : public GeometryRenderer
{
private:
typedef GeometryRenderer base_t;
shared_ptr<RenderState> m_renderState;
int m_indicesCount;
bool m_doPeriodicalUpdate;
double m_updateInterval;
my::Timer m_updateTimer;
public:
struct Params : base_t::Params
{
bool m_doPeriodicalUpdate;
double m_updateInterval;
shared_ptr<RenderState> m_renderState;
Params();
};
RenderStateUpdater(Params const & params);
shared_ptr<RenderState> const & renderState() const;
void drawGeometry(shared_ptr<BaseTexture> const & texture,
shared_ptr<VertexBuffer> const & vertices,
shared_ptr<IndexBuffer> const & indices,
size_t indicesCount);
void beginFrame();
void endFrame();
void setClipRect(m2::RectI const & rect);
virtual void updateActualTarget();
};
}
}

View file

@ -55,7 +55,8 @@ SOURCES += \
info_layer.cpp \
overlay_element.cpp \
symbol_element.cpp \
overlay_renderer.cpp
overlay_renderer.cpp \
render_state_updater.cpp
HEADERS += \
internal/opengl.hpp \
@ -103,7 +104,8 @@ HEADERS += \
info_layer.hpp \
overlay_element.hpp \
symbol_element.hpp \
overlay_renderer.hpp
overlay_renderer.hpp \
render_state_updater.hpp
win32 {
HEADERS += internal/opengl_win32.hpp