mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
render: overlay: fix visual glitches when double buffering
When rendering the overlay for scrollback search, the logic assumed
buffer re-use. On some compositors this isn’t happening (on
e.g. KDE/plasma we’re forced to double buffer).
This resulted in matches not being highlighted correctly.
The problem is in how we calculated the region for which areas to
clear ("un-dim"). It uses the "previous frame’s see-through area"
minus the current frame’s see-through area.
However, when we’ve detected that the current buffer isn’t the same as
the last one, we set the last frame’s see-through region to "the
entire buffer". Thus, when calculating the diff, we end up with an
empty region, and nothing is highlighted.
Fix by simply using the current frame’s see-through region as-is when
we’ve detected we’re not re-using the last frame’s buffer.
This commit is contained in:
parent
4340f8a3b4
commit
3be44fb316
2 changed files with 22 additions and 10 deletions
|
|
@ -74,6 +74,9 @@
|
|||
* Glitchy rendering when scrolling in the scrollback, on compositors
|
||||
that does not allow Wayland buffer re-use (e.g. KDE/plasma)
|
||||
([#1173][1173])
|
||||
* Scrollback search matches not being highlighted correctly, on
|
||||
compositors that does now allow Wayland buffer re-use
|
||||
(e.g. KDE/plasma).
|
||||
|
||||
[1173]: https://codeberg.org/dnkl/foot/issues/1173
|
||||
|
||||
|
|
|
|||
29
render.c
29
render.c
|
|
@ -1563,11 +1563,12 @@ render_overlay(struct terminal *term)
|
|||
*/
|
||||
pixman_region32_t *see_through = &term->render.last_overlay_clip;
|
||||
pixman_region32_t old_see_through;
|
||||
const bool buffer_reuse =
|
||||
buf == term->render.last_overlay_buf &&
|
||||
style == term->render.last_overlay_style &&
|
||||
buf->age == 0;
|
||||
|
||||
if (!(buf == term->render.last_overlay_buf &&
|
||||
style == term->render.last_overlay_style &&
|
||||
buf->age == 0))
|
||||
{
|
||||
if (!buffer_reuse) {
|
||||
/* Can’t re-use last frame’s damage - set to full window,
|
||||
* to ensure *everything* is updated */
|
||||
pixman_region32_init_rect(
|
||||
|
|
@ -1580,8 +1581,8 @@ render_overlay(struct terminal *term)
|
|||
|
||||
pixman_region32_clear(see_through);
|
||||
|
||||
/* Build region consisting of all current search matches */
|
||||
struct search_match_iterator iter = search_matches_new_iter(term);
|
||||
|
||||
for (struct range match = search_matches_next(&iter);
|
||||
match.start.row >= 0;
|
||||
match = search_matches_next(&iter))
|
||||
|
|
@ -1609,20 +1610,28 @@ render_overlay(struct terminal *term)
|
|||
}
|
||||
}
|
||||
|
||||
/* Current see-through, minus old see-through - aka cells that
|
||||
* need to be cleared */
|
||||
/* Areas that need to be cleared: cells that were dimmed in
|
||||
* the last frame but is now see-through */
|
||||
pixman_region32_t new_see_through;
|
||||
pixman_region32_init(&new_see_through);
|
||||
pixman_region32_subtract(&new_see_through, see_through, &old_see_through);
|
||||
|
||||
if (buffer_reuse)
|
||||
pixman_region32_subtract(&new_see_through, see_through, &old_see_through);
|
||||
else {
|
||||
/* Buffer content is unknown - explicitly clear *all*
|
||||
* current see-through areas */
|
||||
pixman_region32_copy(&new_see_through, see_through);
|
||||
}
|
||||
pixman_image_set_clip_region32(buf->pix[0], &new_see_through);
|
||||
|
||||
/* Old see-through, minus new see-through - aka cells that
|
||||
* needs to be dimmed */
|
||||
/* Areas that need to be dimmed: cells that were cleared in
|
||||
* the last frame but is not anymore */
|
||||
pixman_region32_t new_dimmed;
|
||||
pixman_region32_init(&new_dimmed);
|
||||
pixman_region32_subtract(&new_dimmed, &old_see_through, see_through);
|
||||
pixman_region32_fini(&old_see_through);
|
||||
|
||||
/* Total affected area */
|
||||
pixman_region32_t damage;
|
||||
pixman_region32_init(&damage);
|
||||
pixman_region32_union(&damage, &new_see_through, &new_dimmed);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue