diff options
author | Benjamin Otte <otte@redhat.com> | 2010-05-19 12:10:10 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2010-05-20 11:02:49 +0200 |
commit | e4cb46b50015f792b0e8c7b49f3b42f2c3c0ad00 (patch) | |
tree | 88f9319ff2314442b470dfd9d12166e86df3ccd2 | |
parent | 7c8759e279f51ea722c07e4b0c70f4a49f34393d (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.c | 2 | ||||
-rw-r--r-- | src/cairo-gl-surface.c | 129 |
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); |