summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2010-05-18 12:02:54 +0200
committerBenjamin Otte <otte@redhat.com>2010-05-18 13:43:27 +0200
commit050117996339cfe35add1f2cd44d0e5578d4a981 (patch)
tree437cd2a1544e6d4b06eddcf3b82441022381cdf2
parentc489f67d1d1d6079f9b58b726ed42beea1dfc44e (diff)
surface: Add _cairo_surface_release_device_reference() API
See the API documentation for that function about its intended purpose.
-rw-r--r--src/cairo-surface-private.h1
-rw-r--r--src/cairo-surface.c26
-rw-r--r--src/cairoint.h3
3 files changed, 29 insertions, 1 deletions
diff --git a/src/cairo-surface-private.h b/src/cairo-surface-private.h
index bc03119b..19a93c27 100644
--- a/src/cairo-surface-private.h
+++ b/src/cairo-surface-private.h
@@ -65,6 +65,7 @@ struct _cairo_surface {
unsigned finished : 1;
unsigned is_clear : 1;
unsigned has_font_options : 1;
+ unsigned owns_device : 1;
cairo_user_data_array_t user_data;
cairo_user_data_array_t mime_data;
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index cf7e0542..8b67e660 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -58,6 +58,7 @@ const cairo_surface_t name = { \
FALSE, /* finished */ \
TRUE, /* is_clear */ \
FALSE, /* has_font_options */ \
+ FALSE, /* owns_device */ \
{ 0, 0, 0, NULL, }, /* user_data */ \
{ 0, 0, 0, NULL, }, /* mime_data */ \
{ 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* device_transform */ \
@@ -356,6 +357,7 @@ _cairo_surface_init (cairo_surface_t *surface,
surface->unique_id = _cairo_surface_allocate_unique_id ();
surface->finished = FALSE;
surface->is_clear = FALSE;
+ surface->owns_device = (device != NULL);
_cairo_user_data_array_init (&surface->user_data);
_cairo_user_data_array_init (&surface->mime_data);
@@ -595,7 +597,8 @@ cairo_surface_destroy (cairo_surface_t *surface)
_cairo_user_data_array_fini (&surface->user_data);
_cairo_user_data_array_fini (&surface->mime_data);
- cairo_device_destroy (surface->device);
+ if (surface->owns_device)
+ cairo_device_destroy (surface->device);
free (surface);
}
@@ -673,6 +676,27 @@ cairo_surface_finish (cairo_surface_t *surface)
slim_hidden_def (cairo_surface_finish);
/**
+ * _cairo_surface_release_device_reference:
+ * @surface: a #cairo_surface_t
+ *
+ * This function makes @surface release the reference to its device. The
+ * function is intended to be used for avoiding cycling references for
+ * surfaces that are owned by their device, for example cache surfaces.
+ * Note that the @surface will still assume that the device is available.
+ * So it is the caller's responsibility to ensure the device stays around
+ * until the @surface is destroyed. Just calling cairo_surface_finish() is
+ * not enough.
+ **/
+void
+_cairo_surface_release_device_reference (cairo_surface_t *surface)
+{
+ assert (surface->owns_device);
+
+ cairo_device_destroy (surface->device);
+ surface->owns_device = FALSE;
+}
+
+/**
* cairo_surface_get_user_data:
* @surface: a #cairo_surface_t
* @key: the address of the #cairo_user_data_key_t the user data was
diff --git a/src/cairoint.h b/src/cairoint.h
index b52db6d5..1f8643d2 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2119,6 +2119,9 @@ _cairo_surface_set_device_scale (cairo_surface_t *surface,
cairo_private cairo_bool_t
_cairo_surface_has_device_transform (cairo_surface_t *surface) cairo_pure;
+cairo_private void
+_cairo_surface_release_device_reference (cairo_surface_t *surface);
+
/* cairo-image-surface.c */
/* XXX: In cairo 1.2.0 we added a new %CAIRO_FORMAT_RGB16_565 but