diff --git a/platform/platform.hpp b/platform/platform.hpp index be5e8e4db1..d90f3b089d 100644 --- a/platform/platform.hpp +++ b/platform/platform.hpp @@ -173,6 +173,8 @@ public: void RunAsync(TFunctor const & fn, Priority p = EPriorityDefault); //@} + // Please note, that number of active cores can vary at runtime. + // DO NOT assume for the same return value between calls. unsigned CpuCores() const; void GetFontNames(FilesList & res) const; diff --git a/render/basic_tiling_render_policy.cpp b/render/basic_tiling_render_policy.cpp index e43963df11..094a45c110 100644 --- a/render/basic_tiling_render_policy.cpp +++ b/render/basic_tiling_render_policy.cpp @@ -11,7 +11,7 @@ BasicTilingRenderPolicy::BasicTilingRenderPolicy(Params const & p, bool doUseQueuedRenderer) - : RenderPolicy(p, GetPlatform().CpuCores() + 2), + : RenderPolicy(p, m_cpuCoresCount + 2), m_IsEmptyModel(false), m_IsNavigating(false), m_WasAnimatingLastFrame(false), @@ -22,7 +22,7 @@ BasicTilingRenderPolicy::BasicTilingRenderPolicy(Params const & p, LOG(LDEBUG, ("ScreenSize=", p.m_screenWidth, "x", p.m_screenHeight, ", TileSize=", m_TileSize)); if (doUseQueuedRenderer) - m_QueuedRenderer.reset(new QueuedRenderer(GetPlatform().CpuCores() + 1, p.m_primaryRC)); + m_QueuedRenderer.reset(new QueuedRenderer(m_cpuCoresCount + 1, p.m_primaryRC)); } void BasicTilingRenderPolicy::BeginFrame(shared_ptr const & e, ScreenBase const & s) @@ -121,7 +121,7 @@ void BasicTilingRenderPolicy::PauseBackgroundRendering() m_TileRenderer->CancelCommands(); m_CoverageGenerator->Pause(); if (m_QueuedRenderer) - m_QueuedRenderer->SetPartialExecution(GetPlatform().CpuCores(), true); + m_QueuedRenderer->SetPartialExecution(m_cpuCoresCount, true); } void BasicTilingRenderPolicy::ResumeBackgroundRendering() @@ -130,7 +130,7 @@ void BasicTilingRenderPolicy::ResumeBackgroundRendering() m_CoverageGenerator->Resume(); m_DoRecreateCoverage = true; if (m_QueuedRenderer) - m_QueuedRenderer->SetPartialExecution(GetPlatform().CpuCores(), false); + m_QueuedRenderer->SetPartialExecution(m_cpuCoresCount, false); } void BasicTilingRenderPolicy::StartNavigation() diff --git a/render/basic_tiling_render_policy.hpp b/render/basic_tiling_render_policy.hpp index 58cf138225..54bb875329 100644 --- a/render/basic_tiling_render_policy.hpp +++ b/render/basic_tiling_render_policy.hpp @@ -21,7 +21,7 @@ class QueuedRenderer; /// There are threads that are responsible for composing new ScreenCoverage from already drawn tiles, /// and drawing tiles if needed. /// Once the more recent ScreenCoverage are composed it became a currentCoverage. -class BasicTilingRenderPolicy : public RenderPolicy +class BasicTilingRenderPolicy : public RenderPolicyCpuCountHolder, public RenderPolicy { private: diff --git a/render/render_policy.cpp b/render/render_policy.cpp index 1dacc016da..37a3bbb331 100644 --- a/render/render_policy.cpp +++ b/render/render_policy.cpp @@ -21,6 +21,11 @@ #define WHITE_LIST_FILE "fonts_whitelist.txt" #define BLACK_LIST_FILE "fonts_blacklist.txt" +RenderPolicyCpuCountHolder::RenderPolicyCpuCountHolder() + : m_cpuCoresCount(GetPlatform().CpuCores()) +{ +} + RenderPolicy::~RenderPolicy() { LOG(LDEBUG, ("clearing cached drawing rules")); diff --git a/render/render_policy.hpp b/render/render_policy.hpp index 53748228d9..ede40b42a4 100644 --- a/render/render_policy.hpp +++ b/render/render_policy.hpp @@ -40,6 +40,17 @@ namespace anim class WindowHandle; +// Base class for temporary CpuCount initialization work-around. +// m_cpuCoresCount should be initialized before RenderPolicy() constructor is called. +// New graphics library (Drape) does not have this issue. +class RenderPolicyCpuCountHolder +{ +protected: + RenderPolicyCpuCountHolder(); + // Cache this value as it can change dynamically at runtime. + unsigned const m_cpuCoresCount; +}; + class RenderPolicy { public: diff --git a/render/tiling_render_policy_mt.cpp b/render/tiling_render_policy_mt.cpp index 615579389f..d863514ede 100644 --- a/render/tiling_render_policy_mt.cpp +++ b/render/tiling_render_policy_mt.cpp @@ -13,8 +13,6 @@ using namespace graphics; TilingRenderPolicyMT::TilingRenderPolicyMT(Params const & p) : BasicTilingRenderPolicy(p, false) { - int cpuCores = GetPlatform().CpuCores(); - graphics::ResourceManager::Params rmp = p.m_rmParams; rmp.checkDeviceCaps(); @@ -32,8 +30,8 @@ TilingRenderPolicyMT::TilingRenderPolicyMT(Params const & p) rmp.m_glyphCacheParams = GetResourceGlyphCacheParams(Density()); - rmp.m_threadSlotsCount = cpuCores + 2; - rmp.m_renderThreadsCount = cpuCores; + rmp.m_threadSlotsCount = m_cpuCoresCount + 2; + rmp.m_renderThreadsCount = m_cpuCoresCount; rmp.m_useSingleThreadedOGL = false; @@ -66,7 +64,7 @@ TilingRenderPolicyMT::~TilingRenderPolicyMT() void TilingRenderPolicyMT::SetRenderFn(TRenderFn const & renderFn) { m_TileRenderer.reset(new TileRenderer(TileSize(), - GetPlatform().CpuCores(), + m_cpuCoresCount, m_bgColors, renderFn, m_primaryRC, diff --git a/render/tiling_render_policy_st.cpp b/render/tiling_render_policy_st.cpp index e88134c8cf..99bf4ca206 100644 --- a/render/tiling_render_policy_st.cpp +++ b/render/tiling_render_policy_st.cpp @@ -16,8 +16,6 @@ TilingRenderPolicyST::TilingRenderPolicyST(Params const & p) : BasicTilingRenderPolicy(p, true) { - int cpuCores = GetPlatform().CpuCores(); - ResourceManager::Params rmp = p.m_rmParams; rmp.checkDeviceCaps(); @@ -35,8 +33,8 @@ TilingRenderPolicyST::TilingRenderPolicyST(Params const & p) rmp.m_glyphCacheParams = GetResourceGlyphCacheParams(Density()); - rmp.m_threadSlotsCount = cpuCores + 2; - rmp.m_renderThreadsCount = cpuCores; + rmp.m_threadSlotsCount = m_cpuCoresCount + 2; + rmp.m_renderThreadsCount = m_cpuCoresCount; rmp.m_useSingleThreadedOGL = true; @@ -59,24 +57,22 @@ TilingRenderPolicyST::~TilingRenderPolicyST() LOG(LDEBUG, ("cancelling ResourceManager")); m_resourceManager->cancel(); - int cpuCores = GetPlatform().CpuCores(); - LOG(LDEBUG, ("deleting TilingRenderPolicyST")); - m_QueuedRenderer->PrepareQueueCancellation(cpuCores); + m_QueuedRenderer->PrepareQueueCancellation(m_cpuCoresCount); /// now we should process all commands to collect them into queues m_CoverageGenerator->Shutdown(); - m_QueuedRenderer->CancelQueuedCommands(cpuCores); + m_QueuedRenderer->CancelQueuedCommands(m_cpuCoresCount); /// firstly stop all rendering commands in progress and collect all commands into queues - for (unsigned i = 0; i < cpuCores; ++i) + for (unsigned i = 0; i < m_cpuCoresCount; ++i) m_QueuedRenderer->PrepareQueueCancellation(i); m_TileRenderer->Shutdown(); /// now we should cancel all collected commands - for (unsigned i = 0; i < cpuCores; ++i) + for (unsigned i = 0; i < m_cpuCoresCount; ++i) m_QueuedRenderer->CancelQueuedCommands(i); LOG(LDEBUG, ("reseting coverageGenerator")); @@ -88,15 +84,13 @@ TilingRenderPolicyST::~TilingRenderPolicyST() void TilingRenderPolicyST::SetRenderFn(TRenderFn const & renderFn) { - int const cpuCores = GetPlatform().CpuCores(); + graphics::PacketsQueue ** queues = new graphics::PacketsQueue*[m_cpuCoresCount]; - graphics::PacketsQueue ** queues = new graphics::PacketsQueue*[cpuCores]; - - for (unsigned i = 0; i < cpuCores; ++i) + for (unsigned i = 0; i < m_cpuCoresCount; ++i) queues[i] = m_QueuedRenderer->GetPacketsQueue(i); m_TileRenderer.reset(new TileRenderer(TileSize(), - cpuCores, + m_cpuCoresCount, m_bgColors, renderFn, m_primaryRC, @@ -108,10 +102,10 @@ void TilingRenderPolicyST::SetRenderFn(TRenderFn const & renderFn) /// CoverageGenerator rendering queue could execute commands partially /// as there are no render-to-texture calls. -// m_QueuedRenderer->SetPartialExecution(cpuCores, true); +// m_QueuedRenderer->SetPartialExecution(m_cpuCoresCount, true); m_CoverageGenerator.reset(new CoverageGenerator(m_TileRenderer.get(), m_windowHandle, m_primaryRC, m_resourceManager, - m_QueuedRenderer->GetPacketsQueue(cpuCores))); + m_QueuedRenderer->GetPacketsQueue(m_cpuCoresCount))); }