[PATCH 2/2] compositor: add a masking mechanism to weston_layer
Ander Conselvan de Oliveira
conselvan2 at gmail.com
Tue Jan 28 08:21:40 PST 2014
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().
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