diff options
| author | Jonas Ã…dahl <jadahl@gmail.com> | 2015-03-02 22:56:35 +0800 |
|---|---|---|
| committer | Ray Strode <rstrode@redhat.com> | 2015-03-03 14:53:15 -0500 |
| commit | bbcee174ced72b7d447aa185d7413f382b3fbf96 (patch) | |
| tree | e6d3f4808faacd12a9258914220b1c986ec59d9d | |
| parent | 9c6e6ea3813666bb31ed4f614d93079be8b84e7e (diff) | |
| download | mutter-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.c | 49 | ||||
| -rw-r--r-- | src/compositor/meta-surface-actor-wayland.h | 3 | ||||
| -rw-r--r-- | src/compositor/region-utils.c | 29 | ||||
| -rw-r--r-- | src/compositor/region-utils.h | 2 | ||||
| -rw-r--r-- | src/wayland/meta-wayland-surface.c | 51 | ||||
| -rw-r--r-- | 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 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; |
