summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2010-05-19 12:10:10 +0200
committerBenjamin Otte <otte@redhat.com>2010-05-20 11:02:49 +0200
commite4cb46b50015f792b0e8c7b49f3b42f2c3c0ad00 (patch)
tree88f9319ff2314442b470dfd9d12166e86df3ccd2
parent7c8759e279f51ea722c07e4b0c70f4a49f34393d (diff)
gl: Implement texture upload to window with composite()
Instead of custom code that does basically the same thing, use a temporary surface and _cairo_gl_surface_composite() to upload images.
-rw-r--r--src/cairo-gl-shaders.c2
-rw-r--r--src/cairo-gl-surface.c129
2 files changed, 48 insertions, 83 deletions
diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c
index 55c9eb8d..3484321f 100644
--- a/src/cairo-gl-shaders.c
+++ b/src/cairo-gl-shaders.c
@@ -470,7 +470,7 @@ _cairo_gl_shader_cache_destroy (void *data)
cairo_shader_cache_entry_t *entry = data;
_cairo_gl_shader_fini (entry->ctx, &entry->shader);
- if (entry->ctx->current_shader == entry)
+ if (entry->ctx->current_shader == &entry->shader)
entry->ctx->current_shader = NULL;
free (entry);
}
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 5c370b77..ecd30a4a 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -45,12 +45,27 @@
#include "cairo-gl-private.h"
static cairo_int_status_t
-_cairo_gl_surface_fill_rectangles (void *abstract_surface,
+_cairo_gl_surface_fill_rectangles (void *abstract_dst,
cairo_operator_t op,
const cairo_color_t *color,
cairo_rectangle_int_t *rects,
int num_rects);
+static cairo_int_status_t
+_cairo_gl_surface_composite (cairo_operator_t op,
+ const cairo_pattern_t *src,
+ const cairo_pattern_t *mask,
+ void *abstract_dst,
+ int src_x,
+ int src_y,
+ int mask_x,
+ int mask_y,
+ int dst_x,
+ int dst_y,
+ unsigned int width,
+ unsigned int height,
+ cairo_region_t *clip_region);
+
#define BIAS .375
static cairo_bool_t _cairo_surface_is_gl (cairo_surface_t *surface)
@@ -556,90 +571,40 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
} else {
- GLuint tex;
- GLfloat vertices[8], texcoords[8];
-
- if (_cairo_gl_device_has_glsl (&ctx->base)) {
- cairo_gl_shader_t *shader;
-
- status = _cairo_gl_get_shader (ctx,
- CAIRO_GL_OPERAND_TEXTURE,
- CAIRO_GL_OPERAND_NONE,
- CAIRO_GL_SHADER_IN_NORMAL,
- &shader);
- if (unlikely (status)) {
- _cairo_gl_context_release (ctx);
- goto fail;
- }
-
- _cairo_gl_set_shader (ctx, shader);
- } else {
- glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- }
-
- status = CAIRO_STATUS_SUCCESS;
-
- _cairo_gl_context_set_destination (ctx, dst);
-
- glGenTextures (1, &tex);
- glActiveTexture (GL_TEXTURE0);
- glBindTexture (ctx->tex_target, tex);
- glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexImage2D (ctx->tex_target, 0, internal_format, width, height, 0,
- format, type, src->data + src_y * src->stride + src_x * cpp);
-
- glEnable (ctx->tex_target);
- glDisable (GL_BLEND);
-
- vertices[0] = dst_x;
- vertices[1] = dst_y;
- vertices[2] = dst_x + width;
- vertices[3] = dst_y;
- vertices[4] = dst_x + width;
- vertices[5] = dst_y + height;
- vertices[6] = dst_x;
- vertices[7] = dst_y + height;
-
- if (ctx->tex_target != GL_TEXTURE_RECTANGLE_EXT) {
- texcoords[0] = 0;
- texcoords[1] = 0;
- texcoords[2] = 1;
- texcoords[3] = 0;
- texcoords[4] = 1;
- texcoords[5] = 1;
- texcoords[6] = 0;
- texcoords[7] = 1;
- } else {
- texcoords[0] = 0;
- texcoords[1] = 0;
- texcoords[2] = width;
- texcoords[3] = 0;
- texcoords[4] = width;
- texcoords[5] = height;
- texcoords[6] = 0;
- texcoords[7] = height;
- }
-
- glVertexPointer (2, GL_FLOAT, sizeof (GLfloat) * 2, vertices);
- glEnableClientState (GL_VERTEX_ARRAY);
-
- glClientActiveTexture (GL_TEXTURE0);
- glTexCoordPointer (2, GL_FLOAT, sizeof (GLfloat) * 2, texcoords);
- glEnableClientState (GL_TEXTURE_COORD_ARRAY);
-
- glDrawArrays (GL_QUADS, 0, 4);
-
- glDisableClientState (GL_COLOR_ARRAY);
- glDisableClientState (GL_VERTEX_ARRAY);
- glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+ cairo_surface_t *tmp;
+
+ tmp = _cairo_gl_surface_create_scratch (ctx,
+ dst->base.content,
+ width, height);
+ if (unlikely (tmp->status)) {
+ cairo_surface_destroy (tmp);
+ goto FAIL;
+ }
+ status = _cairo_gl_surface_draw_image ((cairo_gl_surface_t *) tmp,
+ src,
+ src_x, src_y,
+ 0, 0,
+ width, height);
+ if (status == CAIRO_STATUS_SUCCESS) {
+ cairo_surface_pattern_t tmp_pattern;
+
+ _cairo_pattern_init_for_surface (&tmp_pattern, tmp);
+ _cairo_gl_surface_composite (CAIRO_OPERATOR_SOURCE,
+ &tmp_pattern.base,
+ NULL,
+ dst,
+ 0, 0,
+ 0, 0,
+ dst_x, dst_y,
+ width, height,
+ NULL);
+ _cairo_pattern_fini (&tmp_pattern.base);
+ }
- _cairo_gl_set_shader (ctx, NULL);
- glDeleteTextures (1, &tex);
- glDisable (ctx->tex_target);
+ cairo_surface_destroy (tmp);
}
-fail:
+FAIL:
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
_cairo_gl_context_release (ctx);