pixman-renderer: hold a reference for renderbuffers on the output state list
Now that struct weston_renderbuffer is refcounted, hold a reference for renderbuffers on the pixman_output_state::renderbuffer_list. This allows backends to destroy the renderer output state and release renderbuffer references in any order without running into an assert(). To avoid breaking resizing, We also have to drop the renderbuffer list during pixman_renderer_resize_output(). The backends have to create new renderbuffers afterwards. Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
This commit is contained in:
parent
2acd2c7489
commit
07734a2564
@ -920,6 +920,7 @@ pixman_renderer_resize_output(struct weston_output *output,
|
|||||||
const struct weston_geometry *area)
|
const struct weston_geometry *area)
|
||||||
{
|
{
|
||||||
struct pixman_output_state *po = get_output_state(output);
|
struct pixman_output_state *po = get_output_state(output);
|
||||||
|
struct pixman_renderbuffer *renderbuffer, *tmp;
|
||||||
|
|
||||||
check_compositing_area(fb_size, area);
|
check_compositing_area(fb_size, area);
|
||||||
|
|
||||||
@ -934,6 +935,11 @@ pixman_renderer_resize_output(struct weston_output *output,
|
|||||||
|
|
||||||
pixman_renderer_output_set_buffer(output, NULL);
|
pixman_renderer_output_set_buffer(output, NULL);
|
||||||
|
|
||||||
|
wl_list_for_each_safe(renderbuffer, tmp, &po->renderbuffer_list, link) {
|
||||||
|
wl_list_remove(&renderbuffer->link);
|
||||||
|
weston_renderbuffer_unref(&renderbuffer->base);
|
||||||
|
}
|
||||||
|
|
||||||
po->fb_size = *fb_size;
|
po->fb_size = *fb_size;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1100,14 +1106,14 @@ pixman_renderer_output_create(struct weston_output *output,
|
|||||||
if (options->use_shadow)
|
if (options->use_shadow)
|
||||||
po->shadow_format = pixel_format_get_info(DRM_FORMAT_XRGB8888);
|
po->shadow_format = pixel_format_get_info(DRM_FORMAT_XRGB8888);
|
||||||
|
|
||||||
|
wl_list_init(&po->renderbuffer_list);
|
||||||
|
|
||||||
if (!pixman_renderer_resize_output(output, &options->fb_size, &area)) {
|
if (!pixman_renderer_resize_output(output, &options->fb_size, &area)) {
|
||||||
output->renderer_state = NULL;
|
output->renderer_state = NULL;
|
||||||
free(po);
|
free(po);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_list_init(&po->renderbuffer_list);
|
|
||||||
|
|
||||||
weston_output_update_capture_info(output,
|
weston_output_update_capture_info(output,
|
||||||
WESTON_OUTPUT_CAPTURE_SOURCE_FRAMEBUFFER,
|
WESTON_OUTPUT_CAPTURE_SOURCE_FRAMEBUFFER,
|
||||||
area.width, area.height,
|
area.width, area.height,
|
||||||
@ -1120,6 +1126,7 @@ static void
|
|||||||
pixman_renderer_output_destroy(struct weston_output *output)
|
pixman_renderer_output_destroy(struct weston_output *output)
|
||||||
{
|
{
|
||||||
struct pixman_output_state *po = get_output_state(output);
|
struct pixman_output_state *po = get_output_state(output);
|
||||||
|
struct pixman_renderbuffer *renderbuffer, *tmp;
|
||||||
|
|
||||||
if (po->shadow_image)
|
if (po->shadow_image)
|
||||||
pixman_image_unref(po->shadow_image);
|
pixman_image_unref(po->shadow_image);
|
||||||
@ -1130,7 +1137,10 @@ 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));
|
wl_list_for_each_safe(renderbuffer, tmp, &po->renderbuffer_list, link) {
|
||||||
|
wl_list_remove(&renderbuffer->link);
|
||||||
|
weston_renderbuffer_unref(&renderbuffer->base);
|
||||||
|
}
|
||||||
|
|
||||||
free(po);
|
free(po);
|
||||||
}
|
}
|
||||||
@ -1160,7 +1170,7 @@ pixman_renderer_create_image_from_ptr(struct weston_output *output,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pixman_region32_init(&renderbuffer->base.damage);
|
pixman_region32_init(&renderbuffer->base.damage);
|
||||||
renderbuffer->base.refcount = 1;
|
renderbuffer->base.refcount = 2;
|
||||||
renderbuffer->base.destroy = pixman_renderer_renderbuffer_destroy;
|
renderbuffer->base.destroy = pixman_renderer_renderbuffer_destroy;
|
||||||
wl_list_insert(&po->renderbuffer_list, &renderbuffer->link);
|
wl_list_insert(&po->renderbuffer_list, &renderbuffer->link);
|
||||||
|
|
||||||
@ -1188,7 +1198,7 @@ pixman_renderer_create_image(struct weston_output *output,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pixman_region32_init(&renderbuffer->base.damage);
|
pixman_region32_init(&renderbuffer->base.damage);
|
||||||
renderbuffer->base.refcount = 1;
|
renderbuffer->base.refcount = 2;
|
||||||
renderbuffer->base.destroy = pixman_renderer_renderbuffer_destroy;
|
renderbuffer->base.destroy = pixman_renderer_renderbuffer_destroy;
|
||||||
wl_list_insert(&po->renderbuffer_list, &renderbuffer->link);
|
wl_list_insert(&po->renderbuffer_list, &renderbuffer->link);
|
||||||
|
|
||||||
@ -1201,7 +1211,6 @@ pixman_renderer_renderbuffer_destroy(struct weston_renderbuffer *renderbuffer)
|
|||||||
struct pixman_renderbuffer *rb;
|
struct pixman_renderbuffer *rb;
|
||||||
|
|
||||||
rb = container_of(renderbuffer, struct pixman_renderbuffer, base);
|
rb = container_of(renderbuffer, struct pixman_renderbuffer, base);
|
||||||
wl_list_remove(&rb->link);
|
|
||||||
pixman_image_unref(rb->image);
|
pixman_image_unref(rb->image);
|
||||||
pixman_region32_fini(&rb->base.damage);
|
pixman_region32_fini(&rb->base.damage);
|
||||||
free(rb);
|
free(rb);
|
||||||
|
Loading…
Reference in New Issue
Block a user