render: render_margin: don't damage margins when rendering scroll damage

When applying scroll damage, we may have to re-render the
margins.

This is because when we SHM-scroll, we actually move the entire
surface, and thus we end up overwriting the top margin area with old
window content, and scroll in uninitialized memory in the bottom
margin.

But, we don't have to tell the compositor about this - the last frame
always contains correct margins; i.e. there's no change between the
last frame and current frame being rendered.

TODO: we _could_ micro-optimize and only damage the margins after a
surface resize. We do it slightly more often now, when dealing with
state changes in screen flash or scrollback searching. But I don't
think it's worth the effort.
This commit is contained in:
Daniel Eklöf 2020-07-13 14:19:07 +02:00
parent 96f480b14d
commit 3f55cf3d14
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F

View file

@ -504,9 +504,7 @@ draw_cursor:
static void
render_margin(struct terminal *term, struct buffer *buf,
int start_line, int end_line,
bool damage_top, bool damage_bottom,
bool damage_left, bool damage_right)
int start_line, int end_line, bool apply_damage)
{
/* Fill area outside the cell grid with the default background color */
const int rmargin = term->width - term->margins.right;
@ -537,25 +535,27 @@ render_margin(struct terminal *term, struct buffer *buf,
term->margins.right, line_count * term->cell_height},
});
if (damage_top)
if (apply_damage) {
/* Top */
wl_surface_damage_buffer(
term->window->surface, 0, 0, term->width, term->margins.top);
if (damage_bottom)
/* Bottom */
wl_surface_damage_buffer(
term->window->surface, 0, bmargin, term->width, term->margins.bottom);
if (damage_left)
/* Left */
wl_surface_damage_buffer(
term->window->surface,
0, term->margins.top + start_line * term->cell_height,
term->margins.left, line_count * term->cell_height);
if (damage_right)
/* Right */
wl_surface_damage_buffer(
term->window->surface,
rmargin, term->margins.top + start_line * term->cell_height,
term->margins.right, line_count * term->cell_height);
}
}
static void
@ -633,8 +633,7 @@ grid_render_scroll(struct terminal *term, struct buffer *buf,
if (did_shm_scroll) {
/* Restore margins */
render_margin(
term, buf, dmg->region.end - dmg->lines, term->rows,
true, true, true, true);
term, buf, dmg->region.end - dmg->lines, term->rows, false);
} else {
/* Fallback for when we either cannot do SHM scrolling, or it failed */
uint8_t *raw = buf->mmapped;
@ -699,8 +698,7 @@ grid_render_scroll_reverse(struct terminal *term, struct buffer *buf,
if (did_shm_scroll) {
/* Restore margins */
render_margin(
term, buf, dmg->region.start, dmg->region.start + dmg->lines,
true, true, true, true);
term, buf, dmg->region.start, dmg->region.start + dmg->lines, false);
} else {
/* Fallback for when we either cannot do SHM scrolling, or it failed */
uint8_t *raw = buf->mmapped;
@ -1341,7 +1339,7 @@ grid_render(struct terminal *term)
else {
tll_free(term->grid->scroll_damage);
render_margin(term, buf, 0, term->rows, true, true, true, true);
render_margin(term, buf, 0, term->rows, true);
term_damage_view(term);
}