Fix ghosting when using background_tint under GNOME+Wayland

The problem was that on Wayland if the buffer contains pixels with alpha
< 1 they are blended with something, even if the window is opaque. Under
mutter that something was the previous frame, under sway it was the
background/whatever is under the window.

So when blending the tint color, use a blend mode that results in opaque
pixels.

Fixes #5605
This commit is contained in:
Kovid Goyal 2022-10-19 19:00:06 +05:30
parent 28c616d3ff
commit 4f90110a7c
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 5 additions and 2 deletions

View File

@ -42,6 +42,8 @@ Detailed list of changes
- Wayland KDE: Fix abort when pasting into Firefox (:iss:`5603`) - Wayland KDE: Fix abort when pasting into Firefox (:iss:`5603`)
- Wayland GNOME: Fix ghosting when using :opt:`background_tint` (:iss:`5605`)
0.26.4 [2022-10-17] 0.26.4 [2022-10-17]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -12,6 +12,7 @@
#include "window_logo.h" #include "window_logo.h"
#define BLEND_ONTO_OPAQUE glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // blending onto opaque colors #define BLEND_ONTO_OPAQUE glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // blending onto opaque colors
#define BLEND_ONTO_OPAQUE_WITH_OPAQUE_OUTPUT glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE); // blending onto opaque colors with final color having alpha 1
#define BLEND_PREMULT glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // blending of pre-multiplied colors #define BLEND_PREMULT glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // blending of pre-multiplied colors
enum { CELL_PROGRAM, CELL_BG_PROGRAM, CELL_SPECIAL_PROGRAM, CELL_FG_PROGRAM, BORDERS_PROGRAM, GRAPHICS_PROGRAM, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_ALPHA_MASK_PROGRAM, BLIT_PROGRAM, BGIMAGE_PROGRAM, TINT_PROGRAM, NUM_PROGRAMS }; enum { CELL_PROGRAM, CELL_BG_PROGRAM, CELL_SPECIAL_PROGRAM, CELL_FG_PROGRAM, BORDERS_PROGRAM, GRAPHICS_PROGRAM, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_ALPHA_MASK_PROGRAM, BLIT_PROGRAM, BGIMAGE_PROGRAM, TINT_PROGRAM, NUM_PROGRAMS };
@ -531,8 +532,7 @@ has_bgimage(OSWindow *w) {
static void static void
draw_tint(bool premult, Screen *screen, const CellRenderData *crd) { draw_tint(bool premult, Screen *screen, const CellRenderData *crd) {
// On GNOME+Wayland this causes ghosting while rendering. Yet another GNOME bug, does not occur under KDE, Hyprland or Sway. if (premult) { BLEND_PREMULT } else { BLEND_ONTO_OPAQUE_WITH_OPAQUE_OUTPUT }
if (premult) { BLEND_PREMULT; } else { BLEND_ONTO_OPAQUE; }
bind_program(TINT_PROGRAM); bind_program(TINT_PROGRAM);
color_type window_bg = colorprofile_to_color(screen->color_profile, screen->color_profile->overridden.default_bg, screen->color_profile->configured.default_bg).rgb; color_type window_bg = colorprofile_to_color(screen->color_profile, screen->color_profile->overridden.default_bg, screen->color_profile->configured.default_bg).rgb;
#define C(shift) ((((GLfloat)((window_bg >> shift) & 0xFF)) / 255.0f)) * premult_factor #define C(shift) ((((GLfloat)((window_bg >> shift) & 0xFF)) / 255.0f)) * premult_factor
@ -1006,6 +1006,7 @@ draw_borders(ssize_t vao_idx, unsigned int num_border_rects, BorderRect *rect_bu
color_type default_bg = (num_visible_windows > 1 && !all_windows_have_same_bg) ? OPT(background) : active_window_bg; color_type default_bg = (num_visible_windows > 1 && !all_windows_have_same_bg) ? OPT(background) : active_window_bg;
glUniform3f(border_uniform_locations[BORDER_default_bg], CV3(default_bg)); glUniform3f(border_uniform_locations[BORDER_default_bg], CV3(default_bg));
#undef CV3 #undef CV3
if (!w->is_semi_transparent && has_bgimage(w)) { BLEND_ONTO_OPAQUE_WITH_OPAQUE_OUTPUT }
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, num_border_rects); glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, num_border_rects);
unbind_vertex_array(); unbind_vertex_array();
unbind_program(); unbind_program();