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" <[email protected]> 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 >> [email protected] >> http://lists.freedesktop.org/mailman/listinfo/wayland-devel >> > > > > _______________________________________________ > wayland-devel mailing list > [email protected] > http://lists.freedesktop.org/mailman/listinfo/wayland-devel > _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
