[mutter/wip/subsurfaces] double-buffer place_above/place_below



commit 2afbf369afe0e7ae96d1a90b8ce8130aa6a30518
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Mon Nov 25 20:26:00 2013 -0500

    double-buffer place_above/place_below

 src/compositor/meta-surface-actor.c |  140 +++++++++++++++++++++++++++++++++++
 src/compositor/meta-surface-actor.h |   12 +++
 src/wayland/meta-wayland-surface.c  |   24 +++---
 3 files changed, 163 insertions(+), 13 deletions(-)
---
diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c
index 37b87b0..9e49e4e 100644
--- a/src/compositor/meta-surface-actor.c
+++ b/src/compositor/meta-surface-actor.c
@@ -24,6 +24,8 @@ struct _MetaSurfaceActorPrivate
 {
   MetaShapedTexture *texture;
   MetaWaylandBuffer *buffer;
+
+  GSList *ops;
 };
 
 static void cullable_iface_init (MetaCullableInterface *iface);
@@ -31,9 +33,23 @@ static void cullable_iface_init (MetaCullableInterface *iface);
 G_DEFINE_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR,
                          G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
 
+static void meta_surface_actor_free_ops (MetaSurfaceActor *self);
+
+static void
+meta_surface_actor_dispose (GObject *object)
+{
+  MetaSurfaceActor *self = META_SURFACE_ACTOR (object);
+
+  meta_surface_actor_free_ops (self);
+}
+
 static void
 meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = meta_surface_actor_dispose;
+
   g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate));
 }
 
@@ -181,3 +197,127 @@ meta_surface_actor_new (void)
 {
   return g_object_new (META_TYPE_SURFACE_ACTOR, NULL);
 }
+
+typedef enum {
+  OP_SET_POSITION,
+  OP_PLACE_ABOVE,
+  OP_PLACE_BELOW,
+} MetaSurfaceActorOpType;
+
+typedef struct {
+  MetaSurfaceActorOpType type;
+} MetaSurfaceActorOp;
+
+typedef struct {
+  MetaSurfaceActorOpType type;
+  ClutterActor *subsurface;
+  int32_t x;
+  int32_t y;
+} MetaSurfaceActorOp_SetPosition;
+
+typedef struct {
+  MetaSurfaceActorOpType type;
+  ClutterActor *subsurface;
+  ClutterActor *sibling;
+} MetaSurfaceActorOp_Stack;
+
+void
+meta_surface_actor_subsurface_set_position (MetaSurfaceActor *self,
+                                            MetaSurfaceActor *subsurface,
+                                            int32_t           x,
+                                            int32_t           y)
+{
+  MetaSurfaceActorPrivate *priv = self->priv;
+  MetaSurfaceActorOp_SetPosition *op = g_slice_new0 (MetaSurfaceActorOp_SetPosition);
+
+  op->type = OP_SET_POSITION;
+  op->subsurface = CLUTTER_ACTOR (subsurface);
+  op->x = x;
+  op->y = y;
+
+  priv->ops = g_slist_append (priv->ops, op);
+}
+
+static void
+meta_surface_actor_stack_op (MetaSurfaceActor       *self,
+                             MetaSurfaceActorOpType  type,
+                             MetaSurfaceActor       *subsurface,
+                             MetaSurfaceActor       *sibling)
+{
+  MetaSurfaceActorPrivate *priv = self->priv;
+  MetaSurfaceActorOp_Stack *op = g_slice_new0 (MetaSurfaceActorOp_Stack);
+
+  op->type = type;
+  op->subsurface = CLUTTER_ACTOR (subsurface);
+  op->sibling = CLUTTER_ACTOR (sibling);
+
+  priv->ops = g_slist_append (priv->ops, op);
+}
+
+void
+meta_surface_actor_subsurface_place_above (MetaSurfaceActor *self,
+                                           MetaSurfaceActor *subsurface,
+                                           MetaSurfaceActor *sibling)
+{
+  meta_surface_actor_stack_op (self, OP_PLACE_ABOVE, subsurface, sibling);
+}
+
+void
+meta_surface_actor_subsurface_place_below (MetaSurfaceActor *self,
+                                           MetaSurfaceActor *subsurface,
+                                           MetaSurfaceActor *sibling)
+{
+  meta_surface_actor_stack_op (self, OP_PLACE_BELOW, subsurface, sibling);
+}
+
+static void
+meta_surface_actor_do_op (MetaSurfaceActor   *self,
+                          MetaSurfaceActorOp *op)
+{
+  MetaSurfaceActorOp_SetPosition *op_pos = (MetaSurfaceActorOp_SetPosition *) op;
+  MetaSurfaceActorOp_Stack *op_stack = (MetaSurfaceActorOp_Stack *) op;
+
+  switch (op->type)
+    {
+    case OP_SET_POSITION:
+      clutter_actor_set_position (op_pos->subsurface, op_pos->x, op_pos->y);
+      break;
+    case OP_PLACE_ABOVE:
+      clutter_actor_set_child_above_sibling (CLUTTER_ACTOR (self), op_stack->subsurface, op_stack->sibling);
+      break;
+    case OP_PLACE_BELOW:
+      clutter_actor_set_child_below_sibling (CLUTTER_ACTOR (self), op_stack->subsurface, op_stack->sibling);
+      break;
+    }
+}
+
+static void
+meta_surface_actor_op_free (MetaSurfaceActorOp *op)
+{
+  g_slice_free (MetaSurfaceActorOp, op);
+}
+
+static void
+meta_surface_actor_free_ops (MetaSurfaceActor *self)
+{
+  MetaSurfaceActorPrivate *priv = self->priv;
+
+  g_slist_free_full (priv->ops, (GDestroyNotify) meta_surface_actor_op_free);
+  priv->ops = NULL;
+}
+
+static void
+meta_surface_actor_do_ops (MetaSurfaceActor *self)
+{
+  MetaSurfaceActorPrivate *priv = self->priv;
+  GSList *l;
+
+  for (l = priv->ops; l; l = l->next)
+    meta_surface_actor_do_op (self, ((MetaSurfaceActorOp *) l->data));
+}
+
+void
+meta_surface_actor_commit (MetaSurfaceActor *self)
+{
+  meta_surface_actor_do_ops (self);
+}
diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h
index 484877b..5dd1d09 100644
--- a/src/compositor/meta-surface-actor.h
+++ b/src/compositor/meta-surface-actor.h
@@ -62,6 +62,18 @@ void meta_surface_actor_set_input_region (MetaSurfaceActor *self,
 void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
                                            cairo_region_t   *region);
 
