broadway: Reuse surfaces passed to server

This way we don't have to reopen all the time for pure updates,
and we can immediately unlink the shm file to avoid "leaking" them
on improper shutdown.
This commit is contained in:
Alexander Larsson 2013-03-29 09:50:59 +01:00
parent c6baa9bc25
commit e9b8b5c1f0

View File

@ -99,6 +99,9 @@ struct BroadwayWindow {
gint32 transient_for; gint32 transient_for;
cairo_surface_t *last_surface; cairo_surface_t *last_surface;
char *cached_surface_name;
cairo_surface_t *cached_surface;
}; };
static void broadway_server_resync_windows (BroadwayServer *server); static void broadway_server_resync_windows (BroadwayServer *server);
@ -1416,6 +1419,12 @@ broadway_server_destroy_window (BroadwayServer *server,
server->toplevels = g_list_remove (server->toplevels, window); server->toplevels = g_list_remove (server->toplevels, window);
g_hash_table_remove (server->id_ht, g_hash_table_remove (server->id_ht,
GINT_TO_POINTER (id)); GINT_TO_POINTER (id));
if (window->cached_surface_name != NULL)
g_free (window->cached_surface_name);
if (window->cached_surface != NULL)
cairo_surface_destroy (window->cached_surface);
g_free (window); g_free (window);
} }
} }
@ -1833,12 +1842,22 @@ broadway_server_open_surface (BroadwayServer *server,
int width, int width,
int height) int height)
{ {
BroadwayWindow *window;
ShmSurfaceData *data; ShmSurfaceData *data;
cairo_surface_t *surface; cairo_surface_t *surface;
gsize size; gsize size;
void *ptr; void *ptr;
int fd; int fd;
window = g_hash_table_lookup (server->id_ht,
GINT_TO_POINTER (id));
if (window == NULL)
return NULL;
if (window->cached_surface_name != NULL &&
strcmp (name, window->cached_surface_name) == 0)
return cairo_surface_reference (window->cached_surface);
size = width * height * sizeof (guint32); size = width * height * sizeof (guint32);
fd = shm_open(name, O_RDONLY, 0600); fd = shm_open(name, O_RDONLY, 0600);
@ -1848,9 +1867,11 @@ broadway_server_open_surface (BroadwayServer *server,
return NULL; return NULL;
} }
ptr = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0); ptr = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
(void) close(fd); (void) close(fd);
shm_unlink (name);
if (ptr == NULL) if (ptr == NULL)
return NULL; return NULL;
@ -1864,10 +1885,18 @@ broadway_server_open_surface (BroadwayServer *server,
width, height, width, height,
width * sizeof (guint32)); width * sizeof (guint32));
g_assert (surface != NULL); g_assert (surface != NULL);
cairo_surface_set_user_data (surface, &shm_cairo_key, cairo_surface_set_user_data (surface, &shm_cairo_key,
data, shm_data_unmap); data, shm_data_unmap);
if (window->cached_surface_name != NULL)
g_free (window->cached_surface_name);
window->cached_surface_name = g_strdup (name);
if (window->cached_surface != NULL)
cairo_surface_destroy (window->cached_surface);
window->cached_surface = cairo_surface_reference (surface);
return surface; return surface;
} }