summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;