[Bug 59436] New: Wayland/EGL: Washed-out colors caused by double sRGB conversion on default framebuffer (GL_FRAMEBUFFER_SRGB)
http://bugs.winehq.org/show_bug.cgi?id=59436 Bug ID: 59436 Summary: Wayland/EGL: Washed-out colors caused by double sRGB conversion on default framebuffer (GL_FRAMEBUFFER_SRGB) Product: Wine Version: 11.3 Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: winewayland Assignee: wine-bugs@list.winehq.org Reporter: tpaniaki@protonmail.com Distribution: --- Created attachment 80417 --> http://bugs.winehq.org/attachment.cgi?id=80417 Patch Fixes https://bugs.winehq.org/show_bug.cgi?id=59073 Summary When running Wine with the Wayland driver (winewayland.drv) using EGL, colors may appear washed out / desaturated in OpenGL applications. The issue is caused by GL_FRAMEBUFFER_SRGB remaining enabled while rendering to the default framebuffer (FBO 0), leading to a double gamma/sRGB conversion in some Wayland/EGL pipelines. Disabling GL_FRAMEBUFFER_SRGB only when rendering to the default framebuffer fixes the color output. Environment Wine: wine-git (tested on 11.x, reproducible on current master) Backend: winewayland.drv (Wayland native, not XWayland) GPU: AMD (Mesa) Compositor: wlroots-based (qtile Wayland) EGL backend in use Application tested: Roon (Chromium/CEF-based UI, OpenGL rendering) Observed behavior Colors appear faded / washed out Gamma looks incorrect (as if double sRGB conversion occurs) Issue only occurs under Wayland/EGL Colors are correct: Under X11/XWayland Or if GL_FRAMEBUFFER_SRGB is manually disabled for FBO 0 Root cause hypothesis Some Wayland/EGL compositors already perform colorspace handling for the window surface. If GL_FRAMEBUFFER_SRGB remains enabled when rendering to the default framebuffer, the pipeline applies sRGB conversion twice: App → GL_FRAMEBUFFER_SRGB → EGL/Compositor colorspace → Display This results in desaturated output. Minimal fix Disable GL_FRAMEBUFFER_SRGB only when binding the default framebuffer (FBO 0), while preserving the application's requested sRGB state for non-default FBOs. Example patch (conceptual) Inside framebuffer binding path: if (!framebuffer && gl_info->supported[ARB_FRAMEBUFFER_SRGB]) { TRACE("glBindFramebuffer disabling GL_FRAMEBUFFER_SRGB on default framebuffer\n"); glDisable(GL_FRAMEBUFFER_SRGB); } else if (framebuffer && app_framebuffer_srgb_enabled) { TRACE("glBindFramebuffer restoring GL_FRAMEBUFFER_SRGB on non-default framebuffer\n"); glEnable(GL_FRAMEBUFFER_SRGB); } Results Colors become correct under Wayland/EGL No regression observed in tested OpenGL apps Behavior matches X11 output sRGB still works correctly for offscreen FBO rendering -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59436 --- Comment #1 from tpaniaki <tpaniaki@protonmail.com> --- Comment on attachment 80417 --> http://bugs.winehq.org/attachment.cgi?id=80417 Patch wrong_upload -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59436 --- Comment #2 from tpaniaki <tpaniaki@protonmail.com> --- Comment on attachment 80417 --> http://bugs.winehq.org/attachment.cgi?id=80417 Patch
diff --git a/dlls/opengl32/thunks.c b/dlls/opengl32/thunks.c index 3c60ec5d6bb..7145c2c1b7f 100644 --- a/dlls/opengl32/thunks.c +++ b/dlls/opengl32/thunks.c @@ -3207,8 +3207,45 @@ static void WINAPI glBindFramebuffer( GLenum target, GLuint framebuffer ) { struct glBindFramebuffer_params args = { .teb = NtCurrentTeb(), .target = target, .framebuffer = framebuffer }; NTSTATUS status; + static BOOL srgb_disabled_for_default_fb; + TRACE( "target %d, framebuffer %d\n", target, framebuffer ); if ((status = UNIX_CALL( glBindFramebuffer, &args ))) WARN( "glBindFramebuffer returned %#lx\n", status ); + + if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER) + { + struct glIsEnabled_params is_enabled_args = { .teb = NtCurrentTeb(), .cap = GL_FRAMEBUFFER_SRGB }; + GLboolean srgb_enabled; + + if ((status = UNIX_CALL( glIsEnabled, &is_enabled_args ))) WARN( "glIsEnabled returned %#lx\n", status ); + srgb_enabled = is_enabled_args.ret; + + if (!framebuffer) + { + /* Avoid double sRGB/gamma conversion on the onscreen framebuffer. */ + if (srgb_enabled) + { + struct glDisable_params disable_args = { .teb = NtCurrentTeb(), .cap = GL_FRAMEBUFFER_SRGB }; + + TRACE( "disabling GL_FRAMEBUFFER_SRGB on default framebuffer\n" ); + if ((status = UNIX_CALL( glDisable, &disable_args ))) WARN( "glDisable returned %#lx\n", status ); + srgb_disabled_for_default_fb = TRUE; + } + else + { + srgb_disabled_for_default_fb = FALSE; + } + } + else if (srgb_disabled_for_default_fb) + { + /* Restore sRGB state for offscreen FBOs if we disabled it for FBO 0. */ + struct glEnable_params enable_args = { .teb = NtCurrentTeb(), .cap = GL_FRAMEBUFFER_SRGB }; + + TRACE( "restoring GL_FRAMEBUFFER_SRGB on non-default framebuffer\n" ); + if ((status = UNIX_CALL( glEnable, &enable_args ))) WARN( "glEnable returned %#lx\n", status ); + srgb_disabled_for_default_fb = FALSE; + } + } }
static void WINAPI glBindFramebufferEXT( GLenum target, GLuint framebuffer )
-- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
participants (1)
-
WineHQ Bugzilla