[mutter/wayland] window-actor: Move all buffer management and damage correction here



commit a02d734243e11043861f2958fb6d3e744f780933
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Mon Nov 4 22:13:33 2013 -0500

    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/compositor/meta-shaped-texture-private.h |   14 +--
 src/compositor/meta-shaped-texture.c         |  167 ++------------------------
 src/compositor/meta-window-actor-private.h   |    2 -
 src/compositor/meta-window-actor.c           |   81 +++++++------
 src/wayland/meta-wayland-seat.c              |    6 -
 src/wayland/meta-xwayland.c                  |    5 -
 6 files changed, 59 insertions(+), 216 deletions(-)
---
diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h
index ec4f081..18d61a7 100644
--- a/src/compositor/meta-shaped-texture-private.h
+++ b/src/compositor/meta-shaped-texture-private.h
@@ -28,17 +28,9 @@
 #define __META_SHAPED_TEXTURE_PRIVATE_H__
 
 #include <meta/meta-shaped-texture.h>
-#include "meta-wayland-private.h"
 
-ClutterActor *meta_shaped_texture_new_with_xwindow (Window xwindow);
-ClutterActor *meta_shaped_texture_new_with_wayland_surface  (MetaWaylandSurface *surface);
-void meta_shaped_texture_set_wayland_surface                (MetaShapedTexture  *stex,
-                                                             MetaWaylandSurface *surface);
-MetaWaylandSurface *meta_shaped_texture_get_wayland_surface (MetaShapedTexture *stex);
-
-void meta_shaped_texture_set_pixmap (MetaShapedTexture *stex,
-                                     Pixmap             pixmap);
-void meta_shaped_texture_attach_wayland_buffer (MetaShapedTexture  *stex,
-                                                MetaWaylandBuffer  *buffer);
+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 c1ac5ff..5462042 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -35,12 +35,9 @@
 #include "meta-texture-tower.h"
 
 #include "meta-shaped-texture-private.h"
-#include "meta-wayland-private.h"
-#include <cogl/cogl-wayland-server.h>
 
 #include <clutter/clutter.h>
 #include <cogl/cogl.h>
-#include <cogl/cogl-texture-pixmap-x11.h>
 #include <gdk/gdk.h> /* for gdk_rectangle_intersect() */
 
 static void meta_shaped_texture_dispose  (GObject    *object);
@@ -61,15 +58,7 @@ static void meta_shaped_texture_get_preferred_height (ClutterActor *self,
 
 static gboolean meta_shaped_texture_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume);
 
-typedef enum _MetaShapedTextureType
-{
-  META_SHAPED_TEXTURE_TYPE_X11_PIXMAP,
-  META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE,
-} MetaShapedTextureType;
-
-
-G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture,
-               CLUTTER_TYPE_ACTOR);
+G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_ACTOR);
 
 #define META_SHAPED_TEXTURE_GET_PRIVATE(obj) \
   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_SHAPED_TEXTURE, \
@@ -79,18 +68,7 @@ struct _MetaShapedTexturePrivate
 {
   MetaTextureTower *paint_tower;
 
-  MetaShapedTextureType type;
-  union {
-    struct {
-      Pixmap pixmap;
-    } x11;
-    struct {
-      MetaWaylandSurface *surface;
-    } wayland;
-  };
-
   CoglTexture *texture;
-
   CoglTexture *mask_texture;
 
   cairo_region_t *clip_region;
@@ -128,9 +106,7 @@ meta_shaped_texture_init (MetaShapedTexture *self)
 
   priv->paint_tower = meta_texture_tower_new ();
 
-  priv->type = META_SHAPED_TEXTURE_TYPE_X11_PIXMAP;
   priv->texture = NULL;
-
   priv->mask_texture = NULL;
   priv->create_mipmaps = TRUE;
 }
@@ -220,10 +196,8 @@ paint_clipped_rectangle (CoglFramebuffer       *fb,
   cogl_framebuffer_draw_multitextured_rectangle (fb, pipeline,
                                                  x1, y1, x2, y2,
                                                  &coords[0], 8);
-
 }
 
-
 static void
 set_cogl_texture (MetaShapedTexture *stex,
                   CoglTexture       *cogl_tex)
@@ -571,48 +545,6 @@ meta_shaped_texture_get_paint_volume (ClutterActor *self,
   return clutter_paint_volume_set_from_allocation (volume, self);
 }
 
