&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);
+}
+
/*
* @}
*/
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)
{
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*/);
};
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;
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;
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
/*
* @}
*/
* @}
*/
+/*
+ * 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
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)
{
.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
};
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*/);
};
*/
}
+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;
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;