@@ -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