On Aug 29, 2014 6:25 PM, "Derek Foreman" <[email protected]> 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" <[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
