diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2021-09-10 22:53:33 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2021-10-12 17:47:41 +0300 |
commit | 6535779c92b90035870047f178cf3eff95f0bdf0 (patch) | |
tree | 3dc5a4704750f2b6fdb9952e5ec11d3ba3fbedcf /intern | |
parent | a2daf92a57e45039fe928a9bc6251e8f8fc2bd6d (diff) |
GHOST: Unify behavior of offscreen context creation
This makes sure the previously bound context is restored after creating a
new context. This follows what is already happening on windows.
All system backend are patched.
This also removes the goto and some code duplication.
Differential Revision: https://developer.blender.org/D12455
Diffstat (limited to 'intern')
-rw-r--r-- | intern/ghost/intern/GHOST_SystemCocoa.mm | 15 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemSDL.cpp | 17 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWayland.cpp | 50 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWin32.cpp | 59 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemX11.cpp | 65 |
5 files changed, 93 insertions, 113 deletions
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 189e663f91a..5a7d6ef2c01 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -767,13 +767,18 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title, */ GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext(GHOST_GLSettings glSettings) { + NSOpenGLContext *prevContext = [NSOpenGLContext currentContext]; + GHOST_Context *context = new GHOST_ContextCGL(false, NULL, NULL, NULL); - if (context->initializeDrawingContext()) - return context; - else + if (context->initializeDrawingContext() == false) { delete context; - - return NULL; + context = nullptr; + } + /* Restore previously bound context. This is just to follow the win32 behavior. */ + if (prevContext) { + [prevContext makeCurrentContext]; + } + return context; } /** diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp index 5370d4df857..77410407e21 100644 --- a/intern/ghost/intern/GHOST_SystemSDL.cpp +++ b/intern/ghost/intern/GHOST_SystemSDL.cpp @@ -141,6 +141,9 @@ uint8_t GHOST_SystemSDL::getNumDisplays() const GHOST_IContext *GHOST_SystemSDL::createOffscreenContext(GHOST_GLSettings glSettings) { + SDL_GLContext prev_context = SDL_GL_GetCurrentContext(); + SDL_Window *prev_window = SDL_GL_GetCurrentWindow(); + GHOST_Context *context = new GHOST_ContextSDL(0, NULL, 0, /* Profile bit. */ @@ -149,12 +152,18 @@ GHOST_IContext *GHOST_SystemSDL::createOffscreenContext(GHOST_GLSettings glSetti GHOST_OPENGL_SDL_CONTEXT_FLAGS, GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY); - if (context->initializeDrawingContext()) - return context; - else + if (context->initializeDrawingContext()) { + /* Pass */ + } + else { delete context; + context = nullptr; + } - return NULL; + if (m_context) { + SDL_GL_MakeCurrent(prev_window, prev_context); + } + return context; } GHOST_TSuccess GHOST_SystemSDL::disposeContext(GHOST_IContext *context) diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index 38700845405..8cc84641d2e 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -1599,45 +1599,47 @@ GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GLSettings /*g GHOST_Context *context; - for (int minor = 6; minor >= 0; --minor) { + EGLDisplay prev_display = eglGetCurrentDisplay(); + /* It doesn't matter which one we query since we use the same surface for both read and write. */ + EGLSurface prev_surface = eglGetCurrentSurface(EGL_DRAW); + EGLContext prev_context = eglGetCurrentContext(); + + const int versions[][2] = {{4, 6}, {4, 5}, {4, 4}, {4, 3}, {4, 2}, {4, 1}, {4, 0}, {3, 3}}; + const int versions_len = sizeof(versions) / sizeof(versions[0]); + + for (int i = 0; i < versions_len; i++) { + int major = versions[i][0]; + int minor = versions[i][1]; + context = new GHOST_ContextEGL(this, false, EGLNativeWindowType(os_egl_window), EGLNativeDisplayType(d->display), EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, - 4, + major, minor, GHOST_OPENGL_EGL_CONTEXT_FLAGS, GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY, EGL_OPENGL_API); - if (context->initializeDrawingContext()) - return context; - else + if (context->initializeDrawingContext()) { + break; + } + else { delete context; + context = nullptr; + } } - context = new GHOST_ContextEGL(this, - false, - EGLNativeWindowType(os_egl_window), - EGLNativeDisplayType(d->display), - EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, - 3, - 3, - GHOST_OPENGL_EGL_CONTEXT_FLAGS, - GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY, - EGL_OPENGL_API); - - if (context->initializeDrawingContext()) { - return context; - } - else { - delete context; + if (context == nullptr) { + GHOST_PRINT("Cannot create off-screen EGL context" << std::endl); } - GHOST_PRINT("Cannot create off-screen EGL context" << std::endl); - - return nullptr; + if (prev_context) { + /* Restore previously bound context. This is just to follow the win32 behavior. */ + eglMakeCurrent(prev_display, prev_surface, prev_surface, prev_context); + } + return context; } GHOST_TSuccess GHOST_SystemWayland::disposeContext(GHOST_IContext *context) diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 482f20f5cd1..e0765ad85d5 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -284,69 +284,36 @@ GHOST_IContext *GHOST_SystemWin32::createOffscreenContext(GHOST_GLSettings glSet HDC mHDC = GetDC(wnd); HDC prev_hdc = wglGetCurrentDC(); HGLRC prev_context = wglGetCurrentContext(); -#if defined(WITH_GL_PROFILE_CORE) - for (int minor = 5; minor >= 0; --minor) { + + const int versions[][2] = {{4, 6}, {4, 5}, {4, 4}, {4, 3}, {4, 2}, {4, 1}, {4, 0}, {3, 3}}; + const int versions_len = sizeof(versions) / sizeof(versions[0]); + + for (int i = 0; i < versions_len; i++) { + int major = versions[i][0]; + int minor = versions[i][1]; + context = new GHOST_ContextWGL(false, true, wnd, mHDC, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - 4, + major, minor, (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); if (context->initializeDrawingContext()) { - goto finished; + break; } else { delete context; + context = nullptr; } } - context = new GHOST_ContextWGL(false, - true, - wnd, - mHDC, - WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - 3, - 3, - (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) { - goto finished; - } - else { - delete context; - return NULL; + if (prev_context) { + wglMakeCurrent(prev_hdc, prev_context); } - -#elif defined(WITH_GL_PROFILE_COMPAT) - // ask for 2.1 context, driver gives any GL version >= 2.1 - // (hopefully the latest compatibility profile) - // 2.1 ignores the profile bit & is incompatible with core profile - context = new GHOST_ContextWGL(false, - true, - NULL, - NULL, - 0, // no profile bit - 2, - 1, - (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) { - return context; - } - else { - delete context; - } -#else -# error // must specify either core or compat at build time -#endif -finished: - wglMakeCurrent(prev_hdc, prev_context); return context; } diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index ab8039ea95d..98f5f41d5e8 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -437,16 +437,32 @@ GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSetti # endif #endif +#if defined(WITH_GL_EGL) + EGLDisplay prev_display = eglGetCurrentDisplay(); + /* It doesn't matter which one we query since we use the same surface for both read and write. */ + EGLSurface prev_surface = eglGetCurrentSurface(EGL_DRAW); + EGLContext prev_context = eglGetCurrentContext(); +#else + Display *prev_display = glXGetCurrentDisplay(); + GLXDrawable prev_drawable = glXGetCurrentDrawable(); + GLXContext prev_context = glXGetCurrentContext(); +#endif + GHOST_Context *context; - for (int minor = 5; minor >= 0; --minor) { + const int versions[][2] = {{4, 6}, {4, 5}, {4, 4}, {4, 3}, {4, 2}, {4, 1}, {4, 0}, {3, 3}}; + const int versions_len = sizeof(versions) / sizeof(versions[0]); + + for (int i = 0; i < versions_len; i++) { + int major = versions[i][0]; + int minor = versions[i][1]; #if defined(WITH_GL_EGL) context = new GHOST_ContextEGL(this, false, EGLNativeWindowType(nullptr), EGLNativeDisplayType(m_display), profile_mask, - 4, + major, minor, GHOST_OPENGL_EGL_CONTEXT_FLAGS | (debug_context ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0), @@ -458,50 +474,31 @@ GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSetti m_display, (GLXFBConfig)NULL, profile_mask, - 4, + major, minor, GHOST_OPENGL_GLX_CONTEXT_FLAGS | (debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY); #endif - if (context->initializeDrawingContext()) - return context; - else + if (context->initializeDrawingContext()) { + break; + } + else { delete context; + context = nullptr; + } } + if (prev_context) { + /* Restore previously bound context. This is just to follow the win32 behavior. */ #if defined(WITH_GL_EGL) - context = new GHOST_ContextEGL(this, - false, - EGLNativeWindowType(nullptr), - EGLNativeDisplayType(m_display), - profile_mask, - 3, - 3, - GHOST_OPENGL_EGL_CONTEXT_FLAGS | - (debug_context ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0), - GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY, - EGL_OPENGL_API); + eglMakeCurrent(prev_display, prev_surface, prev_surface, prev_context); #else - context = new GHOST_ContextGLX(false, - (Window)NULL, - m_display, - (GLXFBConfig)NULL, - profile_mask, - 3, - 3, - GHOST_OPENGL_GLX_CONTEXT_FLAGS | - (debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY); + glXMakeCurrent(prev_display, prev_drawable, prev_context); #endif - - if (context->initializeDrawingContext()) - return context; - else - delete context; - - return NULL; + } + return context; } /** |