summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2010-05-30 22:01:10 +0200
committerBenjamin Otte <otte@redhat.com>2010-06-07 13:37:48 +0200
commitc75460c54d88ce9a50ac59c15a10684043ca4b0e (patch)
tree28df133103ecc76636a66cebcff195b09b44ebe1
parent1ddff8aba35466fe6689536bc5f2d7eeefaea02c (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.c2
-rw-r--r--src/cairo-gl-device.c17
-rw-r--r--src/cairo-gl-private.h8
-rw-r--r--src/cairo-gl-surface.c2
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);