-ClutterActor *
-meta_shaped_texture_new_with_wayland_surface (MetaWaylandSurface *surface)
-{
-  ClutterActor *actor = g_object_new (META_TYPE_SHAPED_TEXTURE, NULL);
-  MetaShapedTexturePrivate *priv = META_SHAPED_TEXTURE (actor)->priv;
-
-  /* XXX: it could probably be better to have a "type" construct-only
-   * property or create wayland/x11 subclasses */
-  priv->type = META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE;
-
-  meta_shaped_texture_set_wayland_surface (META_SHAPED_TEXTURE (actor),
-                                           surface);
-
-  return actor;
-}
-
-void
-meta_shaped_texture_set_wayland_surface (MetaShapedTexture *stex,
-                                         MetaWaylandSurface *surface)
-{
-  MetaShapedTexturePrivate *priv = stex->priv;
-
-  priv->wayland.surface = surface;
-
-  if (surface && surface->buffer_ref.buffer)
-    meta_shaped_texture_attach_wayland_buffer (stex,
-                                               surface->buffer_ref.buffer);
-}
-
-MetaWaylandSurface *
-meta_shaped_texture_get_wayland_surface (MetaShapedTexture *stex)
-{
-  MetaShapedTexturePrivate *priv = stex->priv;
-  return priv->wayland.surface;
-}
-
-ClutterActor *
-meta_shaped_texture_new_with_xwindow (Window xwindow)
-{
-  return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL);
-}
-
 void
 meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
                                        gboolean           create_mipmaps)
@@ -655,35 +587,6 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
   clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
 }
 
-static void
-wayland_surface_update_area (MetaShapedTexture *stex,
-                             int                x,
-                             int                y,
-                             int                width,
-                             int                height)
-{
-  MetaShapedTexturePrivate *priv;
-  MetaWaylandBuffer *buffer;
-
-  priv = stex->priv;
-
-  g_return_if_fail (priv->type == META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE);
-  g_return_if_fail (priv->texture != NULL);
-
-  buffer = priv->wayland.surface->buffer_ref.buffer;
-
-  if (buffer)
-    {
-      struct wl_resource *resource = buffer->resource;
-      struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource);
-
-      if (shm_buffer)
-        cogl_wayland_texture_2d_update_area (COGL_TEXTURE_2D (priv->texture),
-                                             shm_buffer,
-                                             x, y, width, height);
-    }
-}
-
 static gboolean
 get_clip (MetaShapedTexture *stex,
           int x,
@@ -765,17 +668,6 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
   if (priv->texture == NULL)
     return FALSE;
 
-  switch (priv->type)
-    {
-    case META_SHAPED_TEXTURE_TYPE_X11_PIXMAP:
-      cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (priv->texture),
-                                           x, y, width, height);
-      break;
-    case META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE:
-      wayland_surface_update_area (stex, x, y, width, height);
-      break;
-    }
-
   meta_texture_tower_update_area (priv->paint_tower, x, y, width, height);
 
   has_clip = get_clip (stex, x, y, width, height, &clip);
@@ -815,58 +707,17 @@ meta_shaped_texture_update_area (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->x11.pixmap == pixmap)
-    return;
-
-  priv->x11.pixmap = pixmap;
-
-  if (pixmap != None)
-    {
-      CoglContext *ctx =
-        clutter_backend_get_cogl_context (clutter_get_default_backend ());
-      CoglTexture *texture =
-        COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, NULL));
-      set_cogl_texture (stex, texture);
-    }
-  else
-    set_cogl_texture (stex, NULL);
-}
-
-void
-meta_shaped_texture_attach_wayland_buffer (MetaShapedTexture  *stex,
-                                           MetaWaylandBuffer  *buffer)
-{
-  MetaShapedTexturePrivate *priv;
-
-  g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
-
-  priv = stex->priv;
-
-  /* TODO: we should change this api to be something like
-   * meta_shaped_texture_notify_buffer_attach() since we now maintain
-   * a reference to the MetaWaylandSurface where we can access the
-   * buffer without it being explicitly passed as an argument.
-   */
-  g_return_if_fail (priv->wayland.surface->buffer_ref.buffer == buffer);
-
-  if (buffer)
-    set_cogl_texture (stex, buffer->texture);
-  else
-    set_cogl_texture (stex, NULL);
+  set_cogl_texture (stex, texture);
 }
 
 /**
@@ -1077,3 +928,9 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
 
   return surface;
 }
+
+ClutterActor *
+meta_shaped_texture_new (void)
+{
+  return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL);
+}
diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h
index 9f601b5..050b7ad 100644
--- a/src/compositor/meta-window-actor-private.h
+++ b/src/compositor/meta-window-actor-private.h
@@ -35,8 +35,6 @@ void meta_window_actor_process_wayland_damage (MetaWindowActor *self,
                                                int              y,
                                                int              width,
                                                int              height);
-void meta_window_actor_set_wayland_surface    (MetaWindowActor    *self,
-                                               MetaWaylandSurface *surface);
 void meta_window_actor_attach_wayland_buffer  (MetaWindowActor   *self,
                                                MetaWaylandBuffer *buffer);
 
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 2a6314c..b0959af 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -16,6 +16,7 @@
 
 #include <clutter/x11/clutter-x11.h>
 #include <cogl/cogl-texture-pixmap-x11.h>
+#include <cogl/cogl-wayland-server.h>
 #include <gdk/gdk.h> /* for gdk_rectangle_union() */
 #include <string.h>
 
@@ -52,6 +53,8 @@ struct _MetaWindowActorPrivate
 
   ClutterActor     *actor;
 
