forked from organicmaps/organicmaps
[iOS] Fixed OGL context initiailization race
This commit is contained in:
parent
820487db2f
commit
568c2f21e1
6 changed files with 41 additions and 18 deletions
|
@ -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
|
||||
|
|
|
@ -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<T *>(m_factory);
|
||||
}
|
||||
|
||||
void waitForInitialization() override;
|
||||
void waitForInitialization(dp::OGLContext * context) override;
|
||||
|
||||
protected:
|
||||
typedef function<OGLContext * ()> TCreateCtxFn;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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<mutex> lock(m_initializationMutex);
|
||||
m_presentAvailable = available;
|
||||
if (m_isInitialized)
|
||||
{
|
||||
lock_guard<mutex> 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<mutex> 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<mutex> lock(m_initializationMutex);
|
||||
m_initializationCondition.wait(lock, [this] { return m_isInitialized; });
|
||||
if (m_drawContext == context)
|
||||
m_drawContext->setPresentAvailable(m_presentAvailable);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue