[PATCH weston 2/2 v3] compositor: add a masking mechanism to weston_layer

Giulio Camuffo giuliocamuffo at gmail.com
Wed Dec 11 09:55:08 PST 2013


this adds a mechanism to mask the views belonging to a layer
to an arbitrary rect, in the global space. The parts that don't fit
in that rect will be clipped away.
Implemented in the gl and pixman renderers, while it needs to be
implemented in the rpi renderer.
---

v3: no new code. added a comment in the rpi renderer about the
    missing implementation.

 src/compositor.c      | 25 ++++++++++++++++++++++++-
 src/compositor.h      |  9 +++++++++
 src/gl-renderer.c     |  4 ++++
 src/pixman-renderer.c |  4 ++++
 src/rpi-renderer.c    |  6 ++++++
 5 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/src/compositor.c b/src/compositor.c
index 260be3c..18b12a0 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1193,10 +1193,14 @@ weston_compositor_pick_view(struct weston_compositor *compositor,
 			    wl_fixed_t *vx, wl_fixed_t *vy)
 {
 	struct weston_view *view;
+        int ix = wl_fixed_to_int(x);
+        int iy = wl_fixed_to_int(y);
 
 	wl_list_for_each(view, &compositor->view_list, link) {
 		weston_view_from_global_fixed(view, x, y, vx, vy);
-		if (pixman_region32_contains_point(&view->surface->input,
+		if (ix >= view->layer->mask.x1 && iy >= view->layer->mask.y1 &&
+		    ix <= view->layer->mask.x2 && iy <= view->layer->mask.y2 &&
+		    pixman_region32_contains_point(&view->surface->input,
 						   wl_fixed_to_int(*vx),
 						   wl_fixed_to_int(*vy),
 						   NULL))
@@ -1652,6 +1656,7 @@ weston_compositor_build_view_list(struct weston_compositor *compositor)
 	wl_list_init(&compositor->view_list);
 	wl_list_for_each(layer, &compositor->layer_list, link) {
 		wl_list_for_each(view, &layer->view_list, layer_link) {
+			view->layer = layer;
 			view_list_add(compositor, view);
 		}
 	}
@@ -1776,11 +1781,29 @@ WL_EXPORT void
 weston_layer_init(struct weston_layer *layer, struct wl_list *below)
 {
 	wl_list_init(&layer->view_list);
+	weston_layer_set_mask_infinite(layer);
 	if (below != NULL)
 		wl_list_insert(below, &layer->link);
 }
 
 WL_EXPORT void
+weston_layer_set_mask(struct weston_layer *layer,
+		      int x, int y, int width, int height)
+{
+	layer->mask.x1 = x;
+	layer->mask.x2 = x + width;
+	layer->mask.y1 = y;
+	layer->mask.y2 = y + height;
+}
+
+WL_EXPORT void
+weston_layer_set_mask_infinite(struct weston_layer *layer)
+{
+	weston_layer_set_mask(layer, INT32_MIN, INT32_MIN,
+				     UINT32_MAX, UINT32_MAX);
+}
+
+WL_EXPORT void
 weston_output_schedule_repaint(struct weston_output *output)
 {
 	struct weston_compositor *compositor = output->compositor;
diff --git a/src/compositor.h b/src/compositor.h
index 6bd637e..9f34d40 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -519,6 +519,7 @@ enum {
 struct weston_layer {
 	struct wl_list view_list;
 	struct wl_list link;
+	pixman_box32_t mask;
 };
 
 struct weston_plane {
@@ -749,6 +750,8 @@ struct weston_view {
 	struct wl_list link;
 	struct wl_list layer_link;
 	struct weston_plane *plane;
+	/* layer is set when building the views list, it's not always valid! */
+	struct weston_layer *layer;
 
 	pixman_region32_t clip;
 	float alpha;                     /* part of geometry, see below */
@@ -976,6 +979,12 @@ void
 weston_layer_init(struct weston_layer *layer, struct wl_list *below);
 
 void
+weston_layer_set_mask(struct weston_layer *layer, int x, int y, int width, int height);
+
+void
+weston_layer_set_mask_infinite(struct weston_layer *layer);
+
+void
 weston_plane_init(struct weston_plane *plane,
 			struct weston_compositor *ec,
 			int32_t x, int32_t y);
diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index 0e5afbe..b4f94eb 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -521,6 +521,10 @@ draw_view(struct weston_view *ev, struct weston_output *output,
 	pixman_region32_intersect(&repaint,
 				  &ev->transform.boundingbox, damage);
 	pixman_region32_subtract(&repaint, &repaint, &ev->clip);
+	pixman_region32_t mask;
+	pixman_region32_init_with_extents(&mask, &ev->layer->mask);
+	pixman_region32_intersect(&repaint, &repaint, &mask);
+	pixman_region32_fini(&mask);
 
 	if (!pixman_region32_not_empty(&repaint))
 		goto out;
diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c
index e854e2a..69d3ed4 100644
--- a/src/pixman-renderer.c
+++ b/src/pixman-renderer.c
@@ -355,6 +355,10 @@ draw_view(struct weston_view *ev, struct weston_output *output,
 	pixman_region32_intersect(&repaint,
 				  &ev->transform.boundingbox, damage);
 	pixman_region32_subtract(&repaint, &repaint, &ev->clip);
+	pixman_region32_t mask;
+	pixman_region32_init_with_extents(&mask, &ev->layer->mask);
+	pixman_region32_intersect(&repaint, &repaint, &mask);
+	pixman_region32_fini(&mask);
 
 	if (!pixman_region32_not_empty(&repaint))
 		goto out;
diff --git a/src/rpi-renderer.c b/src/rpi-renderer.c
index c6b924c..f0e63fd 100644
--- a/src/rpi-renderer.c
+++ b/src/rpi-renderer.c
@@ -694,6 +694,12 @@ rpir_view_compute_rects(struct rpir_view *view,
 	 * huge elements like 8192x8192.
 	 */
 
+	/* XXX: implement layer masking.
+	 * layers can have an axis aligned rectangular mask to clip
+	 * away parts of the views that don't fit into it.
+	 * view->view->layer_link.layer->mask
+	 */
+
 	src_x = 0 << 16;
 	src_y = 0 << 16;
 
-- 
1.8.5.1



More information about the wayland-devel mailing list