diff options
author | Stanislav Vorobiov <s.vorobiov@samsung.com> | 2014-02-17 19:49:27 +0400 |
---|---|---|
committer | Stanislav Vorobiov <s.vorobiov@samsung.com> | 2014-02-20 12:47:17 +0400 |
commit | e196c7eb9703d1a2c08c1a7da56439f423eeb674 (patch) | |
tree | 61881794831152861867307f912c80780db68313 /hw/vigs | |
parent | 1db14cd1c3e060501dedb7040b1c4c829495e952 (diff) | |
download | qemu-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.c | 36 | ||||
-rw-r--r-- | hw/vigs/vigs_sw_backend.c | 78 |
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; } |