From 305723106d53e83117059e8398a0806f9630666b Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Wed, 3 Jun 2026 19:05:55 +0200 Subject: [PATCH] Only call `eglMakeCurrent` if anything has changed in `CurrentContextGuard::drop` Instead of unconditionally calling `eglMakeCurrent` when restoring the context in `CurrentContextGuard::drop` only do this if anything has changed. This guards against drivers that do too much when calling `eglMakeCurrent`. Signed-off-by: Martin Robinson --- src/platform/generic/egl/context.rs | 63 +++++++++++++++++------------ 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/src/platform/generic/egl/context.rs b/src/platform/generic/egl/context.rs index a43f3dd6..ea3cf643 100644 --- a/src/platform/generic/egl/context.rs +++ b/src/platform/generic/egl/context.rs @@ -62,30 +62,54 @@ pub(crate) struct CurrentContextGuard { old_egl_context: EGLContext, } -impl Drop for EGLBackedContext { - #[inline] - fn drop(&mut self) { - if self.egl_context != egl::NO_CONTEXT && !thread::panicking() { - panic!("Contexts must be destroyed explicitly with `destroy_context`!") - } +impl CurrentContextGuard { + pub(crate) fn new() -> CurrentContextGuard { + EGL_FUNCTIONS.with(|egl| unsafe { + CurrentContextGuard { + egl_display: egl.GetCurrentDisplay(), + old_egl_draw_surface: egl.GetCurrentSurface(egl::DRAW as EGLint), + old_egl_read_surface: egl.GetCurrentSurface(egl::READ as EGLint), + old_egl_context: egl.GetCurrentContext(), + } + }) } } impl Drop for CurrentContextGuard { fn drop(&mut self) { EGL_FUNCTIONS.with(|egl| unsafe { - if self.egl_display != egl::NO_DISPLAY { - egl.MakeCurrent( - self.egl_display, - self.old_egl_draw_surface, - self.old_egl_read_surface, - self.old_egl_context, - ); + if self.egl_display == egl::NO_DISPLAY { + return; } + + // Only call eglMakeCurrent again if anything has changed. + if egl.GetCurrentDisplay() == self.egl_display + && egl.GetCurrentSurface(egl::DRAW as EGLint) == self.old_egl_draw_surface + && egl.GetCurrentSurface(egl::READ as EGLint) == self.old_egl_read_surface + && egl.GetCurrentContext() == self.old_egl_context + { + return; + } + + egl.MakeCurrent( + self.egl_display, + self.old_egl_draw_surface, + self.old_egl_read_surface, + self.old_egl_context, + ); }) } } +impl Drop for EGLBackedContext { + #[inline] + fn drop(&mut self) { + if self.egl_context != egl::NO_CONTEXT && !thread::panicking() { + panic!("Contexts must be destroyed explicitly with `destroy_context`!") + } + } +} + impl EGLBackedContext { pub(crate) unsafe fn new( egl_display: EGLDisplay, @@ -469,19 +493,6 @@ impl ContextDescriptor { } } -impl CurrentContextGuard { - pub(crate) fn new() -> CurrentContextGuard { - EGL_FUNCTIONS.with(|egl| unsafe { - CurrentContextGuard { - egl_display: egl.GetCurrentDisplay(), - old_egl_draw_surface: egl.GetCurrentSurface(egl::DRAW as EGLint), - old_egl_read_surface: egl.GetCurrentSurface(egl::READ as EGLint), - old_egl_context: egl.GetCurrentContext(), - } - }) - } -} - pub(crate) unsafe fn create_context( egl_display: EGLDisplay, descriptor: &ContextDescriptor,