+  MetaWaylandBuffer *buffer;
+
   /* MetaShadowFactory only caches shadows that are actually in use;
    * to avoid unnecessary recomputation we do two things: 1) we store
    * both a focused and unfocused shadow for the window. If the window
@@ -391,10 +394,7 @@ meta_window_actor_constructed (GObject *object)
 
   if (!priv->actor)
     {
-      if (meta_is_wayland_compositor ())
-        priv->actor = meta_shaped_texture_new_with_wayland_surface (window->surface);
-      else
-        priv->actor = meta_shaped_texture_new_with_xwindow (xwindow);
+      priv->actor = meta_shaped_texture_new ();
 
       clutter_actor_add_child (CLUTTER_ACTOR (self), priv->actor);
       clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
@@ -1015,6 +1015,35 @@ queue_send_frame_messages_timeout (MetaWindowActor *self)
 }
 
 static void
+wayland_surface_update_area (MetaWindowActor *self,
+                             int x, int y, int width, int height)
+{
+  MetaWindowActorPrivate *priv = self->priv;
+  struct wl_resource *resource = priv->buffer->resource;
+  struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource);
+
+  if (shm_buffer)
+    cogl_wayland_texture_2d_update_area (COGL_TEXTURE_2D (priv->buffer->texture),
+                                         shm_buffer, x, y, width, height);
+}
+
+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));
+
+  if (meta_is_wayland_compositor ())
+    wayland_surface_update_area (self, x, y, width, height);
+  else
+    cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (texture),
+                                         x, y, width, height);
+}
+
+static void
 meta_window_actor_damage_all (MetaWindowActor *self)
 {
   MetaWindowActorPrivate *priv = self->priv;
@@ -1029,6 +1058,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),
@@ -1350,8 +1380,7 @@ meta_window_actor_detach_x11_pixmap (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);
@@ -1429,9 +1458,6 @@ meta_window_actor_destroy (MetaWindowActor *self)
 
   priv = self->priv;
 
-  if (meta_is_wayland_compositor ())
-    meta_shaped_texture_set_wayland_surface (META_SHAPED_TEXTURE (priv->actor), NULL);
-
   window = priv->window;
   window_type = meta_window_get_window_type (window);
   meta_window_set_compositor_private (window, NULL);
@@ -1975,6 +2001,7 @@ check_needs_x11_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);
@@ -2003,19 +2030,12 @@ check_needs_x11_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_outer_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
@@ -2153,6 +2173,7 @@ meta_window_actor_process_x11_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,
@@ -2178,11 +2199,11 @@ meta_window_actor_process_wayland_damage (MetaWindowActor *self,
   if (!priv->mapped)
     return;
 
+  update_area (self, x, y, width, height);
   redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
                                                    x, y, width, height,
                                                    clutter_actor_has_mapped_clones (priv->actor) ?
                                                    NULL : priv->unobscured_region);
-
   priv->repaint_scheduled = priv->repaint_scheduled  || redraw_queued;
 }
 
@@ -2510,30 +2531,16 @@ maybe_emit_size_changed (MetaWindowActor *self,
 }
 
 void
-meta_window_actor_set_wayland_surface (MetaWindowActor *self,
-                                       MetaWaylandSurface *surface)
-{
-  MetaWindowActorPrivate *priv = self->priv;
-
-  meta_shaped_texture_set_wayland_surface (META_SHAPED_TEXTURE (priv->actor),
-                                           surface);
-  if (surface && surface->buffer_ref.buffer)
-    maybe_emit_size_changed (self, surface->buffer_ref.buffer);
-}
-
-void
 meta_window_actor_attach_wayland_buffer (MetaWindowActor *self,
                                          MetaWaylandBuffer *buffer)
 {
   MetaWindowActorPrivate *priv = self->priv;
   MetaShapedTexture *stex = META_SHAPED_TEXTURE (priv->actor);
-  CoglTexture *prev_tex = meta_shaped_texture_get_texture (stex);
 
-  meta_shaped_texture_attach_wayland_buffer (stex, buffer);
-
-  if (!prev_tex)
-    meta_window_actor_sync_actor_geometry (self, FALSE);
+  priv->buffer = buffer;
 
+  meta_shaped_texture_set_texture (stex, buffer->texture);
+  meta_window_actor_sync_actor_geometry (self, FALSE);
   maybe_emit_size_changed (self, buffer);
 }
 
diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c
index 377e7f2..012cd00 100644
--- a/src/wayland/meta-wayland-seat.c
+++ b/src/wayland/meta-wayland-seat.c
@@ -439,12 +439,6 @@ meta_wayland_seat_repick (MetaWaylandSeat    *seat,
 
       surface = window->surface;
     }
-  else if (META_IS_SHAPED_TEXTURE (actor))
-    {
-      MetaShapedTexture *shaped_texture = META_SHAPED_TEXTURE (actor);
-
-      surface = meta_shaped_texture_get_wayland_surface (shaped_texture);
-    }
 
   pointer->current = surface;
   if (surface != pointer->focus)
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index 0e22448..0207c7d 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -48,11 +48,6 @@ xserver_set_window_id (struct wl_client *client,
   window  = meta_display_lookup_x_window (display, xid);
   if (window)
     {
-      MetaWindowActor *window_actor =
-        META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
-
-      meta_window_actor_set_wayland_surface (window_actor, surface);
-
       surface->window = window;
       window->surface = surface;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]