VIGS: Implement plane flip/rotate 19/26419/1
authorStanislav Vorobiov <s.vorobiov@samsung.com>
Fri, 22 Aug 2014 06:50:02 +0000 (10:50 +0400)
committerStanislav Vorobiov <s.vorobiov@samsung.com>
Fri, 22 Aug 2014 06:57:36 +0000 (10:57 +0400)
Planes can now be horizontally/vertically flipped
and rotated by 90, 180 or 270 degrees

Change-Id: Icfd4f0b59e86cad6ec1ec4990aa280a8dcd135a7
Signed-off-by: Stanislav Vorobiov <s.vorobiov@samsung.com>
hw/vigs/vigs_comm.c
hw/vigs/vigs_comm.h
hw/vigs/vigs_gl_backend.c
hw/vigs/vigs_plane.h
hw/vigs/vigs_protocol.h
hw/vigs/vigs_server.c

index de3b3c7..541fc5c 100644 (file)
@@ -195,7 +195,18 @@ static void vigs_comm_dispatch_set_plane(struct vigs_comm_batch_ops *ops,
                                          void *user_data,
                                          struct vigsp_cmd_set_plane_request *request)
 {
-    VIGS_LOG_TRACE("plane = %u, width = %u, height = %u, format = %u, surfaces = {%u, %u, %u, %u}, src_rect = {%u, %u, %u, %u}, dst_x = %d, dst_y = %d, dst_size = {%u, %u}, z_pos = %d",
+    switch (request->rotation) {
+    case vigsp_rotation0:
+    case vigsp_rotation90:
+    case vigsp_rotation180:
+    case vigsp_rotation270:
+        break;
+    default:
+        VIGS_LOG_CRITICAL("bad plane rotation = %u", request->rotation);
+        return;
+    }
+
+    VIGS_LOG_TRACE("plane = %u, width = %u, height = %u, format = %u, surfaces = {%u, %u, %u, %u}, src_rect = {%u, %u, %u, %u}, dst_x = %d, dst_y = %d, dst_size = {%u, %u}, z_pos = %d, hflip = %u, vflip = %u, rotation = %u",
                    request->plane,
                    request->width,
                    request->height,
@@ -212,12 +223,16 @@ static void vigs_comm_dispatch_set_plane(struct vigs_comm_batch_ops *ops,
                    request->dst_y,
                    request->dst_size.w,
                    request->dst_size.h,
-                   request->z_pos);
+                   request->z_pos,
+                   request->hflip,
+                   request->vflip,
+                   request->rotation);
 
     ops->set_plane(user_data, request->plane, request->width, request->height,
                    request->format, request->surfaces,
                    &request->src_rect, request->dst_x, request->dst_y,
-                   &request->dst_size, request->z_pos);
+                   &request->dst_size, request->z_pos, request->hflip,
+                   request->vflip, request->rotation);
 }
 
 static void vigs_comm_dispatch_ga_copy(struct vigs_comm_batch_ops *ops,
index cea76a6..a42e265 100644 (file)
@@ -97,7 +97,10 @@ struct vigs_comm_batch_ops
                       int /*dst_x*/,
                       int /*dst_y*/,
                       const struct vigsp_size */*dst_size*/,
-                      int /*z_pos*/);
+                      int /*z_pos*/,
+                      bool /*hflip*/,
+                      bool /*vflip*/,
+                      vigsp_rotation /*rotation*/);
 
     void (*ga_copy)(void */*user_data*/,
                     vigsp_surface_id /*src_id*/,
index 3aefd3b..b27f99a 100644 (file)
@@ -1561,6 +1561,7 @@ static bool vigs_gl_backend_composite_planes(struct vigs_gl_backend *gl_backend,
     for (i = 0; i < VIGS_MAX_PLANES; ++i) {
         const struct vigs_plane *plane = planes[i];
         GLfloat src_w, src_h;
+        GLfloat tmp_x, tmp_y;
 
         if (!vigs_plane_enabled(plane) || ((plane->z_pos >= 0) ^ above_root)) {
             continue;
@@ -1587,6 +1588,99 @@ static bool vigs_gl_backend_composite_planes(struct vigs_gl_backend *gl_backend,
         tex_coords[10] = (GLfloat)plane->src_rect.pos.x / src_w;
         tex_coords[11] = (GLfloat)(src_h - (plane->src_rect.pos.y + plane->src_rect.size.h)) / src_h;
 
+        if (plane->hflip) {
+            tmp_x = tex_coords[0];
+            tmp_y = tex_coords[1];
+
+            tex_coords[6] = tex_coords[0] = tex_coords[2];
+            tex_coords[7] = tex_coords[1] = tex_coords[3];
+
+            tex_coords[2] = tmp_x;
+            tex_coords[3] = tmp_y;
+
+            tmp_x = tex_coords[4];
+            tmp_y = tex_coords[5];
+
+            tex_coords[8] = tex_coords[4] = tex_coords[10];
+            tex_coords[9] = tex_coords[5] = tex_coords[11];
+
+            tex_coords[10] = tmp_x;
+            tex_coords[11] = tmp_y;
+        }
+
+        if (plane->vflip) {
+            tmp_x = tex_coords[0];
+            tmp_y = tex_coords[1];
+
+            tex_coords[6] = tex_coords[0] = tex_coords[10];
+            tex_coords[7] = tex_coords[1] = tex_coords[11];
+
+            tex_coords[10] = tmp_x;
+            tex_coords[11] = tmp_y;
+
+            tmp_x = tex_coords[4];
+            tmp_y = tex_coords[5];
+
+            tex_coords[8] = tex_coords[4] = tex_coords[2];
+            tex_coords[9] = tex_coords[5] = tex_coords[3];
+
+            tex_coords[2] = tmp_x;
+            tex_coords[3] = tmp_y;
+        }
+
+        switch (plane->rotation) {
+        case vigsp_rotation90:
+            tmp_x = tex_coords[0];
+            tmp_y = tex_coords[1];
+
+            tex_coords[6] = tex_coords[0] = tex_coords[10];
+            tex_coords[7] = tex_coords[1] = tex_coords[11];
+            tex_coords[10] = tex_coords[4];
+            tex_coords[11] = tex_coords[5];
+            tex_coords[8] = tex_coords[4] = tex_coords[2];
+            tex_coords[9] = tex_coords[5] = tex_coords[3];
+            tex_coords[2] = tmp_x;
+            tex_coords[3] = tmp_y;
+
+            break;
+        case vigsp_rotation180:
+            tmp_x = tex_coords[0];
+            tmp_y = tex_coords[1];
+
+            tex_coords[6] = tex_coords[0] = tex_coords[4];
+            tex_coords[7] = tex_coords[1] = tex_coords[5];
+            tex_coords[8] = tex_coords[4] = tmp_x;
+            tex_coords[9] = tex_coords[5] = tmp_y;
+
+            tmp_x = tex_coords[2];
+            tmp_y = tex_coords[3];
+
+            tex_coords[2] = tex_coords[10];
+            tex_coords[3] = tex_coords[11];
+
+            tex_coords[10] = tmp_x;
+            tex_coords[11] = tmp_y;
+
+            break;
+        case vigsp_rotation270:
+            tmp_x = tex_coords[0];
+            tmp_y = tex_coords[1];
+
+            tex_coords[6] = tex_coords[0] = tex_coords[2];
+            tex_coords[7] = tex_coords[1] = tex_coords[3];
+            tex_coords[2] = tex_coords[4];
+            tex_coords[3] = tex_coords[5];
+            tex_coords[8] = tex_coords[4] = tex_coords[10];
+            tex_coords[9] = tex_coords[5] = tex_coords[11];
+            tex_coords[10] = tmp_x;
+            tex_coords[11] = tmp_y;
+
+            break;
+        case vigsp_rotation0:
+        default:
+            break;
+        }
+
         if (!bottom && (plane->format == vigsp_plane_bgra8888)) {
             /*
              * This is not bottom plane and it has alpha, turn on blending.
index 0ae9720..d997fd9 100644 (file)
@@ -49,6 +49,9 @@ struct vigs_plane
     struct vigsp_size dst_size;
 
     int z_pos;
+    bool hflip;
+    bool vflip;
+    vigsp_rotation rotation;
 
     /*
      * Plane moved/resized, need to recomposite.
index 31a5eeb..8dcc158 100644 (file)
@@ -37,7 +37,7 @@
 /*
  * Bump this whenever protocol changes.
  */
-#define VIGS_PROTOCOL_VERSION 19
+#define VIGS_PROTOCOL_VERSION 20
 
 #define VIGS_MAX_PLANES 2
 
@@ -103,6 +103,14 @@ typedef enum
     vigsp_plane_yuv420 = 0x5
 } vigsp_plane_format;
 
+typedef enum
+{
+    vigsp_rotation0   = 0x0,
+    vigsp_rotation90  = 0x1,
+    vigsp_rotation180 = 0x2,
+    vigsp_rotation270 = 0x3
+} vigsp_rotation;
+
 #pragma pack(1)
 
 struct vigsp_point
@@ -362,6 +370,9 @@ struct vigsp_cmd_set_plane_request
     vigsp_s32 dst_y;
     struct vigsp_size dst_size;
     vigsp_s32 z_pos;
+    vigsp_bool hflip;
+    vigsp_bool vflip;
+    vigsp_rotation rotation;
 };
 
 /*
index 518bf23..4212453 100644 (file)
@@ -312,7 +312,10 @@ static void vigs_server_dispatch_set_plane(void *user_data,
                                            int dst_x,
                                            int dst_y,
                                            const struct vigsp_size *dst_size,
-                                           int z_pos)
+                                           int z_pos,
+                                           bool hflip,
+                                           bool vflip,
+                                           vigsp_rotation rotation)
 {
     struct vigs_server *server = user_data;
     struct vigs_surface *surfaces[4] = { NULL, NULL, NULL, NULL };
@@ -348,6 +351,9 @@ static void vigs_server_dispatch_set_plane(void *user_data,
     server->planes[plane].dst_y = dst_y;
     server->planes[plane].dst_size = *dst_size;
     server->planes[plane].z_pos = z_pos;
+    server->planes[plane].hflip = hflip;
+    server->planes[plane].vflip = vflip;
+    server->planes[plane].rotation = rotation;
     server->planes[plane].is_dirty = true;
 }