[PATCH] pixman-backend: add support for zooming
Jason Ekstrand
jason at jlekstrand.net
Fri Aug 29 23:35:37 PDT 2014
On Aug 29, 2014 6:25 PM, "Derek Foreman" <derekf at osg.samsung.com> wrote:
>
> On 29/08/14 06:42 PM, Jason Ekstrand wrote:
> > Derek,
> > I haven't had a chance to look that hard at or play with this patch yet.
> > Hopefully I can look at it before too long. One quick question though:
> > Have you verified that this works with all of the output transforms?
I'm
> > sorry if this seems premature but a) pixman renderer stuff is hard to
get
> > right and b) people are constantly breaking the pixman renderer with
> > respect to output transforms. So I thought the question was worth
asking
> > even if I haven't had time to review yet.
>
> Ouch - I am now guilty of 'b'
That's OK. I, for one, can never get pixman changes right on the first
try. That's why I asked. ;-)
> Transforms do indeed break - the zoom translation is being applied in
> the wrong direction for some, and the clip region needs to be rotated
> for others.
>
> > FWIW, I have a series on my github that accomplishes the same thing only
> > with substantially deeper changes to Weston:
> >
> > https://github.com/jekstrand/weston/commits/wip/transforms
>
> Interesting...
>
> I think I can re-work my patch to handle rotations/flips pretty easily,
> though the code will bulk up a little.
>
> Is that worth the time, or would you prefer to move forward with yours?
I think mine is ultimately a better way forward. The big advantage is that
it provides a surface to/from buffer coordinates matrix and gets rid of all
of the transform logic from the pixman renderer. Part of the reason the
pixman renderer is always breaking is that it's a separate render/transform
path from the go renderer and the two can get out of sync. Also, pixman
does things more-or-less backwards from GL so it's hard to get right.
My patches shouldn't need much of a rebase. The reason I never pushed them
was that fixing zoom in the pixman renderer was never the end objective and
I never considered the series really finished. However, if else want
zoom+pixman, they are probably good to go.
--Jason Ekstrand
> > On Aug 29, 2014 7:56 AM, "Derek Foreman" <derekf at osg.samsung.com> wrote:
> >
> >> Currently if you try to zoom with mod+scrollwheel the pixman
> >> backend will stop rendering anything at all and will continuously
> >> log "pixman renderer does not support zoom", giving the impression
> >> that the server is hung.
> >>
> >> Instead, this patch adds the missing zoom functionality.
> >>
> >> This should close BUG 80258
> >> ---
> >> src/pixman-renderer.c | 65
> >> ++++++++++++++++++++++++++++++++++++++++++++++-----
> >> 1 file changed, 59 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c
> >> index 4fdcb05..55e8824 100644
> >> --- a/src/pixman-renderer.c
> >> +++ b/src/pixman-renderer.c
> >> @@ -168,6 +168,37 @@ transform_apply_viewport(pixman_transform_t
> >> *transform,
> >> }
> >>
> >> static void
> >> +region_apply_zoom(struct weston_output *output,
> >> + pixman_region32_t *region)
> >> +{
> >> + pixman_box32_t *rects, *zoomed_rects;
> >> + int nrects, i;
> >> + double mag, tx, ty, zoomw, zoomh;
> >> +
> >> + mag = 1.0 / (1.0 - output->zoom.spring_z.current);
> >> + zoomw = mag * output->width;
> >> + zoomh = mag * output->height;
> >> + tx = output->zoom.trans_x * output->width/2.0;
> >> + ty = output->zoom.trans_y * output->height/2.0;
> >> + rects = pixman_region32_rectangles(region, &nrects);
> >> + zoomed_rects = calloc(nrects, sizeof(pixman_box32_t));
> >> +
> >> + for (i = 0; i < nrects; i++) {
> >> + zoomed_rects[i].x1 = (output->width / 2.0)
> >> + + mag * (rects[i].x1 - tx) - zoomw /
> >> 2.0;
> >> + zoomed_rects[i].x2 = (output->width / 2.0)
> >> + + mag * (rects[i].x2 - tx) - zoomw /
> >> 2.0;
> >> + zoomed_rects[i].y1 = (output->height / 2.0)
> >> + + mag * (rects[i].y1 - ty) - zoomh /
> >> 2.0;
> >> + zoomed_rects[i].y2 = (output->height / 2.0)
> >> + + mag * (rects[i].y2 - ty) - zoomh /
> >> 2.0;
> >> + }
> >> + pixman_region32_clear(region);
> >> + pixman_region32_init_rects(region, zoomed_rects, nrects);
> >> + free(zoomed_rects);
> >> +}
> >> +
> >> +static void
> >> repaint_region(struct weston_view *ev, struct weston_output *output,
> >> pixman_region32_t *region, pixman_region32_t
*surf_region,
> >> pixman_op_t pixman_op)
> >> @@ -211,6 +242,10 @@ repaint_region(struct weston_view *ev, struct
> >> weston_output *output,
> >> /* Convert from global to output coord */
> >> region_global_to_output(output, &final_region);
> >>
> >> + /* Apply zoom if applicable */
> >> + if (output->zoom.active)
> >> + region_apply_zoom(output, &final_region);
> >> +
> >> /* And clip to it */
> >> pixman_image_set_clip_region32 (po->shadow_image,
&final_region);
> >>
> >> @@ -218,6 +253,25 @@ repaint_region(struct weston_view *ev, struct
> >> weston_output *output,
> >> position, the output position/transform/scale and the client
> >> specified buffer transform/scale */
> >> pixman_transform_init_identity(&transform);
> >> +
> >> + if (output->zoom.active) {
> >> + double mag, zoomw, zoomh, tx, ty;
> >> +
> >> + mag = 1.0f - output->zoom.spring_z.current;
> >> + zoomw = mag * output->width;
> >> + zoomh = mag * output->height;
> >> + tx = output->zoom.trans_x * output->width/2.0 - (zoomw
-
> >> output->width) / 2.0;
> >> + ty = output->zoom.trans_y * output->height/2.0 -
(zoomh -
> >> output->height) / 2.0;
> >> +
> >> + pixman_transform_scale(&transform, NULL,
> >> + pixman_double_to_fixed (mag),
> >> + pixman_double_to_fixed (mag));
> >> +
> >> + pixman_transform_translate(&transform, NULL,
> >> + pixman_double_to_fixed(tx),
> >> + pixman_double_to_fixed(ty));
> >> + }
> >> +
> >> pixman_transform_scale(&transform, NULL,
> >> pixman_double_to_fixed
> >> ((double)1.0/output->current_scale),
> >> pixman_double_to_fixed
> >> ((double)1.0/output->current_scale));
> >> @@ -334,7 +388,8 @@ repaint_region(struct weston_view *ev, struct
> >> weston_output *output,
> >>
> >> pixman_image_set_transform(ps->image, &transform);
> >>
> >> - if (ev->transform.enabled || output->current_scale !=
> >> vp->buffer.scale)
> >> + if (ev->transform.enabled || output->current_scale !=
> >> vp->buffer.scale
> >> + || output->zoom.active)
> >> pixman_image_set_filter(ps->image,
PIXMAN_FILTER_BILINEAR,
> >> NULL, 0);
> >> else
> >> pixman_image_set_filter(ps->image,
PIXMAN_FILTER_NEAREST,
> >> NULL, 0);
> >> @@ -403,11 +458,6 @@ draw_view(struct weston_view *ev, struct
> >> weston_output *output,
> >> if (!pixman_region32_not_empty(&repaint))
> >> goto out;
> >>
> >> - if (output->zoom.active) {
> >> - weston_log("pixman renderer does not support zoom\n");
> >> - goto out;
> >> - }
> >> -
> >> /* TODO: Implement repaint_region_complex() using
> >> pixman_composite_trapezoids() */
> >> if (ev->alpha != 1.0 ||
> >> (ev->transform.enabled &&
> >> @@ -455,6 +505,9 @@ copy_to_hw_buffer(struct weston_output *output,
> >> pixman_region32_t *region)
> >>
> >> region_global_to_output(output, &output_region);
> >>
> >> + if (output->zoom.active)
> >> + region_apply_zoom(output, &output_region);
> >> +
> >> pixman_image_set_clip_region32 (po->hw_buffer, &output_region);
> >>
> >> pixman_image_composite32(PIXMAN_OP_SRC,
> >> --
> >> 2.1.0.rc1
> >>
> >> _______________________________________________
> >> wayland-devel mailing list
> >> wayland-devel at lists.freedesktop.org
> >> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
> >>
> >
> >
> >
> > _______________________________________________
> > wayland-devel mailing list
> > wayland-devel at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/wayland-devel
> >
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20140829/cd76a987/attachment-0001.html>
More information about the wayland-devel
mailing list