[PATCH weston 2/4] compositor: add weston_view_set_mask() API and state

Pekka Paalanen ppaalanen at gmail.com
Wed Mar 4 01:52:27 PST 2015


On Tue, 03 Mar 2015 16:50:47 -0600
Derek Foreman <derekf at osg.samsung.com> wrote:

> Minor pedantry below.
> 
> On 02/03/15 09:15 AM, Pekka Paalanen wrote:
> > From: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
> > 
> > Add API for setting a clip ('scissor' in the code) rectangle per view,
> > in surface coordinates. Ivi-shell requires this feature to be able to
> > implement the IVI Layer Manager API, which includes clipping of
> > surfaces.
> > 
> > The names weston_view_set_mask() and weston_view_set_mask_infinite()
> > mirror the existing weston_layer_set_mask*() functions.
> > 
> > This view clipping complements the weston_layer clipping, because view
> > clipping is defined in surface local coordinates, while layer
> > mask/clipping is defined in global coordinates.
> > 
> > View clipping requires explicit support from the renderers. Therefore a
> > new Weston capability bit is added: WESTON_CAP_VIEW_CLIP_MASK. Shells
> > (and all users) of this new API are required to check the capability bit
> > is set before using the API. Otherwise the rendering will not be what
> > they expect.
> > 
> > View clips are inherited through the transformation inheritance
> > mechanism. However, there are restrictions. The clip rectangle can be
> > set only on the root view of a transformation inheritance tree. The
> > additional transformations in child views must not rotate the coordinate
> > axes. These restrictions avoid corner cases in clip inheritance, and
> > keep the renderer implementations as simple as they are right now.
> > Renderers only need to do an additional intersection with the clip
> > rectangle which is always aligned to the surface coordinate system.
> > 
> > For more details, see the API documentation in the patch.
> > 
> > Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
> > Reviewed-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA at xddp.denso.co.jp>
> > Tested-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA at xddp.denso.co.jp>
> > ---
> >  src/compositor.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
> >  src/compositor.h |  14 +++++
> >  2 files changed, 169 insertions(+), 9 deletions(-)

...

> > +/** Set a clip mask rectangle on a view
> > + *
> > + * \param view The view to set the clip mask on.
> > + * \param x Top-left corner X coordinate of the clip rectangle.
> > + * \param y Top-left corner X coordinate of the clip rectangle.
> 
> Should say Y coordinate...

Oops :-)

> > + * \param width Width of the clip rectangle, non-negative.
> > + * \param height Height of the clip rectangle, non-negative.
> > + *
> > + * A shell may set a clip mask rectangle on a view. Everything outside
> > + * the rectangle is cut away for input and output purposes: it is
> > + * not drawn and cannot be hit by hit-test based input like pointer
> > + * motion or touch-downs. Everything inside the rectangle will behave
> > + * normal. Clients are unaware of clipping.
> 
> s/normally/normally/
> 
> > + *
> > + * The rectangle is set in the surface local coordinates. Setting a clip
> > + * mask rectangle does not affect the view position, the view is positioned
> > + * as it would be without a clip. The clip also does not change
> > + * weston_surface::width,height.
> > + *
> > + * The clip mask rectangle is part of transformation inheritance
> > + * (weston_view_set_transform_parent()). A clip set in the root of the
> > + * transformation inheritance tree will affect all views in the tree.
> > + * A clip can be set only on the root view. Attempting to set a clip
> > + * on view that has a transformation parent will fail. Assigning a parent
> > + * to a view that has a clip set will cause the clip to be forgotten.
> > + *
> > + * Because the clip mask is an axis-aligned rectangle, it poses restrictions
> > + * on the additional transformations in the child views. These transformations
> > + * may not rotate the coordinate axes, i.e., only translation and scaling
> > + * are allowed. Violating this restriction causes the clipping to malfcuntion.
> 
> malfunction
> 
> > + * Furthermore, using scaling may cause rounding errors in child clipping.
> > + *
> > + * The clip mask rectangle is not automatically adjusted based on
> > + * wl_surface.attach dx and dy arguments.
> > + *
> > + * A clip mask rectangle can be set only if the compositor capability
> > + * WESTON_CAP_VIEW_CLIP_MASK is present.
> > + *
> > + * This function sets the clip mask rectangle and schedules a repaint for
> > + * the view.
> > + */
> > +WL_EXPORT void
> > +weston_view_set_mask(struct weston_view *view,
> > +		     int x, int y, int width, int height)
> > +{
> > +	struct weston_compositor *compositor = view->surface->compositor;
> > +
> > +	if (!(compositor->capabilities & WESTON_CAP_VIEW_CLIP_MASK)) {
> > +		weston_log("%s not allowed without capability!\n", __func__);
> > +		return;
> > +	}
> > +
> > +	if (view->geometry.parent) {
> > +		weston_log("view %p has a parent, clip forbidden!\n", view);
> > +		return;
> > +	}
> > +
> > +	if (width < 0 || height < 0) {
> > +		weston_log("%s: illegal args %d, %d, %d, %d\n", __func__,
> > +			   x, y, width, height);
> > +		return;
> > +	}
> > +
> > +	pixman_region32_fini(&view->geometry.scissor);
> > +	pixman_region32_init_rect(&view->geometry.scissor, x, y, width, height);
> 
> Should x, y, width, height be validated/clamped in some way?  If width
> and height are set very large they can affect weston_compositor_pick_view()?

I don't think they should be clamped, because the underlying surface
size may change after the scissor is set, and I want the scissor to
remain what it was set to. Semantic validation is up to the shell
calling this API.

Nothing bad should happen in pick_view, the scissor is just another
condition to match in addition to all the old ones.

Everywhere where the scissor is used, it should be just an additional
limitation. I shouldn't be able to "expand" what was already there,
only limit.

> > +	view->geometry.scissor_enabled = true;
> > +	weston_view_geometry_dirty(view);
> > +	weston_view_schedule_repaint(view);
> > +}
> > +
> > +/** Remove the clip mask from a view
> > + *
> > + * \param view The view to remove the clip mask from.
> > + *
> > + * Removed the clip mask rectangle and schedules a repaint.
> > + *
> > + * \sa weston_view_set_mask
> > + */
> > +WL_EXPORT void
> > +weston_view_set_mask_infinite(struct weston_view *view)
> > +{
> > +	view->geometry.scissor_enabled = false;
> > +	weston_view_geometry_dirty(view);
> > +	weston_view_schedule_repaint(view);
> > +}
> > +
> >  WL_EXPORT bool
> >  weston_view_is_mapped(struct weston_view *view)
> >  {
> > @@ -1561,6 +1699,11 @@ weston_compositor_pick_view(struct weston_compositor *compositor,
> >  						    view_ix, view_iy, NULL))
> >  			continue;
> >  
> > +		if (view->geometry.scissor_enabled &&
> > +		    !pixman_region32_contains_point(&view->geometry.scissor,
> > +						    view_ix, view_iy, NULL))
> > +			continue;

If scissor is set, it is just another condition that a surface need to
pass to be picked. Note, the 'continue' means "failed the hit test".

> > +
> >  		*vx = view_x;
> >  		*vy = view_y;
> >  		return view;

Are you happy with the explanations?
I fixed all the typos, and will push if you are. :-)


Thanks,
pq


More information about the wayland-devel mailing list