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

Giulio Camuffo giuliocamuffo at gmail.com
Tue Jan 28 08:36:39 PST 2014


2014-01-28 Ander Conselvan de Oliveira <conselvan2 at gmail.com>:
> On 01/27/2014 09:46 PM, Giulio Camuffo wrote:
>>
>> 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 only for now.
>> ---
>>   src/compositor.c      | 26 +++++++++++++++++++++++++-
>>   src/compositor.h      |  7 +++++++
>>   src/gl-renderer.c     |  4 ++++
>>   src/pixman-renderer.c |  4 ++++
>>   4 files changed, 40 insertions(+), 1 deletion(-)
>>
>> diff --git a/src/compositor.c b/src/compositor.c
>> index 9a269e5..25068b8 100644
>
>
> [...]
>
>
>> diff --git a/src/gl-renderer.c b/src/gl-renderer.c
>> index 0e5afbe..899c280 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_link.layer->mask);
>> +       pixman_region32_intersect(&repaint, &repaint, &mask);
>> +       pixman_region32_fini(&mask);
>
>
> There are more things you need to consider in order to clip properly.
>
> 1) Opaque region. This is used to avoid rendering obscured parts of
> surfaces. In compositor_accumulate_damage(), a clip region for each surface
> is determined as the union of the opaque regions of the surfaces on top of
> it. That way, the parts of the surface that are covered by other opaque
> content is not rendered.
>
> You can see the effect of this relatively easily. Patch desktop-shell to set
> a clip for the workspace layer that is smaller than the screen. Then running
> Weston with the X11 backend (or just make sure you have a software rendered
> cursor), open a weston-terminal and move it so that it crosses the border of
> the clipped region. Then move the mouse over the region that should be part
> of the terminal but is clipped away. Notice how the background is not
> redrawn properly.
>
> In order to fix this, the opaque region used for calculating the surface
> clip also needs to be clipped.
>
> 2) Sprite planes. There's another path through which content can get to the
> screen. When a view is put on a sprite plane, it complete bypasses the
> renderer. During the repaint process, the core gives the backend a chance to
> move views to different planes. At that moment, the backend could configure
> the sprite plane to clip the surface or just decide to not to use a sprite
> plane for it. However, it needs the clipping information to make that
> decision.
>
> If I understand correctly, the rpi backend relies heavily on planes. The DRM
> backend has support for sprite planes too, but it is disabled since it can't
> work correctly without a patched kernel. You can try it (with a regular
> kernel) by pressing mod-shift-space followed by 'v'. If you run
> weston-simple-egl -o, you'll notice the clipping won't work when the surface
> is in a sprite plane.
>
>
> Given the points above, I believe it would be better to keep the information
> related to clipping in the weston_view structure. That way the backend and
> the renderer can be completely unaware of the existence of layers. The
> clipping information can be propagated from the layers to the views in the
> beginning of weston_output_repaint() and/or as part of
> weston_view_update_transform().

What's the difference between using view->layer.mask or using
view->mask? I don't seen how the latter helps anything in any way.
Besides, if the mask is in the view it should be in view space, but
that means adding complexity for no real benefit.

>
>
> Cheers,
> Ander
>
>
>
>
>>
>>         if (!pixman_region32_not_empty(&repaint))
>>                 goto out;
>> diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c
>> index 26f6f27..511dd8b 100644
>> --- a/src/pixman-renderer.c
>> +++ b/src/pixman-renderer.c
>> @@ -374,6 +374,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_link.layer->mask);
>> +       pixman_region32_intersect(&repaint, &repaint, &mask);
>> +       pixman_region32_fini(&mask);
>>
>>         if (!pixman_region32_not_empty(&repaint))
>>                 goto out;
>>
>


More information about the wayland-devel mailing list