forked from AuroraMiddleware/gtk
win32: always recreate the cairo surface if requested to do so
When _gdk_windowing_create_cairo_surface() gets called, we should always create a fully new cairo surface, instead of just referencing the available one, which may already be finished (i.e. in CAIRO_STATUS_SURFACE_FINISHED state). A new user_data key is added to the surface to explicitly release the acquired DC when the surface is destroyed, independent to the user_data key added to clear the impl->user_data pointer. https://bugzilla.gnome.org/show_bug.cgi?id=695636
This commit is contained in:
parent
d33c1cf412
commit
4ecbef0791
@ -144,6 +144,7 @@ static GdkVisual* gdk_win32_get_visual (GdkDrawable *drawable);
|
|||||||
static void gdk_drawable_impl_win32_finalize (GObject *object);
|
static void gdk_drawable_impl_win32_finalize (GObject *object);
|
||||||
|
|
||||||
static const cairo_user_data_key_t gdk_win32_cairo_key;
|
static const cairo_user_data_key_t gdk_win32_cairo_key;
|
||||||
|
static const cairo_user_data_key_t gdk_win32_cairo_hdc_key;
|
||||||
|
|
||||||
G_DEFINE_TYPE (GdkDrawableImplWin32, _gdk_drawable_impl_win32, GDK_TYPE_DRAWABLE)
|
G_DEFINE_TYPE (GdkDrawableImplWin32, _gdk_drawable_impl_win32, GDK_TYPE_DRAWABLE)
|
||||||
|
|
||||||
@ -1926,13 +1927,33 @@ _gdk_win32_drawable_release_dc (GdkDrawable *drawable)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdk_win32_cairo_surface_release_hdc (void *data)
|
||||||
|
{
|
||||||
|
_gdk_win32_drawable_release_dc (GDK_DRAWABLE (data));
|
||||||
|
}
|
||||||
|
|
||||||
cairo_surface_t *
|
cairo_surface_t *
|
||||||
_gdk_windowing_create_cairo_surface (GdkDrawable *drawable,
|
_gdk_windowing_create_cairo_surface (GdkDrawable *drawable,
|
||||||
gint width,
|
gint width,
|
||||||
gint height)
|
gint height)
|
||||||
{
|
{
|
||||||
/* width and height are determined from the DC */
|
cairo_surface_t *surface;
|
||||||
return gdk_win32_ref_cairo_surface (drawable);
|
HDC hdc;
|
||||||
|
|
||||||
|
hdc = _gdk_win32_drawable_acquire_dc (drawable);
|
||||||
|
if (!hdc)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
surface = cairo_win32_surface_create (hdc);
|
||||||
|
|
||||||
|
/* Whenever the cairo surface is destroyed, we need to release the
|
||||||
|
* HDC that was acquired */
|
||||||
|
cairo_surface_set_user_data (surface, &gdk_win32_cairo_hdc_key,
|
||||||
|
drawable,
|
||||||
|
gdk_win32_cairo_surface_release_hdc);
|
||||||
|
|
||||||
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1940,7 +1961,6 @@ gdk_win32_cairo_surface_destroy (void *data)
|
|||||||
{
|
{
|
||||||
GdkDrawableImplWin32 *impl = data;
|
GdkDrawableImplWin32 *impl = data;
|
||||||
|
|
||||||
_gdk_win32_drawable_release_dc (GDK_DRAWABLE (impl));
|
|
||||||
impl->cairo_surface = NULL;
|
impl->cairo_surface = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1955,14 +1975,14 @@ gdk_win32_ref_cairo_surface (GdkDrawable *drawable)
|
|||||||
|
|
||||||
if (!impl->cairo_surface)
|
if (!impl->cairo_surface)
|
||||||
{
|
{
|
||||||
HDC hdc = _gdk_win32_drawable_acquire_dc (drawable);
|
/* width and height are determined from the DC */
|
||||||
if (!hdc)
|
impl->cairo_surface = _gdk_windowing_create_cairo_surface (drawable, 0, 0);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
impl->cairo_surface = cairo_win32_surface_create (hdc);
|
|
||||||
|
|
||||||
|
/* Whenever the cairo surface is destroyed, we need to clear the
|
||||||
|
* pointer that we had stored here */
|
||||||
cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_key,
|
cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_key,
|
||||||
drawable, gdk_win32_cairo_surface_destroy);
|
drawable,
|
||||||
|
gdk_win32_cairo_surface_destroy);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cairo_surface_reference (impl->cairo_surface);
|
cairo_surface_reference (impl->cairo_surface);
|
||||||
@ -2041,9 +2061,11 @@ _gdk_win32_drawable_finish (GdkDrawable *drawable)
|
|||||||
if (impl->cairo_surface)
|
if (impl->cairo_surface)
|
||||||
{
|
{
|
||||||
cairo_surface_finish (impl->cairo_surface);
|
cairo_surface_finish (impl->cairo_surface);
|
||||||
|
cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_hdc_key, NULL, NULL);
|
||||||
cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_key, NULL, NULL);
|
cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_key, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_assert (impl->hdc_count == 0);
|
/* impl->hdc_count doesn't have to be 0 here; as there may still be surfaces
|
||||||
|
* created with gdk_windowing_create_cairo_surface() out there, which are not
|
||||||
|
* managed internally by the drawable */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user