renderers: Catch backend programming errors with asserts

Add asserts ensuring that outputs aren't created or destroyed twice
and that a valid pair of output/renderbuffer is passed to
repaint_output().

Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
This commit is contained in:
Loïc Molinari 2024-08-12 12:46:51 +02:00
parent 1656158d6d
commit e8dae983b7
2 changed files with 28 additions and 3 deletions

View file

@ -64,6 +64,9 @@ struct pixman_surface_state {
};
struct pixman_renderbuffer {
#if !defined(NDEBUG)
struct weston_output *output;
#endif
pixman_region32_t damage;
pixman_image_t *image;
bool stale;
@ -637,7 +640,8 @@ pixman_renderer_repaint_output(struct weston_output *output,
struct pixman_output_state *po = get_output_state(output);
struct pixman_renderbuffer *rb;
assert(renderbuffer);
assert(po);
assert(((struct pixman_renderbuffer *) renderbuffer)->output == output);
/* Accumulate damage in all renderbuffers */
wl_list_for_each(rb, &po->renderbuffer_list, link) {
@ -940,6 +944,9 @@ pixman_renderer_create_renderbuffer(struct weston_output *output,
return NULL;
}
#if !defined(NDEBUG)
renderbuffer->output = output;
#endif
pixman_region32_init(&renderbuffer->damage);
pixman_region32_copy(&renderbuffer->damage, &output->region);
renderbuffer->discarded_cb = discarded_cb;
@ -1185,6 +1192,8 @@ pixman_renderer_output_create(struct weston_output *output,
.height = options->fb_size.height
};
assert(!get_output_state(output));
po = zalloc(sizeof *po);
if (po == NULL)
return -1;
@ -1215,6 +1224,8 @@ pixman_renderer_output_destroy(struct weston_output *output)
{
struct pixman_output_state *po = get_output_state(output);
assert(po);
if (po->shadow_image)
pixman_image_unref(po->shadow_image);
@ -1227,6 +1238,7 @@ pixman_renderer_output_destroy(struct weston_output *output)
pixman_renderer_discard_renderbuffers(po, true);
free(po);
output->renderer_state = NULL;
}
static struct pixman_renderer_interface pixman_renderer_interface = {

View file

@ -122,6 +122,7 @@ struct gl_renderbuffer_dmabuf {
};
struct gl_renderbuffer {
struct weston_output *output;
enum gl_renderbuffer_type type;
pixman_region32_t damage;
enum gl_border_status border_damage;
@ -785,6 +786,7 @@ gl_renderbuffer_init(struct gl_renderbuffer *renderbuffer,
{
struct gl_output_state *go = get_output_state(output);
renderbuffer->output = output;
renderbuffer->type = type;
pixman_region32_init(&renderbuffer->damage);
pixman_region32_copy(&renderbuffer->damage, &output->region);
@ -2529,14 +2531,20 @@ gl_renderer_repaint_output(struct weston_output *output,
struct gl_renderer *gr = get_renderer(compositor);
static int errored;
struct weston_paint_node *pnode;
const int32_t area_y =
is_y_flipped(go) ? go->fb_size.height - go->area.height - go->area.y : go->area.y;
int32_t area_y;
struct gl_renderbuffer *rb;
assert(go);
assert(!renderbuffer ||
((struct gl_renderbuffer *) renderbuffer)->output == output);
assert(renderbuffer || go->egl_surface != EGL_NO_SURFACE);
assert(output->from_blend_to_output_by_backend ||
output->color_outcome->from_blend_to_output == NULL ||
shadow_exists(go));
area_y = is_y_flipped(go) ?
go->fb_size.height - go->area.height - go->area.y : go->area.y;
if (use_output(output) < 0)
return;
@ -4273,6 +4281,8 @@ gl_renderer_output_create(struct weston_output *output,
struct gl_renderer *gr = get_renderer(output->compositor);
const struct weston_testsuite_quirks *quirks;
assert(!get_output_state(output));
quirks = &output->compositor->test_data.test_quirks;
go = zalloc(sizeof *go);
@ -4441,6 +4451,8 @@ gl_renderer_output_destroy(struct weston_output *output)
struct gl_output_state *go = get_output_state(output);
struct timeline_render_point *trp, *tmp;
assert(go);
if (shadow_exists(go))
gl_fbo_texture_fini(&go->shadow_fb, &go->shadow_tex);
@ -4465,6 +4477,7 @@ gl_renderer_output_destroy(struct weston_output *output)
gl_renderer_discard_renderbuffers(go, true);
free(go);
output->renderer_state = NULL;
}
static int