Clean up CoglTexturePixmapX11 first

With currently distributed versions of Mesa, calling XFreePixmap()
before glxDestroyPixmap() will cause an X error from DRI. So, we
need to make sure that we get rid of the CoglTexturePixmapX11 before
we XFreePixmap().

clutter_x11_texture_pixmap_dispose(): Call
 clutter_x11_texture_pixmap_set_pixmap() instead of using XFreePixmap
 directly so that we leverage the text-clearing hack and destroy
 things in the right order.

clutter_x11_texture_pixmap_set_pixmap(): Don't do a pointless roundtrip
 and trap a pointless error when setting pixmap to None.

clutter_x11_texture_pixmap_set_pixmap(): Free damage resources when
 we are setting Pixmap to None.

clutter_x11_texture_pixmap_set_window(): When setting a new window
 or setting the window to None, immedediately  call
 cluter_x11_texture_pixmap_set_pixmap(). This means that set_window(None)
 immediately will free any referenced resources related to the window.

http://bugzilla.clutter-project.org/show_bug.cgi?id=2303
This commit is contained in:
Owen W. Taylor 2010-09-08 11:34:58 -04:00 committed by Emmanuele Bassi
parent ca8db4c2ee
commit 2cf1405506

View File

@ -390,17 +390,11 @@ static void
clutter_x11_texture_pixmap_dispose (GObject *object) clutter_x11_texture_pixmap_dispose (GObject *object)
{ {
ClutterX11TexturePixmap *texture = CLUTTER_X11_TEXTURE_PIXMAP (object); ClutterX11TexturePixmap *texture = CLUTTER_X11_TEXTURE_PIXMAP (object);
ClutterX11TexturePixmapPrivate *priv = texture->priv;
free_damage_resources (texture); free_damage_resources (texture);
clutter_x11_remove_filter (on_x_event_filter_too, (gpointer)texture); clutter_x11_remove_filter (on_x_event_filter_too, (gpointer)texture);
clutter_x11_texture_pixmap_set_pixmap (texture, None);
if (priv->owns_pixmap && priv->pixmap)
{
XFreePixmap (clutter_x11_get_default_display (), priv->pixmap);
priv->pixmap = None;
}
G_OBJECT_CLASS (clutter_x11_texture_pixmap_parent_class)->dispose (object); G_OBJECT_CLASS (clutter_x11_texture_pixmap_parent_class)->dispose (object);
} }
@ -814,6 +808,8 @@ clutter_x11_texture_pixmap_set_pixmap (ClutterX11TexturePixmap *texture,
if (material) if (material)
cogl_material_set_layer (material, 0, COGL_INVALID_HANDLE); cogl_material_set_layer (material, 0, COGL_INVALID_HANDLE);
if (pixmap != None)
{
status = XGetGeometry (clutter_x11_get_default_display(), status = XGetGeometry (clutter_x11_get_default_display(),
(Drawable)pixmap, (Drawable)pixmap,
&root, &root,
@ -826,11 +822,15 @@ clutter_x11_texture_pixmap_set_pixmap (ClutterX11TexturePixmap *texture,
if (clutter_x11_untrap_x_errors () || status == 0) if (clutter_x11_untrap_x_errors () || status == 0)
{ {
if (pixmap != None)
g_warning ("Unable to query pixmap: %lx", pixmap); g_warning ("Unable to query pixmap: %lx", pixmap);
pixmap = None; pixmap = None;
width = height = depth = 0; width = height = depth = 0;
} }
}
else
{
width = height = depth = 0;
}
if (priv->pixmap != pixmap) if (priv->pixmap != pixmap)
{ {
@ -843,7 +843,7 @@ clutter_x11_texture_pixmap_set_pixmap (ClutterX11TexturePixmap *texture,
/* The damage object is created on the pixmap, so it needs to be /* The damage object is created on the pixmap, so it needs to be
* recreated with a change in pixmap. * recreated with a change in pixmap.
*/ */
if (priv->automatic_updates && new_pixmap) if (priv->automatic_updates)
{ {
free_damage_resources (texture); free_damage_resources (texture);
create_damage_resources (texture); create_damage_resources (texture);
@ -942,6 +942,8 @@ clutter_x11_texture_pixmap_set_window (ClutterX11TexturePixmap *texture,
CompositeRedirectAutomatic : CompositeRedirectManual); CompositeRedirectAutomatic : CompositeRedirectManual);
XSync (clutter_x11_get_default_display (), False); XSync (clutter_x11_get_default_display (), False);
clutter_x11_untrap_x_errors (); clutter_x11_untrap_x_errors ();
clutter_x11_texture_pixmap_set_pixmap (texture, None);
} }
priv->window = window; priv->window = window;