From 9ca6abd424c7f1a3c24dc5f4c021eed75613a3ae Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 18 Jun 2021 09:36:13 -0400 Subject: [PATCH] vl/dri3: Don't leak regions on the X server I can't tell from a quick read whether this clip region is actually just the bounding box so could be skipped entirely. But the old code never destroyed it, which means we'd leak a couple hundred bytes on the X server side for every SwapBuffers until the client dies of XID exhaustion, which is somewhere north of 2GB for typical systems so you may or may not just run out of memory first. Create the region at swap time and stash it in the drawable state. Reviewed-By: Mike Blumenkrantz Part-of: --- src/gallium/auxiliary/vl/vl_winsys_dri3.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/gallium/auxiliary/vl/vl_winsys_dri3.c b/src/gallium/auxiliary/vl/vl_winsys_dri3.c index 1866dbc413e..f7cd4c1f1a4 100644 --- a/src/gallium/auxiliary/vl/vl_winsys_dri3.c +++ b/src/gallium/auxiliary/vl/vl_winsys_dri3.c @@ -55,6 +55,7 @@ struct vl_dri3_buffer struct pipe_resource *linear_texture; uint32_t pixmap; + uint32_t region; uint32_t sync_fence; struct xshmfence *shm_fence; @@ -107,6 +108,8 @@ static void dri3_free_back_buffer(struct vl_dri3_screen *scrn, struct vl_dri3_buffer *buffer) { + if (buffer->region) + xcb_xfixes_destroy_region(scrn->conn, buffer->region); xcb_free_pixmap(scrn->conn, buffer->pixmap); xcb_sync_destroy_fence(scrn->conn, buffer->sync_fence); xshmfence_unmap_shm(buffer->shm_fence); @@ -564,7 +567,6 @@ vl_dri3_flush_frontbuffer(struct pipe_screen *screen, uint32_t options = XCB_PRESENT_OPTION_NONE; struct vl_dri3_buffer *back; struct pipe_box src_box; - xcb_xfixes_region_t region; xcb_rectangle_t rectangle; back = scrn->back_buffers[scrn->cur_back]; @@ -580,8 +582,11 @@ vl_dri3_flush_frontbuffer(struct pipe_screen *screen, rectangle.width = (scrn->output_texture) ? scrn->clip_width : scrn->width; rectangle.height = (scrn->output_texture) ? scrn->clip_height : scrn->height; - region = xcb_generate_id(scrn->conn); - xcb_xfixes_create_region(scrn->conn, region, 2, &rectangle); + if (!back->region) { + back->region = xcb_generate_id(scrn->conn); + xcb_xfixes_create_region(scrn->conn, back->region, 0, NULL); + } + xcb_xfixes_set_region(scrn->conn, back->region, 1, &rectangle); if (scrn->is_different_gpu) { u_box_origin_2d(back->width, back->height, &src_box); @@ -600,7 +605,7 @@ vl_dri3_flush_frontbuffer(struct pipe_screen *screen, scrn->drawable, back->pixmap, (uint32_t)(++scrn->send_sbc), - 0, region, 0, 0, + 0, back->region, 0, 0, None, None, back->sync_fence, options,