<div dir="ltr"><div>One comment below. Otherwise, it looks good (though I haven't tested it yet.) Also, I'd like to decide what I think about the first patch before merging. I'll get back to you Monday or Tuesday.<br>
</div>--Jason<br><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jul 9, 2014 at 12:12 PM, Giulio Camuffo <span dir="ltr"><<a href="mailto:giuliocamuffo@gmail.com" target="_blank">giuliocamuffo@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">this adds a mechanism to mask the views belonging to a layer<br>
to an arbitrary rect, in the global space. The parts that don't fit<br>
in that rect will be clipped away.<br>
Supported by the gl and pixman renderer only for now.<br>
---<br>
src/compositor.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++---<br>
src/compositor.h | 10 +++++++++<br>
src/gl-renderer.c | 2 +-<br>
src/pixman-renderer.c | 2 +-<br>
4 files changed, 70 insertions(+), 5 deletions(-)<br>
<br>
diff --git a/src/compositor.c b/src/compositor.c<br>
index 1d8d00e..2b52b4f 100644<br>
--- a/src/compositor.c<br>
+++ b/src/compositor.c<br>
@@ -349,8 +349,11 @@ weston_view_create(struct weston_surface *surface)<br>
<br>
view->plane = NULL;<br>
view->layer_link.layer = NULL;<br>
+ view->parent_view = NULL;<br>
<br>
pixman_region32_init(&view->clip);<br>
+ pixman_region32_init(&view->transform.masked_boundingbox);<br>
+ pixman_region32_init(&view->transform.masked_opaque);<br>
<br>
view->alpha = 1.0;<br>
pixman_region32_init(&view->transform.opaque);<br>
@@ -783,7 +786,7 @@ weston_view_damage_below(struct weston_view *view)<br>
pixman_region32_t damage;<br>
<br>
pixman_region32_init(&damage);<br>
- pixman_region32_subtract(&damage, &view->transform.boundingbox,<br>
+ pixman_region32_subtract(&damage, &view->transform.masked_boundingbox,<br>
&view->clip);<br>
if (view->plane)<br>
pixman_region32_union(&view->plane->damage,<br>
@@ -1009,10 +1012,20 @@ weston_view_update_transform_enable(struct weston_view *view)<br>
return 0;<br>
}<br>
<br>
+static struct weston_layer *<br>
+get_view_layer(struct weston_view *view)<br>
+{<br>
+ if (view->parent_view)<br>
+ return get_view_layer(view->parent_view);<br>
+ return view->layer_link.layer;<br>
+}<br>
+<br>
WL_EXPORT void<br>
weston_view_update_transform(struct weston_view *view)<br>
{<br>
struct weston_view *parent = view->geometry.parent;<br>
+ struct weston_layer *layer;<br>
+ pixman_region32_t mask;<br>
<br>
if (!view->transform.dirty)<br>
return;<br>
@@ -1040,6 +1053,16 @@ weston_view_update_transform(struct weston_view *view)<br>
weston_view_update_transform_disable(view);<br>
}<br>
<br>
+ layer = get_view_layer(view);<br>
+ if (layer) {<br>
+ pixman_region32_init_with_extents(&mask, &layer->mask);<br>
+ pixman_region32_intersect(&view->transform.masked_boundingbox,<br>
+ &view->transform.boundingbox, &mask);<br>
+ pixman_region32_intersect(&view->transform.masked_opaque,<br>
+ &view->transform.opaque, &mask);<br>
+ pixman_region32_fini(&mask);<br>
+ }<br></blockquote><div><br></div><div>Don't you want an else case here that just blindly copies the regions? Maybe it doesn't matter since in that case we're not on a layer. However, there should at least be a comment to this effect.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
weston_view_damage_below(view);<br>
<br>
weston_view_assign_output(view);<br>
@@ -1331,10 +1354,15 @@ weston_compositor_pick_view(struct weston_compositor *compositor,<br>
wl_fixed_t *vx, wl_fixed_t *vy)<br>
{<br>
struct weston_view *view;<br>
+ int ix = wl_fixed_to_int(x);<br>
+ int iy = wl_fixed_to_int(y);<br>
<br>
wl_list_for_each(view, &compositor->view_list, link) {<br>
weston_view_from_global_fixed(view, x, y, vx, vy);<br>
- if (pixman_region32_contains_point(&view->surface->input,<br>
+ if (pixman_region32_contains_point(<br>
+ &view->transform.masked_boundingbox,<br>
+ ix, iy, NULL) &&<br>
+ pixman_region32_contains_point(&view->surface->input,<br>
wl_fixed_to_int(*vx),<br>
wl_fixed_to_int(*vy),<br>
NULL))<br>
@@ -1426,6 +1454,8 @@ weston_view_destroy(struct weston_view *view)<br>
<br>
pixman_region32_fini(&view->clip);<br>
pixman_region32_fini(&view->transform.boundingbox);<br>
+ pixman_region32_fini(&view->transform.masked_boundingbox);<br>
+ pixman_region32_fini(&view->transform.masked_opaque);<br>
<br>
weston_view_set_transform_parent(view, NULL);<br>
<br>
@@ -1625,7 +1655,7 @@ view_accumulate_damage(struct weston_view *view,<br>
&view->plane->damage, &damage);<br>
pixman_region32_fini(&damage);<br>
pixman_region32_copy(&view->clip, opaque);<br>
- pixman_region32_union(opaque, opaque, &view->transform.opaque);<br>
+ pixman_region32_union(opaque, opaque, &view->transform.masked_opaque);<br>
}<br>
<br>
static void<br>
@@ -1740,6 +1770,7 @@ view_list_add_subsurface_view(struct weston_compositor *compositor,<br>
weston_view_set_transform_parent(view, parent);<br>
}<br>
<br>
+ view->parent_view = parent;<br>
weston_view_update_transform(view);<br>
<br>
if (wl_list_empty(&sub->surface->subsurface_list)) {<br>
@@ -1933,11 +1964,35 @@ weston_layer_init(struct weston_layer *layer, struct wl_list *below)<br>
{<br>
wl_list_init(&layer->view_list.link);<br>
layer->view_list.layer = layer;<br>
+ weston_layer_set_mask_infinite(layer);<br>
if (below != NULL)<br>
wl_list_insert(below, &layer->link);<br>
}<br>
<br>
WL_EXPORT void<br>
+weston_layer_set_mask(struct weston_layer *layer,<br>
+ int x, int y, int width, int height)<br>
+{<br>
+ struct weston_view *view;<br>
+<br>
+ layer->mask.x1 = x;<br>
+ layer->mask.x2 = x + width;<br>
+ layer->mask.y1 = y;<br>
+ layer->mask.y2 = y + height;<br>
+<br>
+ wl_list_for_each(view, &layer->view_list.link, layer_link.link) {<br>
+ weston_view_geometry_dirty(view);<br>
+ }<br>
+}<br>
+<br>
+WL_EXPORT void<br>
+weston_layer_set_mask_infinite(struct weston_layer *layer)<br>
+{<br>
+ weston_layer_set_mask(layer, INT32_MIN, INT32_MIN,<br>
+ UINT32_MAX, UINT32_MAX);<br>
+}<br>
+<br>
+WL_EXPORT void<br>
weston_output_schedule_repaint(struct weston_output *output)<br>
{<br>
struct weston_compositor *compositor = output->compositor;<br>
diff --git a/src/compositor.h b/src/compositor.h<br>
index 78a59cb..23323de 100644<br>
--- a/src/compositor.h<br>
+++ b/src/compositor.h<br>
@@ -534,6 +534,7 @@ struct weston_layer_entry {<br>
struct weston_layer {<br>
struct weston_layer_entry view_list;<br>
struct wl_list link;<br>
+ pixman_box32_t mask;<br>
};<br>
<br>
struct weston_plane {<br>
@@ -738,6 +739,7 @@ struct weston_view {<br>
struct wl_list link;<br>
struct weston_layer_entry layer_link;<br>
struct weston_plane *plane;<br>
+ struct weston_view *parent_view;<br>
<br>
pixman_region32_t clip;<br>
float alpha; /* part of geometry, see below */<br>
@@ -769,6 +771,8 @@ struct weston_view {<br>
<br>
pixman_region32_t boundingbox;<br>
pixman_region32_t opaque;<br>
+ pixman_region32_t masked_boundingbox;<br>
+ pixman_region32_t masked_opaque;<br>
<br>
/* matrix and inverse are used only if enabled = 1.<br>
* If enabled = 0, use x, y, width, height directly.<br>
@@ -1010,6 +1014,12 @@ void<br>
weston_layer_init(struct weston_layer *layer, struct wl_list *below);<br>
<br>
void<br>
+weston_layer_set_mask(struct weston_layer *layer, int x, int y, int width, int height);<br>
+<br>
+void<br>
+weston_layer_set_mask_infinite(struct weston_layer *layer);<br>
+<br>
+void<br>
weston_plane_init(struct weston_plane *plane,<br>
struct weston_compositor *ec,<br>
int32_t x, int32_t y);<br>
diff --git a/src/gl-renderer.c b/src/gl-renderer.c<br>
index 63af75d..f7f29b3 100644<br>
--- a/src/gl-renderer.c<br>
+++ b/src/gl-renderer.c<br>
@@ -542,7 +542,7 @@ draw_view(struct weston_view *ev, struct weston_output *output,<br>
<br>
pixman_region32_init(&repaint);<br>
pixman_region32_intersect(&repaint,<br>
- &ev->transform.boundingbox, damage);<br>
+ &ev->transform.masked_boundingbox, damage);<br>
pixman_region32_subtract(&repaint, &repaint, &ev->clip);<br>
<br>
if (!pixman_region32_not_empty(&repaint))<br>
diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c<br>
index 93be968..a816d02 100644<br>
--- a/src/pixman-renderer.c<br>
+++ b/src/pixman-renderer.c<br>
@@ -397,7 +397,7 @@ draw_view(struct weston_view *ev, struct weston_output *output,<br>
<br>
pixman_region32_init(&repaint);<br>
pixman_region32_intersect(&repaint,<br>
- &ev->transform.boundingbox, damage);<br>
+ &ev->transform.masked_boundingbox, damage);<br>
pixman_region32_subtract(&repaint, &repaint, &ev->clip);<br>
<br>
if (!pixman_region32_not_empty(&repaint))<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.0.0<br>
<br>
_______________________________________________<br>
wayland-devel mailing list<br>
<a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/wayland-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/wayland-devel</a><br>
</font></span></blockquote></div><br></div></div></div></div>