From 6234cb98d1b2b3b3cd39b18f69ee8cf4aa7efe32 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Thu, 2 Jun 2022 11:24:52 +0300 Subject: [PATCH] gl-renderer: fix performance regression in frag When color management is disabled, the fragment shader was still first ensuring straight alpha and then immediately just going back to pre-multiplied. This is near-impossible for a shader compiler to optimize out, I guess because of the if-statement to handle division by zero. Having view alpha applied in between certainly didn't make it easier. That causes extra fragment computations that are unnecessary. In the issue report this was found to cause a notable performance regression. Fix the performance regression by introducing special-case paths for when straight alpha is not needed. This skips the unnecessary computations. Fixes: https://gitlab.freedesktop.org/wayland/weston/-/issues/623 Fixes: 9a6a4e7032669be727c965ca19e3e30098c892e7 Signed-off-by: Pekka Paalanen --- libweston/renderer-gl/fragment.glsl | 44 ++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/libweston/renderer-gl/fragment.glsl b/libweston/renderer-gl/fragment.glsl index c49a6cd4..e8dae27d 100644 --- a/libweston/renderer-gl/fragment.glsl +++ b/libweston/renderer-gl/fragment.glsl @@ -77,6 +77,10 @@ compile_const bool c_green_tint = DEF_GREEN_TINT; compile_const int c_color_pre_curve = DEF_COLOR_PRE_CURVE; compile_const int c_color_mapping = DEF_COLOR_MAPPING; +compile_const bool c_need_color_pipeline = + c_color_pre_curve != SHADER_COLOR_CURVE_IDENTITY || + c_color_mapping != SHADER_COLOR_MAPPING_IDENTITY; + vec4 yuva2rgba(vec4 yuva) { @@ -245,9 +249,6 @@ color_mapping(vec3 color) vec4 color_pipeline(vec4 color) { - /* View alpha (opacity) */ - color.a *= alpha; - color.rgb = color_pre_curve(color.rgb); color.rgb = color_mapping(color.rgb); @@ -262,18 +263,35 @@ main() /* Electrical (non-linear) RGBA values, may be premult or not */ color = sample_input_texture(); - /* Ensure straight alpha */ - if (c_input_is_premult) { - if (color.a == 0.0) - color.rgb = vec3(0, 0, 0); - else - color.rgb *= 1.0 / color.a; - } + if (c_need_color_pipeline) { + /* Ensure straight alpha */ + if (c_input_is_premult) { + if (color.a == 0.0) + color.rgb = vec3(0, 0, 0); + else + color.rgb *= 1.0 / color.a; + } - color = color_pipeline(color); + color = color_pipeline(color); - /* pre-multiply for blending */ - color.rgb *= color.a; + /* View alpha (opacity) */ + color.a *= alpha; + + /* pre-multiply for blending */ + color.rgb *= color.a; + } else { + /* Fast path for disabled color management */ + + if (c_input_is_premult) { + /* View alpha (opacity) */ + color *= alpha; + } else { + /* View alpha (opacity) */ + color.a *= alpha; + /* pre-multiply for blending */ + color.rgb *= color.a; + } + } if (c_green_tint) color = vec4(0.0, 0.3, 0.0, 0.2) + color * 0.8;