diff options
-rw-r--r-- | hw/vigs/vigs_comm.c | 20 | ||||
-rw-r--r-- | hw/vigs/vigs_comm.h | 7 | ||||
-rw-r--r-- | hw/vigs/vigs_gl_backend.c | 31 | ||||
-rw-r--r-- | hw/vigs/vigs_protocol.h | 25 | ||||
-rw-r--r-- | hw/vigs/vigs_server.c | 41 | ||||
-rw-r--r-- | hw/vigs/vigs_surface.h | 6 | ||||
-rw-r--r-- | hw/vigs/vigs_sw_backend.c | 12 |
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; |