diff --git a/drape/oglcontextfactory.cpp b/drape/oglcontextfactory.cpp index 4d2d17d0b9..5427564cc7 100644 --- a/drape/oglcontextfactory.cpp +++ b/drape/oglcontextfactory.cpp @@ -41,9 +41,9 @@ OGLContext * ThreadSafeFactory::CreateContext(TCreateCtxFn const & createFn, TIs return ctx; } -void ThreadSafeFactory::waitForInitialization() +void ThreadSafeFactory::waitForInitialization(dp::OGLContext * context) { - m_factory->waitForInitialization(); + m_factory->waitForInitialization(context); } } // namespace dp diff --git a/drape/oglcontextfactory.hpp b/drape/oglcontextfactory.hpp index f3cb2fe366..4ad52b3870 100644 --- a/drape/oglcontextfactory.hpp +++ b/drape/oglcontextfactory.hpp @@ -18,7 +18,7 @@ public: virtual OGLContext * getResourcesUploadContext() = 0; virtual bool isDrawContextCreated() const { return false; } virtual bool isUploadContextCreated() const { return false; } - virtual void waitForInitialization() {} + virtual void waitForInitialization(dp::OGLContext * context) {} }; class ThreadSafeFactory : public OGLContextFactory @@ -36,7 +36,7 @@ public: return static_cast(m_factory); } - void waitForInitialization() override; + void waitForInitialization(dp::OGLContext * context) override; protected: typedef function TCreateCtxFn; diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index 9ee1668df6..985ed73397 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -520,8 +520,9 @@ void BackendRenderer::ReleaseResources() void BackendRenderer::OnContextCreate() { LOG(LINFO, ("On context create.")); - m_contextFactory->waitForInitialization(); - m_contextFactory->getResourcesUploadContext()->makeCurrent(); + dp::OGLContext * context = m_contextFactory->getResourcesUploadContext(); + m_contextFactory->waitForInitialization(context); + context->makeCurrent(); GLFunctions::Init(m_apiVersion); diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 711ece2a67..aa23e8d43f 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -1763,9 +1763,9 @@ void FrontendRenderer::OnContextCreate() { LOG(LINFO, ("On context create.")); - m_contextFactory->waitForInitialization(); - dp::OGLContext * context = m_contextFactory->getDrawContext(); + m_contextFactory->waitForInitialization(context); + context->makeCurrent(); GLFunctions::Init(m_apiVersion); diff --git a/iphone/Maps/Classes/iosOGLContextFactory.h b/iphone/Maps/Classes/iosOGLContextFactory.h index 8c0346d856..88433a1624 100644 --- a/iphone/Maps/Classes/iosOGLContextFactory.h +++ b/iphone/Maps/Classes/iosOGLContextFactory.h @@ -20,7 +20,7 @@ public: bool isDrawContextCreated() const override; bool isUploadContextCreated() const override; - void waitForInitialization() override; + void waitForInitialization(dp::OGLContext * context) override; void setPresentAvailable(bool available); @@ -31,6 +31,8 @@ private: iosOGLContext * m_uploadContext; bool m_isInitialized; + size_t m_initializationCounter; + bool m_presentAvailable; condition_variable m_initializationCondition; mutex m_initializationMutex; }; diff --git a/iphone/Maps/Classes/iosOGLContextFactory.mm b/iphone/Maps/Classes/iosOGLContextFactory.mm index 69d0bf8e26..8a844e682b 100644 --- a/iphone/Maps/Classes/iosOGLContextFactory.mm +++ b/iphone/Maps/Classes/iosOGLContextFactory.mm @@ -1,11 +1,15 @@ #import "iosOGLContextFactory.h" +size_t constexpr kGLThreadsCount = 2; + iosOGLContextFactory::iosOGLContextFactory(CAEAGLLayer * layer, dp::ApiVersion apiVersion) : m_layer(layer) , m_apiVersion(apiVersion) , m_drawContext(nullptr) , m_uploadContext(nullptr) , m_isInitialized(false) + , m_initializationCounter(0) + , m_presentAvailable(false) {} iosOGLContextFactory::~iosOGLContextFactory() @@ -40,20 +44,36 @@ bool iosOGLContextFactory::isUploadContextCreated() const void iosOGLContextFactory::setPresentAvailable(bool available) { + lock_guard lock(m_initializationMutex); + m_presentAvailable = available; + if (m_isInitialized) { - lock_guard lock(m_initializationMutex); - if (!m_isInitialized && available) + m_drawContext->setPresentAvailable(m_presentAvailable); + } + else if (m_initializationCounter >= kGLThreadsCount && m_presentAvailable) + { + m_isInitialized = true; + m_initializationCondition.notify_all(); + } +} + +void iosOGLContextFactory::waitForInitialization(dp::OGLContext * context) +{ + unique_lock lock(m_initializationMutex); + if (!m_isInitialized) + { + m_initializationCounter++; + if (m_initializationCounter >= kGLThreadsCount && m_presentAvailable) { m_isInitialized = true; m_initializationCondition.notify_all(); } + else + { + m_initializationCondition.wait(lock, [this] { return m_isInitialized; }); + } } - if (m_drawContext != nullptr) - m_drawContext->setPresentAvailable(available); -} -void iosOGLContextFactory::waitForInitialization() -{ - unique_lock lock(m_initializationMutex); - m_initializationCondition.wait(lock, [this] { return m_isInitialized; }); + if (m_drawContext == context) + m_drawContext->setPresentAvailable(m_presentAvailable); }