[PATCH] pixman-backend: add support for zooming

Jason Ekstrand jason at jlekstrand.net
Fri Aug 29 16:42:44 PDT 2014


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.

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

--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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20140829/c3aae9ea/attachment.html>


More information about the wayland-devel mailing list