summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/vigs/vigs_comm.c20
-rw-r--r--hw/vigs/vigs_comm.h7
-rw-r--r--hw/vigs/vigs_gl_backend.c31
-rw-r--r--hw/vigs/vigs_protocol.h25
-rw-r--r--hw/vigs/vigs_server.c41
-rw-r--r--hw/vigs/vigs_surface.h6
-rw-r--r--hw/vigs/vigs_sw_backend.c12
7 files changed, 139 insertions, 3 deletions
diff --git a/hw/vigs/vigs_comm.c b/hw/vigs/vigs_comm.c
index 541fc5c1bd..35f98714b8 100644
--- a/hw/vigs/vigs_comm.c
+++ b/hw/vigs/vigs_comm.c
@@ -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)
{
diff --git a/hw/vigs/vigs_comm.h b/hw/vigs/vigs_comm.h
index a42e2652e6..ad2d674c0d 100644
--- a/hw/vigs/vigs_comm.h
+++ b/hw/vigs/vigs_comm.h
@@ -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*/);
};
diff --git a/hw/vigs/vigs_gl_backend.c b/hw/vigs/vigs_gl_backend.c
index c09e081b0b..b3d384c9b2 100644
--- a/hw/vigs/vigs_gl_backend.c
+++ b/hw/vigs/vigs_gl_backend.c
@@ -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;
diff --git a/hw/vigs/vigs_protocol.h b/hw/vigs/vigs_protocol.h
index 3c3e1abf30..d328b246df 100644
--- a/hw/vigs/vigs_protocol.h
+++ b/hw/vigs/vigs_protocol.h
@@ -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
diff --git a/hw/vigs/vigs_server.c b/hw/vigs/vigs_server.c
index 3da956a2b6..993ce31c9c 100644
--- a/hw/vigs/vigs_server.c
+++ b/hw/vigs/vigs_server.c
@@ -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
};
diff --git a/hw/vigs/vigs_surface.h b/hw/vigs/vigs_surface.h
index 707f952a92..0182c74301 100644
--- a/hw/vigs/vigs_surface.h
+++ b/hw/vigs/vigs_surface.h
@@ -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*/);
};
diff --git a/hw/vigs/vigs_sw_backend.c b/hw/vigs/vigs_sw_backend.c
index a41e9832fe..3588e7bba1 100644
--- a/hw/vigs/vigs_sw_backend.c
+++ b/hw/vigs/vigs_sw_backend.c
@@ -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;