On Wed, Nov 28, 2012 at 05:10:26PM +0200, Ander Conselvan de Oliveira wrote:
> The implementation of buffer transformation didn't handle transformed
> shm buffers properly. The partial texture upload was broken since the
> damage is in surface coordinates that don't necessarily match the
> buffer's coordinates. It also wouldn't handle the buffer stride
> properly, resulting in incorrect rendering if it didn't match the
> buffer's width.
> 
> The logic used for converting texture coordinates was generalized and
> moved out of the renderer, since this conversion may be useful in other
> places, such as the backends.

Thanks, committed.

Kristian

> ---
>  src/compositor.c  |   71 ++++++++++++++++++++++++++++++++++++++++++
>  src/compositor.h  |    7 +++++
>  src/gl-renderer.c |   90 
> +++++++++++++++--------------------------------------
>  3 files changed, 103 insertions(+), 65 deletions(-)
> 
> diff --git a/src/compositor.c b/src/compositor.c
> index a965fc2..565212d 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -311,6 +311,77 @@ weston_surface_to_global_float(struct weston_surface 
> *surface,
>  }
>  
>  WL_EXPORT void
> +weston_surface_to_buffer_float(struct weston_surface *surface,
> +                            float sx, float sy, float *bx, float *by)
> +{
> +     switch (surface->buffer_transform) {
> +     case WL_OUTPUT_TRANSFORM_NORMAL:
> +     default:
> +             *bx = sx;
> +             *by = sy;
> +             break;
> +     case WL_OUTPUT_TRANSFORM_FLIPPED:
> +             *bx = surface->geometry.width - sx;
> +             *by = sy;
> +             break;
> +     case WL_OUTPUT_TRANSFORM_90:
> +             *bx = surface->geometry.height - sy;
> +             *by = sx;
> +             break;
> +     case WL_OUTPUT_TRANSFORM_FLIPPED_90:
> +             *bx = surface->geometry.height - sy;
> +             *by = surface->geometry.width - sx;
> +             break;
> +     case WL_OUTPUT_TRANSFORM_180:
> +             *bx = surface->geometry.width - sx;
> +             *by = surface->geometry.height - sy;
> +             break;
> +     case WL_OUTPUT_TRANSFORM_FLIPPED_180:
> +             *bx = sx;
> +             *by = surface->geometry.height - sy;
> +             break;
> +     case WL_OUTPUT_TRANSFORM_270:
> +             *bx = sy;
> +             *by = surface->geometry.width - sx;
> +             break;
> +     case WL_OUTPUT_TRANSFORM_FLIPPED_270:
> +             *bx = sy;
> +             *by = sx;
> +             break;
> +     }
> +}
> +
> +WL_EXPORT pixman_box32_t
> +weston_surface_to_buffer_rect(struct weston_surface *surface,
> +                           pixman_box32_t rect)
> +{
> +     float x1, x2, y1, y2;
> +
> +     pixman_box32_t ret;
> +
> +     weston_surface_to_buffer_float(surface, rect.x1, rect.y1, &x1, &y1);
> +     weston_surface_to_buffer_float(surface, rect.x2, rect.y2, &x2, &y2);
> +
> +     if (x1 <= x2) {
> +             ret.x1 = x1;
> +             ret.x2 = x2;
> +     } else {
> +             ret.x1 = x2;
> +             ret.x2 = x1;
> +     }
> +
> +     if (y1 <= y2) {
> +             ret.y1 = y1;
> +             ret.y2 = y2;
> +     } else {
> +             ret.y1 = y2;
> +             ret.y2 = y1;
> +     }
> +
> +     return ret;
> +}
> +
> +WL_EXPORT void
>  weston_surface_move_to_plane(struct weston_surface *surface,
>                            struct weston_plane *plane)
>  {
> diff --git a/src/compositor.h b/src/compositor.h
> index 48633d4..2547da1 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -506,6 +506,13 @@ weston_surface_buffer_width(struct weston_surface 
> *surface);
>  int32_t
>  weston_surface_buffer_height(struct weston_surface *surface);
>  
> +WL_EXPORT void
> +weston_surface_to_buffer_float(struct weston_surface *surface,
> +                            float x, float y, float *bx, float *by);
> +pixman_box32_t
> +weston_surface_to_buffer_rect(struct weston_surface *surface,
> +                           pixman_box32_t rect);
> +
>  void
>  weston_spring_init(struct weston_spring *spring,
>                  double k, double current, double target);
> diff --git a/src/gl-renderer.c b/src/gl-renderer.c
> index c2fdaa3..664f395 100644
> --- a/src/gl-renderer.c
> +++ b/src/gl-renderer.c
> @@ -517,47 +517,6 @@ calculate_edges(struct weston_surface *es, 
> pixman_box32_t *rect,
>       return n;
>  }
>  
> -static void
> -transform_texcoord(struct weston_surface *es, GLfloat sx, GLfloat sy,
> -                GLfloat *tx, GLfloat *ty)
> -{
> -     switch(es->buffer_transform) {
> -     case WL_OUTPUT_TRANSFORM_NORMAL:
> -     default:
> -             *tx = sx;
> -             *ty = sy;
> -             break;
> -     case WL_OUTPUT_TRANSFORM_FLIPPED:
> -             *tx = 1.0 - sx;
> -             *ty = sy;
> -             break;
> -     case WL_OUTPUT_TRANSFORM_90:
> -             *tx = 1.0 - sy;
> -             *ty = sx;
> -             break;
> -     case WL_OUTPUT_TRANSFORM_FLIPPED_90:
> -             *tx = 1.0 - sy;
> -             *ty = 1.0 - sx;
> -             break;
> -     case WL_OUTPUT_TRANSFORM_180:
> -             *tx = 1.0 - sx;
> -             *ty = 1.0 - sy;
> -             break;
> -     case WL_OUTPUT_TRANSFORM_FLIPPED_180:
> -             *tx = sx;
> -             *ty = 1.0 - sy;
> -             break;
> -     case WL_OUTPUT_TRANSFORM_270:
> -             *tx = sy;
> -             *ty = 1.0 - sx;
> -             break;
> -     case WL_OUTPUT_TRANSFORM_FLIPPED_270:
> -             *tx = sy;
> -             *ty = sx;
> -             break;
> -     }
> -}
> -
>  static int
>  texture_region(struct weston_surface *es, pixman_region32_t *region,
>               pixman_region32_t *surf_region)
> @@ -578,13 +537,23 @@ texture_region(struct weston_surface *es, 
> pixman_region32_t *region,
>       vtxcnt = wl_array_add(&ec->vtxcnt, nrects * nsurf * sizeof *vtxcnt);
>  
>       inv_width = 1.0 / es->pitch;
> -     inv_height = 1.0 / es->geometry.height;
> +
> +     switch (es->buffer_transform) {
> +     case WL_OUTPUT_TRANSFORM_90:
> +     case WL_OUTPUT_TRANSFORM_270:
> +     case WL_OUTPUT_TRANSFORM_FLIPPED_90:
> +     case WL_OUTPUT_TRANSFORM_FLIPPED_270:
> +             inv_height = 1.0 / es->geometry.width;
> +             break;
> +     default:
> +             inv_height = 1.0 / es->geometry.height;
> +     }
>  
>       for (i = 0; i < nrects; i++) {
>               pixman_box32_t *rect = &rects[i];
>               for (j = 0; j < nsurf; j++) {
>                       pixman_box32_t *surf_rect = &surf_rects[j];
> -                     GLfloat sx, sy, tx, ty;
> +                     GLfloat sx, sy, bx, by;
>                       GLfloat ex[8], ey[8];          /* edge points in screen 
> space */
>                       int n;
>  
> @@ -613,12 +582,10 @@ texture_region(struct weston_surface *es, 
> pixman_region32_t *region,
>                               *(v++) = ex[k];
>                               *(v++) = ey[k];
>                               /* texcoord: */
> -                             transform_texcoord(es,
> -                                                sx * inv_width,
> -                                                sy * inv_height,
> -                                                &tx, &ty);
> -                             *(v++) = tx;
> -                             *(v++) = ty;
> +                             weston_surface_to_buffer_float(es, sx, sy,
> +                                                            &bx, &by);
> +                             *(v++) = bx * inv_width;
> +                             *(v++) = by * inv_height;
>                       }
>  
>                       vtxcnt[nvtx++] = n;
> @@ -1107,12 +1074,14 @@ gl_renderer_flush_damage(struct weston_surface 
> *surface)
>       data = wl_shm_buffer_get_data(surface->buffer);
>       rectangles = pixman_region32_rectangles(&surface->texture_damage, &n);
>       for (i = 0; i < n; i++) {
> -             glPixelStorei(GL_UNPACK_SKIP_PIXELS, rectangles[i].x1);
> -             glPixelStorei(GL_UNPACK_SKIP_ROWS, rectangles[i].y1);
> -             glTexSubImage2D(GL_TEXTURE_2D, 0,
> -                             rectangles[i].x1, rectangles[i].y1,
> -                             rectangles[i].x2 - rectangles[i].x1,
> -                             rectangles[i].y2 - rectangles[i].y1,
> +             pixman_box32_t r;
> +
> +             r = weston_surface_to_buffer_rect(surface, rectangles[i]);
> +
> +             glPixelStorei(GL_UNPACK_SKIP_PIXELS, r.x1);
> +             glPixelStorei(GL_UNPACK_SKIP_ROWS, r.y1);
> +             glTexSubImage2D(GL_TEXTURE_2D, 0, r.x1, r.y1,
> +                             r.x2 - r.x1, r.y2 - r.y1,
>                               GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
>       }
>  #endif
> @@ -1228,16 +1197,7 @@ gl_renderer_attach(struct weston_surface *es, struct 
> wl_buffer *buffer)
>                                                   gs->images[i]);
>               }
>  
> -             switch(es->buffer_transform) {
> -             case WL_OUTPUT_TRANSFORM_90:
> -             case WL_OUTPUT_TRANSFORM_270:
> -             case WL_OUTPUT_TRANSFORM_FLIPPED_90:
> -             case WL_OUTPUT_TRANSFORM_FLIPPED_270:
> -                     es->pitch = buffer->height;
> -                     break;
> -             default:
> -                     es->pitch = buffer->width;
> -             }
> +             es->pitch = buffer->width;
>       } else {
>               weston_log("unhandled buffer type!\n");
>       }
> -- 
> 1.7.10.4
> 
> _______________________________________________
> 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

Reply via email to