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)
{
ClutterX11TexturePixmap *texture = CLUTTER_X11_TEXTURE_PIXMAP (object);
ClutterX11TexturePixmapPrivate *priv = texture->priv;
free_damage_resources (texture);
clutter_x11_remove_filter (on_x_event_filter_too, (gpointer)texture);
if (priv->owns_pixmap && priv->pixmap)
{
XFreePixmap (clutter_x11_get_default_display (), priv->pixmap);
priv->pixmap = None;
}
clutter_x11_texture_pixmap_set_pixmap (texture, None);
G_OBJECT_CLASS (clutter_x11_texture_pixmap_parent_class)->dispose (object);
}
@ -814,21 +808,27 @@ clutter_x11_texture_pixmap_set_pixmap (ClutterX11TexturePixmap *texture,
if (material)
cogl_material_set_layer (material, 0, COGL_INVALID_HANDLE);
status = XGetGeometry (clutter_x11_get_default_display(),
(Drawable)pixmap,
&root,
&x,
&y,
&width,
&height,
&border_width,
&depth);
if (clutter_x11_untrap_x_errors () || status == 0)
if (pixmap != None)
{
status = XGetGeometry (clutter_x11_get_default_display(),
(Drawable)pixmap,
&root,
&x,
&y,
&width,
&height,
&border_width,
&depth);
if (clutter_x11_untrap_x_errors () || status == 0)
{
g_warning ("Unable to query pixmap: %lx", pixmap);
pixmap = None;
width = height = depth = 0;
}
}
else
{
if (pixmap != None)
g_warning ("Unable to query pixmap: %lx", pixmap);
pixmap = None;
width = height = depth = 0;
}
@ -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
* recreated with a change in pixmap.
*/
if (priv->automatic_updates && new_pixmap)
if (priv->automatic_updates)
{
free_damage_resources (texture);
create_damage_resources (texture);
@ -942,6 +942,8 @@ clutter_x11_texture_pixmap_set_window (ClutterX11TexturePixmap *texture,
CompositeRedirectAutomatic : CompositeRedirectManual);
XSync (clutter_x11_get_default_display (), False);
clutter_x11_untrap_x_errors ();
clutter_x11_texture_pixmap_set_pixmap (texture, None);
}
priv->window = window;