From 16bd14a47da1242482b387c17618b16a145b6cc9 Mon Sep 17 00:00:00 2001 From: rachytski Date: Sat, 10 Sep 2011 18:13:15 +0300 Subject: [PATCH] implemented BenchmarkRenderPolicyMT --- iphone/Maps/Classes/EAGLView.h | 2 -- iphone/Maps/Classes/EAGLView.mm | 27 ++++++++++++----------- iphone/Maps/Classes/RenderBuffer.mm | 2 +- map/benchmark_framework.cpp | 17 ++------------- map/benchmark_render_policy_mt.cpp | 26 +++++++++++++++++++++++ map/benchmark_render_policy_mt.hpp | 15 +++++++++++++ map/map.pro | 8 +++++-- map/render_policy_mt.cpp | 27 ++++++++++++++--------- map/render_policy_mt.hpp | 3 +++ map/render_queue.cpp | 9 ++++---- map/render_queue.hpp | 3 ++- map/render_queue_routine.cpp | 33 ++++++++++++++++------------- map/render_queue_routine.hpp | 5 +++-- map/tile_renderer.cpp | 2 +- yg/renderer.cpp | 5 +++++ yg/renderer.hpp | 2 ++ 16 files changed, 120 insertions(+), 66 deletions(-) create mode 100644 map/benchmark_render_policy_mt.cpp create mode 100644 map/benchmark_render_policy_mt.hpp diff --git a/iphone/Maps/Classes/EAGLView.h b/iphone/Maps/Classes/EAGLView.h index e74a3c9c7a..af17102255 100644 --- a/iphone/Maps/Classes/EAGLView.h +++ b/iphone/Maps/Classes/EAGLView.h @@ -42,7 +42,6 @@ namespace yg shared_ptr textureManager; MapViewController * controller; - bool doRepaint; } // Called as a result of invalidate on iphone::WindowHandle @@ -53,6 +52,5 @@ namespace yg @property (nonatomic, assign) shared_ptr windowHandle; @property (nonatomic, assign) shared_ptr renderContext; @property (nonatomic, assign) shared_ptr resourceManager; -@property (nonatomic, assign) bool doRepaint; @end diff --git a/iphone/Maps/Classes/EAGLView.mm b/iphone/Maps/Classes/EAGLView.mm index 1a04284cb6..f29fc0d9e7 100644 --- a/iphone/Maps/Classes/EAGLView.mm +++ b/iphone/Maps/Classes/EAGLView.mm @@ -13,13 +13,15 @@ #include "RenderBuffer.hpp" #include "RenderContext.hpp" +bool _doRepaint = true; +bool _inRepaint = false; + @implementation EAGLView @synthesize controller; @synthesize windowHandle; @synthesize renderContext; @synthesize resourceManager; -@synthesize doRepaint; @synthesize displayLink; // You must implement this method @@ -28,8 +30,6 @@ return [CAEAGLLayer class]; } -static bool _doRepaint = true; - // The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder: - (id)initWithCoder:(NSCoder*)coder { @@ -141,17 +141,13 @@ static bool _doRepaint = true; drawer = shared_ptr(new DrawerYG(p)); -// frameBuffer->onSize(renderBuffer->width(), renderBuffer->height()); -// frameBuffer->setRenderTarget(renderBuffer); - -// self.doRepaint = true; - windowHandle = shared_ptr(new iphone::WindowHandle(_doRepaint)); windowHandle->setDrawer(drawer); windowHandle->setRenderContext(renderContext); displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawView)]; + displayLink.frameInterval = 1; [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; } @@ -178,11 +174,17 @@ static bool _doRepaint = true; - (void)drawView { - if (_doRepaint) + if (!_inRepaint) { - [controller onPaint]; - renderBuffer->present(); - _doRepaint = false; + _inRepaint = true; + + if (_doRepaint) + { + _doRepaint = false; + [controller onPaint]; + renderBuffer->present(); + } + _inRepaint = false; } } @@ -206,6 +208,7 @@ static bool _doRepaint = true; - (void)dealloc { + [displayLink invalidate]; [displayLink release]; [EAGLContext setCurrentContext:nil]; [super dealloc]; diff --git a/iphone/Maps/Classes/RenderBuffer.mm b/iphone/Maps/Classes/RenderBuffer.mm index 46b1bff699..ba7e69d0f8 100644 --- a/iphone/Maps/Classes/RenderBuffer.mm +++ b/iphone/Maps/Classes/RenderBuffer.mm @@ -48,7 +48,7 @@ namespace iphone NSLog(@"failed to present renderbuffer"); else if (tryCount != 0) - NSLog(@"renderBuffer was presented from %d try", tryCount); + NSLog(@"renderBuffer was presented from %d try", tryCount); } unsigned RenderBuffer::width() const diff --git a/map/benchmark_framework.cpp b/map/benchmark_framework.cpp index a8d627b5ee..67ecc3f582 100644 --- a/map/benchmark_framework.cpp +++ b/map/benchmark_framework.cpp @@ -13,6 +13,7 @@ #include "../version/version.hpp" #include "benchmark_tiling_render_policy_mt.hpp" +#include "benchmark_render_policy_mt.hpp" #include "render_policy_st.hpp" template class DoGetBenchmarks @@ -146,7 +147,7 @@ BenchmarkFramework::BenchmarkFramework(shared_ptr const & if (isBenchmarkingMT) base_type::SetRenderPolicy(make_shared_ptr(new BenchmarkTilingRenderPolicyMT(wh, bind(&base_type::DrawModel, this, _1, _2, _3, _4, _5, true)))); else - base_type::SetRenderPolicy(make_shared_ptr(new RenderPolicyST(wh, bind(&base_type::DrawModel, this, _1, _2, _3, _4, _5, true)))); + base_type::SetRenderPolicy(make_shared_ptr(new BenchmarkRenderPolicyMT(wh, bind(&base_type::DrawModel, this, _1, _2, _3, _4, _5, false)))); m_startTime = my::FormatCurrentTime(); @@ -294,20 +295,6 @@ void BenchmarkFramework::OnSize(int w, int h) template void BenchmarkFramework::Paint(shared_ptr e) { -/* m2::PointD const center = base_type::m_renderQueue.renderState().m_actualScreen.ClipRect().Center(); - base_type::m_informationDisplay.setScreen(m_renderQueue.renderState().m_actualScreen); - base_type::m_informationDisplay.setCenter(m2::PointD(MercatorBounds::XToLon(center.x), MercatorBounds::YToLat(center.y))); - - if (!m_isBenchmarkInitialized) - { - e->drawer()->screen()->beginFrame(); - e->drawer()->screen()->clear(base_type::m_renderPolicy->bgColor()); - base_type::m_informationDisplay.setDisplayRect(m2::RectI(0, 0, 100, 100)); - base_type::m_informationDisplay.enableRuler(false); - base_type::m_informationDisplay.doDraw(e->drawer().get()); - e->drawer()->screen()->endFrame(); - } - else*/ double s = m_benchmarksTimer.ElapsedSeconds(); Framework::Paint(e); m_paintDuration += m_benchmarksTimer.ElapsedSeconds() - s; diff --git a/map/benchmark_render_policy_mt.cpp b/map/benchmark_render_policy_mt.cpp new file mode 100644 index 0000000000..1a849937ce --- /dev/null +++ b/map/benchmark_render_policy_mt.cpp @@ -0,0 +1,26 @@ +#include "../base/SRC_FIRST.hpp" + +#include "benchmark_render_policy_mt.hpp" + +#include "../base/logging.hpp" + +BenchmarkRenderPolicyMT::BenchmarkRenderPolicyMT(shared_ptr const & wh, + RenderPolicy::TRenderFn const & renderFn) + : RenderPolicyMT(wh, renderFn) +{} + +void BenchmarkRenderPolicyMT::Initialize(shared_ptr const & rc, + shared_ptr const & rm) +{ + RenderPolicyMT::Initialize(rc, rm); +} + +void BenchmarkRenderPolicyMT::DrawFrame(shared_ptr const & e, + ScreenBase const & s) +{ + RenderPolicyMT::DrawFrame(e, s); + GetRenderQueue().WaitForEmptyAndFinished(); + RenderPolicyMT::DrawFrame(e, s); +} + + diff --git a/map/benchmark_render_policy_mt.hpp b/map/benchmark_render_policy_mt.hpp new file mode 100644 index 0000000000..9e2a7266ce --- /dev/null +++ b/map/benchmark_render_policy_mt.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "render_policy_mt.hpp" + +class BenchmarkRenderPolicyMT : public RenderPolicyMT +{ +public: + BenchmarkRenderPolicyMT(shared_ptr const & wh, + RenderPolicy::TRenderFn const & renderFn); + + void Initialize(shared_ptr const & rc, + shared_ptr const & rm); + + void DrawFrame(shared_ptr const & e, ScreenBase const & s); +}; diff --git a/map/map.pro b/map/map.pro index e6a27563db..1f9ce3921e 100644 --- a/map/map.pro +++ b/map/map.pro @@ -37,7 +37,8 @@ HEADERS += \ screen_coverage.hpp \ render_policy_mt.hpp \ render_queue.hpp \ - render_queue_routine.hpp + render_queue_routine.hpp \ + benchmark_render_policy_mt.hpp SOURCES += \ feature_vec_model.cpp \ @@ -64,10 +65,13 @@ SOURCES += \ screen_coverage.cpp \ render_policy_mt.cpp \ render_queue_routine.cpp \ - render_queue.cpp + render_queue.cpp \ + benchmark_render_policy_mt.cpp !iphone*:!bada*:!android* { HEADERS += qgl_render_context.hpp SOURCES += qgl_render_context.cpp QT += opengl } + + diff --git a/map/render_policy_mt.cpp b/map/render_policy_mt.cpp index 8d18caaa4e..e52f0e1cfb 100644 --- a/map/render_policy_mt.cpp +++ b/map/render_policy_mt.cpp @@ -51,23 +51,25 @@ void RenderPolicyMT::DrawFrame(shared_ptr const & e, DrawerYG * pDrawer = e->drawer(); - threads::MutexGuard g(*m_renderQueue.renderState().m_mutex.get()); - - e->drawer()->screen()->clear(bgColor()); - - if (m_renderQueue.renderState().m_actualTarget.get() != 0) { - m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(false); + threads::MutexGuard g(*m_renderQueue.renderState().m_mutex.get()); + + e->drawer()->screen()->clear(bgColor()); + + if (m_renderQueue.renderState().m_actualTarget.get() != 0) + { + m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(false); // OGLCHECK(glMatrixMode(GL_MODELVIEW)); // OGLCHECK(glPushMatrix()); // OGLCHECK(glTranslatef(-ptShift.x, -ptShift.y, 0)); - math::Matrix m = m_renderQueue.renderState().m_actualScreen.PtoGMatrix() * s.GtoPMatrix(); - m = math::Shift(m, -ptShift); + math::Matrix m = m_renderQueue.renderState().m_actualScreen.PtoGMatrix() * s.GtoPMatrix(); + m = math::Shift(m, -ptShift); - pDrawer->screen()->blit(m_renderQueue.renderState().m_actualTarget, - m); + pDrawer->screen()->blit(m_renderQueue.renderState().m_actualTarget, + m); + } } } @@ -94,3 +96,8 @@ void RenderPolicyMT::StopScale(m2::PointD const & pt1, m2::PointD const & pt2, d m_DoAddCommand = true; RenderPolicy::StartScale(pt1, pt2, timeInSec); } + +RenderQueue & RenderPolicyMT::GetRenderQueue() +{ + return m_renderQueue; +} diff --git a/map/render_policy_mt.hpp b/map/render_policy_mt.hpp index eb993c88d9..ba3f23ef27 100644 --- a/map/render_policy_mt.hpp +++ b/map/render_policy_mt.hpp @@ -30,4 +30,7 @@ public: void StartScale(m2::PointD const & pt1, m2::PointD const & pt2, double timeInSec); void StopScale(m2::PointD const & pt1, m2::PointD const & pt2, double timeInSec); + + RenderQueue & GetRenderQueue(); + }; diff --git a/map/render_queue.cpp b/map/render_queue.cpp index 267def05f0..8ade11fe25 100644 --- a/map/render_queue.cpp +++ b/map/render_queue.cpp @@ -54,11 +54,6 @@ void RenderQueue::AddCommand(RenderQueueRoutine::render_fn_t const & fn, ScreenB m_routine->addCommand(fn, frameScreen); } -void RenderQueue::AddBenchmarkCommand(RenderQueueRoutine::render_fn_t const & fn, ScreenBase const & frameScreen) -{ - m_routine->addBenchmarkCommand(fn, frameScreen); -} - void RenderQueue::SetRedrawAll() { m_renderState->m_doRepaintAll = true; @@ -106,4 +101,8 @@ void RenderQueue::enterForeground() m_routine->enterForeground(); } +void RenderQueue::WaitForEmptyAndFinished() +{ + m_routine->waitForEmptyAndFinished(); +} diff --git a/map/render_queue.hpp b/map/render_queue.hpp index ec7b205dbd..8da8da6431 100644 --- a/map/render_queue.hpp +++ b/map/render_queue.hpp @@ -46,7 +46,6 @@ public: shared_ptr const & resourceManager); /// add command to the commands queue. void AddCommand(RenderQueueRoutine::render_fn_t const & fn, ScreenBase const & frameScreen); - void AddBenchmarkCommand(RenderQueueRoutine::render_fn_t const & fn, ScreenBase const & frameScreen); void SetRedrawAll(); @@ -70,4 +69,6 @@ public: void enterBackground(); /// load all necessary memory caches and opengl resources. void enterForeground(); + + void WaitForEmptyAndFinished(); }; diff --git a/map/render_queue_routine.cpp b/map/render_queue_routine.cpp index 94a2f9e9af..e5c45af135 100644 --- a/map/render_queue_routine.cpp +++ b/map/render_queue_routine.cpp @@ -431,14 +431,18 @@ void RenderQueueRoutine::Do() /// in the endFrame function /// updateActualTarget(); - threads::ConditionGuard g1(m_hasRenderCommands); { - m_currentRenderCommand.reset(); + threads::ConditionGuard g1(m_hasRenderCommands); { threads::MutexGuard g2(*m_renderState->m_mutex.get()); m_renderState->m_duration = duration; } + + m_currentRenderCommand.reset(); + + if (m_renderCommands.empty()) + g1.Signal(); } invalidate(); @@ -486,19 +490,6 @@ void RenderQueueRoutine::addCommand(render_fn_t const & fn, ScreenBase const & f guard.Signal(); } -void RenderQueueRoutine::addBenchmarkCommand(render_fn_t const & fn, ScreenBase const & frameScreen) -{ - /// Command queue modification is syncronized by mutex - threads::ConditionGuard guard(m_hasRenderCommands); - - bool needToSignal = m_renderCommands.empty(); - - m_benchmarkRenderCommands.push_back(make_shared_ptr(new RenderModelCommand(frameScreen, fn))); - - if (needToSignal) - guard.Signal(); -} - void RenderQueueRoutine::initializeGL(shared_ptr const & renderContext, shared_ptr const & resourceManager) { @@ -521,3 +512,15 @@ void RenderQueueRoutine::enterForeground() m_threadDrawer->screen()->enterForeground(); } +void RenderQueueRoutine::waitForEmptyAndFinished() +{ + /// Command queue modification is syncronized by mutex + threads::ConditionGuard guard(m_hasRenderCommands); + + if (!m_renderCommands.empty() || (m_currentRenderCommand != 0)) + { +// LOG(LINFO, ("Waiting For Guard")); + guard.Wait(); +// LOG(LINFO, ("Completed")); + } +} diff --git a/map/render_queue_routine.hpp b/map/render_queue_routine.hpp index 39b1c8c246..59b334078e 100644 --- a/map/render_queue_routine.hpp +++ b/map/render_queue_routine.hpp @@ -58,6 +58,7 @@ private: shared_ptr m_auxScreen; threads::Condition m_hasRenderCommands; + shared_ptr m_currentRenderCommand; list > m_renderCommands; list > m_benchmarkRenderCommands; @@ -111,8 +112,6 @@ public: void addWindowHandle(shared_ptr window); /// add model rendering command to rendering queue void addCommand(render_fn_t const & fn, ScreenBase const & frameScreen); - /// add benchmark rendering command - void addBenchmarkCommand(render_fn_t const & fn, ScreenBase const & frameScreen); /// set the resolution scale factor to the main thread drawer; void setVisualScale(double visualScale); /// free all available memory @@ -121,4 +120,6 @@ public: void enterBackground(); /// recreate all necessary opengl resources and prepare to run in foreground. void enterForeground(); + /// wait for all commands are processed. + void waitForEmptyAndFinished(); }; diff --git a/map/tile_renderer.cpp b/map/tile_renderer.cpp index ece10042ac..3d07d9fdf4 100644 --- a/map/tile_renderer.cpp +++ b/map/tile_renderer.cpp @@ -64,6 +64,7 @@ void TileRenderer::Initialize(shared_ptr const & primaryC m_threadData[i].m_drawerParams = params; m_threadData[i].m_drawer = 0; m_threadData[i].m_fakeTarget = m_resourceManager->createRenderTarget(2, 2); + m_threadData[i].m_renderContext = m_primaryContext->createShared(); } m_queue.AddInitCommand(bind(&TileRenderer::InitializeThreadGL, this, _1)); @@ -87,7 +88,6 @@ void TileRenderer::InitializeThreadGL(core::CommandsQueue::Environment const & e { ThreadData & threadData = m_threadData[env.GetThreadNum()]; - threadData.m_renderContext = m_primaryContext->createShared(); threadData.m_renderContext->makeCurrent(); threadData.m_drawer = new DrawerYG(threadData.m_drawerParams); } diff --git a/yg/renderer.cpp b/yg/renderer.cpp index 5e91fcd7ed..5c15e4d6a6 100644 --- a/yg/renderer.cpp +++ b/yg/renderer.cpp @@ -78,6 +78,11 @@ namespace yg OGLCHECK(glClear(mask)); } + void Renderer::finish() + { + OGLCHECK(glFinish()); + } + void Renderer::onSize(unsigned int width, unsigned int height) { if (width < 2) width = 2; diff --git a/yg/renderer.hpp b/yg/renderer.hpp index 3fa6442c25..66ff959fbc 100644 --- a/yg/renderer.hpp +++ b/yg/renderer.hpp @@ -73,6 +73,8 @@ namespace yg unsigned int width() const; unsigned int height() const; + void finish(); + bool isDebugging() const; }; }