From 09035aaa9e3d629d1aced43d8fe7ecb42a84f8ae Mon Sep 17 00:00:00 2001 From: rachytski Date: Tue, 17 Jan 2012 00:31:07 +0400 Subject: [PATCH] removed BaseState, simplified PacketsQueue --- base/resource_pool.hpp | 2 +- iphone/Maps/Classes/RenderBuffer.hpp | 1 + iphone/Maps/Classes/RenderBuffer.mm | 8 + map/framework.cpp | 5 +- map/queued_render_policy.cpp | 68 ++++---- map/queued_render_policy.hpp | 24 ++- map/render_policy_mt.cpp | 4 + map/render_policy_st.cpp | 8 +- map/render_queue_routine.cpp | 24 +-- map/tile_renderer.cpp | 34 ++-- map/tile_renderer.hpp | 1 + map/tiler.cpp | 12 +- map/tiling_render_policy_mt.cpp | 49 ++---- map/tiling_render_policy_st.cpp | 20 ++- platform/platform_qt.cpp | 2 +- yg/base_texture.cpp | 23 ++- yg/base_texture.hpp | 4 +- yg/blitter.cpp | 11 +- yg/clipper.cpp | 95 +++++------ yg/clipper.hpp | 23 +-- yg/framebuffer.cpp | 28 +-- yg/geometry_batcher.cpp | 7 +- yg/geometry_batcher.hpp | 1 - yg/geometry_renderer.cpp | 24 --- yg/geometry_renderer.hpp | 7 - yg/internal/opengl.cpp | 1 + yg/internal/opengl.hpp | 12 +- yg/packets_queue.cpp | 71 +++----- yg/packets_queue.hpp | 60 ++++--- yg/path_text_element.cpp | 3 +- yg/render_state.hpp | 3 - yg/render_state_updater.cpp | 54 +++--- yg/render_state_updater.hpp | 10 +- yg/render_target.hpp | 1 + yg/renderbuffer.cpp | 9 + yg/renderbuffer.hpp | 1 + yg/renderer.cpp | 244 ++++++--------------------- yg/renderer.hpp | 36 ++-- yg/resource_manager.cpp | 42 +++-- yg/resource_manager.hpp | 5 +- yg/straight_text_element.cpp | 52 +++--- 41 files changed, 482 insertions(+), 607 deletions(-) diff --git a/base/resource_pool.hpp b/base/resource_pool.hpp index 42f74cf41a..080f07d6cc 100644 --- a/base/resource_pool.hpp +++ b/base/resource_pool.hpp @@ -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")); } } diff --git a/iphone/Maps/Classes/RenderBuffer.hpp b/iphone/Maps/Classes/RenderBuffer.hpp index 50281fd02e..eac348e20c 100644 --- a/iphone/Maps/Classes/RenderBuffer.hpp +++ b/iphone/Maps/Classes/RenderBuffer.hpp @@ -32,5 +32,6 @@ namespace iphone unsigned height() const; void attachToFrameBuffer(); + void detachFromFrameBuffer(); }; } diff --git a/iphone/Maps/Classes/RenderBuffer.mm b/iphone/Maps/Classes/RenderBuffer.mm index cefe0434dc..036f35eb4c 100644 --- a/iphone/Maps/Classes/RenderBuffer.mm +++ b/iphone/Maps/Classes/RenderBuffer.mm @@ -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)); + } } \ No newline at end of file diff --git a/map/framework.cpp b/map/framework.cpp index e59238b584..7a02b71643 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -359,10 +359,10 @@ void Framework::DoPaint(shared_ptr 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 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()*/); diff --git a/map/queued_render_policy.cpp b/map/queued_render_policy.cpp index 3f5f453826..0351d10488 100644 --- a/map/queued_render_policy.cpp +++ b/map/queued_render_policy.cpp @@ -1,5 +1,6 @@ #include "queued_render_policy.hpp" #include "events.hpp" +#include "../yg/internal/opengl.hpp" QueuedRenderPolicy::QueuedRenderPolicy(int pipelinesCount, shared_ptr 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 const & ev, ScreenBase void QueuedRenderPolicy::DrawFrame(shared_ptr const & ev, ScreenBase const & s) { - shared_ptr 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 const & state) +void QueuedRenderPolicy::RenderQueuedCommands(int pipelineNum) { - shared_ptr 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::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_ptrm_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 & renderQueue, int maxFrames) +void QueuedRenderPolicy::PacketsPipeline::FillFrameCommands(list & renderQueue, int maxFrames) { - m_FrameBucket.clear(); + m_FrameCommands.clear(); /// searching for "delimiter" markers @@ -124,16 +120,16 @@ void QueuedRenderPolicy::PacketsPipeline::FillFrameBucket(list & list::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::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 & } /// 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 & 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 &l, list 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::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(); } } diff --git a/map/queued_render_policy.hpp b/map/queued_render_policy.hpp index 5a39dfb136..c19830d70c 100644 --- a/map/queued_render_policy.hpp +++ b/map/queued_render_policy.hpp @@ -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 m_FrameBucket; //< list of commands to execute on current frame - yg::gl::Packet::EType m_Type; + list 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 & 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 & QueueData, int maxCheckPoints); }; /// couldn't use vector here as PacketsPipeline holds non-copyable yg::gl::PacketsQueue @@ -34,8 +40,8 @@ protected: void CopyQueuedCommands(list & l, list & r); - void RenderQueuedCommands(int pipelineNum, shared_ptr const & state); - void DismissQueuedCommands(int pipelineNum); + void RenderQueuedCommands(int pipelineNum); + void CancelQueuedCommands(int pipelineNum); public: diff --git a/map/render_policy_mt.cpp b/map/render_policy_mt.cpp index 1296fdf039..9456220f29 100644 --- a/map/render_policy_mt.cpp +++ b/map/render_policy_mt.cpp @@ -192,6 +192,8 @@ void RenderPolicyMT::DrawFrame(shared_ptr 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 const & e, pDrawer->screen()->blit(m_renderQueue->renderState().m_actualTarget, m); } + + e->drawer()->endFrame(); } void RenderPolicyMT::StartDrag() diff --git a/map/render_policy_st.cpp b/map/render_policy_st.cpp index d9f10941f9..b5de631ec3 100644 --- a/map/render_policy_st.cpp +++ b/map/render_policy_st.cpp @@ -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 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 const & e, pDrawer->screen()->blit(m_renderQueue->renderState().m_actualTarget, m); } + + pDrawer->endFrame(); } void RenderPolicyST::EndFrame(shared_ptr const & ev, diff --git a/map/render_queue_routine.cpp b/map/render_queue_routine.cpp index 0f4bcf6996..dba00ff874 100644 --- a/map/render_queue_routine.cpp +++ b/map/render_queue_routine.cpp @@ -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()); 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; - } } } diff --git a/map/tile_renderer.cpp b/map/tile_renderer.cpp index f932a7f04f..7f1cf7d8e9 100644 --- a/map/tile_renderer.cpp +++ b/map/tile_renderer.cpp @@ -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 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(); } } diff --git a/map/tile_renderer.hpp b/map/tile_renderer.hpp index ca8db03535..abae9d4e46 100644 --- a/map/tile_renderer.hpp +++ b/map/tile_renderer.hpp @@ -40,6 +40,7 @@ protected: { DrawerYG * m_drawer; DrawerYG::params_t m_drawerParams; + shared_ptr m_dummyRT; shared_ptr m_renderContext; }; diff --git a/map/tiler.cpp b/map/tiler.cpp index d59a3a18dd..db4cca7a62 100644 --- a/map/tiler.cpp +++ b/map/tiler.cpp @@ -55,13 +55,19 @@ int Tiler::drawScale(ScreenBase const & s) const ScreenBase tmpS = s; tmpS.Rotate(-tmpS.GetAngle()); + size_t tileSize = min(static_cast(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(ceil(log((MercatorBounds::maxX - MercatorBounds::minX) / glbRectSize) / log(2.0))); + + return res > scales::GetUpperScale() ? scales::GetUpperScale() : res; } int Tiler::tileScale(ScreenBase const & s) const diff --git a/map/tiling_render_policy_mt.cpp b/map/tiling_render_policy_mt.cpp index dcb0d5be44..453ed1f912 100644 --- a/map/tiling_render_policy_mt.cpp +++ b/map/tiling_render_policy_mt.cpp @@ -18,7 +18,7 @@ TilingRenderPolicyMT::TilingRenderPolicyMT(VideoTimer * videoTimer, bool useDefaultFB, yg::ResourceManager::Params const & rmParams, shared_ptr 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 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 const & e, ScreenBas curCvg->Draw(pDrawer->screen().get(), currentScreen); m_drawScale = curCvg->GetDrawScale(); + + pDrawer->endFrame(); } int TilingRenderPolicyMT::GetDrawScale(ScreenBase const & s) const diff --git a/map/tiling_render_policy_st.cpp b/map/tiling_render_policy_st.cpp index fe26164e0d..687ba3e66f 100644 --- a/map/tiling_render_policy_st.cpp +++ b/map/tiling_render_policy_st.cpp @@ -34,7 +34,7 @@ TilingRenderPolicyST::TilingRenderPolicyST(VideoTimer * videoTimer, bool useDefaultFB, yg::ResourceManager::Params const & rmParams, shared_ptr 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 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 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 diff --git a/platform/platform_qt.cpp b/platform/platform_qt.cpp index 9bf74171a5..1c05fde09e 100644 --- a/platform/platform_qt.cpp +++ b/platform/platform_qt.cpp @@ -71,7 +71,7 @@ void Platform::GetFontNames(FilesList & res) const int Platform::MaxTilesCount() const { - return 30; + return 60; } int Platform::TileSize() const diff --git a/yg/base_texture.cpp b/yg/base_texture.cpp index f930245c5d..f68857058f 100644 --- a/yg/base_texture.cpp +++ b/yg/base_texture.cpp @@ -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)); } diff --git a/yg/base_texture.hpp b/yg/base_texture.hpp index 1dbefdc4c8..44e57e335e 100644 --- a/yg/base_texture.hpp +++ b/yg/base_texture.hpp @@ -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; diff --git a/yg/blitter.cpp b/yg/blitter.cpp index 7a9a501bad..1ff118b56a 100644 --- a/yg/blitter.cpp +++ b/yg/blitter.cpp @@ -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. diff --git a/yg/clipper.cpp b/yg/clipper.cpp index 40a2de500d..42f30a48c9 100644 --- a/yg/clipper.cpp +++ b/yg/clipper.cpp @@ -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(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 const Clipper::createState() const - { - return shared_ptr(new State()); - } - - void Clipper::getState(BaseState * s) - { - State * state = static_cast(s); - base_t::getState(s); - - state->m_clipRect = m_clipRect; - state->m_isClippingEnabled = m_isClippingEnabled; - } } } diff --git a/yg/clipper.hpp b/yg/clipper.hpp index da5a8c593c..c53b36275e 100644 --- a/yg/clipper.hpp +++ b/yg/clipper.hpp @@ -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 const createState() const; - void getState(BaseState * state); + public: + + Clipper(base_t::Params const & params); void beginFrame(); void endFrame(); diff --git a/yg/framebuffer.cpp b/yg/framebuffer.cpp index 5b3c2b5123..66db4a05fa 100644 --- a/yg/framebuffer.cpp +++ b/yg/framebuffer.cpp @@ -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 diff --git a/yg/geometry_batcher.cpp b/yg/geometry_batcher.cpp index 4c1f52cd06..697308c58e 100644 --- a/yg/geometry_batcher.cpp +++ b/yg/geometry_batcher.cpp @@ -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(new FinishCommand())); - if (isDebugging()) { for (size_t i = 0; i < m_pipelines.size(); ++i) diff --git a/yg/geometry_batcher.hpp b/yg/geometry_batcher.hpp index e16baa90ec..72ebbd1874 100644 --- a/yg/geometry_batcher.hpp +++ b/yg/geometry_batcher.hpp @@ -128,7 +128,6 @@ namespace yg struct Params : public base_t::Params { - bool m_isSynchronized; bool m_useGuiResources; Params(); }; diff --git a/yg/geometry_renderer.cpp b/yg/geometry_renderer.cpp index 89490ea771..de4e1da09f 100644 --- a/yg/geometry_renderer.cpp +++ b/yg/geometry_renderer.cpp @@ -59,30 +59,6 @@ namespace yg processCommand(command); } - void GeometryRenderer::UploadData::perform() - { - if (isDebugging()) - LOG(LINFO, ("performing UploadData command")); - - static_cast(m_texture.get())->lock(); - - TDynamicTexture * dynTexture = static_cast(m_texture.get()); - - for (size_t i = 0; i < m_styles.size(); ++i) - { - shared_ptr 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(m_texture.get())->unlock(); - } - void GeometryRenderer::applyStates(bool isAntiAliased) { if (renderQueue()) diff --git a/yg/geometry_renderer.hpp b/yg/geometry_renderer.hpp index 5bf6460c9d..30a84b9eb2 100644 --- a/yg/geometry_renderer.hpp +++ b/yg/geometry_renderer.hpp @@ -23,13 +23,6 @@ namespace yg typedef Blitter base_t; - struct UploadData : Command - { - vector > m_styles; - shared_ptr m_texture; - void perform(); - }; - struct DrawGeometry : Command { shared_ptr m_texture; diff --git a/yg/internal/opengl.cpp b/yg/internal/opengl.cpp index f3400188cb..4aea5b113c 100644 --- a/yg/internal/opengl.cpp +++ b/yg/internal/opengl.cpp @@ -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() { diff --git a/yg/internal/opengl.hpp b/yg/internal/opengl.hpp index 4ba42313c0..21c4cbffbe 100644 --- a/yg/internal/opengl.hpp +++ b/yg/internal/opengl.hpp @@ -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) diff --git a/yg/packets_queue.cpp b/yg/packets_queue.cpp index 52232d7cb7..c53f96ebad 100644 --- a/yg/packets_queue.cpp +++ b/yg/packets_queue.cpp @@ -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 const & command, EType type) + Packet::Packet(shared_ptr const & command, + EType type) : m_command(command), m_type(type) {} - Packet::Packet(shared_ptr const & state, - shared_ptr 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(); } } } diff --git a/yg/packets_queue.hpp b/yg/packets_queue.hpp index afa9e9ad86..cc97e77ba7 100644 --- a/yg/packets_queue.hpp +++ b/yg/packets_queue.hpp @@ -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 + 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 m_state; shared_ptr 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 const & command, EType type); - /// opengl command with state - Packet(shared_ptr const & state, - shared_ptr const & command, - EType type); - }; - class PacketsQueue : public ThreadedList + class PacketsQueue { private: + ThreadedList 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 + void processFn(Fn fn, bool performOnCancel = false) + { + processPacket(Packet(make_shared_ptr(new FunctorCommand(fn)), Packet::ECommand)); + } + + template + void processList(Fn fn) + { + m_packets.ProcessList(fn); + } }; } } diff --git a/yg/path_text_element.cpp b/yg/path_text_element.cpp index d0b612a33e..2aac53f6ff 100644 --- a/yg/path_text_element.cpp +++ b/yg/path_text_element.cpp @@ -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 diff --git a/yg/render_state.hpp b/yg/render_state.hpp index 6220378254..5576be9b4c 100644 --- a/yg/render_state.hpp +++ b/yg/render_state.hpp @@ -51,9 +51,6 @@ namespace yg bool m_isEmptyModelCurrent; /// @} - shared_ptr m_shadowActualTarget; - shared_ptr m_shadowBackBuffer; - /// Surface height and width. unsigned int m_surfaceWidth; unsigned int m_surfaceHeight; diff --git a/yg/render_state_updater.cpp b/yg/render_state_updater.cpp index e26f206bc5..36e08eeb12 100644 --- a/yg/render_state_updater.cpp +++ b/yg/render_state_updater.cpp @@ -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(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 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 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(); diff --git a/yg/render_state_updater.hpp b/yg/render_state_updater.hpp index 82f40094a8..8c59ebe091 100644 --- a/yg/render_state_updater.hpp +++ b/yg/render_state_updater.hpp @@ -26,15 +26,6 @@ namespace yg double m_updateInterval; my::Timer m_updateTimer; - struct UpdateActualTarget : Command - { - bool m_doSynchronize; - shared_ptr m_renderState; - ScreenBase m_currentScreen; - - void perform(); - }; - struct UpdateBackBuffer : Command { shared_ptr m_renderState; @@ -42,6 +33,7 @@ namespace yg shared_ptr m_auxFrameBuffer; shared_ptr m_frameBuffer; bool m_isClipRectEnabled; + m2::RectI m_clipRect; bool m_doSynchronize; void perform(); diff --git a/yg/render_target.hpp b/yg/render_target.hpp index c45b5c658a..09d7ff6aa0 100644 --- a/yg/render_target.hpp +++ b/yg/render_target.hpp @@ -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; }; diff --git a/yg/renderbuffer.cpp b/yg/renderbuffer.cpp index 1f9aec4eeb..63f73d68d1 100644 --- a/yg/renderbuffer.cpp +++ b/yg/renderbuffer.cpp @@ -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()) diff --git a/yg/renderbuffer.hpp b/yg/renderbuffer.hpp index 7604bd06e6..2099b92740 100644 --- a/yg/renderbuffer.hpp +++ b/yg/renderbuffer.hpp @@ -26,6 +26,7 @@ namespace yg void makeCurrent() const; void attachToFrameBuffer(); + void detachFromFrameBuffer(); bool isDepthBuffer() const; diff --git a/yg/renderer.cpp b/yg/renderer.cpp index 7d8884d3f9..520e3a95ef 100644 --- a/yg/renderer.cpp +++ b/yg/renderer.cpp @@ -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(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 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 const & Renderer::frameBuffer() const @@ -229,20 +97,14 @@ namespace yg void Renderer::setRenderTarget(shared_ptr 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 const & Renderer::depthBuffer() const @@ -252,18 +114,14 @@ namespace yg void Renderer::setDepthBuffer(shared_ptr 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 const Renderer::createState() const - { - return shared_ptr(new State()); - } - - void Renderer::getState(BaseState * baseState) - { - State * state = static_cast(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 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 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(); + } } } diff --git a/yg/renderer.hpp b/yg/renderer.hpp index ec544386e4..907e93c800 100644 --- a/yg/renderer.hpp +++ b/yg/renderer.hpp @@ -22,16 +22,6 @@ namespace yg { public: - struct State : BaseState - { - shared_ptr m_frameBuffer; - shared_ptr m_renderTarget; - shared_ptr m_depthBuffer; - shared_ptr 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 m_frameBuffer; + + ChangeFrameBuffer(shared_ptr const & fb); + + void perform(); + }; + + struct UnbindRenderTarget : Command + { + shared_ptr m_renderTarget; + UnbindRenderTarget(shared_ptr const & renderTarget); + void perform(); + }; + struct FinishCommand : Command { void perform(); @@ -59,6 +65,8 @@ namespace yg shared_ptr m_resourceManager; shared_ptr 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 const createState() const; - - virtual void getState(BaseState * state); - void processCommand(shared_ptr const & command, Packet::EType type = Packet::ECommand); PacketsQueue * renderQueue(); /// insert empty packet into glQueue to mark the frame boundary void markFrameBoundary(); + void completeCommands(); }; } } diff --git a/yg/resource_manager.cpp b/yg/resource_manager.cpp index d0b226aadb..f0b066f90e 100644 --- a/yg/resource_manager.cpp +++ b/yg/resource_manager.cpp @@ -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 & 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(); } } diff --git a/yg/resource_manager.hpp b/yg/resource_manager.hpp index 017cd075d6..18f773c614 100644 --- a/yg/resource_manager.hpp +++ b/yg/resource_manager.hpp @@ -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); diff --git a/yg/straight_text_element.cpp b/yg/straight_text_element.cpp index bfe69c2409..ab5327cc73 100644 --- a/yg/straight_text_element.cpp +++ b/yg/straight_text_element.cpp @@ -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 & 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