[mutter] wayland: Make the surface actor set its own state



commit bbcee174ced72b7d447aa185d7413f382b3fbf96
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Mon Mar 2 22:56:35 2015 +0800

    wayland: Make the surface actor set its own state
    
    Since the surface actor knows more about how it draws itself, instead of
    pushing texture state (buffer and scale), input region and opaque region
    from MetaWaylandSurface after having transformed into what the surface
    actor expects, make the surface actor set its own state given what state
    the Wayland surface is in.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=744933

 src/compositor/meta-surface-actor-wayland.c |   49 +++++++++++++++++++++++--
 src/compositor/meta-surface-actor-wayland.h |    3 +-
 src/compositor/region-utils.c               |   29 +++++++++++++++
 src/compositor/region-utils.h               |    2 +
 src/wayland/meta-wayland-surface.c          |   51 +++++++-------------------
 src/wayland/meta-wayland-surface.h          |    2 +
 6 files changed, 94 insertions(+), 42 deletions(-)
---
diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c
index ba4e517..7957399 100644
--- a/src/compositor/meta-surface-actor-wayland.c
+++ b/src/compositor/meta-surface-actor-wayland.c
@@ -31,6 +31,8 @@
 
 #include "wayland/meta-wayland-private.h"
 
+#include "compositor/region-utils.h"
+
 struct _MetaSurfaceActorWaylandPrivate
 {
   MetaWaylandSurface *surface;
@@ -126,12 +128,51 @@ meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor)
 }
 
 void
-meta_surface_actor_wayland_scale_texture (MetaSurfaceActorWayland *actor)
+meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self)
 {
-  MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (actor));
-  double output_scale = meta_surface_actor_wayland_get_scale (actor);
+  MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
+  MetaShapedTexture *stex =
+    meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
+  double texture_scale;
+
+  /* Given the surface's window type and what output the surface actor has the
+   * largest region, scale the actor with the determined scale. */
+  texture_scale = meta_surface_actor_wayland_get_scale (self);
+
+  /* Actor scale. */
+  clutter_actor_set_scale (CLUTTER_ACTOR (stex), texture_scale, texture_scale);
+
+  /* Input region */
+  if (surface->input_region)
+    {
+      cairo_region_t *scaled_input_region;
+      int region_scale;
+
+      /* The input region from the Wayland surface is in the Wayland surface
+       * coordinate space, while the surface actor input region is in the
+       * physical pixel coordinate space. */
+      region_scale = (int)(surface->scale * texture_scale);
+      scaled_input_region = meta_region_scale (surface->input_region,
+                                               region_scale);
+      meta_surface_actor_set_input_region (META_SURFACE_ACTOR (self),
+                                           scaled_input_region);
+      cairo_region_destroy (scaled_input_region);
+    }
 
-  clutter_actor_set_scale (CLUTTER_ACTOR (stex), output_scale, output_scale);
+  /* Opaque region */
+  if (surface->opaque_region)
+    {
+      cairo_region_t *scaled_opaque_region;
+
+      /* The opaque region from the Wayland surface is in Wayland surface
+       * coordinate space, while the surface actor opaque region is in the
+       * same coordinate space as the unscaled buffer texture. */
+      scaled_opaque_region = meta_region_scale (surface->opaque_region,
+                                                surface->scale);
+      meta_surface_actor_set_opaque_region (META_SURFACE_ACTOR (self),
+                                            scaled_opaque_region);
+      cairo_region_destroy (scaled_opaque_region);
+    }
 }
 
 static MetaWindow *
diff --git a/src/compositor/meta-surface-actor-wayland.h b/src/compositor/meta-surface-actor-wayland.h
index ed129d7..8ef2b05 100644
--- a/src/compositor/meta-surface-actor-wayland.h
+++ b/src/compositor/meta-surface-actor-wayland.h
@@ -63,7 +63,8 @@ void meta_surface_actor_wayland_set_texture (MetaSurfaceActorWayland *self,
 
 double meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor);
 
-void meta_surface_actor_wayland_scale_texture (MetaSurfaceActorWayland *actor);
+void meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self);
+
 G_END_DECLS
 
 #endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */
diff --git a/src/compositor/region-utils.c b/src/compositor/region-utils.c
index a78321d..1b970ba 100644
--- a/src/compositor/region-utils.c
+++ b/src/compositor/region-utils.c
@@ -172,6 +172,35 @@ meta_region_iterator_next (MetaRegionIterator *iter)
     }
 }
 
