summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-05-06 10:46:49 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-05-06 10:46:49 +0100
commit88986fdbef795c61cd60231046663d3cd80b4947 (patch)
treee5202d37e53ff28ea84a6c1f51e7d490dad66bcd
parent632fabc77d89254e2e6915148fa870f23c2a5722 (diff)
xlib: Remove reference counting for cairo_xlib_screen_t
The screen is owned by the cairo_xlib_display_t device, so we can simplify and close the refleak by removing the surplus reference counting.
-rw-r--r--src/cairo-xlib-display.c84
-rw-r--r--src/cairo-xlib-private.h22
-rw-r--r--src/cairo-xlib-screen.c47
-rw-r--r--src/cairo-xlib-surface.c38
-rw-r--r--src/cairo-xlib-visual.c2
5 files changed, 46 insertions, 147 deletions
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index afa75327..a86c2062 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -73,10 +73,10 @@ _cairo_xlib_remove_close_display_hook_internal (cairo_xlib_display_t *display,
static void
_cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display)
{
- cairo_xlib_screen_t *screen;
- cairo_xlib_hook_t *hook;
+ cairo_xlib_screen_t *screen;
+ cairo_xlib_hook_t *hook;
- for (screen = display->screens; screen != NULL; screen = screen->next)
+ cairo_list_foreach_entry (screen, cairo_xlib_screen_t, &display->screens, link)
_cairo_xlib_screen_close_display (display, screen);
while (TRUE) {
@@ -92,22 +92,6 @@ _cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display)
}
static void
-_cairo_xlib_display_discard_screens (cairo_xlib_display_t *display)
-{
- cairo_xlib_screen_t *screens;
-
- screens = display->screens;
- display->screens = NULL;
-
- while (screens != NULL) {
- cairo_xlib_screen_t *screen = screens;
- screens = screen->next;
-
- _cairo_xlib_screen_destroy (screen);
- }
-}
-
-static void
_cairo_xlib_display_finish (void *abstract_display)
{
cairo_xlib_display_t *display = abstract_display;
@@ -132,6 +116,12 @@ _cairo_xlib_display_destroy (void *abstract_display)
}
_cairo_freelist_fini (&display->wq_freelist);
+ while (! cairo_list_is_empty (&display->screens)) {
+ _cairo_xlib_screen_destroy (cairo_list_first_entry (&display->screens,
+ cairo_xlib_screen_t,
+ link));
+ }
+
free (display);
}
@@ -216,7 +206,6 @@ _cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
_cairo_xlib_display_notify (display);
_cairo_xlib_call_close_display_hooks (display);
- _cairo_xlib_display_discard_screens (display);
/* catch any that arrived before marking the display as closed */
_cairo_xlib_display_notify (display);
@@ -353,7 +342,7 @@ _cairo_xlib_device_create (Display *dpy)
cairo_device_reference (&display->base); /* add one for the CloseDisplay */
display->display = dpy;
- display->screens = NULL;
+ cairo_list_init (&display->screens);
display->workqueue = NULL;
display->close_display_hooks = NULL;
display->closed = FALSE;
@@ -610,56 +599,21 @@ _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t *display,
return xrender_format;
}
-void
-_cairo_xlib_display_remove_screen (cairo_xlib_display_t *display,
- cairo_xlib_screen_t *screen)
-{
- cairo_xlib_screen_t **prev;
- cairo_xlib_screen_t *list;
-
- for (prev = &display->screens; (list = *prev); prev = &list->next) {
- if (list == screen) {
- *prev = screen->next;
- break;
- }
- }
-}
-
-cairo_status_t
+cairo_xlib_screen_t *
_cairo_xlib_display_get_screen (cairo_xlib_display_t *display,
- Screen *screen,
- cairo_xlib_screen_t **out)
+ Screen *screen)
{
- cairo_xlib_screen_t *info = NULL, **prev;
-
- if (display->closed)
- return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+ cairo_xlib_screen_t *info;
- for (prev = &display->screens; (info = *prev); prev = &(*prev)->next) {
+ cairo_list_foreach_entry (info, cairo_xlib_screen_t, &display->screens, link) {
if (info->screen == screen) {
- /*
- * MRU the list
- */
- if (prev != &display->screens) {
- *prev = info->next;
- info->next = display->screens;
- display->screens = info;
- }
- break;
- }
+ if (display->screens.next != &info->link)
+ cairo_list_move (&info->link, &display->screens);
+ return info;
+ }
}
- *out = info;
- return CAIRO_STATUS_SUCCESS;
-}
-
-
-void
-_cairo_xlib_display_add_screen (cairo_xlib_display_t *display,
- cairo_xlib_screen_t *screen)
-{
- screen->next = display->screens;
- display->screens = screen;
+ return NULL;
}
void
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index 345f3e13..24bf5e32 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -71,7 +71,7 @@ struct _cairo_xlib_display {
cairo_xlib_display_t *next;
Display *display;
- cairo_xlib_screen_t *screens;
+ cairo_list_t screens;
int render_major;
int render_minor;
@@ -98,8 +98,7 @@ typedef struct _cairo_xlib_visual_info {
} cairo_xlib_visual_info_t;
struct _cairo_xlib_screen {
- cairo_xlib_screen_t *next;
- cairo_reference_count_t ref_count;
+ cairo_list_t link;
cairo_device_t *device;
Screen *screen;
@@ -116,18 +115,9 @@ struct _cairo_xlib_screen {
cairo_private cairo_device_t *
_cairo_xlib_device_create (Display *display);
-cairo_private void
-_cairo_xlib_display_add_screen (cairo_xlib_display_t *display,
- cairo_xlib_screen_t *screen);
-
-cairo_private cairo_status_t
+cairo_private cairo_xlib_screen_t *
_cairo_xlib_display_get_screen (cairo_xlib_display_t *display,
- Screen *screen,
- cairo_xlib_screen_t **out);
-
-cairo_private void
-_cairo_xlib_display_remove_screen (cairo_xlib_display_t *display,
- cairo_xlib_screen_t *screen);
+ Screen *screen);
cairo_private void
_cairo_xlib_add_close_display_hook (cairo_xlib_display_t *display, cairo_xlib_hook_t *hook);
@@ -170,8 +160,6 @@ _cairo_xlib_screen_get (Display *dpy,
Screen *screen,
cairo_xlib_screen_t **out);
-cairo_private cairo_xlib_screen_t *
-_cairo_xlib_screen_reference (cairo_xlib_screen_t *info);
cairo_private void
_cairo_xlib_screen_destroy (cairo_xlib_screen_t *info);
@@ -207,6 +195,6 @@ _cairo_xlib_visual_info_create (Display *dpy,
cairo_xlib_visual_info_t **out);
cairo_private void
-_cairo_xlib_visual_info_destroy (Display *dpy, cairo_xlib_visual_info_t *info);
+_cairo_xlib_visual_info_destroy (cairo_xlib_visual_info_t *info);
#endif /* CAIRO_XLIB_PRIVATE_H */
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index d1d9cf6c..b094eaf4 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -256,16 +256,6 @@ _cairo_xlib_init_screen_font_options (Display *dpy,
cairo_font_options_set_hint_metrics (&info->font_options, CAIRO_HINT_METRICS_ON);
}
-cairo_xlib_screen_t *
-_cairo_xlib_screen_reference (cairo_xlib_screen_t *info)
-{
- assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count));
-
- _cairo_reference_count_inc (&info->ref_count);
-
- return info;
-}
-
void
_cairo_xlib_screen_close_display (cairo_xlib_display_t *display,
cairo_xlib_screen_t *info)
@@ -274,37 +264,25 @@ _cairo_xlib_screen_close_display (cairo_xlib_display_t *display,
int i;
dpy = display->display;
+
for (i = 0; i < ARRAY_LENGTH (info->gc); i++) {
if ((info->gc_depths >> (8*i)) & 0xff)
XFreeGC (dpy, info->gc[i]);
}
info->gc_depths = 0;
-
- while (! cairo_list_is_empty (&info->visuals)) {
- _cairo_xlib_visual_info_destroy (dpy,
- cairo_list_first_entry (&info->visuals,
- cairo_xlib_visual_info_t,
- link));
- }
}
void
_cairo_xlib_screen_destroy (cairo_xlib_screen_t *info)
{
- cairo_xlib_display_t *display;
-
- assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count));
-
- if (! _cairo_reference_count_dec_and_test (&info->ref_count))
- return;
-
- if (! _cairo_xlib_display_acquire (info->device, &display)) {
- _cairo_xlib_display_remove_screen (display, info);
- _cairo_xlib_screen_close_display (display, info);
-
- cairo_device_release (&display->base);
+ while (! cairo_list_is_empty (&info->visuals)) {
+ _cairo_xlib_visual_info_destroy (cairo_list_first_entry (&info->visuals,
+ cairo_xlib_visual_info_t,
+ link));
}
+ cairo_list_del (&info->link);
+
free (info);
}
@@ -327,12 +305,9 @@ _cairo_xlib_screen_get (Display *dpy,
if (unlikely (status))
goto CLEANUP_DEVICE;
- status = _cairo_xlib_display_get_screen (display, screen, &info);
- if (unlikely (status))
- goto CLEANUP_DISPLAY;
-
+ info = _cairo_xlib_display_get_screen (display, screen);
if (info != NULL) {
- *out = _cairo_xlib_screen_reference (info);
+ *out = info;
goto CLEANUP_DISPLAY;
}
@@ -342,7 +317,6 @@ _cairo_xlib_screen_get (Display *dpy,
goto CLEANUP_DISPLAY;
}
- CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */
info->device = device;
info->screen = screen;
info->has_font_options = FALSE;
@@ -350,8 +324,7 @@ _cairo_xlib_screen_get (Display *dpy,
memset (info->gc, 0, sizeof (info->gc));
cairo_list_init (&info->visuals);
-
- _cairo_xlib_display_add_screen (display, info);
+ cairo_list_add (&info->link, &display->screens);
*out = info;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index fa7d6452..3b01fdeb 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -415,8 +415,6 @@ _cairo_xlib_surface_finish (void *abstract_surface)
cairo_device_release (&display->base);
- _cairo_xlib_screen_destroy (surface->screen);
-
cairo_region_destroy (surface->clip_region);
return status;
@@ -2947,8 +2945,6 @@ _cairo_xlib_surface_create_internal (cairo_xlib_screen_t *screen,
cairo_xlib_surface_t *surface;
cairo_xlib_display_t *display;
cairo_status_t status;
-
- CAIRO_MUTEX_INITIALIZE ();
if (depth == 0) {
if (xrender_format) {
@@ -3019,7 +3015,7 @@ found:
surface->close_display_hook.func = _cairo_xlib_surface_detach_display;
_cairo_xlib_add_close_display_hook (display,
&surface->close_display_hook);
-
+
cairo_device_release (&display->base);
_cairo_surface_init (&surface->base,
@@ -3027,7 +3023,7 @@ found:
screen->device,
_xrender_format_to_content (xrender_format));
- surface->screen = _cairo_xlib_screen_reference (screen);
+ surface->screen = screen;
surface->drawable = drawable;
surface->owns_pixmap = FALSE;
@@ -3161,7 +3157,6 @@ cairo_xlib_surface_create (Display *dpy,
{
Screen *scr;
cairo_xlib_screen_t *screen;
- cairo_surface_t *surface;
cairo_status_t status;
if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX) {
@@ -3179,12 +3174,9 @@ cairo_xlib_surface_create (Display *dpy,
X_DEBUG ((dpy, "create (drawable=%x)", (unsigned int) drawable));
- surface = _cairo_xlib_surface_create_internal (screen, drawable,
- visual, NULL,
- width, height, 0);
- _cairo_xlib_screen_destroy (screen);
-
- return surface;
+ return _cairo_xlib_surface_create_internal (screen, drawable,
+ visual, NULL,
+ width, height, 0);
}
slim_hidden_def (cairo_xlib_surface_create);
@@ -3209,7 +3201,6 @@ cairo_xlib_surface_create_for_bitmap (Display *dpy,
int height)
{
cairo_xlib_screen_t *screen;
- cairo_surface_t *surface;
cairo_status_t status;
if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
@@ -3221,12 +3212,9 @@ cairo_xlib_surface_create_for_bitmap (Display *dpy,
X_DEBUG ((dpy, "create_for_bitmap (drawable=%x)", (unsigned int) bitmap));
- surface = _cairo_xlib_surface_create_internal (screen, bitmap,
- NULL, NULL,
- width, height, 1);
- _cairo_xlib_screen_destroy (screen);
-
- return surface;
+ return _cairo_xlib_surface_create_internal (screen, bitmap,
+ NULL, NULL,
+ width, height, 1);
}
#if CAIRO_HAS_XLIB_XRENDER_SURFACE
@@ -3259,7 +3247,6 @@ cairo_xlib_surface_create_with_xrender_format (Display *dpy,
int height)
{
cairo_xlib_screen_t *screen;
- cairo_surface_t *surface;
cairo_status_t status;
if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
@@ -3271,12 +3258,9 @@ cairo_xlib_surface_create_with_xrender_format (Display *dpy,
X_DEBUG ((dpy, "create_with_xrender_format (drawable=%x)", (unsigned int) drawable));
- surface = _cairo_xlib_surface_create_internal (screen, drawable,
- NULL, format,
- width, height, 0);
- _cairo_xlib_screen_destroy (screen);
-
- return surface;
+ return _cairo_xlib_surface_create_internal (screen, drawable,
+ NULL, format,
+ width, height, 0);
}
slim_hidden_def (cairo_xlib_surface_create_with_xrender_format);
diff --git a/src/cairo-xlib-visual.c b/src/cairo-xlib-visual.c
index a76bf357..e076ed01 100644
--- a/src/cairo-xlib-visual.c
+++ b/src/cairo-xlib-visual.c
@@ -180,7 +180,7 @@ _cairo_xlib_visual_info_create (Display *dpy,
}
void
-_cairo_xlib_visual_info_destroy (Display *dpy, cairo_xlib_visual_info_t *info)
+_cairo_xlib_visual_info_destroy (cairo_xlib_visual_info_t *info)
{
/* No need for XFreeColors() whilst using DefaultColormap */
free (info);