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 drm_fb *dumb[2];
|
||||||
struct weston_renderbuffer *renderbuffer[2];
|
struct weston_renderbuffer *renderbuffer[2];
|
||||||
int current_image;
|
int current_image;
|
||||||
pixman_region32_t previous_damage;
|
|
||||||
|
|
||||||
struct vaapi_recorder *recorder;
|
struct vaapi_recorder *recorder;
|
||||||
struct wl_listener recorder_frame_listener;
|
struct wl_listener recorder_frame_listener;
|
||||||
|
@ -343,14 +343,9 @@ drm_output_render_pixman(struct drm_output_state *state,
|
|||||||
|
|
||||||
output->current_image ^= 1;
|
output->current_image ^= 1;
|
||||||
|
|
||||||
pixman_renderer_output_set_hw_extra_damage(&output->base,
|
|
||||||
&output->previous_damage);
|
|
||||||
|
|
||||||
ec->renderer->repaint_output(&output->base, damage,
|
ec->renderer->repaint_output(&output->base, damage,
|
||||||
output->renderbuffer[output->current_image]);
|
output->renderbuffer[output->current_image]);
|
||||||
|
|
||||||
pixman_region32_copy(&output->previous_damage, damage);
|
|
||||||
|
|
||||||
return drm_fb_ref(output->dumb[output->current_image]);
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pixman->output_create(&output->base, &options) < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
/* FIXME error checking */
|
/* FIXME error checking */
|
||||||
for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
|
for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
|
||||||
output->dumb[i] = drm_fb_create_dumb(device, w, h, format);
|
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]);
|
output->dumb[i]->strides[0]);
|
||||||
if (!output->renderbuffer[i])
|
if (!output->renderbuffer[i])
|
||||||
goto err;
|
goto err;
|
||||||
}
|
|
||||||
|
|
||||||
if (pixman->output_create(&output->base, &options) < 0)
|
pixman_region32_init_rect(&output->renderbuffer[i]->damage,
|
||||||
goto err;
|
output->base.x, output->base.y,
|
||||||
|
output->base.width,
|
||||||
|
output->base.height);
|
||||||
|
}
|
||||||
|
|
||||||
weston_log("DRM: output %s %s shadow framebuffer.\n", output->base.name,
|
weston_log("DRM: output %s %s shadow framebuffer.\n", output->base.name,
|
||||||
b->use_pixman_shadow ? "uses" : "does not use");
|
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;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@ -1239,6 +1236,7 @@ err:
|
|||||||
output->dumb[i] = NULL;
|
output->dumb[i] = NULL;
|
||||||
output->renderbuffer[i] = NULL;
|
output->renderbuffer[i] = NULL;
|
||||||
}
|
}
|
||||||
|
pixman->output_destroy(&output->base);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1258,15 +1256,14 @@ drm_output_fini_pixman(struct drm_output *output)
|
|||||||
drm_plane_reset_state(output->scanout_plane);
|
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++) {
|
for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
|
||||||
renderer->pixman->renderbuffer_destroy(output->renderbuffer[i]);
|
renderer->pixman->renderbuffer_destroy(output->renderbuffer[i]);
|
||||||
drm_fb_unref(output->dumb[i]);
|
drm_fb_unref(output->dumb[i]);
|
||||||
output->dumb[i] = NULL;
|
output->dumb[i] = NULL;
|
||||||
output->renderbuffer[i] = NULL;
|
output->renderbuffer[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderer->pixman->output_destroy(&output->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -192,8 +192,8 @@ headless_output_disable_pixman(struct headless_output *output)
|
|||||||
{
|
{
|
||||||
struct weston_renderer *renderer = output->base.compositor->renderer;
|
struct weston_renderer *renderer = output->base.compositor->renderer;
|
||||||
|
|
||||||
renderer->pixman->output_destroy(&output->base);
|
|
||||||
renderer->pixman->renderbuffer_destroy(output->renderbuffer);
|
renderer->pixman->renderbuffer_destroy(output->renderbuffer);
|
||||||
|
renderer->pixman->output_destroy(&output->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -306,15 +306,15 @@ headless_output_enable_pixman(struct headless_output *output)
|
|||||||
pixman = output->base.compositor->renderer->pixman;
|
pixman = output->base.compositor->renderer->pixman;
|
||||||
pfmt = pixel_format_get_info(headless_formats[0]);
|
pfmt = pixel_format_get_info(headless_formats[0]);
|
||||||
|
|
||||||
|
if (pixman->output_create(&output->base, &options) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
output->renderbuffer =
|
output->renderbuffer =
|
||||||
pixman->create_image_no_clear(&output->base,
|
pixman->create_image_no_clear(&output->base,
|
||||||
pfmt->pixman_format,
|
pfmt->pixman_format,
|
||||||
output->base.current_mode->width,
|
output->base.current_mode->width,
|
||||||
output->base.current_mode->height);
|
output->base.current_mode->height);
|
||||||
if (!output->renderbuffer)
|
if (!output->renderbuffer)
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (pixman->output_create(&output->base, &options) < 0)
|
|
||||||
goto err_renderer;
|
goto err_renderer;
|
||||||
|
|
||||||
weston_output_update_capture_info(&output->base,
|
weston_output_update_capture_info(&output->base,
|
||||||
@ -326,7 +326,7 @@ headless_output_enable_pixman(struct headless_output *output)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_renderer:
|
err_renderer:
|
||||||
pixman->renderbuffer_destroy(output->renderbuffer);
|
pixman->output_destroy(&output->base);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -481,6 +481,10 @@ rdp_output_enable(struct weston_output *base)
|
|||||||
|
|
||||||
b = output->backend;
|
b = output->backend;
|
||||||
|
|
||||||
|
if (renderer->pixman->output_create(&output->base, &options) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
output->renderbuffer =
|
output->renderbuffer =
|
||||||
pixman->create_image_from_ptr(&output->base, PIXMAN_x8r8g8b8,
|
pixman->create_image_from_ptr(&output->base, PIXMAN_x8r8g8b8,
|
||||||
output->base.current_mode->width,
|
output->base.current_mode->width,
|
||||||
@ -489,11 +493,7 @@ rdp_output_enable(struct weston_output *base)
|
|||||||
output->base.current_mode->width * 4);
|
output->base.current_mode->width * 4);
|
||||||
if (output->renderbuffer == NULL) {
|
if (output->renderbuffer == NULL) {
|
||||||
weston_log("Failed to create surface for frame buffer.\n");
|
weston_log("Failed to create surface for frame buffer.\n");
|
||||||
return -1;
|
renderer->pixman->output_destroy(&output->base);
|
||||||
}
|
|
||||||
|
|
||||||
if (renderer->pixman->output_create(&output->base, &options) < 0) {
|
|
||||||
renderer->pixman->renderbuffer_destroy(output->renderbuffer);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,8 @@
|
|||||||
|
|
||||||
struct weston_renderbuffer {
|
struct weston_renderbuffer {
|
||||||
pixman_image_t *image;
|
pixman_image_t *image;
|
||||||
|
pixman_region32_t damage;
|
||||||
|
struct wl_list link;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct weston_renderer_options {
|
struct weston_renderer_options {
|
||||||
|
@ -48,8 +48,8 @@ struct pixman_output_state {
|
|||||||
const struct pixel_format_info *shadow_format;
|
const struct pixel_format_info *shadow_format;
|
||||||
pixman_image_t *hw_buffer;
|
pixman_image_t *hw_buffer;
|
||||||
const struct pixel_format_info *hw_format;
|
const struct pixel_format_info *hw_format;
|
||||||
pixman_region32_t *hw_extra_damage;
|
|
||||||
struct weston_size fb_size;
|
struct weston_size fb_size;
|
||||||
|
struct wl_list renderbuffer_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pixman_surface_state {
|
struct pixman_surface_state {
|
||||||
@ -627,7 +627,7 @@ pixman_renderer_repaint_output(struct weston_output *output,
|
|||||||
struct weston_renderbuffer *renderbuffer)
|
struct weston_renderbuffer *renderbuffer)
|
||||||
{
|
{
|
||||||
struct pixman_output_state *po = get_output_state(output);
|
struct pixman_output_state *po = get_output_state(output);
|
||||||
pixman_region32_t hw_damage;
|
struct weston_renderbuffer *rb;
|
||||||
|
|
||||||
assert(renderbuffer);
|
assert(renderbuffer);
|
||||||
|
|
||||||
@ -636,33 +636,26 @@ pixman_renderer_repaint_output(struct weston_output *output,
|
|||||||
assert(output->from_blend_to_output_by_backend ||
|
assert(output->from_blend_to_output_by_backend ||
|
||||||
output->color_outcome->from_blend_to_output == NULL);
|
output->color_outcome->from_blend_to_output == NULL);
|
||||||
|
|
||||||
if (!po->hw_buffer) {
|
if (!po->hw_buffer)
|
||||||
po->hw_extra_damage = NULL;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
pixman_region32_init(&hw_damage);
|
/* Accumulate damage in all renderbuffers */
|
||||||
if (po->hw_extra_damage) {
|
wl_list_for_each(rb, &po->renderbuffer_list, link)
|
||||||
pixman_region32_union(&hw_damage,
|
pixman_region32_union(&rb->damage, &rb->damage, output_damage);
|
||||||
po->hw_extra_damage, output_damage);
|
|
||||||
po->hw_extra_damage = NULL;
|
|
||||||
} else {
|
|
||||||
pixman_region32_copy(&hw_damage, output_damage);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (po->shadow_image) {
|
if (po->shadow_image) {
|
||||||
repaint_surfaces(output, output_damage);
|
repaint_surfaces(output, output_damage);
|
||||||
pixman_renderer_do_capture_tasks(output,
|
pixman_renderer_do_capture_tasks(output,
|
||||||
WESTON_OUTPUT_CAPTURE_SOURCE_BLENDING,
|
WESTON_OUTPUT_CAPTURE_SOURCE_BLENDING,
|
||||||
po->shadow_image, po->shadow_format);
|
po->shadow_image, po->shadow_format);
|
||||||
copy_to_hw_buffer(output, &hw_damage);
|
copy_to_hw_buffer(output, &renderbuffer->damage);
|
||||||
} else {
|
} else {
|
||||||
repaint_surfaces(output, &hw_damage);
|
repaint_surfaces(output, &renderbuffer->damage);
|
||||||
}
|
}
|
||||||
pixman_renderer_do_capture_tasks(output,
|
pixman_renderer_do_capture_tasks(output,
|
||||||
WESTON_OUTPUT_CAPTURE_SOURCE_FRAMEBUFFER,
|
WESTON_OUTPUT_CAPTURE_SOURCE_FRAMEBUFFER,
|
||||||
po->hw_buffer, po->hw_format);
|
po->hw_buffer, po->hw_format);
|
||||||
pixman_region32_fini(&hw_damage);
|
pixman_region32_clear(&renderbuffer->damage);
|
||||||
|
|
||||||
wl_signal_emit(&output->frame_signal, output_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);
|
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
|
static int
|
||||||
pixman_renderer_output_create(struct weston_output *output,
|
pixman_renderer_output_create(struct weston_output *output,
|
||||||
const struct pixman_renderer_output_options *options)
|
const struct pixman_renderer_output_options *options)
|
||||||
@ -1099,6 +1083,8 @@ pixman_renderer_output_create(struct weston_output *output,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wl_list_init(&po->renderbuffer_list);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1116,6 +1102,8 @@ pixman_renderer_output_destroy(struct weston_output *output)
|
|||||||
po->shadow_image = NULL;
|
po->shadow_image = NULL;
|
||||||
po->hw_buffer = NULL;
|
po->hw_buffer = NULL;
|
||||||
|
|
||||||
|
assert(wl_list_empty(&po->renderbuffer_list));
|
||||||
|
|
||||||
free(po);
|
free(po);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1124,8 +1112,11 @@ pixman_renderer_create_image_from_ptr(struct weston_output *output,
|
|||||||
pixman_format_code_t format, int width,
|
pixman_format_code_t format, int width,
|
||||||
int height, uint32_t *ptr, int rowstride)
|
int height, uint32_t *ptr, int rowstride)
|
||||||
{
|
{
|
||||||
|
struct pixman_output_state *po = get_output_state(output);
|
||||||
struct weston_renderbuffer *renderbuffer;
|
struct weston_renderbuffer *renderbuffer;
|
||||||
|
|
||||||
|
assert(po);
|
||||||
|
|
||||||
renderbuffer = xzalloc(sizeof(*renderbuffer));
|
renderbuffer = xzalloc(sizeof(*renderbuffer));
|
||||||
|
|
||||||
renderbuffer->image = pixman_image_create_bits(format, width, height,
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pixman_region32_init(&renderbuffer->damage);
|
||||||
|
wl_list_insert(&po->renderbuffer_list, &renderbuffer->link);
|
||||||
|
|
||||||
return renderbuffer;
|
return renderbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1143,8 +1137,11 @@ pixman_renderer_create_image_no_clear(struct weston_output *output,
|
|||||||
pixman_format_code_t format, int width,
|
pixman_format_code_t format, int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
|
struct pixman_output_state *po = get_output_state(output);
|
||||||
struct weston_renderbuffer *renderbuffer;
|
struct weston_renderbuffer *renderbuffer;
|
||||||
|
|
||||||
|
assert(po);
|
||||||
|
|
||||||
renderbuffer = xzalloc(sizeof(*renderbuffer));
|
renderbuffer = xzalloc(sizeof(*renderbuffer));
|
||||||
|
|
||||||
renderbuffer->image =
|
renderbuffer->image =
|
||||||
@ -1155,13 +1152,18 @@ pixman_renderer_create_image_no_clear(struct weston_output *output,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pixman_region32_init(&renderbuffer->damage);
|
||||||
|
wl_list_insert(&po->renderbuffer_list, &renderbuffer->link);
|
||||||
|
|
||||||
return renderbuffer;
|
return renderbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pixman_renderer_renderbuffer_destroy(struct weston_renderbuffer *renderbuffer)
|
pixman_renderer_renderbuffer_destroy(struct weston_renderbuffer *renderbuffer)
|
||||||
{
|
{
|
||||||
|
wl_list_remove(&renderbuffer->link);
|
||||||
pixman_image_unref(renderbuffer->image);
|
pixman_image_unref(renderbuffer->image);
|
||||||
|
pixman_region32_fini(&renderbuffer->damage);
|
||||||
free(renderbuffer);
|
free(renderbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,10 +40,6 @@ struct pixman_renderer_output_options {
|
|||||||
struct weston_size fb_size;
|
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 {
|
struct pixman_renderer_interface {
|
||||||
int (*output_create)(struct weston_output *output,
|
int (*output_create)(struct weston_output *output,
|
||||||
const struct pixman_renderer_output_options *options);
|
const struct pixman_renderer_output_options *options);
|
||||||
|
Loading…
Reference in New Issue
Block a user