pixman-renderer: track damage in weston_renderbuffer
Add a damage region to struct weston_renderbuffer and use it to replace the previous_damage tracking in the drm backend. Keep renderbuffers on a list in struct pixman_output_state and use it to accumulate damage on all renderbuffers during repaint_output. Now renderbuffers have to be created when pixman output state already exists. Reorder renderer output state and renderbuffer creation accordingly. With this, pixman_renderer_output_set_hw_extra_damage() can be removed. This can not yet replace the external damage tracking in the VNC backend, which needsto know the accumulated damage that is not returned from repaint_output. Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
This commit is contained in:
parent
6757bae0f3
commit
4d96635a3f
@ -595,7 +595,6 @@ struct drm_output {
|
||||
struct drm_fb *dumb[2];
|
||||
struct weston_renderbuffer *renderbuffer[2];
|
||||
int current_image;
|
||||
pixman_region32_t previous_damage;
|
||||
|
||||
struct vaapi_recorder *recorder;
|
||||
struct wl_listener recorder_frame_listener;
|
||||
|
@ -343,14 +343,9 @@ drm_output_render_pixman(struct drm_output_state *state,
|
||||
|
||||
output->current_image ^= 1;
|
||||
|
||||
pixman_renderer_output_set_hw_extra_damage(&output->base,
|
||||
&output->previous_damage);
|
||||
|
||||
ec->renderer->repaint_output(&output->base, damage,
|
||||
output->renderbuffer[output->current_image]);
|
||||
|
||||
pixman_region32_copy(&output->previous_damage, damage);
|
||||
|
||||
return drm_fb_ref(output->dumb[output->current_image]);
|
||||
}
|
||||
|
||||
@ -1203,6 +1198,9 @@ drm_output_init_pixman(struct drm_output *output, struct drm_backend *b)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pixman->output_create(&output->base, &options) < 0)
|
||||
goto err;
|
||||
|
||||
/* FIXME error checking */
|
||||
for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
|
||||
output->dumb[i] = drm_fb_create_dumb(device, w, h, format);
|
||||
@ -1216,17 +1214,16 @@ drm_output_init_pixman(struct drm_output *output, struct drm_backend *b)
|
||||
output->dumb[i]->strides[0]);
|
||||
if (!output->renderbuffer[i])
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (pixman->output_create(&output->base, &options) < 0)
|
||||
goto err;
|
||||
pixman_region32_init_rect(&output->renderbuffer[i]->damage,
|
||||
output->base.x, output->base.y,
|
||||
output->base.width,
|
||||
output->base.height);
|
||||
}
|
||||
|
||||
weston_log("DRM: output %s %s shadow framebuffer.\n", output->base.name,
|
||||
b->use_pixman_shadow ? "uses" : "does not use");
|
||||
|
||||
pixman_region32_init_rect(&output->previous_damage,
|
||||
output->base.x, output->base.y, output->base.width, output->base.height);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
@ -1239,6 +1236,7 @@ err:
|
||||
output->dumb[i] = NULL;
|
||||
output->renderbuffer[i] = NULL;
|
||||
}
|
||||
pixman->output_destroy(&output->base);
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -1258,15 +1256,14 @@ drm_output_fini_pixman(struct drm_output *output)
|
||||
drm_plane_reset_state(output->scanout_plane);
|
||||
}
|
||||
|
||||
renderer->pixman->output_destroy(&output->base);
|
||||
pixman_region32_fini(&output->previous_damage);
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
|
||||
renderer->pixman->renderbuffer_destroy(output->renderbuffer[i]);
|
||||
drm_fb_unref(output->dumb[i]);
|
||||
output->dumb[i] = NULL;
|
||||
output->renderbuffer[i] = NULL;
|
||||
}
|
||||
|
||||
renderer->pixman->output_destroy(&output->base);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -192,8 +192,8 @@ headless_output_disable_pixman(struct headless_output *output)
|
||||
{
|
||||
struct weston_renderer *renderer = output->base.compositor->renderer;
|
||||
|
||||
renderer->pixman->output_destroy(&output->base);
|
||||
renderer->pixman->renderbuffer_destroy(output->renderbuffer);
|
||||
renderer->pixman->output_destroy(&output->base);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -306,15 +306,15 @@ headless_output_enable_pixman(struct headless_output *output)
|
||||
pixman = output->base.compositor->renderer->pixman;
|
||||
pfmt = pixel_format_get_info(headless_formats[0]);
|
||||
|
||||
if (pixman->output_create(&output->base, &options) < 0)
|
||||
return -1;
|
||||
|
||||
output->renderbuffer =
|
||||
pixman->create_image_no_clear(&output->base,
|
||||
pfmt->pixman_format,
|
||||
output->base.current_mode->width,
|
||||
output->base.current_mode->height);
|
||||
if (!output->renderbuffer)
|
||||
return -1;
|
||||
|
||||
if (pixman->output_create(&output->base, &options) < 0)
|
||||
goto err_renderer;
|
||||
|
||||
weston_output_update_capture_info(&output->base,
|
||||
@ -326,7 +326,7 @@ headless_output_enable_pixman(struct headless_output *output)
|
||||
return 0;
|
||||
|
||||
err_renderer:
|
||||
pixman->renderbuffer_destroy(output->renderbuffer);
|
||||
pixman->output_destroy(&output->base);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -481,6 +481,10 @@ rdp_output_enable(struct weston_output *base)
|
||||
|
||||
b = output->backend;
|
||||
|
||||
if (renderer->pixman->output_create(&output->base, &options) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
output->renderbuffer =
|
||||
pixman->create_image_from_ptr(&output->base, PIXMAN_x8r8g8b8,
|
||||
output->base.current_mode->width,
|
||||
@ -489,11 +493,7 @@ rdp_output_enable(struct weston_output *base)
|
||||
output->base.current_mode->width * 4);
|
||||
if (output->renderbuffer == NULL) {
|
||||
weston_log("Failed to create surface for frame buffer.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (renderer->pixman->output_create(&output->base, &options) < 0) {
|
||||
renderer->pixman->renderbuffer_destroy(output->renderbuffer);
|
||||
renderer->pixman->output_destroy(&output->base);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,8 @@
|
||||
|
||||
struct weston_renderbuffer {
|
||||
pixman_image_t *image;
|
||||
pixman_region32_t damage;
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct weston_renderer_options {
|
||||
|
@ -48,8 +48,8 @@ struct pixman_output_state {
|
||||
const struct pixel_format_info *shadow_format;
|
||||
pixman_image_t *hw_buffer;
|
||||
const struct pixel_format_info *hw_format;
|
||||
pixman_region32_t *hw_extra_damage;
|
||||
struct weston_size fb_size;
|
||||
struct wl_list renderbuffer_list;
|
||||
};
|
||||
|
||||
struct pixman_surface_state {
|
||||
@ -627,7 +627,7 @@ pixman_renderer_repaint_output(struct weston_output *output,
|
||||
struct weston_renderbuffer *renderbuffer)
|
||||
{
|
||||
struct pixman_output_state *po = get_output_state(output);
|
||||
pixman_region32_t hw_damage;
|
||||
struct weston_renderbuffer *rb;
|
||||
|
||||
assert(renderbuffer);
|
||||
|
||||
@ -636,33 +636,26 @@ pixman_renderer_repaint_output(struct weston_output *output,
|
||||
assert(output->from_blend_to_output_by_backend ||
|
||||
output->color_outcome->from_blend_to_output == NULL);
|
||||
|
||||
if (!po->hw_buffer) {
|
||||
po->hw_extra_damage = NULL;
|
||||
if (!po->hw_buffer)
|
||||
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);
|
||||
}
|
||||
/* Accumulate damage in all renderbuffers */
|
||||
wl_list_for_each(rb, &po->renderbuffer_list, link)
|
||||
pixman_region32_union(&rb->damage, &rb->damage, output_damage);
|
||||
|
||||
if (po->shadow_image) {
|
||||
repaint_surfaces(output, output_damage);
|
||||
pixman_renderer_do_capture_tasks(output,
|
||||
WESTON_OUTPUT_CAPTURE_SOURCE_BLENDING,
|
||||
po->shadow_image, po->shadow_format);
|
||||
copy_to_hw_buffer(output, &hw_damage);
|
||||
copy_to_hw_buffer(output, &renderbuffer->damage);
|
||||
} else {
|
||||
repaint_surfaces(output, &hw_damage);
|
||||
repaint_surfaces(output, &renderbuffer->damage);
|
||||
}
|
||||
pixman_renderer_do_capture_tasks(output,
|
||||
WESTON_OUTPUT_CAPTURE_SOURCE_FRAMEBUFFER,
|
||||
po->hw_buffer, po->hw_format);
|
||||
pixman_region32_fini(&hw_damage);
|
||||
pixman_region32_clear(&renderbuffer->damage);
|
||||
|
||||
wl_signal_emit(&output->frame_signal, output_damage);
|
||||
|
||||
@ -1063,15 +1056,6 @@ pixman_renderer_output_set_buffer(struct weston_output *output,
|
||||
po->hw_format);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static int
|
||||
pixman_renderer_output_create(struct weston_output *output,
|
||||
const struct pixman_renderer_output_options *options)
|
||||
@ -1099,6 +1083,8 @@ pixman_renderer_output_create(struct weston_output *output,
|
||||
return -1;
|
||||
}
|
||||
|
||||
wl_list_init(&po->renderbuffer_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1116,6 +1102,8 @@ pixman_renderer_output_destroy(struct weston_output *output)
|
||||
po->shadow_image = NULL;
|
||||
po->hw_buffer = NULL;
|
||||
|
||||
assert(wl_list_empty(&po->renderbuffer_list));
|
||||
|
||||
free(po);
|
||||
}
|
||||
|
||||
@ -1124,8 +1112,11 @@ pixman_renderer_create_image_from_ptr(struct weston_output *output,
|
||||
pixman_format_code_t format, int width,
|
||||
int height, uint32_t *ptr, int rowstride)
|
||||
{
|
||||
struct pixman_output_state *po = get_output_state(output);
|
||||
struct weston_renderbuffer *renderbuffer;
|
||||
|
||||
assert(po);
|
||||
|
||||
renderbuffer = xzalloc(sizeof(*renderbuffer));
|
||||
|
||||
renderbuffer->image = pixman_image_create_bits(format, width, height,
|
||||
@ -1135,6 +1126,9 @@ pixman_renderer_create_image_from_ptr(struct weston_output *output,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pixman_region32_init(&renderbuffer->damage);
|
||||
wl_list_insert(&po->renderbuffer_list, &renderbuffer->link);
|
||||
|
||||
return renderbuffer;
|
||||
}
|
||||
|
||||
@ -1143,8 +1137,11 @@ pixman_renderer_create_image_no_clear(struct weston_output *output,
|
||||
pixman_format_code_t format, int width,
|
||||
int height)
|
||||
{
|
||||
struct pixman_output_state *po = get_output_state(output);
|
||||
struct weston_renderbuffer *renderbuffer;
|
||||
|
||||
assert(po);
|
||||
|
||||
renderbuffer = xzalloc(sizeof(*renderbuffer));
|
||||
|
||||
renderbuffer->image =
|
||||
@ -1155,13 +1152,18 @@ pixman_renderer_create_image_no_clear(struct weston_output *output,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pixman_region32_init(&renderbuffer->damage);
|
||||
wl_list_insert(&po->renderbuffer_list, &renderbuffer->link);
|
||||
|
||||
return renderbuffer;
|
||||
}
|
||||
|
||||
static void
|
||||
pixman_renderer_renderbuffer_destroy(struct weston_renderbuffer *renderbuffer)
|
||||
{
|
||||
wl_list_remove(&renderbuffer->link);
|
||||
pixman_image_unref(renderbuffer->image);
|
||||
pixman_region32_fini(&renderbuffer->damage);
|
||||
free(renderbuffer);
|
||||
}
|
||||
|
||||
|
@ -40,10 +40,6 @@ struct pixman_renderer_output_options {
|
||||
struct weston_size fb_size;
|
||||
};
|
||||
|
||||
void
|
||||
pixman_renderer_output_set_hw_extra_damage(struct weston_output *output,
|
||||
pixman_region32_t *extra_damage);
|
||||
|
||||
struct pixman_renderer_interface {
|
||||
int (*output_create)(struct weston_output *output,
|
||||
const struct pixman_renderer_output_options *options);
|
||||
|
Loading…
Reference in New Issue
Block a user