VIGS: Implement hardware surface convertion cmd 57/146257/1
authorVladislav Andresov <v.andresov@partner.samsung.com>
Wed, 16 Aug 2017 13:11:24 +0000 (16:11 +0300)
committerVasiliy Ulyanov <v.ulyanov@samsung.com>
Fri, 25 Aug 2017 11:20:13 +0000 (14:20 +0300)
Currently it is used only to y-invert surfaces. Proper format conversion
is still to be implemented later.

Change-Id: I07aa288d67d411bdb710d0255824883dabe378e9
Signed-off-by: Vladislav Andresov <v.andresov@partner.samsung.com>
Signed-off-by: Vasiliy Ulyanov <v.ulyanov@samsung.com>
hw/vigs/vigs_comm.c
hw/vigs/vigs_comm.h
hw/vigs/vigs_gl_backend.c
hw/vigs/vigs_protocol.h
hw/vigs/vigs_server.c
hw/vigs/vigs_surface.h
hw/vigs/vigs_sw_backend.c

index 541fc5c..35f9871 100644 (file)
@@ -257,6 +257,20 @@ static void vigs_comm_dispatch_ga_copy(struct vigs_comm_batch_ops *ops,
                  &request->entry);
 }
 
+static void vigs_comm_convert(struct vigs_comm_batch_ops *ops,
+                              void *user_data,
+                              struct vigsp_cmd_convert_request *request)
+{
+    VIGS_LOG_TRACE("src = %u, dst = %u\n", request->src_id, request->dst_id);
+
+    ops->convert(user_data,
+                 request->src_id,
+                 request->src_format,
+                 request->dst_id,
+                 request->dst_format,
+                 request->y_invert);
+}
+
 /*
  * @}
  */
@@ -282,11 +296,13 @@ static const vigs_dispatch_func vigs_dispatch_table[] =
     VIGS_DISPATCH_ENTRY(vigsp_cmd_set_plane,
                         vigs_comm_dispatch_set_plane),
     VIGS_DISPATCH_ENTRY(vigsp_cmd_ga_copy,
-                        vigs_comm_dispatch_ga_copy)
+                        vigs_comm_dispatch_ga_copy),
+    VIGS_DISPATCH_ENTRY(vigsp_cmd_convert,
+                        vigs_comm_convert)
 };
 
 #define VIGS_MIN_BATCH_CMD_ID vigsp_cmd_create_surface
-#define VIGS_MAX_BATCH_CMD_ID vigsp_cmd_ga_copy
+#define VIGS_MAX_BATCH_CMD_ID vigsp_cmd_convert
 
 struct vigs_comm *vigs_comm_create(uint8_t *ram_ptr)
 {
index a42e265..ad2d674 100644 (file)
@@ -111,6 +111,13 @@ struct vigs_comm_batch_ops
                     vigsp_u32 /*dst_stride*/,
                     const struct vigsp_copy */*entry*/);
 
+    void (*convert)(void */*user_data*/,
+                    vigsp_surface_id /*src_id*/,
+                    vigsp_u32 /*src_format*/,
+                    vigsp_surface_id /*dst_id*/,
+                    vigsp_u32 /*dst_format*/,
+                    vigsp_bool /*y_invert*/);
+
     void (*end)(void */*user_data*/, vigsp_fence_seq /*fence_seq*/);
 };
 
index c09e081..b3d384c 100644 (file)
@@ -1605,6 +1605,36 @@ out:
     gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0);
 }
 
+static void vigs_gl_surface_convert(struct vigs_surface *dst,
+                                    uint32_t dst_format,
+                                    struct vigs_surface *src,
+                                    uint32_t src_format,
+                                    int y_invert)
+{
+    uint32_t width = dst->ws_sfc->width;
+    uint32_t height = dst->ws_sfc->height;
+
+    struct vigsp_copy entry = {
+        .from = { 0, 0 },
+        .to = { 0, 0 },
+        .size = { width, height }
+    };
+
+    struct vigs_gl_surface *gl_dst = (struct vigs_gl_surface *)dst;
+
+    if (y_invert) {
+        vigs_gl_create_ortho(0.0f, width, height, 0.0f,
+                             -1.0f, 1.0f, gl_dst->ortho);
+    }
+
+    vigs_gl_surface_copy(dst, src, &entry, 1);
+
+    if (y_invert) {
+        vigs_gl_create_ortho(0.0f, width, 0.0f, height,
+                             -1.0f, 1.0f, gl_dst->ortho);
+    }
+}
+
 static void vigs_gl_surface_destroy(struct vigs_surface *sfc)
 {
     struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)sfc->backend;
