mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-16 05:34:00 -04: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
|
* Glitchy rendering when scrolling in the scrollback, on compositors
|
||||||
that does not allow Wayland buffer re-use (e.g. KDE/plasma)
|
that does not allow Wayland buffer re-use (e.g. KDE/plasma)
|
||||||
([#1173][1173])
|
([#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
|
[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 *see_through = &term->render.last_overlay_clip;
|
||||||
pixman_region32_t old_see_through;
|
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 &&
|
if (!buffer_reuse) {
|
||||||
style == term->render.last_overlay_style &&
|
|
||||||
buf->age == 0))
|
|
||||||
{
|
|
||||||
/* Can’t re-use last frame’s damage - set to full window,
|
/* Can’t re-use last frame’s damage - set to full window,
|
||||||
* to ensure *everything* is updated */
|
* to ensure *everything* is updated */
|
||||||
pixman_region32_init_rect(
|
pixman_region32_init_rect(
|
||||||
|
|
@ -1580,8 +1581,8 @@ render_overlay(struct terminal *term)
|
||||||
|
|
||||||
pixman_region32_clear(see_through);
|
pixman_region32_clear(see_through);
|
||||||
|
|
||||||
|
/* Build region consisting of all current search matches */
|
||||||
struct search_match_iterator iter = search_matches_new_iter(term);
|
struct search_match_iterator iter = search_matches_new_iter(term);
|
||||||
|
|
||||||
for (struct range match = search_matches_next(&iter);
|
for (struct range match = search_matches_next(&iter);
|
||||||
match.start.row >= 0;
|
match.start.row >= 0;
|
||||||
match = search_matches_next(&iter))
|
match = search_matches_next(&iter))
|
||||||
|
|
@ -1609,20 +1610,28 @@ render_overlay(struct terminal *term)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Current see-through, minus old see-through - aka cells that
|
/* Areas that need to be cleared: cells that were dimmed in
|
||||||
* need to be cleared */
|
* the last frame but is now see-through */
|
||||||
pixman_region32_t new_see_through;
|
pixman_region32_t new_see_through;
|
||||||
pixman_region32_init(&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);
|
pixman_image_set_clip_region32(buf->pix[0], &new_see_through);
|
||||||
|
|
||||||
/* Old see-through, minus new see-through - aka cells that
|
/* Areas that need to be dimmed: cells that were cleared in
|
||||||
* needs to be dimmed */
|
* the last frame but is not anymore */
|
||||||
pixman_region32_t new_dimmed;
|
pixman_region32_t new_dimmed;
|
||||||
pixman_region32_init(&new_dimmed);
|
pixman_region32_init(&new_dimmed);
|
||||||
pixman_region32_subtract(&new_dimmed, &old_see_through, see_through);
|
pixman_region32_subtract(&new_dimmed, &old_see_through, see_through);
|
||||||
pixman_region32_fini(&old_see_through);
|
pixman_region32_fini(&old_see_through);
|
||||||
|
|
||||||
|
/* Total affected area */
|
||||||
pixman_region32_t damage;
|
pixman_region32_t damage;
|
||||||
pixman_region32_init(&damage);
|
pixman_region32_init(&damage);
|
||||||
pixman_region32_union(&damage, &new_see_through, &new_dimmed);
|
pixman_region32_union(&damage, &new_see_through, &new_dimmed);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue