<p dir="ltr"><br>
On Aug 29, 2014 6:25 PM, "Derek Foreman" <<a href="mailto:derekf@osg.samsung.com">derekf@osg.samsung.com</a>> wrote:<br>
><br>
> On 29/08/14 06:42 PM, Jason Ekstrand wrote:<br>
> > Derek,<br>
> > I haven't had a chance to look that hard at or play with this patch yet.<br>
> > Hopefully I can look at it before too long.  One quick question though:<br>
> > Have you verified that this works with all of the output transforms?  I'm<br>
> > sorry if this seems premature but a) pixman renderer stuff is hard to get<br>
> > right and b) people are constantly breaking the pixman renderer with<br>
> > respect to output transforms.  So I thought the question was worth asking<br>
> > even if I haven't had time to review yet.<br>
><br>
> Ouch - I am now guilty of 'b'</p>
<p dir="ltr">That's OK. I, for one, can never get pixman changes right on the first try.  That's why I asked. ;-)</p>
<p dir="ltr">> Transforms do indeed break - the zoom translation is being applied in<br>
> the wrong direction for some, and the clip region needs to be rotated<br>
> for others.<br>
><br>
> > FWIW, I have a series on my github that accomplishes the same thing only<br>
> > with substantially deeper changes to Weston:<br>
> ><br>
> > <a href="https://github.com/jekstrand/weston/commits/wip/transforms">https://github.com/jekstrand/weston/commits/wip/transforms</a><br>
><br>
> Interesting...<br>
><br>
> I think I can re-work my patch to handle rotations/flips pretty easily,<br>
> though the code will bulk up a little.<br>
><br>
> Is that worth the time, or would you prefer to move forward with yours?</p>
<p dir="ltr">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.</p>

<p dir="ltr">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.</p>

<p dir="ltr">--Jason Ekstrand</p>
<p dir="ltr">> > On Aug 29, 2014 7:56 AM, "Derek Foreman" <<a href="mailto:derekf@osg.samsung.com">derekf@osg.samsung.com</a>> wrote:<br>
> ><br>
> >> Currently if you try to zoom with mod+scrollwheel the pixman<br>
> >> backend will stop rendering anything at all and will continuously<br>
> >> log "pixman renderer does not support zoom", giving the impression<br>
> >> that the server is hung.<br>
> >><br>
> >> Instead, this patch adds the missing zoom functionality.<br>
> >><br>
> >> This should close BUG 80258<br>
> >> ---<br>
> >>  src/pixman-renderer.c | 65<br>
> >> ++++++++++++++++++++++++++++++++++++++++++++++-----<br>
> >>  1 file changed, 59 insertions(+), 6 deletions(-)<br>
> >><br>
> >> diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c<br>
> >> index 4fdcb05..55e8824 100644<br>
> >> --- a/src/pixman-renderer.c<br>
> >> +++ b/src/pixman-renderer.c<br>
> >> @@ -168,6 +168,37 @@ transform_apply_viewport(pixman_transform_t<br>
> >> *transform,<br>
> >>  }<br>
> >><br>
> >>  static void<br>
> >> +region_apply_zoom(struct weston_output *output,<br>
> >> +                 pixman_region32_t *region)<br>
> >> +{<br>
> >> +       pixman_box32_t *rects, *zoomed_rects;<br>
> >> +       int nrects, i;<br>
> >> +       double mag, tx, ty, zoomw, zoomh;<br>
> >> +<br>
> >> +       mag = 1.0 / (1.0 - output->zoom.spring_z.current);<br>
> >> +       zoomw = mag * output->width;<br>
> >> +       zoomh = mag * output->height;<br>
> >> +       tx = output->zoom.trans_x * output->width/2.0;<br>
> >> +       ty = output->zoom.trans_y * output->height/2.0;<br>
> >> +       rects = pixman_region32_rectangles(region, &nrects);<br>
> >> +       zoomed_rects = calloc(nrects, sizeof(pixman_box32_t));<br>
> >> +<br>
> >> +       for (i = 0; i < nrects; i++) {<br>
> >> +               zoomed_rects[i].x1 = (output->width / 2.0)<br>
> >> +                                  + mag * (rects[i].x1 - tx) - zoomw /<br>
> >> 2.0;<br>
> >> +               zoomed_rects[i].x2 = (output->width / 2.0)<br>
> >> +                                  + mag * (rects[i].x2 - tx) - zoomw /<br>
> >> 2.0;<br>
> >> +               zoomed_rects[i].y1 = (output->height / 2.0)<br>
> >> +                                  + mag * (rects[i].y1 - ty) - zoomh /<br>
> >> 2.0;<br>
> >> +               zoomed_rects[i].y2 = (output->height / 2.0)<br>
> >> +                                  + mag * (rects[i].y2 - ty) - zoomh /<br>
> >> 2.0;<br>
> >> +       }<br>
> >> +       pixman_region32_clear(region);<br>
> >> +       pixman_region32_init_rects(region, zoomed_rects, nrects);<br>
> >> +       free(zoomed_rects);<br>
> >> +}<br>
> >> +<br>
> >> +static void<br>
> >>  repaint_region(struct weston_view *ev, struct weston_output *output,<br>
> >>                pixman_region32_t *region, pixman_region32_t *surf_region,<br>
> >>                pixman_op_t pixman_op)<br>
> >> @@ -211,6 +242,10 @@ repaint_region(struct weston_view *ev, struct<br>
> >> weston_output *output,<br>
> >>         /* Convert from global to output coord */<br>
> >>         region_global_to_output(output, &final_region);<br>
> >><br>
> >> +       /* Apply zoom if applicable */<br>
> >> +       if (output->zoom.active)<br>
> >> +               region_apply_zoom(output, &final_region);<br>
> >> +<br>
> >>         /* And clip to it */<br>
> >>         pixman_image_set_clip_region32 (po->shadow_image, &final_region);<br>
> >><br>
> >> @@ -218,6 +253,25 @@ repaint_region(struct weston_view *ev, struct<br>
> >> weston_output *output,<br>
> >>            position, the output position/transform/scale and the client<br>
> >>            specified buffer transform/scale */<br>
> >>         pixman_transform_init_identity(&transform);<br>
> >> +<br>
> >> +       if (output->zoom.active) {<br>
> >> +               double mag, zoomw, zoomh, tx, ty;<br>
> >> +<br>
> >> +               mag = 1.0f - output->zoom.spring_z.current;<br>
> >> +               zoomw = mag * output->width;<br>
> >> +               zoomh = mag * output->height;<br>
> >> +               tx = output->zoom.trans_x * output->width/2.0 - (zoomw -<br>
> >> output->width) / 2.0;<br>
> >> +               ty = output->zoom.trans_y * output->height/2.0 - (zoomh -<br>
> >> output->height) / 2.0;<br>
> >> +<br>
> >> +               pixman_transform_scale(&transform, NULL,<br>
> >> +                                      pixman_double_to_fixed (mag),<br>
> >> +                                      pixman_double_to_fixed (mag));<br>
> >> +<br>
> >> +               pixman_transform_translate(&transform, NULL,<br>
> >> +                                          pixman_double_to_fixed(tx),<br>
> >> +                                          pixman_double_to_fixed(ty));<br>
> >> +       }<br>
> >> +<br>
> >>         pixman_transform_scale(&transform, NULL,<br>
> >>                                pixman_double_to_fixed<br>
> >> ((double)1.0/output->current_scale),<br>
> >>                                pixman_double_to_fixed<br>
> >> ((double)1.0/output->current_scale));<br>
> >> @@ -334,7 +388,8 @@ repaint_region(struct weston_view *ev, struct<br>
> >> weston_output *output,<br>
> >><br>
> >>         pixman_image_set_transform(ps->image, &transform);<br>
> >><br>
> >> -       if (ev->transform.enabled || output->current_scale !=<br>
> >> vp->buffer.scale)<br>
> >> +       if (ev->transform.enabled || output->current_scale !=<br>
> >> vp->buffer.scale<br>
> >> +           || output->zoom.active)<br>
> >>                 pixman_image_set_filter(ps->image, PIXMAN_FILTER_BILINEAR,<br>
> >> NULL, 0);<br>
> >>         else<br>
> >>                 pixman_image_set_filter(ps->image, PIXMAN_FILTER_NEAREST,<br>
> >> NULL, 0);<br>
> >> @@ -403,11 +458,6 @@ draw_view(struct weston_view *ev, struct<br>
> >> weston_output *output,<br>
> >>         if (!pixman_region32_not_empty(&repaint))<br>
> >>                 goto out;<br>
> >><br>
> >> -       if (output->zoom.active) {<br>
> >> -               weston_log("pixman renderer does not support zoom\n");<br>
> >> -               goto out;<br>
> >> -       }<br>
> >> -<br>
> >>         /* TODO: Implement repaint_region_complex() using<br>
> >> pixman_composite_trapezoids() */<br>
> >>         if (ev->alpha != 1.0 ||<br>
> >>             (ev->transform.enabled &&<br>
> >> @@ -455,6 +505,9 @@ copy_to_hw_buffer(struct weston_output *output,<br>
> >> pixman_region32_t *region)<br>
> >><br>
> >>         region_global_to_output(output, &output_region);<br>
> >><br>
> >> +       if (output->zoom.active)<br>
> >> +               region_apply_zoom(output, &output_region);<br>
> >> +<br>
> >>         pixman_image_set_clip_region32 (po->hw_buffer, &output_region);<br>
> >><br>
> >>         pixman_image_composite32(PIXMAN_OP_SRC,<br>
> >> --<br>
> >> 2.1.0.rc1<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">http://lists.freedesktop.org/mailman/listinfo/wayland-devel</a><br>
> >><br>
> ><br>
> ><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">http://lists.freedesktop.org/mailman/listinfo/wayland-devel</a><br>
> ><br>
</p>