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