From cd07b0c61ef20434b9d8219845f9f4087d833335 Mon Sep 17 00:00:00 2001 From: rachytski Date: Fri, 30 Dec 2011 01:29:32 +0400 Subject: [PATCH] [android] switched to TilingRenderPolicyST by default. --- map/framework.cpp | 7 +- map/map.pro | 4 +- map/partial_render_policy.cpp | 33 +++- map/partial_render_policy.hpp | 2 - map/queued_render_policy.hpp | 16 ++ map/render_policy.cpp | 2 +- map/render_queue_routine.cpp | 6 +- map/screen_coverage.cpp | 8 +- map/test_render_policy.cpp | 59 +++--- map/test_render_policy.hpp | 2 + map/tile_renderer.cpp | 4 +- map/tile_renderer.hpp | 3 +- map/tiling_render_policy_mt.cpp | 3 +- map/tiling_render_policy_st.cpp | 334 ++++++++++++++++++++------------ map/tiling_render_policy_st.hpp | 60 ++++-- yg/blitter.cpp | 10 +- yg/render_state_updater.cpp | 7 +- yg/renderer.cpp | 6 + yg/renderer.hpp | 7 +- 19 files changed, 381 insertions(+), 192 deletions(-) create mode 100644 map/queued_render_policy.hpp diff --git a/map/framework.cpp b/map/framework.cpp index cf4f6f1905..1a06ccd2a4 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -313,8 +313,11 @@ void Framework::DrawModel(shared_ptr const & e, } catch (redraw_operation_cancelled const &) { - e->drawer()->screen()->renderState()->m_isEmptyModelCurrent = false; - e->drawer()->screen()->renderState()->m_isEmptyModelActual = false; + if (e->drawer()->screen()->renderState()) + { + e->drawer()->screen()->renderState()->m_isEmptyModelCurrent = false; + e->drawer()->screen()->renderState()->m_isEmptyModelActual = false; + } } if (m_navigator.Update(m_timer.ElapsedSeconds())) diff --git a/map/map.pro b/map/map.pro index b72c9c7e46..0d239fe4de 100644 --- a/map/map.pro +++ b/map/map.pro @@ -43,7 +43,8 @@ HEADERS += \ measurement_utils.hpp \ partial_render_policy.hpp \ proto_to_yg_styles.hpp \ - test_render_policy.hpp + test_render_policy.hpp \ + queued_render_policy.hpp SOURCES += \ feature_vec_model.cpp \ @@ -85,3 +86,4 @@ SOURCES += \ } + diff --git a/map/partial_render_policy.cpp b/map/partial_render_policy.cpp index becf88b368..9c401d7510 100644 --- a/map/partial_render_policy.cpp +++ b/map/partial_render_policy.cpp @@ -194,17 +194,33 @@ void PartialRenderPolicy::ProcessRenderQueue(list & re else { if (renderQueue.empty()) - { - m_hasPacket = false; m_glCondition.Signal(); - } else { - m_hasPacket = true; - while ((maxPackets != 0) && (!renderQueue.empty())) + /// searching for "frame boundary" markers (empty packets) + + list::iterator first = renderQueue.begin(); + list::iterator last = renderQueue.begin(); + + int packetsLeft = maxPackets; + + while ((packetsLeft != 0) && (last != renderQueue.end())) { - m_frameGLQueue.push_back(renderQueue.front()); - renderQueue.pop_front(); + yg::gl::Renderer::Packet p = *last; + if ((p.m_command == 0) && (p.m_state == 0)) + { + LOG(LINFO, ("found frame boundary")); + /// found frame boundary, copying + copy(first, last++, back_inserter(m_frameGLQueue)); + /// erasing from the main queue + renderQueue.erase(first, last); + first = renderQueue.begin(); + last = renderQueue.begin(); + } + else + ++last; + + --packetsLeft; } } } @@ -252,7 +268,10 @@ void PartialRenderPolicy::DrawFrame(shared_ptr const & e, m_frameGLQueue.clear(); if (m_IsDebugging) + { LOG(LINFO, ("processed", cmdProcessed, "commands")); + LOG(LINFO, (m_glQueue.Size(), "commands left")); + } { threads::ConditionGuard guard(m_glCondition); diff --git a/map/partial_render_policy.hpp b/map/partial_render_policy.hpp index 8407bf82e0..ce601e1bc4 100644 --- a/map/partial_render_policy.hpp +++ b/map/partial_render_policy.hpp @@ -17,9 +17,7 @@ private: threads::Condition m_glCondition; - yg::gl::Renderer::Packet m_currentPacket; shared_ptr m_curState; - bool m_hasPacket; shared_ptr m_state; diff --git a/map/queued_render_policy.hpp b/map/queued_render_policy.hpp new file mode 100644 index 0000000000..818e3551be --- /dev/null +++ b/map/queued_render_policy.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "../base/threaded_list.hpp" +#include "../yg/renderer.hpp" +/* +/// base class for policy using separate queue of gl commands. +class QueuedRenderPolicy : public RenderPolicy +{ +private: + + ThreadedList m_glQueue; + +public: + + ThreadedList * GetGLQueue() const; +};*/ diff --git a/map/render_policy.cpp b/map/render_policy.cpp index 9c16eb06b8..6d178f0d3d 100644 --- a/map/render_policy.cpp +++ b/map/render_policy.cpp @@ -157,7 +157,7 @@ RenderPolicy * CreateRenderPolicy(VideoTimer * videoTimer, else { #ifdef OMIM_OS_ANDROID - return new PartialRenderPolicy(videoTimer, useDefaultFB, rmParams, primaryRC); + return new TilingRenderPolicyST(videoTimer, useDefaultFB, rmParams, primaryRC); #endif #ifdef OMIM_OS_IPHONE return new RenderPolicyMT(videoTimer, useDefaultFB, rmParams, primaryRC); diff --git a/map/render_queue_routine.cpp b/map/render_queue_routine.cpp index 8390c8a14b..9465477c59 100644 --- a/map/render_queue_routine.cpp +++ b/map/render_queue_routine.cpp @@ -271,7 +271,8 @@ void RenderQueueRoutine::Do() /* params.m_isDebugging = true; params.m_drawPathes = false; params.m_drawAreas = false; - params.m_drawTexts = false;*/ + params.m_drawTexts = false; + params.m_drawSymbols = false;*/ m_threadDrawer = make_shared_ptr(new DrawerYG(params)); @@ -538,6 +539,9 @@ void RenderQueueRoutine::invalidate() command->m_windowHandles = m_windowHandles; m_glQueue->PushBack(yg::gl::Renderer::Packet(command)); } + + if (m_glQueue) + m_glQueue->PushBack(yg::gl::Renderer::Packet()); } void RenderQueueRoutine::addCommand(render_fn_t const & fn, ScreenBase const & frameScreen) diff --git a/map/screen_coverage.cpp b/map/screen_coverage.cpp index 834a9a4422..24f6514417 100644 --- a/map/screen_coverage.cpp +++ b/map/screen_coverage.cpp @@ -105,7 +105,7 @@ void ScreenCoverage::Merge(Tiler::RectInfo const & ri) else { m_infoLayer.cache(m_stylesCache); - m_stylesCache->upload(); +// m_stylesCache->upload(); } } } @@ -198,7 +198,7 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen) else { m_infoLayer.cache(m_stylesCache); - m_stylesCache->upload(); +// m_stylesCache->upload(); } /// clearing all old commands @@ -251,10 +251,10 @@ void ScreenCoverage::Draw(yg::gl::Screen * s, ScreenBase const & screen) s->blit(&infos[0], infos.size(), true); - if (m_stylesCache) +/* if (m_stylesCache) s->setAdditionalSkinPage(m_stylesCache->cachePage()); - m_infoLayer.draw(s, m_screen.PtoGMatrix() * screen.GtoPMatrix()); + m_infoLayer.draw(s, m_screen.PtoGMatrix() * screen.GtoPMatrix());*/ } void ScreenCoverage::EndFrame(yg::gl::Screen *s) diff --git a/map/test_render_policy.cpp b/map/test_render_policy.cpp index 5bf14c4897..437b54f5ba 100644 --- a/map/test_render_policy.cpp +++ b/map/test_render_policy.cpp @@ -129,17 +129,6 @@ void TestRenderPolicy::DrawFrame(shared_ptr const & e, using namespace yg::gl; -/* OGLCHECK(glBindFramebufferFn(GL_FRAMEBUFFER_MWM, m_auxFrameBuffer->id())); - OGLCHECK(glFramebufferTexture2DFn(GL_FRAMEBUFFER_MWM, GL_COLOR_ATTACHMENT0_MWM, GL_TEXTURE_2D, m_backBuffer->id(), 0)); - utils::setupCoordinates(512, 512, false); - - make_shared_ptr(new Renderer::ClearCommand(m_bgColor))->perform(); - - OGLCHECK(glFramebufferTexture2DFn(GL_FRAMEBUFFER_MWM, GL_COLOR_ATTACHMENT0_MWM, GL_TEXTURE_2D, m_actualTarget->id(), 0)); - utils::setupCoordinates(512, 512, false); - - make_shared_ptr(new Renderer::ClearCommand(m_bgColor))->perform();*/ - OGLCHECK(glBindFramebufferFn(GL_FRAMEBUFFER_MWM, m_frameBuffer->id())); utils::setupCoordinates(512, 512, false); @@ -160,12 +149,7 @@ void TestRenderPolicy::DrawFrame(shared_ptr const & e, /// performing updateActualTarget - swap(m_actualTarget, m_backBuffer); - - OGLCHECK(glBindFramebufferFn(GL_FRAMEBUFFER_MWM, m_auxFrameBuffer->id())); - utils::setupCoordinates(512, 512, false); - - OGLCHECK(glFramebufferTexture2DFn(GL_FRAMEBUFFER_MWM, GL_COLOR_ATTACHMENT0_MWM, GL_TEXTURE_2D, m_backBuffer->id(), 0)); + OGLCHECK(glFramebufferTexture2DFn(GL_FRAMEBUFFER_MWM, GL_COLOR_ATTACHMENT0_MWM, GL_TEXTURE_2D, m_actualTarget->id(), 0)); /* OGLCHECK(glClearColor(m_bgColor.r / 255.0, m_bgColor.g / 255.0, @@ -177,15 +161,15 @@ void TestRenderPolicy::DrawFrame(shared_ptr const & e, shared_ptr immDrawTexturedRect; immDrawTexturedRect.reset( - new Blitter::IMMDrawTexturedRect(m2::RectF(0, 0, m_actualTarget->width(), m_actualTarget->height()), + new Blitter::IMMDrawTexturedRect(m2::RectF(0, 0, m_backBuffer->width(), m_backBuffer->height()), m2::RectF(0, 0, 1, 1), - m_actualTarget, + m_backBuffer, m_resourceManager)); immDrawTexturedRect->perform(); immDrawTexturedRect.reset(); - OGLCHECK(glBindFramebufferFn(GL_FRAMEBUFFER_MWM, m_frameBuffer->id())); +// OGLCHECK(glBindFramebufferFn(GL_FRAMEBUFFER_MWM, m_frameBuffer->id())); OGLCHECK(glFramebufferTexture2DFn(GL_FRAMEBUFFER_MWM, GL_COLOR_ATTACHMENT0_MWM, GL_TEXTURE_2D, m_backBuffer->id(), 0)); /// drawing with Z-order @@ -196,10 +180,8 @@ void TestRenderPolicy::DrawFrame(shared_ptr const & e, /// performing last updateActualTarget - swap(m_actualTarget, m_backBuffer); - - OGLCHECK(glBindFramebufferFn(GL_FRAMEBUFFER_MWM, m_auxFrameBuffer->id())); - OGLCHECK(glFramebufferTexture2DFn(GL_FRAMEBUFFER_MWM, GL_COLOR_ATTACHMENT0_MWM, GL_TEXTURE_2D, m_backBuffer->id(), 0)); +// OGLCHECK(glBindFramebufferFn(GL_FRAMEBUFFER_MWM, m_auxFrameBuffer->id())); + OGLCHECK(glFramebufferTexture2DFn(GL_FRAMEBUFFER_MWM, GL_COLOR_ATTACHMENT0_MWM, GL_TEXTURE_2D, m_actualTarget->id(), 0)); /* OGLCHECK(glClearColor(m_bgColor.r / 255.0, m_bgColor.g / 255.0, @@ -209,17 +191,42 @@ void TestRenderPolicy::DrawFrame(shared_ptr const & e, OGLCHECK(glClear(GL_COLOR_BUFFER_BIT));*/ immDrawTexturedRect.reset( - new Blitter::IMMDrawTexturedRect(m2::RectF(0, 0, m_actualTarget->width(), m_actualTarget->height()), + new Blitter::IMMDrawTexturedRect(m2::RectF(0, 0, m_backBuffer->width(), m_backBuffer->height()), m2::RectF(0, 0, 1, 1), - m_actualTarget, + m_backBuffer, + m_resourceManager)); + + immDrawTexturedRect->perform(); + immDrawTexturedRect.reset(); + + OGLCHECK(glFramebufferTexture2DFn(GL_FRAMEBUFFER_MWM, GL_COLOR_ATTACHMENT0_MWM, GL_TEXTURE_2D, m_backBuffer->id(), 0)); + + e->drawer()->screen()->drawRectangle(m2::RectD(90, 150, 190, 250), yg::Color(255, 0, 255, 255), 20); + e->drawer()->screen()->drawRectangle(m2::RectD(120, 180, 220, 280), yg::Color(128, 128, 255, 255), 10); + e->drawer()->screen()->flush(-1); + + /// performing updateActualTarget + OGLCHECK(glFramebufferTexture2DFn(GL_FRAMEBUFFER_MWM, GL_COLOR_ATTACHMENT0_MWM, GL_TEXTURE_2D, m_actualTarget->id(), 0)); + + immDrawTexturedRect.reset( + new Blitter::IMMDrawTexturedRect(m2::RectF(0, 0, m_backBuffer->width(), m_backBuffer->height()), + m2::RectF(0, 0, 1, 1), + m_backBuffer, m_resourceManager)); immDrawTexturedRect->perform(); immDrawTexturedRect.reset(); m_primaryFrameBuffer->makeCurrent(); + utils::setupCoordinates(m_primaryFrameBuffer->width(), m_primaryFrameBuffer->height(), true); e->drawer()->screen()->clear(m_bgColor); e->drawer()->screen()->blit(m_actualTarget, m_screen, s); } + +m2::RectI const TestRenderPolicy::OnSize(int w, int h) +{ + m_primaryFrameBuffer->onSize(w, h); + return RenderPolicy::OnSize(w, h); +} diff --git a/map/test_render_policy.hpp b/map/test_render_policy.hpp index 34b992fe50..f23d334e83 100644 --- a/map/test_render_policy.hpp +++ b/map/test_render_policy.hpp @@ -26,4 +26,6 @@ public: void DrawFrame(shared_ptr const & pe, ScreenBase const & screenBase); + + m2::RectI const OnSize(int w, int h); }; diff --git a/map/tile_renderer.cpp b/map/tile_renderer.cpp index 7a3fbdcae2..f9aad540c1 100644 --- a/map/tile_renderer.cpp +++ b/map/tile_renderer.cpp @@ -20,7 +20,8 @@ TileRenderer::TileRenderer( RenderPolicy::TRenderFn const & renderFn, shared_ptr const & primaryRC, shared_ptr const & rm, - double visualScale + double visualScale, + yg::gl::Renderer::PacketsQueue * packetsQueue ) : m_queue(executorsCount), m_tileCache(maxTilesCount - executorsCount - 1), m_renderFn(renderFn), @@ -52,6 +53,7 @@ TileRenderer::TileRenderer( params.m_threadID = i; params.m_visualScale = visualScale; params.m_skinName = m_skinName; + params.m_renderQueue = packetsQueue; /* params.m_isDebugging = true; params.m_drawPathes = false; params.m_drawAreas = false; diff --git a/map/tile_renderer.hpp b/map/tile_renderer.hpp index 47c9161249..bff9225859 100644 --- a/map/tile_renderer.hpp +++ b/map/tile_renderer.hpp @@ -73,7 +73,8 @@ public: RenderPolicy::TRenderFn const & renderFn, shared_ptr const & primaryRC, shared_ptr const & rm, - double visualScale); + double visualScale, + yg::gl::Renderer::PacketsQueue * packetsQueue); /// destructor. virtual ~TileRenderer(); /// add command to the commands queue. diff --git a/map/tiling_render_policy_mt.cpp b/map/tiling_render_policy_mt.cpp index c62b5937ef..fd96d7cb3c 100644 --- a/map/tiling_render_policy_mt.cpp +++ b/map/tiling_render_policy_mt.cpp @@ -170,7 +170,8 @@ void TilingRenderPolicyMT::SetRenderFn(TRenderFn renderFn) renderFn, m_primaryRC, m_resourceManager, - GetPlatform().VisualScale())); + GetPlatform().VisualScale(), + 0)); m_coverageGenerator.reset(new CoverageGenerator(GetPlatform().TileSize(), GetPlatform().ScaleEtalonSize(), diff --git a/map/tiling_render_policy_st.cpp b/map/tiling_render_policy_st.cpp index 39e515b4bf..f6af359660 100644 --- a/map/tiling_render_policy_st.cpp +++ b/map/tiling_render_policy_st.cpp @@ -14,33 +14,47 @@ #include "../platform/platform.hpp" +#include "../base/SRC_FIRST.hpp" + +#include "../platform/platform.hpp" +#include "../std/bind.hpp" + +#include "../geometry/screenbase.hpp" + +#include "../yg/base_texture.hpp" +#include "../yg/internal/opengl.hpp" + +#include "drawer_yg.hpp" +#include "events.hpp" +#include "tiling_render_policy_mt.hpp" +#include "window_handle.hpp" +#include "screen_coverage.hpp" + TilingRenderPolicyST::TilingRenderPolicyST(VideoTimer * videoTimer, bool useDefaultFB, yg::ResourceManager::Params const & rmParams, shared_ptr const & primaryRC) - : RenderPolicy(primaryRC, true), - m_tileCache(GetPlatform().MaxTilesCount() - 1), - m_tiler(GetPlatform().TileSize(), GetPlatform().ScaleEtalonSize()) + : RenderPolicy(primaryRC, true) { yg::ResourceManager::Params rmp = rmParams; - rmp.m_primaryStoragesParams = yg::ResourceManager::StoragePoolParams(50000 * sizeof(yg::gl::Vertex), + rmp.m_primaryStoragesParams = yg::ResourceManager::StoragePoolParams(5000 * sizeof(yg::gl::Vertex), sizeof(yg::gl::Vertex), 10000 * sizeof(unsigned short), sizeof(unsigned short), - 15, - false, + 4, true, - 1, + false, + 2, "primaryStorage"); - rmp.m_smallStoragesParams = yg::ResourceManager::StoragePoolParams(5000 * sizeof(yg::gl::Vertex), + rmp.m_smallStoragesParams = yg::ResourceManager::StoragePoolParams(2000 * sizeof(yg::gl::Vertex), sizeof(yg::gl::Vertex), - 10000 * sizeof(unsigned short), + 4000 * sizeof(unsigned short), sizeof(unsigned short), 100, - false, true, + false, 1, "smallStorage"); @@ -54,9 +68,9 @@ TilingRenderPolicyST::TilingRenderPolicyST(VideoTimer * videoTimer, 1, "blitStorage"); - rmp.m_multiBlitStoragesParams = yg::ResourceManager::StoragePoolParams(500 * sizeof(yg::gl::Vertex), + rmp.m_multiBlitStoragesParams = yg::ResourceManager::StoragePoolParams(1500 * sizeof(yg::gl::Vertex), sizeof(yg::gl::Vertex), - 500 * sizeof(unsigned short), + 3000 * sizeof(unsigned short), sizeof(unsigned short), 10, true, @@ -65,14 +79,14 @@ TilingRenderPolicyST::TilingRenderPolicyST(VideoTimer * videoTimer, "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"); + sizeof(yg::gl::Vertex), + 600 * sizeof(unsigned short), + sizeof(unsigned short), + 20, + true, + true, + 1, + "guiThreadStorage"); rmp.m_primaryTexturesParams = yg::ResourceManager::TexturePoolParams(512, 256, @@ -101,9 +115,19 @@ TilingRenderPolicyST::TilingRenderPolicyST(VideoTimer * videoTimer, true, true, false, - 5, + 4, "renderTargetTexture"); + rmp.m_styleCacheTexturesParams = yg::ResourceManager::TexturePoolParams(rmp.m_fontTexturesParams.m_texWidth, + rmp.m_fontTexturesParams.m_texHeight, + 2, + rmp.m_texFormat, + true, + true, + true, + 1, + "styleCacheTexture"); + rmp.m_guiThreadTexturesParams = yg::ResourceManager::TexturePoolParams(256, 128, 4, @@ -121,10 +145,13 @@ TilingRenderPolicyST::TilingRenderPolicyST(VideoTimer * videoTimer, GetPlatform().CpuCores() + 2, GetPlatform().CpuCores()); - - rmp.m_useSingleThreadedOGL = false; + rmp.m_useSingleThreadedOGL = true; rmp.m_useVA = !yg::gl::g_isBufferObjectsSupported; + rmp.fitIntoLimits(); + + m_maxTilesCount = rmp.m_renderTargetTexturesParams.m_texCount; + m_resourceManager.reset(new yg::ResourceManager(rmp)); Platform::FilesList fonts; @@ -140,8 +167,8 @@ TilingRenderPolicyST::TilingRenderPolicyST(VideoTimer * videoTimer, p.m_glyphCacheID = m_resourceManager->guiThreadGlyphCacheID(); p.m_skinName = GetPlatform().SkinName(); p.m_visualScale = GetPlatform().VisualScale(); - p.m_isSynchronized = true; p.m_useGuiResources = true; + p.m_isSynchronized = false; m_drawer.reset(new DrawerYG(p)); @@ -150,132 +177,187 @@ TilingRenderPolicyST::TilingRenderPolicyST(VideoTimer * videoTimer, m_windowHandle->setUpdatesEnabled(false); m_windowHandle->setVideoTimer(videoTimer); m_windowHandle->setRenderContext(primaryRC); +} - /// render single tile on the same thread - shared_ptr frameBuffer(new yg::gl::FrameBuffer()); +void TilingRenderPolicyST::SetRenderFn(TRenderFn renderFn) +{ + RenderPolicy::SetRenderFn(renderFn); - unsigned tileWidth = m_resourceManager->params().m_renderTargetTexturesParams.m_texWidth; - unsigned tileHeight = m_resourceManager->params().m_renderTargetTexturesParams.m_texHeight; + m_tileRenderer.reset(new TileRenderer(GetPlatform().SkinName(), + m_maxTilesCount, + 1, //GetPlatform().CpuCores(), + m_bgColor, + renderFn, + m_primaryRC, + m_resourceManager, + GetPlatform().VisualScale(), + &m_glQueue)); - shared_ptr depthBuffer(new yg::gl::RenderBuffer(tileWidth, tileHeight, true)); - frameBuffer->setDepthBuffer(depthBuffer); + m_coverageGenerator.reset(new CoverageGenerator(GetPlatform().TileSize(), + GetPlatform().ScaleEtalonSize(), + m_tileRenderer.get(), + m_windowHandle, + m_primaryRC, + m_resourceManager + )); +} - p = DrawerYG::Params(); +void TilingRenderPolicyST::BeginFrame(shared_ptr const & e, ScreenBase const & s) +{ + m_IsDebugging = false; + if (m_IsDebugging) + LOG(LINFO, ("-------BeginFrame-------")); +} - p.m_resourceManager = m_resourceManager; - p.m_frameBuffer = frameBuffer; - p.m_glyphCacheID = m_resourceManager->guiThreadGlyphCacheID(); - p.m_threadID = 0; - p.m_skinName = GetPlatform().SkinName(); - p.m_visualScale = GetPlatform().VisualScale(); +void TilingRenderPolicyST::EndFrame(shared_ptr const & e, ScreenBase const & s) +{ + ScreenCoverage * curCvg = &m_coverageGenerator->CurrentCoverage(); + curCvg->EndFrame(e->drawer()->screen().get()); + m_coverageGenerator->Mutex().Unlock(); - m_tileDrawer = make_shared_ptr(new DrawerYG(p)); - m_tileDrawer->onSize(tileWidth, tileHeight); + if (m_IsDebugging) + LOG(LINFO, ("-------EndFrame-------")); +} - m2::RectI renderRect(1, 1, tileWidth - 1, tileWidth - 1); - m_tileScreen.OnSize(renderRect); +bool TilingRenderPolicyST::NeedRedraw() const +{ + return RenderPolicy::NeedRedraw() || !m_glQueue.Empty(); } void TilingRenderPolicyST::DrawFrame(shared_ptr const & e, ScreenBase const & currentScreen) { + m_resourceManager->mergeFreeResources(); + + RenderQueuedCommands(e->drawer()->screen().get()); + DrawerYG * pDrawer = e->drawer(); pDrawer->screen()->clear(m_bgColor); - m_infoLayer.clear(); + m_coverageGenerator->AddCoverScreenTask(currentScreen); - m_tiler.seed(currentScreen, - currentScreen.GlobalRect().GetGlobalRect().Center()); + m_coverageGenerator->Mutex().Lock(); - vector visibleTiles; - m_tiler.visibleTiles(visibleTiles); + ScreenCoverage * curCvg = &m_coverageGenerator->CurrentCoverage(); - for (unsigned i = 0; i < visibleTiles.size(); ++i) - { - Tiler::RectInfo ri = visibleTiles[i]; + curCvg->Draw(pDrawer->screen().get(), currentScreen); +} - m_tileCache.readLock(); +TileRenderer & TilingRenderPolicyST::GetTileRenderer() +{ + return *m_tileRenderer.get(); +} - if (m_tileCache.hasTile(ri)) - { - m_tileCache.touchTile(ri); - Tile tile = m_tileCache.getTile(ri); - m_tileCache.readUnlock(); +void TilingRenderPolicyST::StartScale() +{ + m_isScaling = true; +} - size_t tileWidth = tile.m_renderTarget->width(); - size_t tileHeight = tile.m_renderTarget->height(); - - pDrawer->screen()->blit(tile.m_renderTarget, tile.m_tileScreen, currentScreen, true, - yg::Color(), - m2::RectI(0, 0, tileWidth - 2, tileHeight - 2), - m2::RectU(1, 1, tileWidth - 1, tileHeight - 1)); - - m_infoLayer.merge(*tile.m_infoLayer.get(), tile.m_tileScreen.PtoGMatrix() * currentScreen.GtoPMatrix()); - } - else - { - m_tileCache.readUnlock(); - shared_ptr paintEvent(new PaintEvent(m_tileDrawer.get())); - shared_ptr tileTarget = m_resourceManager->renderTargetTextures()->Reserve(); - - shared_ptr tileInfoLayer(new yg::InfoLayer()); - - m_tileDrawer->screen()->setRenderTarget(tileTarget); - m_tileDrawer->screen()->setInfoLayer(tileInfoLayer); - - m_tileDrawer->beginFrame(); - - yg::Color c = m_bgColor; - - m_tileDrawer->clear(yg::Color(c.r, c.g, c.b, 0)); - - unsigned tileWidth = m_resourceManager->params().m_renderTargetTexturesParams.m_texWidth; - unsigned tileHeight = m_resourceManager->params().m_renderTargetTexturesParams.m_texHeight; - - m2::RectI renderRect(1, 1, tileWidth - 1, tileHeight - 1); - m_tileDrawer->screen()->setClipRect(renderRect); - m_tileDrawer->clear(c); - - m_tileScreen.SetFromRect(m2::AnyRectD(ri.m_rect)); - - m2::RectD selectRect; - m2::RectD clipRect; - - double inflationSize = 24 * GetPlatform().VisualScale(); - - m_tileScreen.PtoG(m2::RectD(renderRect), selectRect); - m_tileScreen.PtoG(m2::Inflate(m2::RectD(renderRect), inflationSize, inflationSize), clipRect); - - m_renderFn(paintEvent, - m_tileScreen, - selectRect, - clipRect, - ri.m_drawScale); - - m_tileDrawer->endFrame(); - m_tileDrawer->screen()->resetInfoLayer(); - - Tile tile(tileTarget, tileInfoLayer, m_tileScreen, ri, 0); - m_tileCache.writeLock(); - m_tileCache.addTile(ri, TileCache::Entry(tile, m_resourceManager)); - m_tileCache.writeUnlock(); - - m_tileCache.readLock(); - m_tileCache.touchTile(ri); - tile = m_tileCache.getTile(ri); - m_tileCache.readUnlock(); - - pDrawer->screen()->blit(tile.m_renderTarget, tile.m_tileScreen, currentScreen, true, - yg::Color(), - m2::RectI(0, 0, tileWidth - 2, tileHeight - 2), - m2::RectU(1, 1, tileWidth - 1, tileHeight - 1)); - - m_windowHandle->invalidate(); - } - } +void TilingRenderPolicyST::StopScale() +{ + m_isScaling = false; } bool TilingRenderPolicyST::IsTiling() const { return true; } + +void TilingRenderPolicyST::RenderQueuedCommands(yg::gl::Screen * screen) +{ + if (!m_state) + { + m_state = screen->createState(); + m_state->m_isDebugging = m_IsDebugging; + } + + screen->getState(m_state.get()); + + m_curState = m_state; + + unsigned cmdProcessed = 0; + unsigned const maxCmdPerFrame = 10000; + + m_glQueue.ProcessList(bind(&TilingRenderPolicyST::ProcessRenderQueue, this, _1, maxCmdPerFrame)); + + cmdProcessed = m_frameGLQueue.size(); + + for (list::iterator it = m_frameGLQueue.begin(); it != m_frameGLQueue.end(); ++it) + { + if (it->m_state) + { + it->m_state->m_isDebugging = m_IsDebugging; + it->m_state->apply(m_curState.get()); +// OGLCHECK(glFinish()); + m_curState = it->m_state; + } + it->m_command->setIsDebugging(m_IsDebugging); + it->m_command->perform(); +// OGLCHECK(glFinish()); + } + + /// should clear to release resources, refered from the stored commands. + m_frameGLQueue.clear(); + + if (m_IsDebugging) + { + LOG(LINFO, ("processed", cmdProcessed, "commands")); + LOG(LINFO, (m_glQueue.Size(), "commands left")); + } + + { + threads::ConditionGuard guard(m_glCondition); + if (m_glQueue.Empty()) + guard.Signal(); + } + +// OGLCHECK(glFinish()); + + m_state->apply(m_curState.get()); + +// OGLCHECK(glFinish()); +} + +void TilingRenderPolicyST::ProcessRenderQueue(list & renderQueue, int maxPackets) +{ + m_frameGLQueue.clear(); + if (maxPackets == -1) + { + m_frameGLQueue = renderQueue; + renderQueue.clear(); + } + else + { + if (renderQueue.empty()) + m_glCondition.Signal(); + else + { + /// searching for "frame boundary" markers (empty packets) + + list::iterator first = renderQueue.begin(); + list::iterator last = renderQueue.begin(); + + int packetsLeft = maxPackets; + + while ((packetsLeft != 0) && (last != renderQueue.end())) + { + yg::gl::Renderer::Packet p = *last; + if ((p.m_command == 0) && (p.m_state == 0)) + { + if (m_IsDebugging) + LOG(LINFO, ("found frame boundary")); + /// found frame boundary, copying + copy(first, last++, back_inserter(m_frameGLQueue)); + /// erasing from the main queue + renderQueue.erase(first, last); + first = renderQueue.begin(); + last = renderQueue.begin(); + } + else + ++last; + + --packetsLeft; + } + } + } +} diff --git a/map/tiling_render_policy_st.hpp b/map/tiling_render_policy_st.hpp index bb954a7100..be10c58523 100644 --- a/map/tiling_render_policy_st.hpp +++ b/map/tiling_render_policy_st.hpp @@ -1,38 +1,60 @@ #pragma once #include "render_policy.hpp" -#include "drawer_yg.hpp" +#include "tile_renderer.hpp" +#include "coverage_generator.hpp" #include "tiler.hpp" -#include "tile_cache.hpp" +#include "screen_coverage.hpp" +#include "render_policy.hpp" #include "../yg/info_layer.hpp" - -#include "../std/shared_ptr.hpp" - -#include "../geometry/screenbase.hpp" - -class WindowHandle; -class VideoTimer; +#include "../std/scoped_ptr.hpp" namespace yg { namespace gl { + class Screen; class RenderContext; } + class ResourceManager; } +class WindowHandle; + class TilingRenderPolicyST : public RenderPolicy { private: - shared_ptr m_tileDrawer; - ScreenBase m_tileScreen; + scoped_ptr m_tileRenderer; - yg::InfoLayer m_infoLayer; + scoped_ptr m_coverageGenerator; - TileCache m_tileCache; - Tiler m_tiler; + ScreenBase m_currentScreen; + + bool m_isScaling; + int m_maxTilesCount; + + /// --- COPY/PASTE HERE --- + + ThreadedList m_glQueue; + list m_frameGLQueue; + + threads::Condition m_glCondition; + + shared_ptr m_curState; + + shared_ptr m_state; + + void ProcessRenderQueue(list & renderQueue, int maxPackets); + + bool m_IsDebugging; + + void RenderQueuedCommands(yg::gl::Screen * screen); + +protected: + + TileRenderer & GetTileRenderer(); public: @@ -41,7 +63,15 @@ public: yg::ResourceManager::Params const & rmParams, shared_ptr const & primaryRC); - void DrawFrame(shared_ptr const & paintEvent, ScreenBase const & screenBase); + void BeginFrame(shared_ptr const & ev, ScreenBase const & s); + void DrawFrame(shared_ptr const & ev, ScreenBase const & s); + void EndFrame(shared_ptr const & ev, ScreenBase const & s); + virtual void StartScale(); + virtual void StopScale(); + + bool NeedRedraw() const; bool IsTiling() const; + + void SetRenderFn(TRenderFn renderFn); }; diff --git a/yg/blitter.cpp b/yg/blitter.cpp index be745c89cd..7a9a501bad 100644 --- a/yg/blitter.cpp +++ b/yg/blitter.cpp @@ -114,7 +114,13 @@ namespace yg yg::gl::Storage storage = resourceManager()->multiBlitStorages()->Reserve(); - Vertex * pointsData = (Vertex*)storage.m_vertices->lock(); + /// TODO : Bad lock/unlock checking pattern. Should refactor + if (!storage.m_vertices->isLocked()) + storage.m_vertices->lock(); + if (!storage.m_indices->isLocked()) + storage.m_indices->lock(); + + Vertex * pointsData = (Vertex*)storage.m_vertices->data(); for (size_t i = 0; i < s * 4; ++i) { @@ -135,7 +141,7 @@ namespace yg OGLCHECK(glDisable(GL_DEPTH_TEST)); OGLCHECK(glDepthMask(GL_FALSE)); - memcpy(storage.m_indices->lock(), &idxData[0], idxData.size() * sizeof(unsigned short)); + memcpy(storage.m_indices->data(), &idxData[0], idxData.size() * sizeof(unsigned short)); storage.m_indices->unlock(); storage.m_indices->makeCurrent(); diff --git a/yg/render_state_updater.cpp b/yg/render_state_updater.cpp index 76425ed001..e26f206bc5 100644 --- a/yg/render_state_updater.cpp +++ b/yg/render_state_updater.cpp @@ -155,6 +155,8 @@ namespace yg command2->m_renderState = m_renderState; processCommand(command2); + + markFrameBoundary(); } void RenderStateUpdater::beginFrame() @@ -178,8 +180,11 @@ namespace yg void RenderStateUpdater::endFrame() { - if (m_renderState) + if ((m_renderState) && (m_indicesCount)) updateActualTarget(); + else + markFrameBoundary(); + m_indicesCount = 0; m_updateTimer.Reset(); base_t::endFrame(); diff --git a/yg/renderer.cpp b/yg/renderer.cpp index 6f75016928..a28ca432e1 100644 --- a/yg/renderer.cpp +++ b/yg/renderer.cpp @@ -401,5 +401,11 @@ namespace yg { return m_renderQueue; } + + void Renderer::markFrameBoundary() + { + if (m_renderQueue) + m_renderQueue->PushBack(Packet()); + } } } diff --git a/yg/renderer.hpp b/yg/renderer.hpp index a6a2c0dfef..45a3324d08 100644 --- a/yg/renderer.hpp +++ b/yg/renderer.hpp @@ -66,6 +66,8 @@ namespace yg shared_ptr const & command); }; + typedef ThreadedList PacketsQueue; + struct ClearCommand : Command { yg::Color m_color; @@ -93,7 +95,7 @@ namespace yg shared_ptr m_resourceManager; shared_ptr m_frameBuffer; bool m_isDebugging; - ThreadedList * m_renderQueue; + PacketsQueue * m_renderQueue; Params(); }; @@ -156,6 +158,9 @@ namespace yg void processCommand(shared_ptr const & command); ThreadedList * renderQueue(); + + /// insert empty packet into glQueue to mark the frame boundary + void markFrameBoundary(); }; } }