removed BaseState, simplified PacketsQueue

This commit is contained in:
rachytski 2012-01-17 00:31:07 +04:00 committed by Alex Zolotarev
parent 9826b1b37a
commit 09035aaa9e
41 changed files with 482 additions and 607 deletions

View file

@ -82,7 +82,7 @@ struct SeparateFreePoolTraits : TBase
int oldMaxFreePoolSize = m_maxFreePoolSize;
m_maxFreePoolSize = max(m_maxFreePoolSize, (int)m_freePool.Size());
if (oldMaxFreePoolSize != m_maxFreePoolSize)
LOG(LINFO, ("freePool maximum size has reached", m_maxFreePoolSize, "elements"));
LOG(LINFO, (base_t::m_pool.GetName(), "freePool maximum size has reached", m_maxFreePoolSize, "elements"));
}
}

View file

@ -32,5 +32,6 @@ namespace iphone
unsigned height() const;
void attachToFrameBuffer();
void detachFromFrameBuffer();
};
}

View file

@ -69,4 +69,12 @@ namespace iphone
m_id));
yg::gl::utils::setupCoordinates(width(), height(), true);
}
void RenderBuffer::detachFromFrameBuffer()
{
OGLCHECK(glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
GL_COLOR_ATTACHMENT0_OES,
GL_RENDERBUFFER_OES,
0));
}
}

View file

