Skip to content

Commit 4878add

Browse files
committed
egl: restore foreign current displays
1 parent 36a73e7 commit 4878add

1 file changed

Lines changed: 24 additions & 27 deletions

File tree

src/glue/gl_egl.cpp

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ struct eglglue_contextdata {
156156
EGLContext context;
157157
EGLSurface surface;
158158
EGLConfig config;
159+
EGLDisplay previousDisplay;
159160
EGLContext previousContext;
160161
EGLSurface previousDrawSurface;
161162
EGLSurface previousReadSurface;
@@ -173,6 +174,7 @@ eglglue_contextdata_init(unsigned int width, unsigned int height)
173174
ctx->context = EGL_NO_CONTEXT;
174175
ctx->surface = EGL_NO_SURFACE;
175176
ctx->config = (EGLConfig) 0;
177+
ctx->previousDisplay = EGL_NO_DISPLAY;
176178
ctx->previousContext = EGL_NO_CONTEXT;
177179
ctx->previousDrawSurface = EGL_NO_SURFACE;
178180
ctx->previousReadSurface = EGL_NO_SURFACE;
@@ -448,18 +450,13 @@ eglglue_context_make_current(void * ctx)
448450
return FALSE;
449451
}
450452

451-
// A context and its surfaces can only be restored through the display they
452-
// belong to. The EGL backend uses one display, so discard foreign current
453-
// state rather than passing it to eglMakeCurrent() with the wrong display.
454-
if (eglGetCurrentDisplay() == display) {
455-
context->previousContext = eglGetCurrentContext();
456-
context->previousDrawSurface = eglGetCurrentSurface(EGL_DRAW);
457-
context->previousReadSurface = eglGetCurrentSurface(EGL_READ);
458-
} else {
459-
context->previousContext = EGL_NO_CONTEXT;
460-
context->previousDrawSurface = EGL_NO_SURFACE;
461-
context->previousReadSurface = EGL_NO_SURFACE;
462-
}
453+
// Save the complete current EGL binding. The application may be using a
454+
// different display from Coin's offscreen display, and EGL requires the
455+
// display associated with a context when restoring it.
456+
context->previousDisplay = eglGetCurrentDisplay();
457+
context->previousContext = eglGetCurrentContext();
458+
context->previousDrawSurface = eglGetCurrentSurface(EGL_DRAW);
459+
context->previousReadSurface = eglGetCurrentSurface(EGL_READ);
463460

464461
if (eglMakeCurrent(display, context->surface, context->surface, context->context) == EGL_FALSE) {
465462
cc_debugerror_post("eglglue_context_make_current",
@@ -486,26 +483,26 @@ eglglue_context_reinstate_previous(void * ctx)
486483
return;
487484
}
488485

489-
// Release the offscreen context even when there was no previous EGL
490-
// context. Leaving it current makes the next offscreen context operation
491-
// observe a stale context handle.
492-
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
493-
494-
if (context->previousContext != EGL_NO_CONTEXT) {
495-
if (eglMakeCurrent(display,
496-
context->previousDrawSurface,
497-
context->previousReadSurface,
498-
context->previousContext) == EGL_TRUE) {
486+
// Restore the previous binding directly. This also releases Coin's
487+
// offscreen context when the previous binding was EGL_NO_CONTEXT, while
488+
// preserving applications whose context belongs to another EGL display.
489+
EGLDisplay previousDisplay = context->previousDisplay;
490+
if (previousDisplay == EGL_NO_DISPLAY) {
491+
previousDisplay = display;
492+
}
493+
if (eglMakeCurrent(previousDisplay,
494+
context->previousDrawSurface,
495+
context->previousReadSurface,
496+
context->previousContext) == EGL_TRUE) {
499497
if (coin_glglue_debug()) {
500498
cc_debugerror_postinfo("eglglue_context_make_current",
501499
"EGL Context (0x%X)\n",
502500
context->context);
503501
}
504-
} else {
505-
cc_debugerror_post("eglglue_context_make_current",
506-
"eglMakeCurrent failed: %s",
507-
eglErrorString(eglGetError()));
508-
}
502+
} else {
503+
cc_debugerror_post("eglglue_context_make_current",
504+
"eglMakeCurrent failed: %s",
505+
eglErrorString(eglGetError()));
509506
}
510507
}
511508

0 commit comments

Comments
 (0)