diff options
author | Benjamin Otte <otte@redhat.com> | 2010-05-30 22:01:10 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2010-06-07 13:37:48 +0200 |
commit | c75460c54d88ce9a50ac59c15a10684043ca4b0e (patch) | |
tree | 28df133103ecc76636a66cebcff195b09b44ebe1 | |
parent | 1ddff8aba35466fe6689536bc5f2d7eeefaea02c (diff) |
gl: Introduce a temporary texture unit
...and use it for image uploads. This makes sure that the texture units
used for SOURCE and MASK get not clobbered when images get uploaded to
textures.
-rw-r--r-- | src/cairo-gl-composite.c | 2 | ||||
-rw-r--r-- | src/cairo-gl-device.c | 17 | ||||
-rw-r--r-- | src/cairo-gl-private.h | 8 | ||||
-rw-r--r-- | src/cairo-gl-surface.c | 2 |
4 files changed, 28 insertions, 1 deletions
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c index f7206140..1b7f6bb3 100644 --- a/src/cairo-gl-composite.c +++ b/src/cairo-gl-composite.c @@ -181,6 +181,7 @@ _cairo_gl_create_gradient_texture (cairo_gl_surface_t *dst, glUnmapBufferARB (GL_PIXEL_UNPACK_BUFFER_ARB); glGenTextures (1, tex); + _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP); glBindTexture (GL_TEXTURE_1D, *tex); glTexImage1D (GL_TEXTURE_1D, 0, GL_RGBA8, tex_width, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0); @@ -642,6 +643,7 @@ _cairo_gl_operand_setup_fixed (cairo_gl_operand_t *operand, } switch (tex_unit) { + case CAIRO_GL_TEX_TEMP: default: ASSERT_NOT_REACHED; break; diff --git a/src/cairo-gl-device.c b/src/cairo-gl-device.c index 2e6bfb94..af897f15 100644 --- a/src/cairo-gl-device.c +++ b/src/cairo-gl-device.c @@ -214,6 +214,8 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx) glGetIntegerv (GL_MAX_RENDERBUFFER_SIZE, &ctx->max_framebuffer_size); ctx->max_texture_size = 0; glGetIntegerv (GL_MAX_TEXTURE_SIZE, &ctx->max_texture_size); + ctx->max_textures = 0; + glGetIntegerv (GL_MAX_TEXTURE_UNITS, &ctx->max_textures); for (n = 0; n < ARRAY_LENGTH (ctx->glyph_cache); n++) _cairo_gl_glyph_cache_init (&ctx->glyph_cache[n]); @@ -221,6 +223,21 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx) return CAIRO_STATUS_SUCCESS; } +void +_cairo_gl_context_activate (cairo_gl_context_t *ctx, + cairo_gl_tex_t tex_unit) +{ + if (ctx->max_textures <= (GLint) tex_unit) { + if (tex_unit < 2) { + _cairo_gl_composite_flush (ctx); + _cairo_gl_context_destroy_operand (ctx, ctx->max_textures - 1); + } + glActiveTexture (ctx->max_textures - 1); + } else { + glActiveTexture (GL_TEXTURE0 + tex_unit); + } +} + static void _cairo_gl_ensure_framebuffer (cairo_gl_context_t *ctx, cairo_gl_surface_t *surface) diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h index eaf11434..a6aea40b 100644 --- a/src/cairo-gl-private.h +++ b/src/cairo-gl-private.h @@ -90,7 +90,8 @@ typedef struct cairo_gl_glyph_cache { typedef enum cairo_gl_tex { CAIRO_GL_TEX_SOURCE = 0, - CAIRO_GL_TEX_MASK = 1 + CAIRO_GL_TEX_MASK = 1, + CAIRO_GL_TEX_TEMP = 2 } cairo_gl_tex_t; typedef enum cairo_gl_operand_type { @@ -167,6 +168,7 @@ typedef struct _cairo_gl_context { GLuint vbo; GLint max_framebuffer_size; GLint max_texture_size; + GLint max_textures; GLenum tex_target; const cairo_gl_shader_impl_t *shader_impl; @@ -279,6 +281,10 @@ _cairo_gl_context_acquire (cairo_device_t *device, cairo_private void _cairo_gl_context_set_destination (cairo_gl_context_t *ctx, cairo_gl_surface_t *surface); +cairo_private void +_cairo_gl_context_activate (cairo_gl_context_t *ctx, + cairo_gl_tex_t tex_unit); + cairo_private cairo_bool_t _cairo_gl_operator_is_supported (cairo_operator_t op); diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c index 9a75e28d..59053a43 100644 --- a/src/cairo-gl-surface.c +++ b/src/cairo-gl-surface.c @@ -281,6 +281,7 @@ _cairo_gl_surface_create_scratch (cairo_gl_context_t *ctx, } /* Create the texture used to store the surface's data. */ + _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP); glGenTextures (1, &surface->tex); glBindTexture (ctx->tex_target, surface->tex); glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -525,6 +526,7 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst, glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glPixelStorei (GL_UNPACK_ROW_LENGTH, src->stride / cpp); if (_cairo_gl_surface_is_texture (dst)) { + _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP); glBindTexture (ctx->tex_target, dst->tex); glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |