summaryrefslogtreecommitdiff
path: root/hw/vigs
diff options
context:
space:
mode:
authorStanislav Vorobiov <s.vorobiov@samsung.com>2014-02-17 19:49:27 +0400
committerStanislav Vorobiov <s.vorobiov@samsung.com>2014-02-20 12:47:17 +0400
commite196c7eb9703d1a2c08c1a7da56439f423eeb674 (patch)
tree61881794831152861867307f912c80780db68313 /hw/vigs
parent1db14cd1c3e060501dedb7040b1c4c829495e952 (diff)
downloadqemu-e196c7eb9703d1a2c08c1a7da56439f423eeb674.tar.gz
qemu-e196c7eb9703d1a2c08c1a7da56439f423eeb674.tar.bz2
qemu-e196c7eb9703d1a2c08c1a7da56439f423eeb674.zip
VIGS: Add 'draw_pixels' operation to winsys_surface
We introduce new method to winsys_surface - draw_pixels, some winsys_interface users just want to write raw pixel data to surfaces, they don't care if it's OpenGL texture or some memory chunk or something else, so we provide a generic way to write pixel data to winsys surfaces Change-Id: I9d2e2ac17c88ea844c02d2160986c44642285735
Diffstat (limited to 'hw/vigs')
-rw-r--r--hw/vigs/vigs_gl_backend.c36
-rw-r--r--hw/vigs/vigs_sw_backend.c78
2 files changed, 103 insertions, 11 deletions
diff --git a/hw/vigs/vigs_gl_backend.c b/hw/vigs/vigs_gl_backend.c
index 1824bf248f..01b2136c67 100644
--- a/hw/vigs/vigs_gl_backend.c
+++ b/hw/vigs/vigs_gl_backend.c
@@ -252,6 +252,41 @@ static void vigs_winsys_gl_surface_set_dirty(struct winsys_surface *sfc)
}
}
+static void vigs_winsys_gl_surface_draw_pixels(struct winsys_surface *sfc,
+ uint8_t *pixels)
+{
+ struct vigs_winsys_gl_surface *vigs_sfc = (struct vigs_winsys_gl_surface*)sfc;
+ bool has_current = vigs_sfc->backend->has_current(vigs_sfc->backend);
+ if (!vigs_sfc->parent) {
+ return;
+ }
+
+ if (has_current ||
+ vigs_sfc->backend->make_current(vigs_sfc->backend, true)) {
+ struct vigsp_rect rect;
+
+ rect.pos.x = 0;
+ rect.pos.y = 0;
+ rect.size.w = sfc->width;
+ rect.size.h = sfc->height;
+
+ vigs_sfc->parent->base.draw_pixels(&vigs_sfc->parent->base,
+ pixels,
+ &rect,
+ 1);
+
+ vigs_sfc->parent->base.is_dirty = true;
+
+ vigs_sfc->backend->Finish();
+
+ if (!has_current) {
+ vigs_sfc->backend->make_current(vigs_sfc->backend, false);
+ }
+ } else {
+ VIGS_LOG_CRITICAL("make_current failed");
+ }
+}
+
static GLuint vigs_winsys_gl_surface_get_texture(struct winsys_gl_surface *sfc)
{
struct vigs_winsys_gl_surface *vigs_sfc = (struct vigs_winsys_gl_surface*)sfc;
@@ -312,6 +347,7 @@ static struct vigs_winsys_gl_surface
ws_sfc->base.base.acquire = &vigs_winsys_gl_surface_acquire;
ws_sfc->base.base.release = &vigs_winsys_gl_surface_release;
ws_sfc->base.base.set_dirty = &vigs_winsys_gl_surface_set_dirty;
+ ws_sfc->base.base.draw_pixels = &vigs_winsys_gl_surface_draw_pixels;
ws_sfc->base.get_texture = &vigs_winsys_gl_surface_get_texture;
ws_sfc->tex_internalformat = tex_internalformat;
ws_sfc->tex_format = tex_format;
diff --git a/hw/vigs/vigs_sw_backend.c b/hw/vigs/vigs_sw_backend.c
index 53886b7dc3..52e524ba08 100644
--- a/hw/vigs/vigs_sw_backend.c
+++ b/hw/vigs/vigs_sw_backend.c
@@ -34,11 +34,25 @@
#include "vigs_ref.h"
#include "winsys.h"
+struct vigs_sw_surface;
+
+struct vigs_sw_backend
+{
+ struct vigs_backend base;
+
+ struct winsys_info ws_info;
+};
+
struct vigs_winsys_sw_surface
{
struct winsys_surface base;
struct vigs_ref ref;
+
+ /*
+ * Will be set to NULL when orphaned.
+ */
+ struct vigs_sw_surface *parent;
};
struct vigs_sw_surface
@@ -48,6 +62,12 @@ struct vigs_sw_surface
uint8_t *data;
};
+static __inline struct vigs_winsys_sw_surface
+ *get_ws_sfc(struct vigs_sw_surface *sfc)
+{
+ return (struct vigs_winsys_sw_surface*)sfc->base.ws_sfc;
+}
+
/*
* vigs_winsys_sw_surface.
* @{
@@ -69,6 +89,29 @@ static void vigs_winsys_sw_surface_set_dirty(struct winsys_surface *sfc)
{
}
+static void vigs_winsys_sw_surface_draw_pixels(struct winsys_surface *sfc,
+ uint8_t *pixels)
+{
+ struct vigsp_rect rect;
+ struct vigs_winsys_sw_surface *vigs_sfc = (struct vigs_winsys_sw_surface*)sfc;
+
+ if (!vigs_sfc->parent) {
+ return;
+ }
+
+ rect.pos.x = 0;
+ rect.pos.y = 0;
+ rect.size.w = sfc->width;
+ rect.size.h = sfc->height;
+
+ vigs_sfc->parent->base.draw_pixels(&vigs_sfc->parent->base,
+ pixels,
+ &rect,
+ 1);
+
+ vigs_sfc->parent->base.is_dirty = true;
+}
+
static void vigs_winsys_sw_surface_destroy(struct vigs_ref *ref)
{
struct vigs_winsys_sw_surface *vigs_sfc =
@@ -80,7 +123,8 @@ static void vigs_winsys_sw_surface_destroy(struct vigs_ref *ref)
}
static struct vigs_winsys_sw_surface
- *vigs_winsys_sw_surface_create(uint32_t width,
+ *vigs_winsys_sw_surface_create(struct vigs_sw_surface *parent,
+ uint32_t width,
uint32_t height)
{
struct vigs_winsys_sw_surface *ws_sfc;
@@ -92,12 +136,19 @@ static struct vigs_winsys_sw_surface
ws_sfc->base.acquire = &vigs_winsys_sw_surface_acquire;
ws_sfc->base.release = &vigs_winsys_sw_surface_release;
ws_sfc->base.set_dirty = &vigs_winsys_sw_surface_set_dirty;
+ ws_sfc->base.draw_pixels = &vigs_winsys_sw_surface_draw_pixels;
+ ws_sfc->parent = parent;
vigs_ref_init(&ws_sfc->ref, &vigs_winsys_sw_surface_destroy);
return ws_sfc;
}
+static void vigs_winsys_sw_surface_orphan(struct vigs_winsys_sw_surface *sfc)
+{
+ sfc->parent = NULL;
+}
+
/*
* @}
*/
@@ -264,6 +315,9 @@ static void vigs_sw_surface_solid_fill(struct vigs_surface *sfc,
static void vigs_sw_surface_destroy(struct vigs_surface *sfc)
{
struct vigs_sw_surface *sw_sfc = (struct vigs_sw_surface*)sfc;
+ struct vigs_winsys_sw_surface *ws_sfc = get_ws_sfc(sw_sfc);
+
+ vigs_winsys_sw_surface_orphan(ws_sfc);
g_free(sw_sfc->data);
@@ -290,7 +344,7 @@ static struct vigs_surface *vigs_sw_backend_create_surface(struct vigs_backend *
sw_sfc->data = g_malloc(stride * height);
- ws_sfc = vigs_winsys_sw_surface_create(width, height);
+ ws_sfc = vigs_winsys_sw_surface_create(sw_sfc, width, height);
vigs_surface_init(&sw_sfc->base,
&ws_sfc->base,
@@ -345,23 +399,25 @@ static void vigs_sw_backend_batch_end(struct vigs_backend *backend)
static void vigs_sw_backend_destroy(struct vigs_backend *backend)
{
+ struct vigs_sw_backend *sw_backend = (struct vigs_sw_backend*)backend;
+
vigs_backend_cleanup(backend);
- g_free(backend);
+ g_free(sw_backend);
}
struct vigs_backend *vigs_sw_backend_create(void)
{
- struct vigs_backend *backend;
+ struct vigs_sw_backend *backend;
backend = g_malloc0(sizeof(*backend));
- vigs_backend_init(backend, NULL);
+ vigs_backend_init(&backend->base, &backend->ws_info);
- backend->batch_start = &vigs_sw_backend_batch_start;
- backend->create_surface = &vigs_sw_backend_create_surface;
- backend->composite = &vigs_sw_backend_composite;
- backend->batch_end = &vigs_sw_backend_batch_end;
- backend->destroy = &vigs_sw_backend_destroy;
+ backend->base.batch_start = &vigs_sw_backend_batch_start;
+ backend->base.create_surface = &vigs_sw_backend_create_surface;
+ backend->base.composite = &vigs_sw_backend_composite;
+ backend->base.batch_end = &vigs_sw_backend_batch_end;
+ backend->base.destroy = &vigs_sw_backend_destroy;
- return backend;
+ return &backend->base;
}