+void meta_surface_actor_subsurface_set_position (MetaSurfaceActor *self,
+                                                 MetaSurfaceActor *subsurface,
+                                                 int32_t           x,
+                                                 int32_t           y);
+void meta_surface_actor_subsurface_place_above (MetaSurfaceActor *self,
+                                                MetaSurfaceActor *subsurface,
+                                                MetaSurfaceActor *sibling);
+void meta_surface_actor_subsurface_place_below (MetaSurfaceActor *self,
+                                                MetaSurfaceActor *subsurface,
+                                                MetaSurfaceActor *sibling);
+void meta_surface_actor_commit (MetaSurfaceActor *self);
+
 G_END_DECLS
 
 #endif /* META_SURFACE_ACTOR_PRIVATE_H */
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 1ca38e5..ad647bc 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -339,6 +339,8 @@ meta_wayland_surface_commit (struct wl_client *client,
 
   compositor = surface->compositor;
 
+  meta_surface_actor_commit (surface->surface_actor);
+
   if (surface == compositor->seat->sprite)
     cursor_surface_commit (surface);
   else if (surface->window)
@@ -1010,6 +1012,12 @@ wl_subsurface_destroy (struct wl_client *client,
   wl_resource_destroy (resource);
 }
 
+static MetaSurfaceActor *
+get_parent (MetaWaylandSurface *surface)
+{
+  return META_SURFACE_ACTOR (clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor)));
+}
+
 static void
 wl_subsurface_set_position (struct wl_client *client,
                             struct wl_resource *resource,
@@ -1019,7 +1027,7 @@ wl_subsurface_set_position (struct wl_client *client,
   MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
   MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
 
-  clutter_actor_set_position (CLUTTER_ACTOR (surface->surface_actor), x, y);
+  meta_surface_actor_subsurface_set_position (get_parent (surface), surface->surface_actor, x, y);
 }
 
 static void
@@ -1027,16 +1035,11 @@ wl_subsurface_place_above (struct wl_client *client,
                            struct wl_resource *resource,
                            struct wl_resource *sibling_resource)
 {
-  ClutterActor *parent_actor;
   MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
   MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
   MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
 
-  parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor));
-
-  clutter_actor_set_child_above_sibling (parent_actor,
-                                         CLUTTER_ACTOR (surface->surface_actor),
-                                         CLUTTER_ACTOR (sibling->surface_actor));
+  meta_surface_actor_subsurface_place_above (get_parent (surface), surface->surface_actor, 
sibling->surface_actor);
 }
 
 static void
@@ -1044,16 +1047,11 @@ wl_subsurface_place_below (struct wl_client *client,
                            struct wl_resource *resource,
                            struct wl_resource *sibling_resource)
 {
-  ClutterActor *parent_actor;
   MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
   MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
   MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
 
-  parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor));
-
-  clutter_actor_set_child_below_sibling (parent_actor,
-                                         CLUTTER_ACTOR (surface->surface_actor),
-                                         CLUTTER_ACTOR (sibling->surface_actor));
+  meta_surface_actor_subsurface_place_below (get_parent (surface), surface->surface_actor, 
sibling->surface_actor);
 }
 
 static void


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