Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2021-09-10 22:53:33 +0300
committerClément Foucault <foucault.clem@gmail.com>2021-10-12 17:47:41 +0300
commit6535779c92b90035870047f178cf3eff95f0bdf0 (patch)
tree3dc5a4704750f2b6fdb9952e5ec11d3ba3fbedcf /intern/ghost
parenta2daf92a57e45039fe928a9bc6251e8f8fc2bd6d (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/ghost')
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm15
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.cpp17
-rw-r--r--intern/ghost/intern/GHOST_SystemWayland.cpp50
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp59
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp65
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;
}
/**