[PATCH] pixman-backend: add support for zooming

Derek Foreman derekf at osg.samsung.com
Fri Aug 29 18:24:59 PDT 2014


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'

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?

> --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
> 


More information about the wayland-devel mailing list