summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Ã…dahl <jadahl@gmail.com>2015-03-02 22:56:35 +0800
committerRay Strode <rstrode@redhat.com>2015-03-03 14:53:15 -0500
commitbbcee174ced72b7d447aa185d7413f382b3fbf96 (patch)
treee6d3f4808faacd12a9258914220b1c986ec59d9d
parent9c6e6ea3813666bb31ed4f614d93079be8b84e7e (diff)
downloadmutter-bbcee174ced72b7d447aa185d7413f382b3fbf96.tar.gz
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
-rw-r--r--src/compositor/meta-surface-actor-wayland.c49
-rw-r--r--src/compositor/meta-surface-actor-wayland.h3
-rw-r--r--src/compositor/region-utils.c29
-rw-r--r--src/compositor/region-utils.h2
-rw-r--r--src/wayland/meta-wayland-surface.c51
-rw-r--r--src/wayland/meta-wayland-surface.h2
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 ba4e5175b..7957399d0 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 ed129d7e1..8ef2b05cd 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 a78321d11..1b970ba27 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 16304dc70..526e6ecc9 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 3a6f6b616..1ee1c6920 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 9f8b9de1a..5783a465a 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;