mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-20 23:20:10 +01:00
xcb: Steal from the pending list for GetImage
Before using some piece of SHM again, we must be sure that the X11 server is no longer working with it. For this, we send a GetInputFocus when we are done with the SHM locally and will only use the memory again when the reply comes in. However, if we are allocating the memory for SHM GetImage, then we can re-use memory earlier, because the server processes requests in order. So it will only start writing to the memory after it is done with earlier requests for this memory. So instead of using GetInputFocus for synchronisation, the SHM GetImage request will automatically do this for us. Thanks to Chris Wilson for this idea. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
ea52556531
commit
968eb30bba
4 changed files with 25 additions and 2 deletions
|
|
@ -77,6 +77,7 @@ struct _cairo_xcb_shm_info {
|
|||
cairo_xcb_connection_t *connection;
|
||||
uint32_t shm;
|
||||
uint32_t offset;
|
||||
size_t size;
|
||||
void *mem;
|
||||
cairo_xcb_shm_mem_pool_t *pool;
|
||||
xcb_get_input_focus_cookie_t sync;
|
||||
|
|
@ -307,6 +308,7 @@ _cairo_xcb_connection_destroy (cairo_xcb_connection_t *connection)
|
|||
cairo_private cairo_int_status_t
|
||||
_cairo_xcb_connection_allocate_shm_info (cairo_xcb_connection_t *display,
|
||||
size_t size,
|
||||
cairo_bool_t might_reuse,
|
||||
cairo_xcb_shm_info_t **shm_info_out);
|
||||
|
||||
cairo_private void
|
||||
|
|
|
|||
|
|
@ -492,6 +492,7 @@ _cairo_xcb_shm_process_pending (cairo_xcb_connection_t *connection, shm_wait_typ
|
|||
cairo_int_status_t
|
||||
_cairo_xcb_connection_allocate_shm_info (cairo_xcb_connection_t *connection,
|
||||
size_t size,
|
||||
cairo_bool_t might_reuse,
|
||||
cairo_xcb_shm_info_t **shm_info_out)
|
||||
{
|
||||
cairo_xcb_shm_info_t *shm_info;
|
||||
|
|
@ -506,6 +507,22 @@ _cairo_xcb_connection_allocate_shm_info (cairo_xcb_connection_t *connection,
|
|||
CAIRO_MUTEX_LOCK (connection->shm_mutex);
|
||||
_cairo_xcb_shm_process_pending (connection, PENDING_POLL);
|
||||
|
||||
if (might_reuse) {
|
||||
cairo_list_foreach_entry (shm_info, cairo_xcb_shm_info_t,
|
||||
&connection->shm_pending, pending) {
|
||||
if (shm_info->size >= size) {
|
||||
cairo_list_del (&shm_info->pending);
|
||||
CAIRO_MUTEX_UNLOCK (connection->shm_mutex);
|
||||
|
||||
xcb_discard_reply (connection->xcb_connection, shm_info->sync.sequence);
|
||||
shm_info->sync.sequence = XCB_NONE;
|
||||
|
||||
*shm_info_out = shm_info;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cairo_list_foreach_entry_safe (pool, next, cairo_xcb_shm_mem_pool_t,
|
||||
&connection->shm_pools, link)
|
||||
{
|
||||
|
|
@ -599,6 +616,7 @@ _cairo_xcb_connection_allocate_shm_info (cairo_xcb_connection_t *connection,
|
|||
shm_info->connection = connection;
|
||||
shm_info->pool = pool;
|
||||
shm_info->shm = pool->shmseg;
|
||||
shm_info->size = size;
|
||||
shm_info->offset = (char *) mem - (char *) pool->base;
|
||||
shm_info->mem = mem;
|
||||
shm_info->sync.sequence = XCB_NONE;
|
||||
|
|
|
|||
|
|
@ -164,8 +164,8 @@ _cairo_xcb_shm_image_create_shm (cairo_xcb_connection_t *connection,
|
|||
if (size <= CAIRO_XCB_SHM_SMALL_IMAGE)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
status = _cairo_xcb_connection_allocate_shm_info (connection,
|
||||
size, &shm_info);
|
||||
status = _cairo_xcb_connection_allocate_shm_info (connection, size,
|
||||
FALSE, &shm_info);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
|
|
|
|||
|
|
@ -221,6 +221,7 @@ static cairo_surface_t *
|
|||
_cairo_xcb_surface_create_shm_image (cairo_xcb_connection_t *connection,
|
||||
pixman_format_code_t pixman_format,
|
||||
int width, int height,
|
||||
cairo_bool_t might_reuse,
|
||||
cairo_xcb_shm_info_t **shm_info_out)
|
||||
{
|
||||
cairo_surface_t *image;
|
||||
|
|
@ -234,6 +235,7 @@ _cairo_xcb_surface_create_shm_image (cairo_xcb_connection_t *connection,
|
|||
PIXMAN_FORMAT_BPP (pixman_format));
|
||||
status = _cairo_xcb_connection_allocate_shm_info (connection,
|
||||
stride * height,
|
||||
might_reuse,
|
||||
&shm_info);
|
||||
if (unlikely (status))
|
||||
return _cairo_surface_create_in_error (status);
|
||||
|
|
@ -278,6 +280,7 @@ _get_shm_image (cairo_xcb_surface_t *surface,
|
|||
image = _cairo_xcb_surface_create_shm_image (surface->connection,
|
||||
surface->pixman_format,
|
||||
width, height,
|
||||
TRUE,
|
||||
&shm_info);
|
||||
if (unlikely (image == NULL || image->status))
|
||||
goto done;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue