From cdc5179b905e0ca21820b906b14d2f7932ca0f5b Mon Sep 17 00:00:00 2001 From: Amit Feller Date: Thu, 30 Jun 2011 13:05:28 +0300 Subject: [PATCH] EGL translator: fixes shared context on windows On windows it is not possible to create a context which shares with another context if the other context is already current to some thread. This change makes the "global context" be a dummy context on windows which we create during the first createContext call, this dummy context will never bind to any thread so it is safe to share with it at any time. --- .../host/libs/Translator/EGL/EglDisplay.cpp | 38 ++++++++++++++++++- .../host/libs/Translator/EGL/EglDisplay.h | 4 +- .../host/libs/Translator/EGL/EglImp.cpp | 4 +- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.cpp b/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.cpp index 2bf9d185b..f20f51c78 100644 --- a/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.cpp +++ b/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.cpp @@ -23,7 +23,8 @@ EglDisplay::EglDisplay(EGLNativeDisplayType dpy,bool isDefault) : m_initialized(false), m_configInitialized(false), m_isDefault(isDefault), - m_nextEglImageId(0) + m_nextEglImageId(0), + m_globalSharedContext(NULL) { m_manager[GLES_1_1] = new ObjectNameManager(&m_globalNameSpace); m_manager[GLES_2_0] = new ObjectNameManager(&m_globalNameSpace); @@ -31,6 +32,15 @@ EglDisplay::EglDisplay(EGLNativeDisplayType dpy,bool isDefault) : EglDisplay::~EglDisplay() { android::Mutex::Autolock mutex(m_lock); + + // + // Destroy the global context if one was created. + // (should be true for windows platform only) + // + if (m_globalSharedContext != NULL) { + EglOS::destroyContext( m_dpy, m_globalSharedContext); + } + if(m_isDefault) { EglOS::releaseDisplay(m_dpy); } @@ -264,7 +274,6 @@ EGLContext EglDisplay::addContext(ContextPtr ctx ) { if(m_contexts.find(hndl) != m_contexts.end()) { return ret; } - m_contexts[hndl] = ctx; return ret; } @@ -294,3 +303,28 @@ bool EglDisplay:: destroyImageKHR(EGLImageKHR img) { } return false; } + +EGLNativeContextType EglDisplay::getGlobalSharedContext(){ + android::Mutex::Autolock mutex(m_lock); +#ifndef _WIN32 + return (EGLNativeContextType)m_manager[GLES_1_1]->getGlobalContext(); +#else + if (!m_globalSharedContext) { + // + // On windows we create a dummy context to serve as the + // "global context" which all contexts share with. + // This is because on windows it is not possible to share + // with a context which is already current. This dummy context + // will never be current to any thread so it is safe to share with. + // Create that context using the first config + if (m_configs.size() < 1) { + // Should not happen! config list should be initialized at this point + return NULL; + } + EglConfig *cfg = (*m_configs.begin()); + m_globalSharedContext = EglOS::createContext(m_dpy,cfg,NULL); + } + + return m_globalSharedContext; +#endif +} diff --git a/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.h b/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.h index c5262b197..f60c90f86 100644 --- a/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.h +++ b/tools/emulator/opengl/host/libs/Translator/EGL/EglDisplay.h @@ -65,6 +65,7 @@ public: ImagePtr getImage(EGLImageKHR img); EGLImageKHR addImageKHR(ImagePtr); bool destroyImageKHR(EGLImageKHR img); + EGLNativeContextType getGlobalSharedContext(); private: int doChooseConfigs(const EglConfig& dummy,EGLConfig* configs,int config_size); @@ -81,8 +82,9 @@ private: GlobalNameSpace m_globalNameSpace; ObjectNameManager *m_manager[MAX_GLES_VERSION]; android::Mutex m_lock; - ImagesHndlMap m_eglImages; + ImagesHndlMap m_eglImages; unsigned int m_nextEglImageId; + EGLNativeContextType m_globalSharedContext; }; #endif diff --git a/tools/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp b/tools/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp index b6c8ab4b7..a3db30c0e 100644 --- a/tools/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp +++ b/tools/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp @@ -641,7 +641,9 @@ EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay display, EGLConfig con nativeShared = sharedCtxPtr->nativeType(); } - EGLNativeContextType nativeContext = EglOS::createContext(dpy->nativeType(),cfg,static_cast(dpy->getManager(version)->getGlobalContext())); + EGLNativeContextType globalSharedContext = dpy->getGlobalSharedContext(); + EGLNativeContextType nativeContext = EglOS::createContext(dpy->nativeType(),cfg,globalSharedContext); + if(nativeContext) { ContextPtr ctx(new EglContext(nativeContext,sharedCtxPtr,cfg,glesCtx,version,dpy->getManager(version))); return dpy->addContext(ctx);