summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Ekstrand <jason@jlekstrand.net>2014-05-20 17:57:08 -0500
committerJason Ekstrand <jason@jlekstrand.net>2014-05-20 17:57:08 -0500
commite9714f83056f654c32630d1441650c8b888dbf81 (patch)
treed24e8e5a12f7bd883f4c5e1667998fc3a98011e2
parent25b633a320e8a20d425524bc4d856fe59bc61d17 (diff)
weston_surface: Add surface-to-buffer and buffer-to-surface matrices
-rw-r--r--src/compositor.c81
-rw-r--r--src/compositor.h6
2 files changed, 87 insertions, 0 deletions
diff --git a/src/compositor.c b/src/compositor.c
index 5f5722a3..c6aaaf3e 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -2042,6 +2042,82 @@ weston_surface_commit_subsurface_order(struct weston_surface *surface)
}
static void
+weston_surface_build_buffer_matrix(struct weston_surface *surface,
+ struct weston_matrix *matrix)
+{
+ struct weston_buffer_viewport *vp = &surface->buffer_viewport;
+ double src_width, src_height, dest_width, dest_height;
+
+ weston_matrix_init(matrix);
+
+ if (vp->buffer.src_width == wl_fixed_from_int(-1)) {
+ src_width = surface->width_from_buffer;
+ src_height = surface->height_from_buffer;
+ } else {
+ src_width = wl_fixed_to_double(vp->buffer.src_width);
+ src_height = wl_fixed_to_double(vp->buffer.src_height);
+ }
+
+ if (vp->surface.width == -1) {
+ dest_width = src_width;
+ dest_height = src_height;
+ } else {
+ dest_width = vp->surface.width;
+ dest_height = vp->surface.height;
+ }
+
+ if (src_width != dest_width || src_height != dest_height)
+ weston_matrix_scale(matrix,
+ src_width / dest_width,
+ src_height / dest_height, 1);
+
+ if (vp->buffer.src_width != wl_fixed_from_int(-1))
+ weston_matrix_translate(matrix,
+ wl_fixed_to_double(vp->buffer.src_x),
+ wl_fixed_to_double(vp->buffer.src_y),
+ 0);
+
+ switch (vp->buffer.transform) {
+ case WL_OUTPUT_TRANSFORM_FLIPPED:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+ weston_matrix_scale(matrix, -1, 1, 1);
+ weston_matrix_translate(matrix,
+ surface->width_from_buffer, 0, 0);
+ break;
+ }
+
+ switch (vp->buffer.transform) {
+ default:
+ case WL_OUTPUT_TRANSFORM_NORMAL:
+ case WL_OUTPUT_TRANSFORM_FLIPPED:
+ break;
+ case WL_OUTPUT_TRANSFORM_90:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+ weston_matrix_rotate_xy(matrix, 0, 1);
+ weston_matrix_translate(matrix,
+ surface->height_from_buffer, 0, 0);
+ break;
+ case WL_OUTPUT_TRANSFORM_180:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+ weston_matrix_rotate_xy(matrix, -1, 0);
+ weston_matrix_translate(matrix,
+ surface->width_from_buffer,
+ surface->height_from_buffer, 0);
+ break;
+ case WL_OUTPUT_TRANSFORM_270:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+ weston_matrix_rotate_xy(matrix, 0, -1);
+ weston_matrix_translate(matrix,
+ 0, surface->width_from_buffer, 0);
+ break;
+ }
+
+ weston_matrix_scale(matrix, vp->buffer.scale, vp->buffer.scale, 1);
+}
+
+static void
weston_surface_commit_state(struct weston_surface *surface,
struct weston_surface_state *state)
{
@@ -2060,6 +2136,11 @@ weston_surface_commit_state(struct weston_surface *surface,
weston_surface_attach(surface, state->buffer);
state->buffer = NULL;
+ weston_surface_build_buffer_matrix(surface,
+ &surface->surface_to_buffer_matrix);
+ weston_matrix_invert(&surface->buffer_to_surface_matrix,
+ &surface->surface_to_buffer_matrix);
+
if (surface->configure && state->newly_attached)
surface->configure(surface, state->sx, state->sy);
state->sx = 0;
diff --git a/src/compositor.h b/src/compositor.h
index 8abf7e14..ee0d0e49 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -859,6 +859,12 @@ struct weston_surface {
struct weston_surface_state pending;
struct wl_listener pending_buffer_destroy_listener;
+ /* Matrices representating of the full transformation between
+ * buffer and surface coordinates. These matrices are updated
+ * using the weston_surface_build_buffer_matrix function. */
+ struct weston_matrix buffer_to_surface_matrix;
+ struct weston_matrix surface_to_buffer_matrix;
+
/*
* If non-NULL, this function will be called on
* wl_surface::commit after a new buffer has been set up for