@ -359,10 +359,10 @@ void Framework::DoPaint(shared_ptr<PaintEvent> const & e)
{
DrawerYG * pDrawer = e->drawer();
e->drawer()->screen()->beginFrame();
m_renderPolicy->DrawFrame(e, m_navigator.Screen());
e->drawer()->screen()->beginFrame();
/// m_informationDisplay is set and drawn after the m_renderPolicy
m2::PointD const center = m_navigator.Screen().GlobalRect().GlobalCenter();
@ -373,7 +373,6 @@ void Framework::DoPaint(shared_ptr<PaintEvent> const & e)
m_informationDisplay.setDebugInfo(0/*m_renderQueue.renderState().m_duration*/,
GetDrawScale());
m_informationDisplay.setCenter(m2::PointD(MercatorBounds::XToLon(center.x), MercatorBounds::YToLat(center.y)));
m_informationDisplay.enableRuler(true/*!IsEmptyModel()*/);

View file

@ -1,5 +1,6 @@
#include "queued_render_policy.hpp"
#include "events.hpp"
#include "../yg/internal/opengl.hpp"
QueuedRenderPolicy::QueuedRenderPolicy(int pipelinesCount,
shared_ptr<yg::gl::RenderContext> const & primaryRC,
@ -13,7 +14,7 @@ QueuedRenderPolicy::QueuedRenderPolicy(int pipelinesCount,
QueuedRenderPolicy::~QueuedRenderPolicy()
{
for (unsigned i = 0; i < m_PipelinesCount; ++i)
DismissQueuedCommands(i);
CancelQueuedCommands(i);
delete [] m_Pipelines;
@ -26,7 +27,7 @@ bool QueuedRenderPolicy::NeedRedraw() const
return true;
for (unsigned i = 0; i < m_PipelinesCount; ++i)
if (!m_Pipelines[i].m_Queue.Empty())
if (!m_Pipelines[i].m_Queue.empty())
return true;
return false;
@ -49,34 +50,34 @@ void QueuedRenderPolicy::EndFrame(shared_ptr<PaintEvent> const & ev, ScreenBase
void QueuedRenderPolicy::DrawFrame(shared_ptr<PaintEvent> const & ev, ScreenBase const & s)
{
shared_ptr<yg::gl::BaseState> state = ev->drawer()->screen()->createState();
state->m_isDebugging = m_IsDebugging;
ev->drawer()->screen()->getState(state.get());
for (unsigned i = 0; i < m_PipelinesCount; ++i)
{
RenderQueuedCommands(i, state);
RenderQueuedCommands(i);
m_resourceManager->updatePoolState();
}
}
void QueuedRenderPolicy::RenderQueuedCommands(int pipelineNum, shared_ptr<yg::gl::BaseState> const & state)
void QueuedRenderPolicy::RenderQueuedCommands(int pipelineNum)
{
shared_ptr<yg::gl::BaseState> curState = state;
/// logging only calls that is made while rendering tiles.
// if ((pipelineNum == 0) && (m_IsDebugging))
// yg::gl::g_doLogOGLCalls = true;
if (m_IsDebugging)
LOG(LINFO, ("--- Processing Pipeline #", pipelineNum, " ---"));
unsigned cmdProcessed = 0;
m_Pipelines[pipelineNum].m_Queue.ProcessList(bind(&QueuedRenderPolicy::PacketsPipeline::FillFrameBucket, &m_Pipelines[pipelineNum], _1, 1));
m_Pipelines[pipelineNum].m_Queue.processList(bind(&QueuedRenderPolicy::PacketsPipeline::FillFrameCommands, &m_Pipelines[pipelineNum], _1, 1));
cmdProcessed = m_Pipelines[pipelineNum].m_FrameBucket.size();
cmdProcessed = m_Pipelines[pipelineNum].m_FrameCommands.size();
list<yg::gl::Packet>::iterator it;
yg::gl::Packet::EType bucketType = m_Pipelines[pipelineNum].m_Type;
for (it = m_Pipelines[pipelineNum].m_FrameBucket.begin();
it != m_Pipelines[pipelineNum].m_FrameBucket.end();
for (it = m_Pipelines[pipelineNum].m_FrameCommands.begin();
it != m_Pipelines[pipelineNum].m_FrameCommands.end();
++it)
{
if (it->m_command)
@ -91,32 +92,27 @@ void QueuedRenderPolicy::RenderQueuedCommands(int pipelineNum, shared_ptr<yg::gl
{
ASSERT(bucketType == yg::gl::Packet::ECheckPoint, ());
if (it->m_state)
{
it->m_state->m_isDebugging = m_IsDebugging;
it->m_state->apply(curState.get());
curState = it->m_state;
}
if (it->m_command)
it->m_command->perform();
}
}
/// should clear to release resources, refered from the stored commands.
m_Pipelines[pipelineNum].m_FrameBucket.clear();
m_Pipelines[pipelineNum].m_FrameCommands.clear();
if (m_IsDebugging)
{
LOG(LINFO, ("processed", cmdProcessed, "commands"));
LOG(LINFO, (m_Pipelines[pipelineNum].m_Queue.Size(), "commands left"));
LOG(LINFO, (m_Pipelines[pipelineNum].m_Queue.size(), "commands left"));
}
state->apply(curState.get());
// if ((pipelineNum == 0) && (m_IsDebugging))
// yg::gl::g_doLogOGLCalls = false;
}
void QueuedRenderPolicy::PacketsPipeline::FillFrameBucket(list<yg::gl::Packet> & renderQueue, int maxFrames)
void QueuedRenderPolicy::PacketsPipeline::FillFrameCommands(list<yg::gl::Packet> & renderQueue, int maxFrames)
{
m_FrameBucket.clear();
m_FrameCommands.clear();
/// searching for "delimiter" markers
@ -124,16 +120,16 @@ void QueuedRenderPolicy::PacketsPipeline::FillFrameBucket(list<yg::gl::Packet> &
list<yg::gl::Packet>::iterator last = renderQueue.begin();
/// checking whether there are a CancelPoint packet in the queue.
/// In this case - fill m_FrameBucket till this packet
/// In this case - fill m_FrameCommands till this packet
for (list<yg::gl::Packet>::iterator it = renderQueue.begin();
it != renderQueue.end();
++it)
{
yg::gl::Packet p = *last;
yg::gl::Packet p = *it;
if (p.m_type == yg::gl::Packet::ECancelPoint)
{
copy(first, ++it, back_inserter(m_FrameBucket));
copy(first, ++it, back_inserter(m_FrameCommands));
renderQueue.erase(first, it);
m_Type = p.m_type;
return;
@ -141,7 +137,7 @@ void QueuedRenderPolicy::PacketsPipeline::FillFrameBucket(list<yg::gl::Packet> &
}
/// we know, that there are no CancelPoint packets in the queue.
/// so fill up the m_FrameBucket up to maxFrames frames.
/// so fill up the m_FrameCommands up to maxFrames frames.
int packetsLeft = 100000;
int framesLeft = maxFrames;
@ -153,7 +149,7 @@ void QueuedRenderPolicy::PacketsPipeline::FillFrameBucket(list<yg::gl::Packet> &
if (p.m_type == yg::gl::Packet::ECheckPoint)
{
/// found frame boundary, copying
copy(first, ++last, back_inserter(m_FrameBucket));
copy(first, ++last, back_inserter(m_FrameCommands));
/// erasing from the main queue
renderQueue.erase(first, last);
first = renderQueue.begin();
@ -173,7 +169,7 @@ void QueuedRenderPolicy::CopyQueuedCommands(list<yg::gl::Packet> &l, list<yg::gl
swap(l, r);
}
void QueuedRenderPolicy::DismissQueuedCommands(int pipelineNum)
void QueuedRenderPolicy::CancelQueuedCommands(int pipelineNum)
{
if (m_IsDebugging)
LOG(LINFO, ("cancelling packetsQueue for pipeline", pipelineNum));
@ -182,18 +178,14 @@ void QueuedRenderPolicy::DismissQueuedCommands(int pipelineNum)
list<yg::gl::Packet> l;
m_Pipelines[pipelineNum].m_Queue.ProcessList(bind(&QueuedRenderPolicy::CopyQueuedCommands, this, _1, ref(l)));
m_Pipelines[pipelineNum].m_Queue.processList(bind(&QueuedRenderPolicy::CopyQueuedCommands, this, _1, ref(l)));
for (list<yg::gl::Packet>::iterator it = l.begin(); it != l.end(); ++it)
{
yg::gl::Packet p = *it;
if ((p.m_type == yg::gl::Packet::ECheckPoint)
|| (p.m_type == yg::gl::Packet::ECancelPoint))
{
if (p.m_command)
p.m_command->perform();
}
if (p.m_command)
p.m_command->cancel();
}
}

View file

@ -4,24 +4,30 @@
#include "../base/threaded_list.hpp"
#include "../yg/renderer.hpp"
/// base class for policy using separate queue of gl commands.
/// base class for policy used on the devices that do not support
/// OpenGL context sharing.
class QueuedRenderPolicy : public RenderPolicy
{
private:
typedef RenderPolicy base_t;
/// separate pipeline for packets, collected on the single thread.
/// although it's possible to collect all the packet from all threads
/// into single queue it's better to separate them for finer optimization
/// of "heavy" commands.
struct PacketsPipeline
{
yg::gl::PacketsQueue m_Queue; //< all enqueued commands
list<yg::gl::Packet> m_FrameBucket; //< list of commands to execute on current frame
yg::gl::Packet::EType m_Type;
list<yg::gl::Packet> m_FrameCommands; //< list of commands to execute on current frame
yg::gl::Packet::EType m_Type; //< type of the actions to perform with FrameCommands
/// - fill m_FrameBucket with the packets from the QueueData
/// which corresponds to maxFrames frames, delimited by SimpleDelimiter markers,
/// - this function is passed to ThreadedList::ProcessQueue to fill up
/// the FrameCommands from the QueueData, taking at maximum maxCheckPoints chunks,
/// skipping empty frames.
void FillFrameBucket(list<yg::gl::Packet> & QueueData, int maxFrames);
/// - if there are a CancelPoint in the QueueData than the packets are copied up to
/// CancelPoint packet ignoring maxCheckPoints param
void FillFrameCommands(list<yg::gl::Packet> & QueueData, int maxCheckPoints);
};
/// couldn't use vector here as PacketsPipeline holds non-copyable yg::gl::PacketsQueue
@ -34,8 +40,8 @@ protected:
void CopyQueuedCommands(list<yg::gl::Packet> & l, list<yg::gl::Packet> & r);
void RenderQueuedCommands(int pipelineNum, shared_ptr<yg::gl::BaseState> const & state);
void DismissQueuedCommands(int pipelineNum);
void RenderQueuedCommands(int pipelineNum);
void CancelQueuedCommands(int pipelineNum);
public:

View file

@ -192,6 +192,8 @@ void RenderPolicyMT::DrawFrame(shared_ptr<PaintEvent> const & e,
m_renderQueue->renderState().m_mutex->Lock();
e->drawer()->beginFrame();
e->drawer()->screen()->clear(m_bgColor);
if (m_renderQueue->renderState().m_actualTarget.get() != 0)
@ -203,6 +205,8 @@ void RenderPolicyMT::DrawFrame(shared_ptr<PaintEvent> const & e,
pDrawer->screen()->blit(m_renderQueue->renderState().m_actualTarget, m);
}
e->drawer()->endFrame();
}
void RenderPolicyMT::StartDrag()

View file

@ -134,7 +134,7 @@ RenderPolicyST::RenderPolicyST(VideoTimer * videoTimer,
m_renderQueue.reset(new RenderQueue(GetPlatform().SkinName(),
false,
true,
false,
0.1,
false,
GetPlatform().ScaleEtalonSize(),
@ -161,7 +161,7 @@ RenderPolicyST::~RenderPolicyST()
{
LOG(LINFO, ("destroying RenderPolicyST"));
base_t::DismissQueuedCommands(0);
base_t::CancelQueuedCommands(0);
LOG(LINFO, ("shutting down renderQueue"));
@ -186,6 +186,8 @@ void RenderPolicyST::DrawFrame(shared_ptr<PaintEvent> const & e,
DrawerYG * pDrawer = e->drawer();
pDrawer->beginFrame();
e->drawer()->screen()->clear(m_bgColor);
m_renderQueue->renderState().m_mutex->Lock();
@ -199,6 +201,8 @@ void RenderPolicyST::DrawFrame(shared_ptr<PaintEvent> const & e,
pDrawer->screen()->blit(m_renderQueue->renderState().m_actualTarget, m);
}
pDrawer->endFrame();
}
void RenderPolicyST::EndFrame(shared_ptr<PaintEvent> const & ev,

View file

@ -133,9 +133,6 @@ void RenderQueueRoutine::processResize(ScreenBase const & frameScreen)
/// TODO : make as a command
m_renderState->m_actualScreen = frameScreen;
m_renderState->m_shadowActualTarget = m_renderState->m_actualTarget;
m_renderState->m_shadowBackBuffer = m_renderState->m_backBuffer;
m_renderState->m_isResized = false;
}
}
@ -414,6 +411,8 @@ void RenderQueueRoutine::Do()
m_renderState->m_currentScreen);
}
m_threadDrawer->endFrame();
//m_threadDrawer->screen()->setNeedTextRedraw(isPanning);
ScreenBase const & frameScreen = m_currentRenderCommand->m_frameScreen;
@ -435,6 +434,8 @@ void RenderQueueRoutine::Do()
continue;
m_threadDrawer->screen()->setClipRect(areas[i]);
m_threadDrawer->screen()->enableClipRect(true);
m_threadDrawer->screen()->beginFrame();
m_currentRenderCommand->m_renderFn(
m_currentRenderCommand->m_paintEvent,
@ -446,11 +447,13 @@ void RenderQueueRoutine::Do()
/// all unprocessed commands should be cancelled
if (m_currentRenderCommand->m_paintEvent->isCancelled() && m_glQueue)
m_glQueue->insertCancelPoint();
m_glQueue->cancelCommands();
if (!m_renderState->m_isEmptyModelCurrent)
cumulativeEmptyModelCurrent = m_renderState->m_isEmptyModelCurrent;
m_threadDrawer->screen()->endFrame();
if (IsCancelled())
break;
}
@ -466,6 +469,8 @@ void RenderQueueRoutine::Do()
/// setting the "whole texture" clip rect to render texts opened by panning.
m_threadDrawer->screen()->setClipRect(textureRect);
m_threadDrawer->beginFrame();
m_threadDrawer->screen()->infoLayer()->draw(m_threadDrawer->screen().get(), math::Identity<double, 3>());
m_threadDrawer->endFrame();
@ -490,17 +495,6 @@ void RenderQueueRoutine::Do()
}
invalidate();
/// waiting for all collected commands to complete.
if (m_glQueue)
m_glQueue->completeCommands();
{
threads::MutexGuard guard(*m_renderState->m_mutex.get());
/// refreshing shadow parameters from the primary parameters
m_renderState->m_shadowActualTarget = m_renderState->m_actualTarget;
m_renderState->m_shadowBackBuffer = m_renderState->m_backBuffer;
}
}
}

View file

@ -3,6 +3,7 @@
#include "tile_renderer.hpp"
#include "window_handle.hpp"
#include "../yg/internal/opengl.hpp"
#include "../yg/render_state.hpp"
#include "../yg/rendercontext.hpp"
#include "../yg/base_texture.hpp"
@ -47,23 +48,24 @@ TileRenderer::TileRenderer(
params.m_resourceManager = m_resourceManager;
params.m_frameBuffer = make_shared_ptr(new yg::gl::FrameBuffer());
shared_ptr<yg::gl::RenderBuffer> depthBuffer(new yg::gl::RenderBuffer(tileWidth, tileHeight, true));
params.m_frameBuffer->setDepthBuffer(depthBuffer);
params.m_frameBuffer->setDepthBuffer(make_shared_ptr(new yg::gl::RenderBuffer(tileWidth, tileHeight, true)));
params.m_glyphCacheID = m_resourceManager->renderThreadGlyphCacheID(i);
params.m_threadID = i;
params.m_visualScale = visualScale;
params.m_skinName = m_skinName;
params.m_renderQueue = packetsQueue;
params.m_doUnbindRT = true;
params.m_isSynchronized = true;
/* params.m_isDebugging = true;
params.m_drawPathes = false;
params.m_drawPathes = false ;
params.m_drawAreas = false;
params.m_drawTexts = false; */
m_threadData[i].m_drawerParams = params;
m_threadData[i].m_drawer = 0;
m_threadData[i].m_renderContext = m_primaryContext->createShared();
m_threadData[i].m_dummyRT = m_resourceManager->createRenderTarget(2, 2);
}
m_queue.AddInitCommand(bind(&TileRenderer::InitializeThreadGL, this, _1));
@ -119,6 +121,8 @@ void TileRenderer::DrawTile(core::CommandsQueue::Environment const & env,
ThreadData & threadData = m_threadData[env.threadNum()];
yg::gl::PacketsQueue * glQueue = threadData.m_drawerParams.m_renderQueue;
DrawerYG * drawer = threadData.m_drawer;
ScreenBase frameScreen;
@ -146,11 +150,15 @@ void TileRenderer::DrawTile(core::CommandsQueue::Environment const & env,
drawer->screen()->setInfoLayer(tileInfoLayer);
/// ensuring, that the render target is not bound as a texture
threadData.m_dummyRT->makeCurrent(glQueue);
drawer->beginFrame();
drawer->clear(yg::Color(m_bgColor.r, m_bgColor.g, m_bgColor.b, 0));
drawer->screen()->setClipRect(renderRect);
drawer->clear(m_bgColor);
/* drawer->clear(yg::Color(rand() % 255, rand() % 64, rand() % 128, 128));
/* drawer->clear(yg::Color(rand() % 32 + 128, rand() % 64 + 128, rand() % 32 + 128, 255));
std::stringstream out;
out << rectInfo.m_y << ", " << rectInfo.m_x << ", " << rectInfo.m_tileScale << ", " << rectInfo.m_drawScale;
@ -180,35 +188,25 @@ void TileRenderer::DrawTile(core::CommandsQueue::Environment const & env,
rectInfo.m_tileScale <= 17
);
if (!env.isCancelled())
drawer->endFrame();
drawer->endFrame();
if (!env.isCancelled())
drawer->screen()->resetInfoLayer();
drawer->screen()->resetInfoLayer();
/// filter out the overlay elements that are out of the bound rect for the tile
if (!env.isCancelled())
tileInfoLayer->clip(renderRect);
yg::gl::PacketsQueue * glQueue = threadData.m_drawerParams.m_renderQueue;
if (!env.isCancelled())
{
if (glQueue)
{
glQueue->insertCheckPoint();
glQueue->completeCommands();
}
}
else
{
if (!m_isExiting)
{
if (glQueue)
{
glQueue->insertCancelPoint();
glQueue->completeCommands();
}
glQueue->cancelCommands();
}
}

View file

@ -40,6 +40,7 @@ protected:
{
DrawerYG * m_drawer;
DrawerYG::params_t m_drawerParams;
shared_ptr<yg::gl::BaseTexture> m_dummyRT;
shared_ptr<yg::gl::RenderContext> m_renderContext;
};

View file

@ -55,13 +55,19 @@ int Tiler::drawScale(ScreenBase const & s) const
ScreenBase tmpS = s;
tmpS.Rotate(-tmpS.GetAngle());
size_t tileSize = min(static_cast<size_t>(m_tileSize / 1.05), (size_t)512);
m2::RectD glbRect;
m2::PointD pxCenter = tmpS.PixelRect().Center();
tmpS.PtoG(m2::RectD(pxCenter - m2::PointD(m_scaleEtalonSize / 2, m_scaleEtalonSize / 2),
pxCenter + m2::PointD(m_scaleEtalonSize / 2, m_scaleEtalonSize / 2)),
tmpS.PtoG(m2::RectD(pxCenter - m2::PointD(tileSize / 2, tileSize / 2),
pxCenter + m2::PointD(tileSize / 2, tileSize / 2)),
glbRect);
return scales::GetScaleLevel(glbRect);
double glbRectSize = min(glbRect.SizeX(), glbRect.SizeY());
int res = static_cast<int>(ceil(log((MercatorBounds::maxX - MercatorBounds::minX) / glbRectSize) / log(2.0)));
return res > scales::GetUpperScale() ? scales::GetUpperScale() : res;
}
int Tiler::tileScale(ScreenBase const & s) const

View file

@ -18,7 +18,7 @@ TilingRenderPolicyMT::TilingRenderPolicyMT(VideoTimer * videoTimer,
bool useDefaultFB,
yg::ResourceManager::Params const & rmParams,
shared_ptr<yg::gl::RenderContext> const & primaryRC)
: RenderPolicy(primaryRC, true)
: RenderPolicy(primaryRC, false)
{
yg::ResourceManager::Params rmp = rmParams;
@ -32,25 +32,6 @@ TilingRenderPolicyMT::TilingRenderPolicyMT(VideoTimer * videoTimer,
1,
"primaryStorage");
rmp.m_smallStoragesParams = yg::ResourceManager::StoragePoolParams(5000 * sizeof(yg::gl::Vertex),
sizeof(yg::gl::Vertex),
10000 * sizeof(unsigned short),
sizeof(unsigned short),
100,
false,
true,
1,
"smallStorage");
rmp.m_blitStoragesParams = yg::ResourceManager::StoragePoolParams(10 * sizeof(yg::gl::Vertex),
sizeof(yg::gl::Vertex),
10 * sizeof(unsigned short),
sizeof(unsigned short),
50,
true,
true,
1,
"blitStorage");
rmp.m_multiBlitStoragesParams = yg::ResourceManager::StoragePoolParams(500 * sizeof(yg::gl::Vertex),
sizeof(yg::gl::Vertex),
@ -62,15 +43,15 @@ TilingRenderPolicyMT::TilingRenderPolicyMT(VideoTimer * videoTimer,
1,
"multiBlitStorage");
rmp.m_guiThreadStoragesParams = yg::ResourceManager::StoragePoolParams(300 * sizeof(yg::gl::Vertex),
sizeof(yg::gl::Vertex),
600 * sizeof(unsigned short),
sizeof(unsigned short),
20,
true,
true,
1,
"guiThreadStorage");
rmp.m_guiThreadStoragesParams = yg::ResourceManager::StoragePoolParams(5000 * sizeof(yg::gl::Vertex),
sizeof(yg::gl::Vertex),
10000 * sizeof(unsigned short),
sizeof(unsigned short),
10,
true,
true,
1,
"guiThreadStorage");
rmp.m_primaryTexturesParams = yg::ResourceManager::TexturePoolParams(512,
256,
@ -84,7 +65,7 @@ TilingRenderPolicyMT::TilingRenderPolicyMT(VideoTimer * videoTimer,
rmp.m_fontTexturesParams = yg::ResourceManager::TexturePoolParams(512,
256,
5,
2,
rmp.m_texFormat,
true,
true,
@ -95,7 +76,7 @@ TilingRenderPolicyMT::TilingRenderPolicyMT(VideoTimer * videoTimer,
rmp.m_renderTargetTexturesParams = yg::ResourceManager::TexturePoolParams(GetPlatform().TileSize(),
GetPlatform().TileSize(),
GetPlatform().MaxTilesCount(),
rmp.m_rtFormat,
rmp.m_texFormat,
true,
true,
false,
@ -103,7 +84,7 @@ TilingRenderPolicyMT::TilingRenderPolicyMT(VideoTimer * videoTimer,
"renderTargetTexture");
rmp.m_styleCacheTexturesParams = yg::ResourceManager::TexturePoolParams(rmp.m_fontTexturesParams.m_texWidth,
rmp.m_fontTexturesParams.m_texHeight,
rmp.m_fontTexturesParams.m_texHeight * 4,
2,
rmp.m_texFormat,
true,
@ -198,6 +179,8 @@ void TilingRenderPolicyMT::DrawFrame(shared_ptr<PaintEvent> const & e, ScreenBas
{
DrawerYG * pDrawer = e->drawer();
pDrawer->beginFrame();
pDrawer->screen()->clear(m_bgColor);
m_coverageGenerator->AddCoverScreenTask(currentScreen);
@ -209,6 +192,8 @@ void TilingRenderPolicyMT::DrawFrame(shared_ptr<PaintEvent> const & e, ScreenBas
curCvg->Draw(pDrawer->screen().get(), currentScreen);
m_drawScale = curCvg->GetDrawScale();
pDrawer->endFrame();
}
int TilingRenderPolicyMT::GetDrawScale(ScreenBase const & s) const

View file

@ -34,7 +34,7 @@ TilingRenderPolicyST::TilingRenderPolicyST(VideoTimer * videoTimer,
bool useDefaultFB,
yg::ResourceManager::Params const & rmParams,
shared_ptr<yg::gl::RenderContext> const & primaryRC)
: QueuedRenderPolicy(2, primaryRC, true)
: QueuedRenderPolicy(2, primaryRC, false)
{
yg::ResourceManager::Params rmp = rmParams;
@ -49,7 +49,7 @@ TilingRenderPolicyST::TilingRenderPolicyST(VideoTimer * videoTimer,
"primaryStorage",
true);
rmp.m_smallStoragesParams = yg::ResourceManager::StoragePoolParams(2000 * sizeof(yg::gl::Vertex),
/* rmp.m_smallStoragesParams = yg::ResourceManager::StoragePoolParams(2000 * sizeof(yg::gl::Vertex),
sizeof(yg::gl::Vertex),
4000 * sizeof(unsigned short),
sizeof(unsigned short),
@ -68,7 +68,7 @@ TilingRenderPolicyST::TilingRenderPolicyST(VideoTimer * videoTimer,
true,
1,
"blitStorage");
*/
rmp.m_multiBlitStoragesParams = yg::ResourceManager::StoragePoolParams(1500 * sizeof(yg::gl::Vertex),
sizeof(yg::gl::Vertex),
3000 * sizeof(unsigned short),
@ -112,7 +112,7 @@ TilingRenderPolicyST::TilingRenderPolicyST(VideoTimer * videoTimer,
rmp.m_renderTargetTexturesParams = yg::ResourceManager::TexturePoolParams(GetPlatform().TileSize(),
GetPlatform().TileSize(),
GetPlatform().MaxTilesCount(),
rmp.m_rtFormat,
rmp.m_texFormat,
true,
true,
false,
@ -190,12 +190,12 @@ TilingRenderPolicyST::~TilingRenderPolicyST()
LOG(LINFO, ("deleting TilingRenderPolicyST"));
base_t::DismissQueuedCommands(1);
base_t::CancelQueuedCommands(1);
LOG(LINFO, ("reseting coverageGenerator"));
m_coverageGenerator.reset();
base_t::DismissQueuedCommands(0);
base_t::CancelQueuedCommands(0);
LOG(LINFO, ("reseting tileRenderer"));
m_tileRenderer.reset();
@ -238,8 +238,12 @@ void TilingRenderPolicyST::DrawFrame(shared_ptr<PaintEvent> const & e, ScreenBas
{
base_t::DrawFrame(e, currentScreen);
// yg::gl::g_doLogOGLCalls = true;
DrawerYG * pDrawer = e->drawer();
pDrawer->beginFrame();
pDrawer->screen()->clear(m_bgColor);
m_coverageGenerator->AddCoverScreenTask(currentScreen);
@ -251,6 +255,10 @@ void TilingRenderPolicyST::DrawFrame(shared_ptr<PaintEvent> const & e, ScreenBas
curCvg->Draw(pDrawer->screen().get(), currentScreen);
m_drawScale = curCvg->GetDrawScale();
pDrawer->endFrame();
// yg::gl::g_doLogOGLCalls = false;
}
int TilingRenderPolicyST::GetDrawScale(ScreenBase const & s) const

View file

@ -71,7 +71,7 @@ void Platform::GetFontNames(FilesList & res) const
int Platform::MaxTilesCount() const
{
return 30;
return 60;
}
int Platform::TileSize() const

View file

@ -4,7 +4,7 @@
#include "base_texture.hpp"
#include "utils.hpp"
#include "../base/logging.hpp"
#include "../std/bind.hpp"
namespace yg
{
@ -53,10 +53,22 @@ namespace yg
void BaseTexture::attachToFrameBuffer()
{
OGLCHECK(glFramebufferTexture2DFn(GL_FRAMEBUFFER_MWM,
GL_COLOR_ATTACHMENT0_MWM, GL_TEXTURE_2D, id(), 0));
GL_COLOR_ATTACHMENT0_MWM,
GL_TEXTURE_2D,
id(),
0));
utils::setupCoordinates(width(), height(), false);
}
void BaseTexture::detachFromFrameBuffer()
{
OGLCHECK(glFramebufferTexture2DFn(GL_FRAMEBUFFER_MWM,
GL_COLOR_ATTACHMENT0_MWM,
GL_TEXTURE_2D,
0,
0));
}
unsigned BaseTexture::current()
{
int id;
@ -64,9 +76,14 @@ namespace yg
return id;
}
void BaseTexture::makeCurrent() const
void BaseTexture::makeCurrent(yg::gl::PacketsQueue * queue) const
{
if (queue)
queue->processFn(bind(&BaseTexture::makeCurrent, this, (yg::gl::PacketsQueue*)0));
#ifndef OMIM_OS_ANDROID
if (current() != m_id)
#endif
OGLCHECK(glBindTexture(GL_TEXTURE_2D, m_id));
}

View file

@ -3,6 +3,7 @@
#include "../geometry/rect2d.hpp"
#include "../geometry/point2d.hpp"
#include "render_target.hpp"
#include "packets_queue.hpp"
namespace yg
{
@ -33,8 +34,9 @@ namespace yg
unsigned height() const;
unsigned id() const;
void makeCurrent() const;
void makeCurrent(yg::gl::PacketsQueue * queue = 0) const;
void attachToFrameBuffer();
void detachFromFrameBuffer();
m2::PointF const mapPixel(m2::PointF const & p) const;
m2::RectF const mapRect(m2::RectF const & r) const;

View file

@ -137,15 +137,17 @@ namespace yg
Vertex::setupLayout(storage.m_vertices->glPtr());
OGLCHECK(glDisable(GL_BLEND));
OGLCHECK(glDisable(GL_DEPTH_TEST));
OGLCHECK(glDepthMask(GL_FALSE));
memcpy(storage.m_indices->data(), &idxData[0], idxData.size() * sizeof(unsigned short));
storage.m_indices->unlock();
storage.m_indices->makeCurrent();
OGLCHECK(glEnable(GL_TEXTURE_2D));
OGLCHECK(glDisable(GL_BLEND));
OGLCHECK(glDisable(GL_DEPTH_TEST));
OGLCHECK(glDepthMask(GL_FALSE));
for (unsigned i = 0; i < s; ++i)
{
if (blitInfo[i].m_srcSurface)
@ -155,7 +157,6 @@ namespace yg
}
OGLCHECK(glEnable(GL_DEPTH_TEST));
OGLCHECK(glEnable(GL_TEXTURE_2D));
OGLCHECK(glEnable(GL_BLEND));
OGLCHECK(glDepthMask(GL_TRUE));
// /// This call is necessary to avoid parasite blitting in updateActualTarget() on IPhone.

View file

@ -13,36 +13,6 @@ namespace yg
m_isClippingEnabled(false)
{}
void Clipper::State::apply(BaseState const * prev)
{
base_t::State::apply(prev);
State const * state = static_cast<State const *>(prev);
if (state->m_isClippingEnabled != m_isClippingEnabled)
{
if (m_isClippingEnabled)
{
if (m_isDebugging)
LOG(LINFO, ("enabling scissors"));
OGLCHECK(glEnable(GL_SCISSOR_TEST));
}
else
{
if (m_isDebugging)
LOG(LINFO, ("disabling scissors"));
OGLCHECK(glDisable(GL_SCISSOR_TEST));
}
}
if (state->m_clipRect != m_clipRect)
{
if (m_isDebugging)
LOG(LINFO, ("scissor(", m_clipRect.minX(), m_clipRect.minY(), m_clipRect.maxX(), m_clipRect.maxY(), ")"));
OGLCHECK(glScissor(m_clipRect.minX(), m_clipRect.minY(), m_clipRect.SizeX(), m_clipRect.SizeY()));
}
}
void Clipper::beginFrame()
{
base_t::beginFrame();
@ -57,17 +27,36 @@ namespace yg
base_t::endFrame();
}
Clipper::EnableClipRect::EnableClipRect(bool flag)
: m_flag(flag)
{}
void Clipper::EnableClipRect::perform()
{
if (isDebugging())
LOG(LINFO, ("performing EnableClipRect command"));
if (m_flag)
{
if (isDebugging())
LOG(LINFO, ("enabling scissor test"));
OGLCHECK(glEnable(GL_SCISSOR_TEST));
}
else
{
if (isDebugging())
{
LOG(LINFO, ("disabling scissor test"));
OGLCHECK(glDisable(GL_SCISSOR_TEST));
}
}
}
void Clipper::enableClipRect(bool flag)
{
m_isClippingEnabled = flag;
if (renderQueue())
return;
if (m_isClippingEnabled)
OGLCHECK(glEnable(GL_SCISSOR_TEST));
else
OGLCHECK(glDisable(GL_SCISSOR_TEST));
processCommand(make_shared_ptr(new EnableClipRect(flag)));
}
bool Clipper::clipRectEnabled() const
@ -75,36 +64,32 @@ namespace yg
return m_isClippingEnabled;
}
Clipper::SetClipRect::SetClipRect(m2::RectI const & rect)
: m_rect(rect)
{}
void Clipper::SetClipRect::perform()
{
if (isDebugging())
LOG(LINFO, ("performing SetClipRect command"));
OGLCHECK(glScissor(m_rect.minX(), m_rect.minY(), m_rect.SizeX(), m_rect.SizeY()));
}
void Clipper::setClipRect(m2::RectI const & rect)
{
m_clipRect = rect;
if (!m_clipRect.Intersect(m2::RectI(0, 0, width(), height())))
m_clipRect = m2::RectI(0, 0, 0, 0);
if (renderQueue())
return;
ASSERT ( m_clipRect.IsValid(), (m_clipRect) );
OGLCHECK(glScissor(m_clipRect.minX(), m_clipRect.minY(), m_clipRect.SizeX(), m_clipRect.SizeY()));
processCommand(make_shared_ptr(new SetClipRect(m_clipRect)));
}
m2::RectI const & Clipper::clipRect() const
{
return m_clipRect;
}
shared_ptr<BaseState> const Clipper::createState() const
{
return shared_ptr<BaseState>(new State());
}
void Clipper::getState(BaseState * s)
{
State * state = static_cast<State *>(s);
base_t::getState(s);
state->m_clipRect = m_clipRect;
state->m_isClippingEnabled = m_isClippingEnabled;
}
}
}

View file

@ -19,20 +19,23 @@ namespace yg
void enableClipRectImpl(bool flag);
void setClipRectImpl(m2::RectI const & rect);
public:
struct State : public base_t::State
struct EnableClipRect : public Command
{
bool m_isClippingEnabled;
m2::RectI m_clipRect;
void apply(BaseState const * prev);
bool m_flag;
EnableClipRect(bool flag);
void perform();
};
Clipper(base_t::Params const & params);
struct SetClipRect : public Command
{
m2::RectI m_rect;
SetClipRect(m2::RectI const & rect);
void perform();
};
shared_ptr<BaseState> const createState() const;
void getState(BaseState * state);
public:
Clipper(base_t::Params const & params);
void beginFrame();
void endFrame();

View file

@ -41,19 +41,6 @@ namespace yg
if (m_id != current())
OGLCHECK(glBindFramebufferFn(GL_FRAMEBUFFER_MWM, m_id));
if (m_renderTarget)
m_renderTarget->attachToFrameBuffer();
else
{
if (m_id != 0)
OGLCHECK(glFramebufferRenderbufferFn(
GL_FRAMEBUFFER_MWM,
GL_COLOR_ATTACHMENT0_MWM,
GL_RENDERBUFFER_MWM,
0));
utils::setupCoordinates(width(), height(), true);
}
if (m_depthBuffer)
m_depthBuffer->attachToFrameBuffer();
else
@ -66,6 +53,21 @@ namespace yg
0));
}
if (m_renderTarget)
m_renderTarget->attachToFrameBuffer();
else
{
if (m_id != 0)
OGLCHECK(glFramebufferTexture2DFn(
GL_FRAMEBUFFER_MWM,
GL_COLOR_ATTACHMENT0_MWM,
GL_TEXTURE_2D,
0,
0));
utils::setupCoordinates(width(), height(), true);
}
/// !!! it's a must for a correct work.
/// update: it was necessary for multisampling,
/// but without it on KindleFire this function produces bug

View file

@ -23,14 +23,12 @@ namespace yg
namespace gl
{
GeometryBatcher::Params::Params()
: m_isSynchronized(true),
m_useGuiResources(false)
: m_useGuiResources(false)
{}
GeometryBatcher::GeometryBatcher(Params const & params)
: base_t(params),
m_isAntiAliased(true),
m_isSynchronized(params.m_isSynchronized),
m_useGuiResources(params.m_useGuiResources)
{
reset(-1);
@ -269,9 +267,6 @@ namespace yg
/// Syncronization point.
enableClipRect(false);
if (m_isSynchronized)
processCommand(shared_ptr<Command>(new FinishCommand()));
if (isDebugging())
{
for (size_t i = 0; i < m_pipelines.size(); ++i)

View file

@ -128,7 +128,6 @@ namespace yg
struct Params : public base_t::Params
{
bool m_isSynchronized;
bool m_useGuiResources;
Params();
};

View file

@ -59,30 +59,6 @@ namespace yg
processCommand(command);
}
void GeometryRenderer::UploadData::perform()
{
if (isDebugging())
LOG(LINFO, ("performing UploadData command"));
static_cast<gl::ManagedTexture*>(m_texture.get())->lock();
TDynamicTexture * dynTexture = static_cast<TDynamicTexture*>(m_texture.get());
for (size_t i = 0; i < m_styles.size(); ++i)
{
shared_ptr<ResourceStyle> const & style = m_styles[i];
TDynamicTexture::view_t v = dynTexture->view(style->m_texRect.SizeX(),
style->m_texRect.SizeY());
style->render(&v(0, 0));
dynTexture->upload(&v(0, 0), style->m_texRect);
}
static_cast<gl::ManagedTexture*>(m_texture.get())->unlock();
}
void GeometryRenderer::applyStates(bool isAntiAliased)
{
if (renderQueue())

View file

@ -23,13 +23,6 @@ namespace yg
typedef Blitter base_t;
struct UploadData : Command
{
vector<shared_ptr<ResourceStyle> > m_styles;
shared_ptr<BaseTexture> m_texture;
void perform();
};
struct DrawGeometry : Command
{
shared_ptr<BaseTexture> m_texture;

View file

@ -86,6 +86,7 @@ namespace yg
void (OPENGL_CALLING_CONVENTION * glBlendFuncSeparateFn) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
bool g_doDeleteOnDestroy = true;
bool g_doLogOGLCalls = false;
void CheckExtensionSupport()
{

View file

@ -1,5 +1,6 @@
#pragma once
#include "../../std/target_os.hpp"
#include "../../base/logging.hpp"
#include "../../base/logging.hpp"
@ -112,6 +113,11 @@ namespace yg
extern bool g_doDeleteOnDestroy;
/// This flag controls, whether the OGLCHECK macroses should log OGL calls.
/// This is for debugging purpose only.
extern bool g_doLogOGLCalls;
/// each platform should have an implementation of this function
/// to check extensions support and initialize function pointers.
void InitExtensions();
@ -139,12 +145,12 @@ namespace yg
}
}
//#define OMIM_GL_ENABLE_TRACE 1
#define OMIM_GL_ENABLE_TRACE 1
#ifdef DEBUG
#ifdef OMIM_GL_ENABLE_TRACE
#define OGLCHECK(f) do { LOG(LDEBUG, (#f)); f; yg::gl::CheckError(SRC()); } while(false)
#define OGLCHECKAFTER LOG(LDEBUG, ("OGLCHECKAFTER")); yg::gl::CheckError(SRC())
#define OGLCHECK(f) do { if (yg::gl::g_doLogOGLCalls) LOG(LDEBUG, (#f)); f; yg::gl::CheckError(SRC()); } while(false)
#define OGLCHECKAFTER if (yg::gl::g_doLogOGLCalls) LOG(LDEBUG, ("OGLCHECKAFTER")); yg::gl::CheckError(SRC())
#define EGLCHECK do { LOG(LDEBUG, ("EGLCHECK")); yg::gl::CheckEGLError(SRC()); } while(false)
#else
#define OGLCHECK(f) do { f; yg::gl::CheckError(SRC()); } while(false)

View file

@ -5,13 +5,6 @@ namespace yg
{
namespace gl
{
BaseState::BaseState()
: m_isDebugging(false)
{}
BaseState::~BaseState()
{}
bool Command::isDebugging() const
{
return m_isDebugging;
@ -30,16 +23,10 @@ namespace yg
{}
void Command::cancel()
{
if ((m_isDebugging) && (!m_name.empty()))
LOG(LINFO, ("cancelling", m_name, "command"));
}
{}
void Command::perform()
{
if ((m_isDebugging) && (!m_name.empty()))
LOG(LINFO, ("performing", m_name, "command"));
}
{}
Packet::Packet()
{}
@ -48,35 +35,16 @@ namespace yg
: m_type(type)
{}
Packet::Packet(shared_ptr<Command> const & command, EType type)
Packet::Packet(shared_ptr<Command> const & command,
EType type)
: m_command(command),
m_type(type)
{}
Packet::Packet(shared_ptr<BaseState> const & state,
shared_ptr<Command> const & command,
EType type)
: m_state(state),
m_command(command),
m_type(type)
{
if (m_state && m_command)
m_state->m_isDebugging = m_command->isDebugging();
}
PacketsQueue::PacketsQueue() : m_fenceManager(5)
PacketsQueue::PacketsQueue()
: m_fenceManager(5)
{}
void PacketsQueue::insertCheckPoint()
{
processPacket(Packet(Packet::ECheckPoint));
}
void PacketsQueue::insertCancelPoint()
{
processPacket(Packet(Packet::ECancelPoint));
}
struct SignalFence : public Command
{
int m_id;
@ -97,10 +65,10 @@ namespace yg
}
};
int PacketsQueue::insertFence()
int PacketsQueue::insertFence(Packet::EType type)
{
int id = m_fenceManager.insertFence();
processPacket(Packet(make_shared_ptr(new SignalFence(id, &m_fenceManager)), Packet::ECheckPoint));
processPacket(Packet(make_shared_ptr(new SignalFence(id, &m_fenceManager)), type));
return id;
}
@ -111,23 +79,38 @@ namespace yg
void PacketsQueue::completeCommands()
{
joinFence(insertFence());
joinFence(insertFence(Packet::ECheckPoint));
}
void PacketsQueue::cancelCommands()
{
joinFence(insertFence(Packet::ECancelPoint));
}
void PacketsQueue::cancel()
{
Cancel();
m_packets.Cancel();
}
void PacketsQueue::processPacket(Packet const & packet)
{
if (IsCancelled())
if (m_packets.IsCancelled())
{
if (packet.m_command)
packet.m_command->cancel();
}
else
PushBack(packet);
m_packets.PushBack(packet);
}
bool PacketsQueue::empty() const
{
return m_packets.Empty();
}
size_t PacketsQueue::size() const
{
return m_packets.Size();
}
}
}

View file

@ -12,14 +12,6 @@ namespace yg
{
namespace gl
{
struct BaseState
{
bool m_isDebugging;
BaseState();
virtual ~BaseState();
virtual void apply(BaseState const * prev) = 0;
};
struct Command
{
private:
@ -41,6 +33,28 @@ namespace yg
friend class Renderer;
};
template <typename Fn>
struct FunctorCommand : Command
{
Fn m_fn;
bool m_performOnCancel;
FunctorCommand(Fn fn, bool performOnCancel = false)
: m_fn(fn), m_performOnCancel(performOnCancel)
{}
void perform()
{
m_fn();
}
void cancel()
{
if (m_performOnCancel)
m_fn();
}
};
struct Packet
{
enum EType
@ -50,27 +64,22 @@ namespace yg
ECancelPoint
};
shared_ptr<BaseState> m_state;
shared_ptr<Command> m_command;
EType m_type;
Packet();
/// empty packet act as a frame delimiter
explicit Packet(EType type);
/// non-opengl command, without any state
/// simple command
Packet(shared_ptr<Command> const & command,
EType type);
/// opengl command with state
Packet(shared_ptr<BaseState> const & state,
shared_ptr<Command> const & command,
EType type);
};
class PacketsQueue : public ThreadedList<Packet>
class PacketsQueue
{
private:
ThreadedList<Packet> m_packets;
FenceManager m_fenceManager;
public:
@ -79,15 +88,28 @@ namespace yg
void processPacket(Packet const & packet);
void cancel();
bool empty() const;
size_t size() const;
void insertCheckPoint();
void insertCancelPoint();
int insertFence();
int insertFence(Packet::EType type);
void joinFence(int id);
/// Convenience functions
void completeCommands();
void cancelCommands();
template <typename Fn>
void processFn(Fn fn, bool performOnCancel = false)
{
processPacket(Packet(make_shared_ptr(new FunctorCommand<Fn>(fn)), Packet::ECommand));
}
template <typename Fn>
void processList(Fn fn)
{
m_packets.ProcessList(fn);
}
};
}
}

View file

@ -57,6 +57,7 @@ namespace yg
for (unsigned i = 0; i < boundRects().size(); ++i)
screen->drawRectangle(boundRects()[i], c, yg::maxDepth - 3);
}
if (!isNeedRedraw())
return;
@ -102,7 +103,7 @@ namespace yg
desc.m_isMasked = false;
}
return TextElement::getNonPackedRects(m_glyphLayout, desc, stylesCache, v);
TextElement::getNonPackedRects(m_glyphLayout, desc, stylesCache, v);
}
void PathTextElement::map(StylesCache * stylesCache) const

View file

@ -51,9 +51,6 @@ namespace yg
bool m_isEmptyModelCurrent;
/// @}
shared_ptr<BaseTexture> m_shadowActualTarget;
shared_ptr<BaseTexture> m_shadowBackBuffer;
/// Surface height and width.
unsigned int m_surfaceWidth;
unsigned int m_surfaceHeight;

View file

@ -54,23 +54,6 @@ namespace yg
}
}
void RenderStateUpdater::UpdateActualTarget::perform()
{
if (isDebugging())
LOG(LINFO, ("performing UpdateActualTarget command"));
OGLCHECK(glFinish());
if (m_doSynchronize)
m_renderState->m_mutex->Lock();
swap(m_renderState->m_actualTarget, m_renderState->m_backBuffer);
if (!m_renderState->m_isEmptyModelCurrent)
m_renderState->m_isEmptyModelActual = m_renderState->m_isEmptyModelCurrent;
m_renderState->m_actualScreen = m_currentScreen;
if (m_doSynchronize)
m_renderState->m_mutex->Unlock();
}
void RenderStateUpdater::UpdateBackBuffer::perform()
{
if (isDebugging())
@ -107,6 +90,8 @@ namespace yg
if (m_isClipRectEnabled)
OGLCHECK(glEnable(GL_SCISSOR_TEST));
OGLCHECK(glScissor(m_clipRect.minX(), m_clipRect.minY(), m_clipRect.maxX(), m_clipRect.maxY()));
OGLCHECK(glFinish());
if (m_doSynchronize)
@ -121,31 +106,38 @@ namespace yg
void RenderStateUpdater::updateActualTarget()
{
/// Carefully synchronizing the access to the m_renderState to minimize wait time.
processCommand(shared_ptr<Command>(new FinishCommand()));
finish();
completeCommands();
/// to re-set the states
base_t::endFrame();
base_t::beginFrame();
m_renderState->m_mutex->Lock();
swap(m_renderState->m_shadowActualTarget, m_renderState->m_shadowBackBuffer);
swap(m_renderState->m_actualTarget, m_renderState->m_backBuffer);
m_renderState->m_actualScreen = m_renderState->m_currentScreen;
if (!m_renderState->m_isEmptyModelCurrent)
m_renderState->m_isEmptyModelActual = m_renderState->m_isEmptyModelCurrent;
shared_ptr<UpdateActualTarget> command(new UpdateActualTarget());
command->m_renderState = m_renderState;
command->m_currentScreen = m_renderState->m_currentScreen;
command->m_doSynchronize = (renderQueue() != 0);
m_renderState->m_mutex->Unlock();
processCommand(command);
base_t::endFrame();
setRenderTarget(m_renderState->m_backBuffer);
shared_ptr<UpdateBackBuffer> command1(new UpdateBackBuffer());
command1->m_renderState = m_renderState;
command1->m_resourceManager = resourceManager();
command1->m_isClipRectEnabled = clipRectEnabled();
command1->m_clipRect = clipRect();
command1->m_doSynchronize = renderQueue();
command1->m_auxFrameBuffer = m_auxFrameBuffer;
command1->m_frameBuffer = frameBuffer();
setRenderTarget(m_renderState->m_shadowBackBuffer);
m_renderState->m_mutex->Unlock();
base_t::beginFrame();
processCommand(command1);
@ -156,7 +148,11 @@ namespace yg
processCommand(command2);
markFrameBoundary();
base_t::endFrame();
completeCommands();
setRenderTarget(m_renderState->m_backBuffer);
base_t::beginFrame();
}
void RenderStateUpdater::beginFrame()
@ -182,8 +178,6 @@ namespace yg
{
if ((m_renderState) && (m_indicesCount))
updateActualTarget();
else
markFrameBoundary();
m_indicesCount = 0;
m_updateTimer.Reset();

View file

@ -26,15 +26,6 @@ namespace yg
double m_updateInterval;
my::Timer m_updateTimer;
struct UpdateActualTarget : Command
{
bool m_doSynchronize;
shared_ptr<RenderState> m_renderState;
ScreenBase m_currentScreen;
void perform();
};
struct UpdateBackBuffer : Command
{
shared_ptr<RenderState> m_renderState;
@ -42,6 +33,7 @@ namespace yg
shared_ptr<FrameBuffer> m_auxFrameBuffer;
shared_ptr<FrameBuffer> m_frameBuffer;
bool m_isClipRectEnabled;
m2::RectI m_clipRect;
bool m_doSynchronize;
void perform();

View file

@ -11,6 +11,7 @@ namespace yg
/// attach render target to framebuffer and setup coordinate system
virtual unsigned int id() const = 0;
virtual void attachToFrameBuffer() = 0;
virtual void detachFromFrameBuffer() = 0;
virtual unsigned width() const = 0;
virtual unsigned height() const = 0;
};

View file

@ -93,6 +93,15 @@ namespace yg
utils::setupCoordinates(width(), height(), false);
}
void RenderBuffer::detachFromFrameBuffer()
{
OGLCHECK(glFramebufferRenderbufferFn(
GL_FRAMEBUFFER_MWM,
isDepthBuffer() ? GL_DEPTH_ATTACHMENT_MWM : GL_COLOR_ATTACHMENT0_MWM,
GL_RENDERBUFFER_MWM,
0));
}
void RenderBuffer::makeCurrent() const
{
if (m_id != current())

View file

@ -26,6 +26,7 @@ namespace yg
void makeCurrent() const;
void attachToFrameBuffer();
void detachFromFrameBuffer();
bool isDepthBuffer() const;

View file

@ -13,165 +13,17 @@ namespace yg
{
const yg::Color Renderer::s_bgColor(192, 192, 192, 255);
void Renderer::State::apply(BaseState const * prevBase)
{
State const * prevState = static_cast<State const *>(prevBase);
if (m_frameBuffer)
{
bool shouldApply = false;
if (m_frameBuffer == prevState->m_frameBuffer)
{
if (m_isDebugging)
{
std::ostringstream out;
out << "equal frameBuffers, ";
if (m_frameBuffer)
out << m_frameBuffer->id() << ", " << prevState->m_frameBuffer->id();
else
out << "(null), (null)";
LOG(LINFO, (out.str().c_str()));
}
if (m_renderTarget != prevState->m_renderTarget)
{
if (m_isDebugging)
{
std::ostringstream out;
out << "non-equal renderBuffers, ";
if (prevState->m_renderTarget)
out << prevState->m_renderTarget->id();
else
out << "(null)";
out << " => ";
if (m_renderTarget)
out << m_renderTarget->id();
else
out << "(null)";
LOG(LINFO, (out.str().c_str()));
}
m_frameBuffer->setRenderTarget(m_renderTarget);
shouldApply = true;
}
else
{
if (m_isDebugging)
{
std::ostringstream out;
out << "equal renderBuffers, ";
if (m_renderTarget)
out << m_renderTarget->id() << ", " << m_renderTarget->id();
else
out << "(null), (null)";
LOG(LINFO, (out.str().c_str()));
}
}
if (m_depthBuffer != prevState->m_depthBuffer)
{
if (m_isDebugging)
{
std::ostringstream out;
out << "non-equal depthBuffers, ";
if (prevState->m_depthBuffer)
out << prevState->m_depthBuffer->id();
else
out << "(null)";
out << " => ";
if (m_depthBuffer)
out << m_depthBuffer->id();
else
out << "(null)";
LOG(LINFO, (out.str().c_str()));
}
m_frameBuffer->setDepthBuffer(m_depthBuffer);
shouldApply = true;
}
else
{
if (m_isDebugging)
{
std::ostringstream out;
out << "equal depthBuffers, ";
if (m_depthBuffer)
out << m_depthBuffer->id() << ", " << m_depthBuffer->id();
else
out << "(null), (null)";
LOG(LINFO, (out.str().c_str()));
}
}
}
else
{
if (m_isDebugging)
{
ostringstream out;
out << "non-equal frameBuffers, ";
if (prevState->m_frameBuffer)
out << prevState->m_frameBuffer->id() << ", ";
else
out << "(null)";
out << " => ";
if (m_frameBuffer)
out << m_frameBuffer->id() << ", ";
else
out << "(null)";
LOG(LINFO, (out.str().c_str()));
out.str("");
out << "renderTarget=";
if (m_renderTarget)
out << m_renderTarget->id();
else
out << "(null)";
out << ", depthBuffer=";
if (m_depthBuffer)
out << m_depthBuffer->id();
else
out << "(null)";
LOG(LINFO, (out.str().c_str()));
}
m_frameBuffer->setRenderTarget(m_renderTarget);
m_frameBuffer->setDepthBuffer(m_depthBuffer);
shouldApply = true;
}
if (shouldApply)
m_frameBuffer->makeCurrent();
}
else
CHECK(false, ());
}
Renderer::Params::Params()
: m_isDebugging(false),
m_doUnbindRT(false),
m_isSynchronized(true),
m_renderQueue(0)
{}
Renderer::Renderer(Params const & params)
: m_isDebugging(params.m_isDebugging),
m_doUnbindRT(params.m_doUnbindRT),
m_isSynchronized(params.m_isSynchronized),
m_isRendering(false),
m_width(0),
m_height(0)
@ -200,11 +52,12 @@ namespace yg
{
m_isRendering = true;
if (m_renderQueue)
return;
m_frameBuffer->setRenderTarget(m_renderTarget);
m_frameBuffer->setDepthBuffer(m_depthBuffer);
if (m_frameBuffer)
m_frameBuffer->makeCurrent();
processCommand(make_shared_ptr(new ChangeFrameBuffer(m_frameBuffer)));
// checkStatus();
}
bool Renderer::isRendering() const
@ -212,9 +65,24 @@ namespace yg
return m_isRendering;
}
Renderer::UnbindRenderTarget::UnbindRenderTarget(shared_ptr<RenderTarget> const & rt)
: m_renderTarget(rt)
{}
void Renderer::UnbindRenderTarget::perform()
{
m_renderTarget->detachFromFrameBuffer();
}
void Renderer::endFrame()
{
m_isRendering = false;
if (m_doUnbindRT && m_renderTarget)
processCommand(make_shared_ptr(new UnbindRenderTarget(m_renderTarget)));
if (m_isSynchronized)
finish();
m_isRendering = false;
}
shared_ptr<FrameBuffer> const & Renderer::frameBuffer() const
@ -229,20 +97,14 @@ namespace yg
void Renderer::setRenderTarget(shared_ptr<RenderTarget> const & rt)
{
CHECK(!isRendering(), ("should call this function only outside beginFrame/endFrame"));
m_renderTarget = rt;
if (!m_renderQueue)
{
m_frameBuffer->setRenderTarget(rt);
m_frameBuffer->makeCurrent(); //< to attach renderTarget
}
}
void Renderer::resetRenderTarget()
{
CHECK(!isRendering(), ("should call this function only outside beginFrame/endFrame"));
m_renderTarget.reset();
if (!m_renderQueue)
m_frameBuffer->resetRenderTarget();
}
shared_ptr<RenderBuffer> const & Renderer::depthBuffer() const
@ -252,18 +114,14 @@ namespace yg
void Renderer::setDepthBuffer(shared_ptr<RenderBuffer> const & rt)
{
CHECK(!isRendering(), ("should call this function only outside beginFrame/endFrame"));
m_depthBuffer = rt;
if (!m_renderQueue)
m_frameBuffer->setDepthBuffer(rt);
}
void Renderer::resetDepthBuffer()
{
CHECK(!isRendering(), ("should call this function only outside beginFrame/endFrame"));
m_depthBuffer.reset();
if (!m_renderQueue)
m_frameBuffer->resetDepthBuffer();
}
Renderer::ClearCommand::ClearCommand(yg::Color const & color,
@ -307,24 +165,9 @@ namespace yg
processCommand(command);
}
shared_ptr<BaseState> const Renderer::createState() const
{
return shared_ptr<BaseState>(new State());
}
void Renderer::getState(BaseState * baseState)
{
State * state = static_cast<State *>(baseState);
state->m_frameBuffer = m_frameBuffer;
state->m_renderTarget = m_renderTarget;
state->m_depthBuffer = m_depthBuffer;
state->m_resourceManager = m_resourceManager;
}
void Renderer::FinishCommand::perform()
{
if (m_isDebugging)
if (isDebugging())
LOG(LINFO, ("performing FinishCommand command"));
OGLCHECK(glFinish());
}
@ -335,6 +178,21 @@ namespace yg
processCommand(command);
}
Renderer::ChangeFrameBuffer::ChangeFrameBuffer(shared_ptr<FrameBuffer> const & fb)
: m_frameBuffer(fb)
{}
void Renderer::ChangeFrameBuffer::perform()
{
if (isDebugging())
{
LOG(LINFO, ("performing ChangeFrameBuffer command"));
LOG(LINFO, ("frameBufferID=", m_frameBuffer->id()));
}
m_frameBuffer->makeCurrent();
}
void Renderer::onSize(unsigned int width, unsigned int height)
{
if (width < 2) width = 2;
@ -368,11 +226,7 @@ namespace yg
command->m_isDebugging = renderQueue();
if (renderQueue())
{
shared_ptr<BaseState> state = createState();
getState(state.get());
m_renderQueue->processPacket(Packet(state, command, type));
}
renderQueue()->processPacket(Packet(command, type));
else
command->perform();
}
@ -387,5 +241,11 @@ namespace yg
if (m_renderQueue)
m_renderQueue->processPacket(Packet(Packet::ECheckPoint));
}
void Renderer::completeCommands()
{
if (m_renderQueue)
m_renderQueue->completeCommands();
}
}
}

View file

@ -22,16 +22,6 @@ namespace yg
{
public:
struct State : BaseState
{
shared_ptr<FrameBuffer> m_frameBuffer;
shared_ptr<RenderTarget> m_renderTarget;
shared_ptr<RenderBuffer> m_depthBuffer;
shared_ptr<ResourceManager> m_resourceManager;
void apply(BaseState const * prev);
};
struct ClearCommand : Command
{
yg::Color m_color;
@ -47,6 +37,22 @@ namespace yg
void perform();
};
struct ChangeFrameBuffer : Command
{
shared_ptr<FrameBuffer> m_frameBuffer;
ChangeFrameBuffer(shared_ptr<FrameBuffer> const & fb);
void perform();
};
struct UnbindRenderTarget : Command
{
shared_ptr<RenderTarget> m_renderTarget;
UnbindRenderTarget(shared_ptr<RenderTarget> const & renderTarget);
void perform();
};
struct FinishCommand : Command
{
void perform();
@ -59,6 +65,8 @@ namespace yg
shared_ptr<ResourceManager> m_resourceManager;
shared_ptr<FrameBuffer> m_frameBuffer;
bool m_isDebugging;
bool m_doUnbindRT;
bool m_isSynchronized;
PacketsQueue * m_renderQueue;
Params();
};
@ -74,6 +82,9 @@ namespace yg
bool m_isDebugging;
bool m_doUnbindRT;
bool m_isSynchronized;
bool m_isRendering;
unsigned int m_width;
@ -118,15 +129,12 @@ namespace yg
bool isDebugging() const;
virtual shared_ptr<BaseState> const createState() const;
virtual void getState(BaseState * state);
void processCommand(shared_ptr<Command> const & command, Packet::EType type = Packet::ECommand);
PacketsQueue * renderQueue();
/// insert empty packet into glQueue to mark the frame boundary
void markFrameBoundary();
void completeCommands();
};
}
}

View file

@ -188,7 +188,8 @@ namespace yg
m_isHeightFixed(true),
m_isCountFixed(true),
m_scalePriority(0),
m_poolName(poolName)
m_poolName(poolName),
m_isDebugging(false)
{}
ResourceManager::TexturePoolParams::TexturePoolParams(size_t texWidth,
@ -199,7 +200,8 @@ namespace yg
bool isHeightFixed,
bool isCountFixed,
int scalePriority,
string const & poolName)
string const & poolName,
bool isDebugging)
: m_texWidth(texWidth),
m_texHeight(texHeight),
m_texCount(texCount),
@ -208,7 +210,8 @@ namespace yg
m_isHeightFixed(isHeightFixed),
m_isCountFixed(isCountFixed),
m_scalePriority(scalePriority),
m_poolName(poolName)
m_poolName(poolName),
m_isDebugging(isDebugging)
{}
bool ResourceManager::TexturePoolParams::isFixed() const
@ -505,7 +508,10 @@ namespace yg
void ResourceManager::initTexturePool(TexturePoolParams const & p, auto_ptr<TTexturePool> & pool)
{
if (p.isValid())
{
pool.reset(new TTexturePoolImpl(new TTexturePoolTraits(TTextureFactory(p.m_texWidth, p.m_texHeight, p.m_format, p.m_poolName.c_str()), p.m_texCount)));
pool->SetIsDebugging(p.m_isDebugging);
}
else
LOG(LINFO, ("no ", p.m_poolName, " resource"));
}
@ -732,16 +738,26 @@ namespace yg
void ResourceManager::cancel()
{
m_primaryTextures->Cancel();
m_fontTextures->Cancel();
m_styleCacheTextures->Cancel();
m_renderTargets->Cancel();
m_guiThreadTextures->Cancel();
if (m_primaryTextures.get())
m_primaryTextures->Cancel();
if (m_fontTextures.get())
m_fontTextures->Cancel();
if (m_styleCacheTextures.get())
m_styleCacheTextures->Cancel();
if (m_renderTargets.get())
m_renderTargets->Cancel();
if (m_guiThreadTextures.get())
m_guiThreadTextures->Cancel();
m_primaryStorages->Cancel();
m_smallStorages->Cancel();
m_blitStorages->Cancel();
m_multiBlitStorages->Cancel();
m_guiThreadStorages->Cancel();
if (m_primaryStorages.get())
m_primaryStorages->Cancel();
if (m_smallStorages.get())
m_smallStorages->Cancel();
if (m_blitStorages.get())
m_blitStorages->Cancel();
if (m_multiBlitStorages.get())
m_multiBlitStorages->Cancel();
if (m_guiThreadStorages.get())
m_guiThreadStorages->Cancel();
}
}

View file

@ -125,6 +125,8 @@ namespace yg
string m_poolName;
bool m_isDebugging;
TexturePoolParams(size_t texWidth,
size_t texHeight,
size_t texCount,
@ -133,7 +135,8 @@ namespace yg
bool isHeightFixed,
bool isCountFixed,
int scalePriority,
string const & poolName);
string const & poolName,
bool isDebugging = false);
TexturePoolParams(string const & poolName);

View file

@ -261,9 +261,9 @@ namespace yg
for (unsigned i = 0 ; i < boundRects().size(); ++i)
screen->drawRectangle(boundRects()[i], c, yg::maxDepth - 3);
}
else
if (!isNeedRedraw())
return;
if (!isNeedRedraw())
return;
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
{
@ -289,52 +289,54 @@ namespace yg
void StraightTextElement::map(StylesCache * stylesCache) const
{
yg::FontDesc desc = m_fontDesc;
if (desc.m_isMasked)
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
{
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
TextElement::map(m_glyphLayouts[i], stylesCache, desc);
desc.m_isMasked = false;
if (m_glyphLayouts[i].fontDesc().m_isMasked)
TextElement::map(m_glyphLayouts[i], stylesCache, m_glyphLayouts[i].fontDesc());
}
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
TextElement::map(m_glyphLayouts[i], stylesCache, desc);
{
yg::FontDesc fontDesc = m_glyphLayouts[i].fontDesc();
fontDesc.m_isMasked = false;
TextElement::map(m_glyphLayouts[i], stylesCache, fontDesc);
}
}
bool StraightTextElement::find(StylesCache * stylesCache) const
{
yg::FontDesc desc = m_fontDesc;
if (desc.m_isMasked)
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
{
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
if (!TextElement::find(m_glyphLayouts[i], stylesCache, desc))
if (m_glyphLayouts[i].fontDesc().m_isMasked)
if (!TextElement::find(m_glyphLayouts[i], stylesCache, m_glyphLayouts[i].fontDesc()))
return false;
desc.m_isMasked = false;
}
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
if (!TextElement::find(m_glyphLayouts[i], stylesCache, desc))
{
yg::FontDesc fontDesc = m_glyphLayouts[i].fontDesc();
fontDesc.m_isMasked = false;
if (!TextElement::find(m_glyphLayouts[i], stylesCache, fontDesc))
return false;
}
return true;
}
void StraightTextElement::getNonPackedRects(StylesCache * stylesCache, vector<m2::PointU> & v) const
{
yg::FontDesc desc = m_fontDesc;
if (desc.m_isMasked)
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
{
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
TextElement::getNonPackedRects(m_glyphLayouts[i], desc, stylesCache, v);
desc.m_isMasked = false;
if (m_glyphLayouts[i].fontDesc().m_isMasked)
TextElement::getNonPackedRects(m_glyphLayouts[i], m_glyphLayouts[i].fontDesc(), stylesCache, v);
}
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
TextElement::getNonPackedRects(m_glyphLayouts[i], desc, stylesCache, v);
{
yg::FontDesc fontDesc = m_glyphLayouts[i].fontDesc();
fontDesc.m_isMasked = false;
TextElement::getNonPackedRects(m_glyphLayouts[i], fontDesc, stylesCache, v);
}
}
int StraightTextElement::visualRank() const