From d3c2607e53c72edb3f71cef6b2e111489ede9230 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 4 Nov 2013 22:13:33 -0500 Subject: [PATCH] window-actor: Move all buffer management and damage correction here We want ShapedTexture to be a dumb actor that knows how to pick/paint fairly easily, without any "platform knowledge", so to say... --- src/Makefile.am | 1 + src/compositor/meta-shaped-texture-private.h | 36 +++++++++++++++ src/compositor/meta-shaped-texture.c | 47 +++++--------------- src/compositor/meta-window-actor.c | 33 +++++++++----- src/meta/meta-shaped-texture.h | 5 --- 5 files changed, 70 insertions(+), 52 deletions(-) create mode 100644 src/compositor/meta-shaped-texture-private.h diff --git a/src/Makefile.am b/src/Makefile.am index ba4122e9d..b0442e069 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -65,6 +65,7 @@ libmutter_la_SOURCES = \ compositor/meta-shadow-factory.c \ compositor/meta-shadow-factory-private.h \ compositor/meta-shaped-texture.c \ + compositor/meta-shaped-texture-private.h \ compositor/meta-texture-rectangle.c \ compositor/meta-texture-rectangle.h \ compositor/meta-texture-tower.c \ diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h new file mode 100644 index 000000000..18d61a728 --- /dev/null +++ b/src/compositor/meta-shaped-texture-private.h @@ -0,0 +1,36 @@ +/* + * shaped texture + * + * An actor to draw a texture clipped to a list of rectangles + * + * Authored By Neil Roberts + * + * Copyright (C) 2008 Intel Corporation + * 2013 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef __META_SHAPED_TEXTURE_PRIVATE_H__ +#define __META_SHAPED_TEXTURE_PRIVATE_H__ + +#include + +ClutterActor *meta_shaped_texture_new (void); +void meta_shaped_texture_set_texture (MetaShapedTexture *stex, + CoglTexture *texture); + +#endif diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index fc1e5551a..4a97199f3 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -31,9 +31,10 @@ #include "clutter-utils.h" #include "meta-texture-tower.h" +#include "meta-shaped-texture-private.h" + #include #include -#include #include /* for gdk_rectangle_intersect() */ #include "meta-cullable.h" @@ -67,8 +68,8 @@ G_DEFINE_TYPE_WITH_CODE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_AC struct _MetaShapedTexturePrivate { MetaTextureTower *paint_tower; - Pixmap pixmap; - CoglTexturePixmapX11 *texture; + + CoglTexture *texture; CoglTexture *mask_texture; cairo_region_t *clip_region; @@ -105,6 +106,7 @@ meta_shaped_texture_init (MetaShapedTexture *self) priv = self->priv = META_SHAPED_TEXTURE_GET_PRIVATE (self); priv->paint_tower = meta_texture_tower_new (); + priv->texture = NULL; priv->mask_texture = NULL; priv->create_mipmaps = TRUE; @@ -206,10 +208,8 @@ paint_clipped_rectangle (CoglFramebuffer *fb, cogl_framebuffer_draw_multitextured_rectangle (fb, pipeline, x1, y1, x2, y2, &coords[0], 8); - } - static void meta_shaped_texture_paint (ClutterActor *actor) { @@ -581,9 +581,6 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, if (priv->texture == NULL) return FALSE; - cogl_texture_pixmap_x11_update_area (priv->texture, - x, y, width, height); - meta_texture_tower_update_area (priv->paint_tower, x, y, width, height); if (unobscured_region) @@ -616,8 +613,8 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, } static void -set_cogl_texture (MetaShapedTexture *stex, - CoglTexturePixmapX11 *cogl_tex) +set_cogl_texture (MetaShapedTexture *stex, + CoglTexture *cogl_tex) { MetaShapedTexturePrivate *priv; guint width, height; @@ -657,37 +654,17 @@ set_cogl_texture (MetaShapedTexture *stex, } /** - * meta_shaped_texture_set_pixmap: + * meta_shaped_texture_set_texture: * @stex: The #MetaShapedTexture - * @pixmap: The pixmap you want the stex to assume + * @pixmap: The #CoglTexture to display */ void -meta_shaped_texture_set_pixmap (MetaShapedTexture *stex, - Pixmap pixmap) +meta_shaped_texture_set_texture (MetaShapedTexture *stex, + CoglTexture *texture) { - MetaShapedTexturePrivate *priv; - g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); - priv = stex->priv; - - if (priv->pixmap == pixmap) - return; - - priv->pixmap = pixmap; - - if (pixmap != None) - { - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - set_cogl_texture (stex, cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, NULL)); - } - else - set_cogl_texture (stex, NULL); - - if (priv->create_mipmaps) - meta_texture_tower_set_base_texture (priv->paint_tower, - COGL_TEXTURE (priv->texture)); + set_cogl_texture (stex, texture); } /** diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 61483415c..4b1d0db16 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -27,6 +27,7 @@ #include "xprops.h" #include "compositor-private.h" +#include "meta-shaped-texture-private.h" #include "meta-shadow-factory-private.h" #include "meta-window-actor-private.h" #include "meta-texture-rectangle.h" @@ -872,6 +873,19 @@ queue_send_frame_messages_timeout (MetaWindowActor *self) priv->send_frame_messages_timer = g_timeout_add_full (META_PRIORITY_REDRAW, offset, send_frame_messages_timeout, self, NULL); } +static void +update_area (MetaWindowActor *self, + int x, int y, int width, int height) +{ + MetaWindowActorPrivate *priv = self->priv; + CoglTexture *texture; + + texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor)); + + cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (texture), + x, y, width, height); +} + static void meta_window_actor_damage_all (MetaWindowActor *self) { @@ -887,6 +901,7 @@ meta_window_actor_damage_all (MetaWindowActor *self) if (!priv->mapped || priv->needs_pixmap) return; + update_area (self, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture)); redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor), 0, 0, cogl_texture_get_width (texture), @@ -1200,8 +1215,7 @@ meta_window_actor_detach (MetaWindowActor *self) * you are supposed to be able to free a GLXPixmap after freeing the underlying * pixmap, but it certainly doesn't work with current DRI/Mesa */ - meta_shaped_texture_set_pixmap (META_SHAPED_TEXTURE (priv->actor), - None); + meta_shaped_texture_set_texture (META_SHAPED_TEXTURE (priv->actor), NULL); cogl_flush(); XFreePixmap (xdisplay, priv->back_pixmap); @@ -1750,6 +1764,7 @@ check_needs_pixmap (MetaWindowActor *self) if (priv->back_pixmap == None) { + CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); CoglTexture *texture; meta_error_trap_push (display); @@ -1778,19 +1793,12 @@ check_needs_pixmap (MetaWindowActor *self) meta_shaped_texture_set_create_mipmaps (META_SHAPED_TEXTURE (priv->actor), FALSE); - meta_shaped_texture_set_pixmap (META_SHAPED_TEXTURE (priv->actor), - priv->back_pixmap); - - texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor)); - - /* - * This only works *after* actually setting the pixmap, so we have to - * do it here. - * See: http://bugzilla.clutter-project.org/show_bug.cgi?id=2236 - */ + texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->back_pixmap, FALSE, NULL)); if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture)))) g_warning ("NOTE: Not using GLX TFP!\n"); + meta_shaped_texture_set_texture (META_SHAPED_TEXTURE (priv->actor), texture); + /* ::size-changed is supposed to refer to meta_window_get_frame_rect(). * Emitting it here works pretty much OK because a new value of the * *input* rect (which is the outer rect with the addition of invisible @@ -1928,6 +1936,7 @@ meta_window_actor_process_damage (MetaWindowActor *self, if (!priv->mapped || priv->needs_pixmap) return; + update_area (self, event->area.x, event->area.y, event->area.width, event->area.height); redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor), event->area.x, event->area.y, diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h index bec6bd69c..9eea4b8d9 100644 --- a/src/meta/meta-shaped-texture.h +++ b/src/meta/meta-shaped-texture.h @@ -62,8 +62,6 @@ struct _MetaShapedTexture GType meta_shaped_texture_get_type (void) G_GNUC_CONST; -ClutterActor *meta_shaped_texture_new (void); - void meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex, gboolean create_mipmaps); @@ -74,9 +72,6 @@ gboolean meta_shaped_texture_update_area (MetaShapedTexture *stex, int height, cairo_region_t *unobscured_region); -void meta_shaped_texture_set_pixmap (MetaShapedTexture *stex, - Pixmap pixmap); - CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex); void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,