From: Pekka Paalanen Date: Mon, 6 Feb 2012 12:54:20 +0000 (+0200) Subject: compositor: q&d solution for surface drift X-Git-Tag: 20120702.1049~508^2~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ddae03cf9bd0012b96be834a3e4797dfe2f1be6f;p=profile%2Fivi%2Fweston.git compositor: q&d solution for surface drift When a transformed (rotated) surface is continuously resized from its top-left corner, its location will drift. This is due to accumulating rounding errors in transforming an offset from surface-local to global coordinates in surface_attach(). Diminish the drift down to unobservable level by changing the weston_surface global position from integer to float. The offset transformation is now done without rounding. To preserve the precision, wl_shell::configure() interface must use floats, and so does weston_surface_configure(), too. The con of this patch is that it adds inconsistency to the surface position coordinates: sometimes they are floats, sometimes integers. --- diff --git a/src/compositor.c b/src/compositor.c index 6b15a54..bd5d2e7 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -311,12 +311,10 @@ weston_surface_update_transform(struct weston_surface *surface) &surface->transform.boundingbox); } -WL_EXPORT void -weston_surface_to_global(struct weston_surface *surface, - int32_t sx, int32_t sy, int32_t *x, int32_t *y) +static void +surface_to_global_float(struct weston_surface *surface, + int32_t sx, int32_t sy, GLfloat *x, GLfloat *y) { - weston_surface_update_transform(surface); - if (surface->transform.enabled) { struct weston_vector v = { { sx, sy, 0.0f, 1.0f } }; @@ -331,14 +329,27 @@ weston_surface_to_global(struct weston_surface *surface, return; } - *x = floorf(v.f[0] / v.f[3]); - *y = floorf(v.f[1] / v.f[3]); + *x = v.f[0] / v.f[3]; + *y = v.f[1] / v.f[3]; } else { *x = sx + surface->geometry.x; *y = sy + surface->geometry.y; } } +WL_EXPORT void +weston_surface_to_global(struct weston_surface *surface, + int32_t sx, int32_t sy, int32_t *x, int32_t *y) +{ + GLfloat xf, yf; + + weston_surface_update_transform(surface); + + surface_to_global_float(surface, sx, sy, &xf, &yf); + *x = floorf(xf); + *y = floorf(yf); +} + static void surface_from_global_float(struct weston_surface *surface, int32_t x, int32_t y, GLfloat *sx, GLfloat *sy) @@ -449,7 +460,7 @@ weston_surface_flush_damage(struct weston_surface *surface) WL_EXPORT void weston_surface_configure(struct weston_surface *surface, - int x, int y, int width, int height) + GLfloat x, GLfloat y, int width, int height) { weston_surface_damage_below(surface); @@ -1100,12 +1111,11 @@ surface_attach(struct wl_client *client, } else if (sx != 0 || sy != 0 || es->geometry.width != buffer->width || es->geometry.height != buffer->height) { - int32_t from_x, from_y; - int32_t to_x, to_y; + GLfloat from_x, from_y; + GLfloat to_x, to_y; - /* FIXME: this has serious cumulating rounding errors */ - weston_surface_to_global(es, 0, 0, &from_x, &from_y); - weston_surface_to_global(es, sx, sy, &to_x, &to_y); + surface_to_global_float(es, 0, 0, &from_x, &from_y); + surface_to_global_float(es, sx, sy, &to_x, &to_y); shell->configure(shell, es, es->geometry.x + to_x - from_x, es->geometry.y + to_y - from_y, diff --git a/src/compositor.h b/src/compositor.h index 5d12d43..4495412 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -128,7 +128,7 @@ struct weston_shell { int32_t width, int32_t height); void (*configure)(struct weston_shell *shell, struct weston_surface *surface, - int32_t x, int32_t y, int32_t width, int32_t height); + GLfloat x, GLfloat y, int32_t width, int32_t height); void (*destroy)(struct weston_shell *shell); }; @@ -228,7 +228,7 @@ struct weston_surface { * That includes the transformations referenced from the list. */ struct { - int32_t x, y; /* surface translation on display */ + GLfloat x, y; /* surface translation on display */ int32_t width, height; /* struct weston_transform */ @@ -372,7 +372,7 @@ weston_surface_create(struct weston_compositor *compositor); void weston_surface_configure(struct weston_surface *surface, - int x, int y, int width, int height); + GLfloat x, GLfloat y, int width, int height); void weston_surface_assign_output(struct weston_surface *surface); diff --git a/src/shell.c b/src/shell.c index d15c8e2..78120ef 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1397,7 +1397,7 @@ map(struct weston_shell *base, static void configure(struct weston_shell *base, struct weston_surface *surface, - int32_t x, int32_t y, int32_t width, int32_t height) + GLfloat x, GLfloat y, int32_t width, int32_t height) { struct wl_shell *shell = container_of(base, struct wl_shell, shell); int do_configure = !shell->locked; diff --git a/src/tablet-shell.c b/src/tablet-shell.c index 14ac889..bcaba16 100644 --- a/src/tablet-shell.c +++ b/src/tablet-shell.c @@ -141,7 +141,7 @@ tablet_shell_map(struct weston_shell *base, struct weston_surface *surface, static void tablet_shell_configure(struct weston_shell *base, struct weston_surface *surface, - int32_t x, int32_t y, + GLfloat x, GLfloat y, int32_t width, int32_t height) { weston_surface_configure(surface, x, y, width, height);