@@ -1696,6 +1726,7 @@ static struct vigs_surface *vigs_gl_backend_create_surface(struct vigs_backend *
     gl_sfc->base.copy = &vigs_gl_surface_copy;
     gl_sfc->base.solid_fill = &vigs_gl_surface_solid_fill;
     gl_sfc->base.ga_copy = &vigs_gl_surface_ga_copy;
+    gl_sfc->base.convert = &vigs_gl_surface_convert;
     gl_sfc->base.destroy = &vigs_gl_surface_destroy;
 
     return &gl_sfc->base;
index 3c3e1ab..d328b24 100644 (file)
@@ -81,7 +81,8 @@ typedef enum
     vigsp_cmd_copy = 0x8,
     vigsp_cmd_solid_fill = 0x9,
     vigsp_cmd_set_plane = 0xA,
-    vigsp_cmd_ga_copy = 0xB
+    vigsp_cmd_ga_copy = 0xB,
+    vigsp_cmd_convert = 0xC
     /*
      * @}
      */
@@ -404,6 +405,28 @@ struct vigsp_cmd_ga_copy_request
  * @}
  */
 
+/*
+ * cmd_convert
+ *
+ * Convert surface 'src_id' to
+ * surface 'dst_id'.
+ *
+ * @{
+ */
+
+struct vigsp_cmd_convert_request
+{
+    vigsp_surface_id src_id;
+    vigsp_u32 src_format;
+    vigsp_surface_id dst_id;
+    vigsp_u32 dst_format;
+    vigsp_bool y_invert;
+};
+
+/*
+ * @}
+ */
+
 #pragma pack()
 
 #endif
index 3da956a..993ce31 100644 (file)
@@ -401,6 +401,46 @@ static void vigs_server_dispatch_ga_copy(void *user_data,
     dst->is_dirty = true;
 }
 
+static void vigs_server_dispatch_convert(void *user_data,
+                                         vigsp_surface_id src_id,
+                                         vigsp_u32 src_format,
+                                         vigsp_surface_id dst_id,
+                                         vigsp_u32 dst_format,
+                                         vigsp_bool y_invert)
+{
+    struct vigs_server *server = user_data;
+    struct vigs_surface *src;
+    struct vigs_surface *dst;
+
+    if (!server->initialized) {
+        VIGS_LOG_ERROR("not initialized");
+        return;
+    }
+
+    src = g_hash_table_lookup(server->surfaces, GUINT_TO_POINTER(src_id));
+
+    if (!src) {
+        VIGS_LOG_ERROR("src surface %u not found", src_id);
+        return;
+    }
+
+    if (src_id == dst_id) {
+        dst = src;
+    } else {
+        dst = g_hash_table_lookup(server->surfaces, GUINT_TO_POINTER(dst_id));
+
+        if (!dst) {
+            VIGS_LOG_ERROR("dst surface %u not found", dst_id);
+            return;
+        }
+    }
+
+
+    dst->convert(dst, dst_format, src, src_format, y_invert);
+
+    dst->is_dirty = true;
+}
+
 static void vigs_server_dispatch_batch_end(void *user_data,
                                            vigsp_fence_seq fence_seq)
 {
@@ -424,6 +464,7 @@ static struct vigs_comm_batch_ops vigs_server_dispatch_batch_ops =
     .solid_fill = &vigs_server_dispatch_solid_fill,
     .set_plane = &vigs_server_dispatch_set_plane,
     .ga_copy = &vigs_server_dispatch_ga_copy,
+    .convert = &vigs_server_dispatch_convert,
     .end = &vigs_server_dispatch_batch_end
 };
 
index 707f952..0182c74 100644 (file)
@@ -82,6 +82,12 @@ struct vigs_surface
                     uint32_t /*src_stride*/,
                     const struct vigsp_copy */*entry*/);
 
+    void (*convert)(struct vigs_surface */*dst*/,
+                    uint32_t /*dst_format*/,
+                    struct vigs_surface */*src*/,
+                    uint32_t /*src_format*/,
+                    int /*y_invert*/);
+
     void (*destroy)(struct vigs_surface */*sfc*/);
 };
 
index a41e983..3588e7b 100644 (file)
@@ -352,6 +352,17 @@ static void vigs_sw_surface_ga_copy(struct vigs_surface *dst,
      */
 }
 
+static void vigs_sw_surface_convert(struct vigs_surface *dst,
+                                    uint32_t dst_format,
+                                    struct vigs_surface *src,
+                                    uint32_t src_format,
+                                    int y_invert)
+{
+    /*
+     * Dummy. Not needed.
+     */
+}
+
 static void vigs_sw_surface_destroy(struct vigs_surface *sfc)
 {
     struct vigs_sw_surface *sw_sfc = (struct vigs_sw_surface*)sfc;
@@ -401,6 +412,7 @@ static struct vigs_surface *vigs_sw_backend_create_surface(struct vigs_backend *
     sw_sfc->base.copy = &vigs_sw_surface_copy;
     sw_sfc->base.solid_fill = &vigs_sw_surface_solid_fill;
     sw_sfc->base.ga_copy = &vigs_sw_surface_ga_copy;
+    sw_sfc->base.convert = &vigs_sw_surface_convert;
     sw_sfc->base.destroy = &vigs_sw_surface_destroy;
 
     return &sw_sfc->base;