pixman,drm: do not composite previous damage

Pixman-renderer uses a single internal shadow buffer. It is enough to
composite the current damage into shadow, but the copy to hw buffer
needs to include the previous damage because of double-buffering in
DRM-backend.

This patch lets pixman-renderer do exactly that without compositing also
the previous damage on DRM-renderer.

Arguably weston_output should not have field previous_damage to begin
with, because it implies double-buffering, which e.g. EGL does not
guarantee. It would be better for each backend explicitly always provide
any extra damage that should be copied to hw.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Signed-off-by: Fabien Lahoudere <fabien.lahoudere@collabora.com>
Reviewed-by: Ian Ray <ian.ray@ge.com>
This commit is contained in:
Pekka Paalanen 2018-04-23 11:44:56 +02:00
parent 944fae8887
commit acf50c3d96
3 changed files with 40 additions and 18 deletions

View File

@ -1673,25 +1673,17 @@ drm_output_render_pixman(struct drm_output_state *state,
{ {
struct drm_output *output = state->output; struct drm_output *output = state->output;
struct weston_compositor *ec = output->base.compositor; struct weston_compositor *ec = output->base.compositor;
pixman_region32_t total_damage, previous_damage;
pixman_region32_init(&total_damage);
pixman_region32_init(&previous_damage);
pixman_region32_copy(&previous_damage, damage);
pixman_region32_union(&total_damage, damage, &output->previous_damage);
pixman_region32_copy(&output->previous_damage, &previous_damage);
output->current_image ^= 1; output->current_image ^= 1;
pixman_renderer_output_set_buffer(&output->base, pixman_renderer_output_set_buffer(&output->base,
output->image[output->current_image]); output->image[output->current_image]);
pixman_renderer_output_set_hw_extra_damage(&output->base,
&output->previous_damage);
ec->renderer->repaint_output(&output->base, &total_damage); ec->renderer->repaint_output(&output->base, damage);
pixman_region32_fini(&total_damage); pixman_region32_copy(&output->previous_damage, damage);
pixman_region32_fini(&previous_damage);
return drm_fb_ref(output->dumb[output->current_image]); return drm_fb_ref(output->dumb[output->current_image]);
} }

View File

@ -41,6 +41,7 @@ struct pixman_output_state {
void *shadow_buffer; void *shadow_buffer;
pixman_image_t *shadow_image; pixman_image_t *shadow_image;
pixman_image_t *hw_buffer; pixman_image_t *hw_buffer;
pixman_region32_t *hw_extra_damage;
}; };
struct pixman_surface_state { struct pixman_surface_state {
@ -555,15 +556,29 @@ copy_to_hw_buffer(struct weston_output *output, pixman_region32_t *region)
static void static void
pixman_renderer_repaint_output(struct weston_output *output, pixman_renderer_repaint_output(struct weston_output *output,
pixman_region32_t *output_damage) pixman_region32_t *output_damage)
{ {
struct pixman_output_state *po = get_output_state(output); struct pixman_output_state *po = get_output_state(output);
pixman_region32_t hw_damage;
if (!po->hw_buffer) if (!po->hw_buffer) {
return; po->hw_extra_damage = NULL;
return;
}
pixman_region32_init(&hw_damage);
if (po->hw_extra_damage) {
pixman_region32_union(&hw_damage,
po->hw_extra_damage, output_damage);
po->hw_extra_damage = NULL;
} else {
pixman_region32_copy(&hw_damage, output_damage);
}
repaint_surfaces(output, output_damage); repaint_surfaces(output, output_damage);
copy_to_hw_buffer(output, output_damage);
copy_to_hw_buffer(output, &hw_damage);
pixman_region32_fini(&hw_damage);
pixman_region32_copy(&output->previous_damage, output_damage); pixman_region32_copy(&output->previous_damage, output_damage);
wl_signal_emit(&output->frame_signal, output); wl_signal_emit(&output->frame_signal, output);
@ -862,7 +877,8 @@ pixman_renderer_init(struct weston_compositor *ec)
} }
WL_EXPORT void WL_EXPORT void
pixman_renderer_output_set_buffer(struct weston_output *output, pixman_image_t *buffer) pixman_renderer_output_set_buffer(struct weston_output *output,
pixman_image_t *buffer)
{ {
struct pixman_output_state *po = get_output_state(output); struct pixman_output_state *po = get_output_state(output);
@ -876,6 +892,15 @@ pixman_renderer_output_set_buffer(struct weston_output *output, pixman_image_t *
} }
} }
WL_EXPORT void
pixman_renderer_output_set_hw_extra_damage(struct weston_output *output,
pixman_region32_t *extra_damage)
{
struct pixman_output_state *po = get_output_state(output);
po->hw_extra_damage = extra_damage;
}
WL_EXPORT int WL_EXPORT int
pixman_renderer_output_create(struct weston_output *output) pixman_renderer_output_create(struct weston_output *output)
{ {

View File

@ -34,7 +34,12 @@ int
pixman_renderer_output_create(struct weston_output *output); pixman_renderer_output_create(struct weston_output *output);
void void
pixman_renderer_output_set_buffer(struct weston_output *output, pixman_image_t *buffer); pixman_renderer_output_set_buffer(struct weston_output *output,
pixman_image_t *buffer);
void
pixman_renderer_output_set_hw_extra_damage(struct weston_output *output,
pixman_region32_t *extra_damage);
void void
pixman_renderer_output_destroy(struct weston_output *output); pixman_renderer_output_destroy(struct weston_output *output);