}
}
+static void vigs_winsys_gl_surface_draw_pixels_scaled(struct winsys_surface *sfc,
+ uint8_t *pixels,
+ uint32_t width,
+ uint32_t height)
+{
+ 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)) {
+
+ vigs_sfc->parent->base.draw_pixels_scaled(&vigs_sfc->parent->base,
+ pixels,
+ width,
+ height);
+
+ 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.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.base.draw_pixels_scaled = &vigs_winsys_gl_surface_draw_pixels_scaled;
ws_sfc->base.get_texture = &vigs_winsys_gl_surface_get_texture;
ws_sfc->tex_internalformat = tex_internalformat;
ws_sfc->tex_format = tex_format;
gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0);
}
+static void vigs_gl_surface_draw_pixels_scaled(struct vigs_surface *sfc,
+ uint8_t *pixels,
+ uint32_t width,
+ uint32_t height)
+{
+ struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)sfc->backend;
+ struct vigs_gl_surface *gl_sfc = (struct vigs_gl_surface*)sfc;
+ struct vigs_winsys_gl_surface *ws_sfc = get_ws_sfc(gl_sfc);
+ GLfloat sfc_w, sfc_h;
+ GLfloat *vert_coords;
+ GLfloat *tex_coords;
+
+ sfc_w = ws_sfc->base.base.width;
+ sfc_h = ws_sfc->base.base.height;
+
+ if (!vigs_winsys_gl_surface_create_texture(ws_sfc)) {
+ goto out;
+ }
+
+ if (!vigs_gl_surface_create_tmp_texture(gl_sfc)) {
+ goto out;
+ }
+
+ if (!vigs_gl_surface_setup_framebuffer(gl_sfc,
+ gl_backend->tex_prog_id,
+ gl_backend->tex_prog_proj_loc)) {
+ goto out;
+ }
+
+ gl_backend->BindTexture(GL_TEXTURE_2D, gl_sfc->tmp_tex);
+
+ gl_backend->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl_backend->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gl_backend->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl_backend->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ gl_backend->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ gl_backend->PixelStorei(GL_UNPACK_ROW_LENGTH, width);
+ gl_backend->PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ gl_backend->PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+
+ if (width > sfc_w || height > sfc_h) {
+ gl_backend->TexImage2D(GL_TEXTURE_2D, 0, ws_sfc->tex_internalformat,
+ width, height, 0,
+ ws_sfc->tex_format,
+ ws_sfc->tex_type,
+ pixels);
+ } else {
+ gl_backend->TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
+ width, height,
+ ws_sfc->tex_format,
+ ws_sfc->tex_type,
+ pixels);
+ }
+
+ vigs_vector_resize(&gl_backend->v1, 0);
+ vigs_vector_resize(&gl_backend->v2, 0);
+
+ gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, ws_sfc->tex, 0);
+
+ vert_coords = vigs_vector_append(&gl_backend->v1,
+ (12 * sizeof(GLfloat)));
+ tex_coords = vigs_vector_append(&gl_backend->v2,
+ (12 * sizeof(GLfloat)));
+
+ vert_coords[6] = vert_coords[0] = 0;
+ vert_coords[7] = vert_coords[1] = sfc_h;
+ vert_coords[2] = sfc_w;
+ vert_coords[3] = sfc_h;
+ vert_coords[8] = vert_coords[4] = sfc_w;
+ vert_coords[9] = vert_coords[5] = 0;
+ vert_coords[10] = 0;
+ vert_coords[11] = 0;
+
+ tex_coords[6] = tex_coords[0] = 0;
+ tex_coords[7] = tex_coords[1] = 0;
+ tex_coords[2] = (GLfloat)width / sfc_w;
+ tex_coords[3] = 0;
+ tex_coords[8] = tex_coords[4] = (GLfloat)width / sfc_w;
+ tex_coords[9] = tex_coords[5] = (GLfloat)height / sfc_h;
+ tex_coords[10] = 0;
+ tex_coords[11] = (GLfloat)height / sfc_h;
+
+ vigs_gl_draw_tex_prog(gl_backend, 6);
+
+out:
+ gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
static void vigs_gl_surface_copy(struct vigs_surface *dst,
struct vigs_surface *src,
const struct vigsp_copy *entries,
gl_sfc->base.read_pixels = &vigs_gl_surface_read_pixels;
gl_sfc->base.draw_pixels = &vigs_gl_surface_draw_pixels;
+ gl_sfc->base.draw_pixels_scaled = &vigs_gl_surface_draw_pixels_scaled;
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;
vigs_sfc->parent->base.is_dirty = true;
}
+static void vigs_winsys_sw_surface_draw_pixels_scaled(struct winsys_surface *sfc,
+ uint8_t *pixels,
+ uint32_t width,
+ uint32_t height)
+{
+ struct vigs_winsys_sw_surface *vigs_sfc = (struct vigs_winsys_sw_surface*)sfc;
+
+ if (!vigs_sfc->parent) {
+ return;
+ }
+
+ vigs_sfc->parent->base.draw_pixels_scaled(&vigs_sfc->parent->base,
+ pixels,
+ width,
+ height);
+
+ 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 =
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->base.draw_pixels_scaled = &vigs_winsys_sw_surface_draw_pixels_scaled;
ws_sfc->parent = parent;
vigs_ref_init(&ws_sfc->ref, &vigs_winsys_sw_surface_destroy);
}
}
+static void vigs_sw_surface_draw_pixels_scaled(struct vigs_surface *sfc,
+ uint8_t *pixels,
+ uint32_t width,
+ uint32_t height)
+{
+ /* TODO: implement */
+}
+
static void vigs_sw_surface_copy(struct vigs_surface *dst,
struct vigs_surface *src,
const struct vigsp_copy *entries,
sw_sfc->base.read_pixels = &vigs_sw_surface_read_pixels;
sw_sfc->base.draw_pixels = &vigs_sw_surface_draw_pixels;
+ sw_sfc->base.draw_pixels_scaled = &vigs_sw_surface_draw_pixels_scaled;
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;