forked from AuroraMiddleware/gtk
[broadway] Ensure gdk_ref_cairo_surface object can be destroyed
If we return a direct ref that is not possible, since we own a ref to it. This is problematic as the gdkwindow.c code uses destruction to track outstanding surfaces. We fix this by returning a subsurface.
This commit is contained in:
parent
f02b7c9ed2
commit
db288f3233
@ -67,11 +67,18 @@ _gdk_broadway_drawable_finish (GdkDrawable *drawable)
|
|||||||
{
|
{
|
||||||
GdkDrawableImplBroadway *impl = GDK_DRAWABLE_IMPL_BROADWAY (drawable);
|
GdkDrawableImplBroadway *impl = GDK_DRAWABLE_IMPL_BROADWAY (drawable);
|
||||||
|
|
||||||
|
if (impl->ref_surface)
|
||||||
|
{
|
||||||
|
cairo_surface_finish (impl->ref_surface);
|
||||||
|
cairo_surface_set_user_data (impl->ref_surface, &gdk_broadway_cairo_key,
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (impl->surface)
|
if (impl->surface)
|
||||||
{
|
{
|
||||||
cairo_surface_finish (impl->surface);
|
cairo_surface_destroy (impl->surface);
|
||||||
impl->surface = NULL;
|
impl->surface = NULL;
|
||||||
cairo_surface_finish (impl->last_surface);
|
cairo_surface_destroy (impl->last_surface);
|
||||||
impl->last_surface = NULL;
|
impl->last_surface = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,8 +110,8 @@ _gdk_broadway_drawable_update_size (GdkDrawable *drawable)
|
|||||||
|
|
||||||
/* TODO: copy old contents */
|
/* TODO: copy old contents */
|
||||||
|
|
||||||
cairo_surface_finish (old);
|
cairo_surface_destroy (old);
|
||||||
cairo_surface_finish (last_old);
|
cairo_surface_destroy (last_old);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,6 +119,14 @@ _gdk_broadway_drawable_update_size (GdkDrawable *drawable)
|
|||||||
* Broadway specific implementations of generic functions *
|
* Broadway specific implementations of generic functions *
|
||||||
*****************************************************/
|
*****************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_broadway_cairo_surface_destroy (void *data)
|
||||||
|
{
|
||||||
|
GdkDrawableImplBroadway *impl = data;
|
||||||
|
|
||||||
|
impl->ref_surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
gdk_broadway_ref_cairo_surface (GdkDrawable *drawable)
|
gdk_broadway_ref_cairo_surface (GdkDrawable *drawable)
|
||||||
{
|
{
|
||||||
@ -123,10 +138,12 @@ gdk_broadway_ref_cairo_surface (GdkDrawable *drawable)
|
|||||||
GDK_WINDOW_DESTROYED (impl->wrapper))
|
GDK_WINDOW_DESTROYED (impl->wrapper))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
w = gdk_window_get_width (impl->wrapper);
|
||||||
|
h = gdk_window_get_height (impl->wrapper);
|
||||||
|
|
||||||
|
/* Create actual backing store if missing */
|
||||||
if (!impl->surface)
|
if (!impl->surface)
|
||||||
{
|
{
|
||||||
w = gdk_window_get_width (impl->wrapper);
|
|
||||||
h = gdk_window_get_height (impl->wrapper);
|
|
||||||
impl->surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h);
|
impl->surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h);
|
||||||
impl->last_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h);
|
impl->last_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h);
|
||||||
|
|
||||||
@ -143,5 +160,19 @@ gdk_broadway_ref_cairo_surface (GdkDrawable *drawable)
|
|||||||
cairo_destroy (cr);
|
cairo_destroy (cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cairo_surface_reference (impl->surface);
|
/* Create a destroyable surface referencing the real one */
|
||||||
|
if (!impl->ref_surface)
|
||||||
|
{
|
||||||
|
impl->ref_surface =
|
||||||
|
cairo_surface_create_for_rectangle (impl->surface,
|
||||||
|
0, 0,
|
||||||
|
w, h);
|
||||||
|
if (impl->ref_surface)
|
||||||
|
cairo_surface_set_user_data (impl->ref_surface, &gdk_broadway_cairo_key,
|
||||||
|
drawable, gdk_broadway_cairo_surface_destroy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cairo_surface_reference (impl->ref_surface);
|
||||||
|
|
||||||
|
return impl->ref_surface;
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ struct _GdkDrawableImplBroadway
|
|||||||
GdkScreen *screen;
|
GdkScreen *screen;
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
cairo_surface_t *last_surface;
|
cairo_surface_t *last_surface;
|
||||||
|
cairo_surface_t *ref_surface;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GdkDrawableImplBroadwayClass
|
struct _GdkDrawableImplBroadwayClass
|
||||||
|
@ -230,9 +230,9 @@ _gdk_broadway_window_destroy (GdkWindow *window,
|
|||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
gdk_window_broadway_resize_cairo_surface (GdkWindow *window,
|
gdk_window_broadway_resize_cairo_surface (GdkWindow *window,
|
||||||
cairo_surface_t *surface,
|
cairo_surface_t *surface,
|
||||||
gint width,
|
gint width,
|
||||||
gint height)
|
gint height)
|
||||||
{
|
{
|
||||||
/* Image surfaces cannot be resized */
|
/* Image surfaces cannot be resized */
|
||||||
cairo_surface_destroy (surface);
|
cairo_surface_destroy (surface);
|
||||||
|
Loading…
Reference in New Issue
Block a user