+cairo_region_t *
+meta_region_scale (cairo_region_t *region, int scale)
+{
+  int n_rects, i;
+  cairo_rectangle_int_t *rects;
+  cairo_region_t *scaled_region;
+
+  if (scale == 1)
+    return cairo_region_copy (region);
+
+  n_rects = cairo_region_num_rectangles (region);
+
+  rects = g_malloc (sizeof(cairo_rectangle_int_t) * n_rects);
+  for (i = 0; i < n_rects; i++)
+    {
+      cairo_region_get_rectangle (region, i, &rects[i]);
+      rects[i].x *= scale;
+      rects[i].y *= scale;
+      rects[i].width *= scale;
+      rects[i].height *= scale;
+    }
+
+  scaled_region = cairo_region_create_rectangles (rects, n_rects);
+
+  g_free (rects);
+
+  return scaled_region;
+}
+
 static void
 add_expanded_rect (MetaRegionBuilder  *builder,
                    int                 x,
diff --git a/src/compositor/region-utils.h b/src/compositor/region-utils.h
index 16304dc..526e6ec 100644
--- a/src/compositor/region-utils.h
+++ b/src/compositor/region-utils.h
@@ -92,6 +92,8 @@ void     meta_region_iterator_init      (MetaRegionIterator *iter,
 gboolean meta_region_iterator_at_end    (MetaRegionIterator *iter);
 void     meta_region_iterator_next      (MetaRegionIterator *iter);
 
+cairo_region_t *meta_region_scale (cairo_region_t *region, int scale);
+
 cairo_region_t *meta_make_border_region (cairo_region_t *region,
                                          int             x_amount,
                                          int             y_amount,
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 3a6f6b6..1ee1c69 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -356,36 +356,6 @@ parent_surface_committed (gpointer data, gpointer user_data)
   subsurface_parent_surface_committed (data);
 }
 
-static cairo_region_t*
-scale_region (cairo_region_t *region, int scale)
-{
-  int n_rects, i;
-  cairo_rectangle_int_t *rects;
-  cairo_region_t *scaled_region;
-
-  if (scale == 1)
-    return region;
-
-  n_rects = cairo_region_num_rectangles (region);
-
-  rects = g_malloc (sizeof(cairo_rectangle_int_t) * n_rects);
-  for (i = 0; i < n_rects; i++)
-    {
-      cairo_region_get_rectangle (region, i, &rects[i]);
-      rects[i].x *= scale;
-      rects[i].y *= scale;
-      rects[i].width *= scale;
-      rects[i].height *= scale;
-    }
-
-  scaled_region = cairo_region_create_rectangles (rects, n_rects);
-
-  g_free (rects);
-  cairo_region_destroy (region);
-
-  return scaled_region;
-}
-
 static void
 commit_pending_state (MetaWaylandSurface      *surface,
                       MetaWaylandPendingState *pending)
@@ -426,18 +396,20 @@ commit_pending_state (MetaWaylandSurface      *surface,
 
   if (pending->opaque_region)
     {
-      pending->opaque_region = scale_region (pending->opaque_region, surface->scale);
-      meta_surface_actor_set_opaque_region (surface->surface_actor, pending->opaque_region);
+      if (surface->opaque_region)
+        cairo_region_destroy (surface->opaque_region);
+      surface->opaque_region = cairo_region_reference (pending->opaque_region);
     }
+
   if (pending->input_region)
     {
-      pending->input_region = scale_region (pending->input_region,
-                                            meta_surface_actor_wayland_get_scale (META_SURFACE_ACTOR_WAYLAND 
(surface->surface_actor)));
-      meta_surface_actor_set_input_region (surface->surface_actor, pending->input_region);
+      if (surface->input_region)
+        cairo_region_destroy (surface->input_region);
+      surface->input_region = cairo_region_reference (pending->input_region);
     }
 
-  /* scale surface texture */
-  meta_surface_actor_wayland_scale_texture (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor));
+  meta_surface_actor_wayland_sync_state (
+    META_SURFACE_ACTOR_WAYLAND (surface->surface_actor));
 
   /* wl_surface.frame */
   wl_list_insert_list (&compositor->frame_callbacks, &pending->frame_callback_list);
@@ -692,6 +664,11 @@ wl_surface_destructor (struct wl_resource *resource)
   surface_set_buffer (surface, NULL);
   pending_state_destroy (&surface->pending);
 
+  if (surface->opaque_region)
+    cairo_region_destroy (surface->opaque_region);
+  if (surface->input_region)
+    cairo_region_destroy (surface->input_region);
+
   g_object_unref (surface->surface_actor);
 
   if (surface->resource)
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index 9f8b9de..5783a46 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -81,6 +81,8 @@ struct _MetaWaylandSurface
   MetaWindow *window;
   MetaWaylandBuffer *buffer;
   struct wl_listener buffer_destroy_listener;
+  cairo_region_t *input_region;
+  cairo_region_t *opaque_region;
   int scale;
   int32_t offset_x, offset_y;
   GList *subsurfaces;


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