summaryrefslogtreecommitdiff
path: root/src/cairo-xcb-shm.c
diff options
context:
space:
mode:
authorUli Schlachter <psychon@znc.in>2011-09-01 13:34:43 +0200
committerUli Schlachter <psychon@znc.in>2011-09-02 15:21:20 +0200
commit968eb30bba1dc942ccd31e4450fdd3bb74c83cb6 (patch)
tree127a02b29ef399f4a33dafd6fb2a5d773c80608e /src/cairo-xcb-shm.c
parentea5255653176dfab0fdfe78a3186587b01559735 (diff)
downloadcairo-968eb30bba1dc942ccd31e4450fdd3bb74c83cb6.tar.gz
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>
Diffstat (limited to 'src/cairo-xcb-shm.c')
-rw-r--r--src/cairo-xcb-shm.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/cairo-xcb-shm.c b/src/cairo-xcb-shm.c
index ffcaec8f1..6972720b0 100644
--- a/src/cairo-xcb-shm.c
+++ b/src/cairo-xcb-shm.c
@@ -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;