[cairo-commit] 23 commits - src/cairo-gl-composite.c src/cairo-gl-device.c src/cairo-gl-glyphs.c src/cairo-gl-private.h src/cairo-gl-shaders.c src/cairo-gl-surface.c src/cairoint.h src/cairo-surface.c src/cairo-surface-private.h
Benjamin Otte
company at kemper.freedesktop.org
Thu May 20 02:03:04 PDT 2010
src/cairo-gl-composite.c | 811 ++++++++++++++++++++++----------------------
src/cairo-gl-device.c | 4
src/cairo-gl-glyphs.c | 125 ++----
src/cairo-gl-private.h | 75 +---
src/cairo-gl-shaders.c | 47 +-
src/cairo-gl-surface.c | 260 +++++---------
src/cairo-surface-private.h | 1
src/cairo-surface.c | 26 +
src/cairoint.h | 3
9 files changed, 633 insertions(+), 719 deletions(-)
New commits:
commit 4c7dd1be4526c85b47f1fe1d4663e7fbec0926b1
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 19 22:03:18 2010 +0200
gl: Move vertex array setup code into the texture setup code
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index 76b6da0..0df0502 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -609,14 +609,19 @@ _cairo_gl_texture_set_attributes (cairo_gl_context_t *ctx,
static void
_cairo_gl_operand_setup_texture (cairo_gl_context_t *ctx,
cairo_gl_operand_t *operand,
- GLuint tex_unit)
+ GLuint tex_unit,
+ unsigned int vertex_offset)
{
switch (operand->type) {
default:
case CAIRO_GL_OPERAND_COUNT:
ASSERT_NOT_REACHED;
case CAIRO_GL_OPERAND_NONE:
+ break;
case CAIRO_GL_OPERAND_SPANS:
+ glColorPointer (4, GL_UNSIGNED_BYTE, ctx->vertex_size,
+ (void *) (uintptr_t) vertex_offset);
+ glEnableClientState (GL_COLOR_ARRAY);
break;
case CAIRO_GL_OPERAND_CONSTANT:
if (ctx->current_shader == NULL) {
@@ -633,6 +638,11 @@ _cairo_gl_operand_setup_texture (cairo_gl_context_t *ctx,
glBindTexture (ctx->tex_target, operand->texture.tex);
glEnable (ctx->tex_target);
_cairo_gl_texture_set_attributes (ctx, &operand->texture.attributes);
+
+ glClientActiveTexture (GL_TEXTURE0 + tex_unit);
+ glTexCoordPointer (2, GL_FLOAT, ctx->vertex_size,
+ (void *) (uintptr_t) vertex_offset);
+ glEnableClientState (GL_TEXTURE_COORD_ARRAY);
break;
case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
glActiveTexture (GL_TEXTURE0 + tex_unit);
@@ -1108,37 +1118,20 @@ _cairo_gl_composite_begin (cairo_gl_context_t *ctx,
_cairo_gl_composite_bind_to_shader (ctx, setup);
- _cairo_gl_operand_setup_texture (ctx, &setup->src, 0);
- _cairo_gl_operand_setup_texture (ctx, &setup->mask, 1);
-
glBindBufferARB (GL_ARRAY_BUFFER_ARB, ctx->vbo);
glVertexPointer (2, GL_FLOAT, ctx->vertex_size, NULL);
glEnableClientState (GL_VERTEX_ARRAY);
+ _cairo_gl_operand_setup_texture (ctx, &setup->src, 0, dst_size);
+ _cairo_gl_operand_setup_texture (ctx, &setup->mask, 1, dst_size + src_size);
+
_cairo_gl_set_src_operand (ctx, setup);
- if (setup->src.type == CAIRO_GL_OPERAND_TEXTURE) {
- glClientActiveTexture (GL_TEXTURE0);
- glTexCoordPointer (2, GL_FLOAT, ctx->vertex_size,
- (void *) (uintptr_t) dst_size);
- glEnableClientState (GL_TEXTURE_COORD_ARRAY);
- }
if (setup->has_component_alpha)
_cairo_gl_set_component_alpha_mask_operand (ctx, setup);
else
_cairo_gl_set_mask_operand (ctx, setup);
- if (setup->mask.type == CAIRO_GL_OPERAND_TEXTURE) {
- glClientActiveTexture (GL_TEXTURE1);
- glTexCoordPointer (2, GL_FLOAT, ctx->vertex_size,
- (void *) (uintptr_t) (dst_size + src_size));
- glEnableClientState (GL_TEXTURE_COORD_ARRAY);
- } else if (setup->mask.type == CAIRO_GL_OPERAND_SPANS) {
- glColorPointer (4, GL_UNSIGNED_BYTE, ctx->vertex_size,
- (void *) (uintptr_t) (dst_size + src_size));
- glEnableClientState (GL_COLOR_ARRAY);
- }
-
if (setup->clip_region)
glEnable (GL_SCISSOR_TEST);
commit d9d5976bdf333a5a7ea7707bc3076696f3c079d2
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 19 21:54:32 2010 +0200
gl: Add an assertion that a context cannot call _begin() twice
Evert _begin() call must be followed by an _end() call to avoid any
nastiness. Just like GL. :)
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index 8e3d32e..76b6da0 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -1072,6 +1072,8 @@ _cairo_gl_composite_begin (cairo_gl_context_t *ctx,
unsigned int dst_size, src_size, mask_size;
cairo_status_t status;
+ assert (! _cairo_gl_context_is_in_progress (ctx));
+
/* Do various magic for component alpha */
if (setup->has_component_alpha) {
status = _cairo_gl_composite_begin_component_alpha (ctx, setup);
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index b88751d..0cdbe73 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -221,6 +221,13 @@ _cairo_gl_context_create_in_error (cairo_status_t status)
cairo_private cairo_status_t
_cairo_gl_context_init (cairo_gl_context_t *ctx);
+static cairo_always_inline cairo_bool_t cairo_warn
+_cairo_gl_context_is_in_progress (cairo_gl_context_t *ctx)
+{
+ /* This variable gets set when _begin() is called */
+ return ctx->vertex_size != 0;
+}
+
cairo_private void
_cairo_gl_surface_init (cairo_device_t *device,
cairo_gl_surface_t *surface,
commit 5b8b1fe1cb692530b40db330c3040cd85a8b6bd7
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 19 21:10:26 2010 +0200
gl: Move vertex buffer handling from setup into context
We can only emit one vertex buffer at a time anyway.
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index adb63bb..8e3d32e 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -1097,7 +1097,7 @@ _cairo_gl_composite_begin (cairo_gl_context_t *ctx,
src_size = _cairo_gl_operand_get_vertex_size (setup->src.type);
mask_size = _cairo_gl_operand_get_vertex_size (setup->mask.type);
- setup->vertex_size = dst_size + src_size + mask_size;
+ ctx->vertex_size = dst_size + src_size + mask_size;
_cairo_gl_context_set_destination (ctx, setup->dst);
_cairo_gl_set_operator (setup->dst,
@@ -1111,13 +1111,13 @@ _cairo_gl_composite_begin (cairo_gl_context_t *ctx,
glBindBufferARB (GL_ARRAY_BUFFER_ARB, ctx->vbo);
- glVertexPointer (2, GL_FLOAT, setup->vertex_size, NULL);
+ glVertexPointer (2, GL_FLOAT, ctx->vertex_size, NULL);
glEnableClientState (GL_VERTEX_ARRAY);
_cairo_gl_set_src_operand (ctx, setup);
if (setup->src.type == CAIRO_GL_OPERAND_TEXTURE) {
glClientActiveTexture (GL_TEXTURE0);
- glTexCoordPointer (2, GL_FLOAT, setup->vertex_size,
+ glTexCoordPointer (2, GL_FLOAT, ctx->vertex_size,
(void *) (uintptr_t) dst_size);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
}
@@ -1128,11 +1128,11 @@ _cairo_gl_composite_begin (cairo_gl_context_t *ctx,
if (setup->mask.type == CAIRO_GL_OPERAND_TEXTURE) {
glClientActiveTexture (GL_TEXTURE1);
- glTexCoordPointer (2, GL_FLOAT, setup->vertex_size,
+ glTexCoordPointer (2, GL_FLOAT, ctx->vertex_size,
(void *) (uintptr_t) (dst_size + src_size));
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
} else if (setup->mask.type == CAIRO_GL_OPERAND_SPANS) {
- glColorPointer (4, GL_UNSIGNED_BYTE, setup->vertex_size,
+ glColorPointer (4, GL_UNSIGNED_BYTE, ctx->vertex_size,
(void *) (uintptr_t) (dst_size + src_size));
glEnableClientState (GL_COLOR_ARRAY);
}
@@ -1147,7 +1147,7 @@ static inline void
_cairo_gl_composite_draw (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup)
{
- unsigned int count = setup->vb_offset / setup->vertex_size;
+ unsigned int count = ctx->vb_offset / ctx->vertex_size;
if (! setup->pre_shader) {
glDrawArrays (GL_TRIANGLES, 0, count);
@@ -1172,7 +1172,7 @@ void
_cairo_gl_composite_flush (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup)
{
- if (setup->vb_offset == 0)
+ if (ctx->vb_offset == 0)
return;
if (setup->clip_region) {
@@ -1191,7 +1191,8 @@ _cairo_gl_composite_flush (cairo_gl_context_t *ctx,
}
glUnmapBufferARB (GL_ARRAY_BUFFER_ARB);
- setup->vb = NULL;
+ ctx->vb = NULL;
+ ctx->vb_offset = 0;
}
static void
@@ -1199,14 +1200,13 @@ _cairo_gl_composite_prepare_buffer (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup,
unsigned int n_vertices)
{
- if (setup->vb_offset + n_vertices * setup->vertex_size > CAIRO_GL_VBO_SIZE)
+ if (ctx->vb_offset + n_vertices * ctx->vertex_size > CAIRO_GL_VBO_SIZE)
_cairo_gl_composite_flush (ctx, setup);
- if (setup->vb == NULL) {
+ if (ctx->vb == NULL) {
glBufferDataARB (GL_ARRAY_BUFFER_ARB, CAIRO_GL_VBO_SIZE,
NULL, GL_STREAM_DRAW_ARB);
- setup->vb = glMapBufferARB (GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
- setup->vb_offset = 0;
+ ctx->vb = glMapBufferARB (GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
}
@@ -1258,7 +1258,7 @@ _cairo_gl_composite_emit_vertex (cairo_gl_context_t *ctx,
GLfloat y,
uint32_t color)
{
- GLfloat *vb = (GLfloat *) (void *) &setup->vb[setup->vb_offset];
+ GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
*vb++ = x;
*vb++ = y;
@@ -1266,7 +1266,7 @@ _cairo_gl_composite_emit_vertex (cairo_gl_context_t *ctx,
_cairo_gl_operand_emit (&setup->src, &vb, x, y, color);
_cairo_gl_operand_emit (&setup->mask, &vb, x, y, color);
- setup->vb_offset += setup->vertex_size;
+ ctx->vb_offset += ctx->vertex_size;
}
void
@@ -1297,7 +1297,7 @@ _cairo_gl_composite_emit_glyph_vertex (cairo_gl_context_t *ctx,
GLfloat glyph_x,
GLfloat glyph_y)
{
- GLfloat *vb = (GLfloat *) (void *) &setup->vb[setup->vb_offset];
+ GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
*vb++ = x;
*vb++ = y;
@@ -1307,7 +1307,7 @@ _cairo_gl_composite_emit_glyph_vertex (cairo_gl_context_t *ctx,
*vb++ = glyph_x;
*vb++ = glyph_y;
- setup->vb_offset += setup->vertex_size;
+ ctx->vb_offset += ctx->vertex_size;
}
void
@@ -1363,6 +1363,8 @@ _cairo_gl_composite_end (cairo_gl_context_t *ctx,
glDisable (ctx->tex_target);
setup->pre_shader = NULL;
+
+ ctx->vertex_size = 0;
}
void
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 0a66813..b88751d 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -145,6 +145,10 @@ typedef struct _cairo_gl_context {
cairo_gl_surface_t *current_target;
cairo_gl_shader_t *current_shader;
+ char *vb;
+ unsigned int vb_offset;
+ unsigned int vertex_size;
+
void (*acquire) (void *ctx);
void (*release) (void *ctx);
@@ -195,10 +199,6 @@ typedef struct _cairo_gl_composite {
cairo_gl_operand_t src;
cairo_gl_operand_t mask;
cairo_gl_shader_t *pre_shader; /* for component alpha */
-
- char *vb;
- unsigned int vb_offset;
- unsigned int vertex_size;
} cairo_gl_composite_t;
cairo_private extern const cairo_surface_backend_t _cairo_gl_surface_backend;
commit 0d5f2eab77f055b063538dcd345a1e0db480f3bc
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 19 20:49:49 2010 +0200
gl: Actuall do fall back to fixed function paths.
Previously we were just returning UNSUPPORTED all the time. I guess that
explains why my code got so slow...
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index 12c6225..adb63bb 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -1086,7 +1086,9 @@ _cairo_gl_composite_begin (cairo_gl_context_t *ctx,
: CAIRO_GL_SHADER_IN_NORMAL);
if (unlikely (status)) {
setup->pre_shader = NULL;
- return status;
+ if (_cairo_status_is_error (status))
+ return status;
+ /* fall back to fixed function here */
}
status = CAIRO_STATUS_SUCCESS;
commit bb7ca71c1af416ca084f03089f5fe762403635dd
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 19 20:47:31 2010 +0200
gl: Don't store the shader in the composite_t anymore
Now that we have ctx->current_shader, there's no need to keep it in the
composite setup code.
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index 15fa838..12c6225 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -842,7 +842,7 @@ static void
_cairo_gl_set_mask_operand (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup)
{
- if (setup->shader)
+ if (ctx->current_shader)
return;
switch (setup->mask.type) {
@@ -1052,15 +1052,14 @@ _cairo_gl_composite_begin_component_alpha (cairo_gl_context_t *ctx,
*/
if (setup->op == CAIRO_OPERATOR_OVER) {
setup->op = CAIRO_OPERATOR_ADD;
- status = _cairo_gl_get_shader (ctx,
- setup->src.type,
- setup->mask.type,
- CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA,
- &setup->pre_shader);
+ status = _cairo_gl_set_shader_by_type (ctx,
+ setup->src.type,
+ setup->mask.type,
+ CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA);
if (unlikely (status))
return status;
- _cairo_gl_set_shader (ctx, setup->pre_shader);
_cairo_gl_composite_bind_to_shader (ctx, setup);
+ setup->pre_shader = ctx->current_shader;
}
return CAIRO_STATUS_SUCCESS;
@@ -1080,12 +1079,11 @@ _cairo_gl_composite_begin (cairo_gl_context_t *ctx,
return status;
}
- status = _cairo_gl_get_shader (ctx,
- setup->src.type,
- setup->mask.type,
- setup->has_component_alpha ? CAIRO_GL_SHADER_IN_CA_SOURCE
- : CAIRO_GL_SHADER_IN_NORMAL,
- &setup->shader);
+ status = _cairo_gl_set_shader_by_type (ctx,
+ setup->src.type,
+ setup->mask.type,
+ setup->has_component_alpha ? CAIRO_GL_SHADER_IN_CA_SOURCE
+ : CAIRO_GL_SHADER_IN_NORMAL);
if (unlikely (status)) {
setup->pre_shader = NULL;
return status;
@@ -1104,7 +1102,6 @@ _cairo_gl_composite_begin (cairo_gl_context_t *ctx,
setup->op,
setup->has_component_alpha);
- _cairo_gl_set_shader (ctx, setup->shader);
_cairo_gl_composite_bind_to_shader (ctx, setup);
_cairo_gl_operand_setup_texture (ctx, &setup->src, 0);
@@ -1153,13 +1150,15 @@ _cairo_gl_composite_draw (cairo_gl_context_t *ctx,
if (! setup->pre_shader) {
glDrawArrays (GL_TRIANGLES, 0, count);
} else {
+ cairo_gl_shader_t *prev_shader = ctx->current_shader;
+
_cairo_gl_set_shader (ctx, setup->pre_shader);
_cairo_gl_set_operator (setup->dst, CAIRO_OPERATOR_DEST_OUT, TRUE);
_cairo_gl_set_src_alpha_operand (ctx, setup);
_cairo_gl_set_component_alpha_mask_operand (ctx, setup);
glDrawArrays (GL_TRIANGLES, 0, count);
- _cairo_gl_set_shader (ctx, setup->shader);
+ _cairo_gl_set_shader (ctx, prev_shader);
_cairo_gl_set_operator (setup->dst, setup->op, TRUE);
_cairo_gl_set_src_operand (ctx, setup);
_cairo_gl_set_component_alpha_mask_operand (ctx, setup);
@@ -1361,7 +1360,6 @@ _cairo_gl_composite_end (cairo_gl_context_t *ctx,
glDisable (GL_TEXTURE_1D);
glDisable (ctx->tex_target);
- setup->shader = NULL;
setup->pre_shader = NULL;
}
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 6f191c9..0a66813 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -194,7 +194,6 @@ typedef struct _cairo_gl_composite {
cairo_gl_operand_t src;
cairo_gl_operand_t mask;
- cairo_gl_shader_t *shader;
cairo_gl_shader_t *pre_shader; /* for component alpha */
char *vb;
@@ -397,11 +396,10 @@ _cairo_gl_shader_compile (cairo_gl_context_t *ctx,
const char *fragment_text);
cairo_private cairo_status_t
-_cairo_gl_get_shader (cairo_gl_context_t *ctx,
- cairo_gl_operand_type_t source,
- cairo_gl_operand_type_t mask,
- cairo_gl_shader_in_t in,
- cairo_gl_shader_t **out_program);
+_cairo_gl_set_shader_by_type (cairo_gl_context_t *ctx,
+ cairo_gl_operand_type_t source,
+ cairo_gl_operand_type_t mask,
+ cairo_gl_shader_in_t in);
cairo_private void
_cairo_gl_shader_bind_float (cairo_gl_context_t *ctx,
diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c
index 246598c..d2c1973 100644
--- a/src/cairo-gl-shaders.c
+++ b/src/cairo-gl-shaders.c
@@ -925,17 +925,15 @@ _cairo_gl_set_shader (cairo_gl_context_t *ctx,
}
cairo_status_t
-_cairo_gl_get_shader (cairo_gl_context_t *ctx,
- cairo_gl_operand_type_t source,
- cairo_gl_operand_type_t mask,
- cairo_gl_shader_in_t in,
- cairo_gl_shader_t **out)
+_cairo_gl_set_shader_by_type (cairo_gl_context_t *ctx,
+ cairo_gl_operand_type_t source,
+ cairo_gl_operand_type_t mask,
+ cairo_gl_shader_in_t in)
{
cairo_shader_cache_entry_t lookup, *entry;
char *fs_source;
cairo_status_t status;
- *out = NULL;
if (ctx->shader_impl == NULL)
return CAIRO_STATUS_SUCCESS;
@@ -949,7 +947,7 @@ _cairo_gl_get_shader (cairo_gl_context_t *ctx,
entry = _cairo_cache_lookup (&ctx->shaders, &lookup.base);
if (entry) {
assert (entry->shader.program);
- *out = &entry->shader;
+ _cairo_gl_set_shader (ctx, &entry->shader);
return CAIRO_STATUS_SUCCESS;
}
@@ -992,6 +990,7 @@ _cairo_gl_get_shader (cairo_gl_context_t *ctx,
}
_cairo_gl_set_shader (ctx, &entry->shader);
+
if (source != CAIRO_GL_OPERAND_CONSTANT) {
_cairo_gl_shader_bind_texture (ctx, "source_sampler", 0);
}
@@ -1001,8 +1000,5 @@ _cairo_gl_get_shader (cairo_gl_context_t *ctx,
_cairo_gl_shader_bind_texture (ctx, "mask_sampler", 1);
}
- _cairo_gl_set_shader (ctx, NULL);
-
- *out = &entry->shader;
return CAIRO_STATUS_SUCCESS;
}
commit 6c477b4a945a8f8b866bb2f5e125d4a0328d05f4
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 19 20:10:19 2010 +0200
gl: Move shader checking in the TexEnv setup code
As the previously generic setup code only contains non-shader code now,
we can check in advance that no shader is in use and do all the other
stuff without checks.
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index dd1c026..15fa838 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -685,6 +685,9 @@ _cairo_gl_set_src_operand (cairo_gl_context_t *ctx,
cairo_surface_attributes_t *src_attributes;
GLfloat constant_color[4] = {0.0, 0.0, 0.0, 0.0};
+ if (ctx->current_shader)
+ return;
+
src_attributes = &setup->src.texture.attributes;
switch (setup->src.type) {
@@ -693,27 +696,25 @@ _cairo_gl_set_src_operand (cairo_gl_context_t *ctx,
setup->src.constant.color);
break;
case CAIRO_GL_OPERAND_TEXTURE:
- if (!setup->shader) {
- /* Set up the constant color we use to set color to 0 if needed. */
- glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant_color);
- /* Set up the combiner to just set color to the sampled texture. */
- glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
- glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
-
- /* Force the src color to 0 if the surface should be
- * alpha-only. We may have a teximage with color bits if
- * the implementation doesn't support GL_ALPHA FBOs.
- */
- if (setup->src.texture.surface->base.content !=
- CAIRO_CONTENT_ALPHA)
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE0);
- else
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_CONSTANT);
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE0);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
- }
+ /* Set up the constant color we use to set color to 0 if needed. */
+ glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant_color);
+ /* Set up the combiner to just set color to the sampled texture. */
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
+ glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
+
+ /* Force the src color to 0 if the surface should be
+ * alpha-only. We may have a teximage with color bits if
+ * the implementation doesn't support GL_ALPHA FBOs.
+ */
+ if (setup->src.texture.surface->base.content !=
+ CAIRO_CONTENT_ALPHA)
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE0);
+ else
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_CONSTANT);
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE0);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
break;
default:
@@ -738,6 +739,9 @@ _cairo_gl_set_src_alpha_operand (cairo_gl_context_t *ctx,
GLfloat constant_color[4] = {0.0, 0.0, 0.0, 0.0};
cairo_surface_attributes_t *src_attributes;
+ if (ctx->current_shader)
+ return;
+
src_attributes = &setup->src.texture.attributes;
switch (setup->src.type) {
@@ -750,17 +754,15 @@ _cairo_gl_set_src_alpha_operand (cairo_gl_context_t *ctx,
constant_color);
break;
case CAIRO_GL_OPERAND_TEXTURE:
- if (!setup->shader) {
- /* Set up the combiner to just set color to the sampled texture. */
- glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
- glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
-
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE0);
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE0);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_ALPHA);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
- }
+ /* Set up the combiner to just set color to the sampled texture. */
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
+ glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
+
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE0);
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE0);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_ALPHA);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
break;
case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT:
@@ -783,50 +785,46 @@ _cairo_gl_set_component_alpha_mask_operand (cairo_gl_context_t *ctx,
cairo_surface_attributes_t *mask_attributes;
GLfloat constant_color[4] = {0.0, 0.0, 0.0, 0.0};
+ if (ctx->current_shader)
+ return;
+
mask_attributes = &setup->mask.texture.attributes;
- if (!setup->shader) {
- glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
- glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+ glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PREVIOUS);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
- }
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PREVIOUS);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
switch (setup->mask.type) {
case CAIRO_GL_OPERAND_CONSTANT:
- /* Have to have a dummy texture bound in order to use the combiner unit. */
- if (! setup->shader) {
- glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,
- setup->mask.constant.color);
-
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_CONSTANT);
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_CONSTANT);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
- }
+ glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,
+ setup->mask.constant.color);
+
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_CONSTANT);
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_CONSTANT);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
break;
case CAIRO_GL_OPERAND_TEXTURE:
- if (!setup->shader) {
- /* Set up the constant color we use to set color to 0 if needed. */
- glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant_color);
-
- /* Force the mask color to 0 if the surface should be
- * alpha-only. We may have a teximage with color bits if
- * the implementation doesn't support GL_ALPHA FBOs.
- */
- if (setup->mask.texture.surface == NULL ||
- setup->mask.texture.surface->base.content != CAIRO_CONTENT_ALPHA)
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE1);
- else
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_CONSTANT);
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE1);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
- }
+ /* Set up the constant color we use to set color to 0 if needed. */
+ glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant_color);
+
+ /* Force the mask color to 0 if the surface should be
+ * alpha-only. We may have a teximage with color bits if
+ * the implementation doesn't support GL_ALPHA FBOs.
+ */
+ if (setup->mask.texture.surface == NULL ||
+ setup->mask.texture.surface->base.content != CAIRO_CONTENT_ALPHA)
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE1);
+ else
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_CONSTANT);
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE1);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
break;
case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
@@ -844,6 +842,9 @@ static void
_cairo_gl_set_mask_operand (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup)
{
+ if (setup->shader)
+ return;
+
switch (setup->mask.type) {
case CAIRO_GL_OPERAND_CONSTANT:
_cairo_gl_set_tex_combine_constant_color (ctx, setup, 1,
@@ -851,43 +852,39 @@ _cairo_gl_set_mask_operand (cairo_gl_context_t *ctx,
break;
case CAIRO_GL_OPERAND_TEXTURE:
- if (! setup->shader) {
- glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
- glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
-
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
-
- /* IN: dst.argb = src.argb * mask.aaaa */
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE1);
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE1);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_ALPHA);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
- }
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+ glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+
+ /* IN: dst.argb = src.argb * mask.aaaa */
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE1);
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE1);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_ALPHA);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
break;
case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT:
case CAIRO_GL_OPERAND_NONE:
break;
case CAIRO_GL_OPERAND_SPANS:
- if (! setup->shader) {
- glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
- glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
-
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
-
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
- glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PRIMARY_COLOR);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_ALPHA);
- glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
- }
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+ glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
+ glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PRIMARY_COLOR);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_ALPHA);
+ glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
break;
case CAIRO_GL_OPERAND_COUNT:
default:
@@ -1118,20 +1115,17 @@ _cairo_gl_composite_begin (cairo_gl_context_t *ctx,
glVertexPointer (2, GL_FLOAT, setup->vertex_size, NULL);
glEnableClientState (GL_VERTEX_ARRAY);
- if (! setup->pre_shader)
- _cairo_gl_set_src_operand (ctx, setup);
+ _cairo_gl_set_src_operand (ctx, setup);
if (setup->src.type == CAIRO_GL_OPERAND_TEXTURE) {
glClientActiveTexture (GL_TEXTURE0);
glTexCoordPointer (2, GL_FLOAT, setup->vertex_size,
(void *) (uintptr_t) dst_size);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
}
- if (! setup->pre_shader) {
- if (setup->has_component_alpha)
- _cairo_gl_set_component_alpha_mask_operand (ctx, setup);
- else
- _cairo_gl_set_mask_operand (ctx, setup);
- }
+ if (setup->has_component_alpha)
+ _cairo_gl_set_component_alpha_mask_operand (ctx, setup);
+ else
+ _cairo_gl_set_mask_operand (ctx, setup);
if (setup->mask.type == CAIRO_GL_OPERAND_TEXTURE) {
glClientActiveTexture (GL_TEXTURE1);
commit 73262edd8201de8ab8a01e01f83af5b5d6470f9e
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 19 19:25:03 2010 +0200
gl: Move texture setup code into its own file
This ensures textures don't need to be (re)set when doing component
alpha and running 2 shaders.
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index f06a0c4..dd1c026 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -43,56 +43,6 @@
#include "cairo-error-private.h"
#include "cairo-gl-private.h"
-static void
-_cairo_gl_set_texture_surface (int tex_unit, GLuint tex,
- cairo_surface_attributes_t *attributes,
- GLint tex_target)
-{
-
- if (tex_target == GL_TEXTURE_RECTANGLE_EXT) {
- assert (attributes->extend != CAIRO_EXTEND_REPEAT &&
- attributes->extend != CAIRO_EXTEND_REFLECT);
- }
-
- glActiveTexture (GL_TEXTURE0 + tex_unit);
- glBindTexture (tex_target, tex);
- switch (attributes->extend) {
- case CAIRO_EXTEND_NONE:
- glTexParameteri (tex_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameteri (tex_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
- break;
- case CAIRO_EXTEND_PAD:
- glTexParameteri (tex_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri (tex_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- break;
- case CAIRO_EXTEND_REPEAT:
- glTexParameteri (tex_target, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri (tex_target, GL_TEXTURE_WRAP_T, GL_REPEAT);
- break;
- case CAIRO_EXTEND_REFLECT:
- glTexParameteri (tex_target, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
- glTexParameteri (tex_target, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
- break;
- }
- switch (attributes->filter) {
- case CAIRO_FILTER_FAST:
- case CAIRO_FILTER_NEAREST:
- glTexParameteri (tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri (tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- break;
- case CAIRO_FILTER_GOOD:
- case CAIRO_FILTER_BEST:
- case CAIRO_FILTER_BILINEAR:
- glTexParameteri (tex_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri (tex_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- break;
- default:
- case CAIRO_FILTER_GAUSSIAN:
- ASSERT_NOT_REACHED;
- }
- glEnable (tex_target);
-}
-
static int
_cairo_gl_gradient_sample_width (const cairo_gradient_pattern_t *gradient)
{
@@ -611,16 +561,98 @@ _cairo_gl_composite_bind_to_shader (cairo_gl_context_t *ctx,
}
static void
+_cairo_gl_texture_set_attributes (cairo_gl_context_t *ctx,
+ cairo_surface_attributes_t *attributes)
+{
+ if (ctx->tex_target == GL_TEXTURE_RECTANGLE_EXT) {
+ assert (attributes->extend != CAIRO_EXTEND_REPEAT &&
+ attributes->extend != CAIRO_EXTEND_REFLECT);
+ }
+
+ switch (attributes->extend) {
+ case CAIRO_EXTEND_NONE:
+ glTexParameteri (ctx->tex_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+ glTexParameteri (ctx->tex_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ break;
+ case CAIRO_EXTEND_PAD:
+ glTexParameteri (ctx->tex_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri (ctx->tex_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ break;
+ case CAIRO_EXTEND_REPEAT:
+ glTexParameteri (ctx->tex_target, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri (ctx->tex_target, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ break;
+ case CAIRO_EXTEND_REFLECT:
+ glTexParameteri (ctx->tex_target, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
+ glTexParameteri (ctx->tex_target, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
+ break;
+ }
+
+ switch (attributes->filter) {
+ case CAIRO_FILTER_FAST:
+ case CAIRO_FILTER_NEAREST:
+ glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ break;
+ case CAIRO_FILTER_GOOD:
+ case CAIRO_FILTER_BEST:
+ case CAIRO_FILTER_BILINEAR:
+ glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ break;
+ default:
+ case CAIRO_FILTER_GAUSSIAN:
+ ASSERT_NOT_REACHED;
+ }
+}
+
+static void
+_cairo_gl_operand_setup_texture (cairo_gl_context_t *ctx,
+ cairo_gl_operand_t *operand,
+ GLuint tex_unit)
+{
+ switch (operand->type) {
+ default:
+ case CAIRO_GL_OPERAND_COUNT:
+ ASSERT_NOT_REACHED;
+ case CAIRO_GL_OPERAND_NONE:
+ case CAIRO_GL_OPERAND_SPANS:
+ break;
+ case CAIRO_GL_OPERAND_CONSTANT:
+ if (ctx->current_shader == NULL) {
+ glActiveTexture (GL_TEXTURE0 + tex_unit);
+ /* Have to have a dummy texture bound in order to use the combiner unit. */
+ glBindTexture (ctx->tex_target, ctx->dummy_tex);
+ glEnable (ctx->tex_target);
+ } else {
+ glDisable (ctx->tex_target);
+ }
+ break;
+ case CAIRO_GL_OPERAND_TEXTURE:
+ glActiveTexture (GL_TEXTURE0 + tex_unit);
+ glBindTexture (ctx->tex_target, operand->texture.tex);
+ glEnable (ctx->tex_target);
+ _cairo_gl_texture_set_attributes (ctx, &operand->texture.attributes);
+ break;
+ case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
+ glActiveTexture (GL_TEXTURE0 + tex_unit);
+ glBindTexture (GL_TEXTURE_1D, operand->linear.tex);
+ glEnable (GL_TEXTURE_1D);
+ break;
+ case CAIRO_GL_OPERAND_RADIAL_GRADIENT:
+ glActiveTexture (GL_TEXTURE0 + tex_unit);
+ glBindTexture (GL_TEXTURE_1D, operand->radial.tex);
+ glEnable (GL_TEXTURE_1D);
+ break;
+ }
+}
+
+static void
_cairo_gl_set_tex_combine_constant_color (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup,
int tex_unit,
GLfloat *color)
{
- glActiveTexture (GL_TEXTURE0 + tex_unit);
- /* Have to have a dummy texture bound in order to use the combiner unit. */
- glBindTexture (ctx->tex_target, ctx->dummy_tex);
- glEnable (ctx->tex_target);
-
glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
if (tex_unit == 0) {
@@ -661,8 +693,6 @@ _cairo_gl_set_src_operand (cairo_gl_context_t *ctx,
setup->src.constant.color);
break;
case CAIRO_GL_OPERAND_TEXTURE:
- _cairo_gl_set_texture_surface (0, setup->src.texture.tex,
- src_attributes, ctx->tex_target);
if (!setup->shader) {
/* Set up the constant color we use to set color to 0 if needed. */
glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant_color);
@@ -686,22 +716,13 @@ _cairo_gl_set_src_operand (cairo_gl_context_t *ctx,
}
break;
- case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
- glActiveTexture (GL_TEXTURE0);
- glBindTexture (GL_TEXTURE_1D, setup->src.linear.tex);
- glEnable (GL_TEXTURE_1D);
- break;
-
- case CAIRO_GL_OPERAND_RADIAL_GRADIENT:
- glActiveTexture (GL_TEXTURE0);
- glBindTexture (GL_TEXTURE_1D, setup->src.linear.tex);
- glEnable (GL_TEXTURE_1D);
- break;
default:
case CAIRO_GL_OPERAND_COUNT:
ASSERT_NOT_REACHED;
case CAIRO_GL_OPERAND_NONE:
case CAIRO_GL_OPERAND_SPANS:
+ case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
+ case CAIRO_GL_OPERAND_RADIAL_GRADIENT:
break;
}
}
@@ -729,8 +750,6 @@ _cairo_gl_set_src_alpha_operand (cairo_gl_context_t *ctx,
constant_color);
break;
case CAIRO_GL_OPERAND_TEXTURE:
- _cairo_gl_set_texture_surface (0, setup->src.texture.tex,
- src_attributes, ctx->tex_target);
if (!setup->shader) {
/* Set up the combiner to just set color to the sampled texture. */
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
@@ -754,28 +773,6 @@ _cairo_gl_set_src_alpha_operand (cairo_gl_context_t *ctx,
}
}
-static void
-_cairo_gl_set_linear_gradient_mask_operand (cairo_gl_context_t *ctx,
- cairo_gl_composite_t *setup)
-{
- assert(setup->shader);
-
- glActiveTexture (GL_TEXTURE1);
- glBindTexture (GL_TEXTURE_1D, setup->mask.linear.tex);
- glEnable (GL_TEXTURE_1D);
-}
-
-static void
-_cairo_gl_set_radial_gradient_mask_operand (cairo_gl_context_t *ctx,
- cairo_gl_composite_t *setup)
-{
- assert(setup->shader);
-
- glActiveTexture (GL_TEXTURE1);
- glBindTexture (GL_TEXTURE_1D, setup->mask.radial.tex);
- glEnable (GL_TEXTURE_1D);
-}
-
/* This is like _cairo_gl_set_src_alpha_operand, for component alpha setup
* of the mask part of IN to produce a "source alpha" value.
*/
@@ -803,10 +800,6 @@ _cairo_gl_set_component_alpha_mask_operand (cairo_gl_context_t *ctx,
case CAIRO_GL_OPERAND_CONSTANT:
/* Have to have a dummy texture bound in order to use the combiner unit. */
if (! setup->shader) {
- glBindTexture (ctx->tex_target, ctx->dummy_tex);
- glActiveTexture (GL_TEXTURE1);
- glEnable (ctx->tex_target);
-
glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,
setup->mask.constant.color);
@@ -817,8 +810,6 @@ _cairo_gl_set_component_alpha_mask_operand (cairo_gl_context_t *ctx,
}
break;
case CAIRO_GL_OPERAND_TEXTURE:
- _cairo_gl_set_texture_surface (1, setup->mask.texture.tex,
- mask_attributes, ctx->tex_target);
if (!setup->shader) {
/* Set up the constant color we use to set color to 0 if needed. */
glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant_color);
@@ -839,12 +830,7 @@ _cairo_gl_set_component_alpha_mask_operand (cairo_gl_context_t *ctx,
break;
case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
- _cairo_gl_set_linear_gradient_mask_operand (ctx, setup);
- break;
-
case CAIRO_GL_OPERAND_RADIAL_GRADIENT:
- _cairo_gl_set_radial_gradient_mask_operand (ctx, setup);
- break;
case CAIRO_GL_OPERAND_NONE:
case CAIRO_GL_OPERAND_SPANS:
case CAIRO_GL_OPERAND_COUNT:
@@ -865,10 +851,6 @@ _cairo_gl_set_mask_operand (cairo_gl_context_t *ctx,
break;
case CAIRO_GL_OPERAND_TEXTURE:
- _cairo_gl_set_texture_surface (1, setup->mask.texture.tex,
- &setup->mask.texture.attributes,
- ctx->tex_target);
-
if (! setup->shader) {
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
@@ -887,20 +869,11 @@ _cairo_gl_set_mask_operand (cairo_gl_context_t *ctx,
}
break;
case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
- _cairo_gl_set_linear_gradient_mask_operand (ctx, setup);
- break;
case CAIRO_GL_OPERAND_RADIAL_GRADIENT:
- _cairo_gl_set_radial_gradient_mask_operand (ctx, setup);
- break;
case CAIRO_GL_OPERAND_NONE:
break;
case CAIRO_GL_OPERAND_SPANS:
if (! setup->shader) {
- /* Set up the mask to source from the incoming vertex color. */
- glActiveTexture (GL_TEXTURE1);
- /* Have to have a dummy texture bound in order to use the combiner unit. */
- glBindTexture (ctx->tex_target, ctx->dummy_tex);
- glEnable (ctx->tex_target);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
@@ -1137,6 +1110,9 @@ _cairo_gl_composite_begin (cairo_gl_context_t *ctx,
_cairo_gl_set_shader (ctx, setup->shader);
_cairo_gl_composite_bind_to_shader (ctx, setup);
+ _cairo_gl_operand_setup_texture (ctx, &setup->src, 0);
+ _cairo_gl_operand_setup_texture (ctx, &setup->mask, 1);
+
glBindBufferARB (GL_ARRAY_BUFFER_ARB, ctx->vbo);
glVertexPointer (2, GL_FLOAT, setup->vertex_size, NULL);
commit 970c879dd897019f90b0c8ff5a18781be4935c55
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 19 18:34:00 2010 +0200
gl: Binding variables only works for the current shader
So make the code reflect that.
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index 76ae6cd..f06a0c4 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -540,7 +540,6 @@ _cairo_gl_composite_set_clip_region (cairo_gl_context_t *ctx,
static void
_cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
- cairo_gl_shader_t *shader,
cairo_gl_operand_t *operand,
const char *name)
{
@@ -561,7 +560,6 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
case CAIRO_GL_OPERAND_CONSTANT:
strcpy (custom_part, "_constant");
_cairo_gl_shader_bind_vec4 (ctx,
- shader,
uniform_name,
operand->constant.color[0],
operand->constant.color[1],
@@ -570,31 +568,31 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
break;
case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
strcpy (custom_part, "_matrix");
- _cairo_gl_shader_bind_matrix (ctx, shader,
+ _cairo_gl_shader_bind_matrix (ctx,
uniform_name,
&operand->linear.m);
strcpy (custom_part, "_segment");
- _cairo_gl_shader_bind_vec2 (ctx, shader,
+ _cairo_gl_shader_bind_vec2 (ctx,
uniform_name,
operand->linear.segment_x,
operand->linear.segment_y);
break;
case CAIRO_GL_OPERAND_RADIAL_GRADIENT:
strcpy (custom_part, "_matrix");
- _cairo_gl_shader_bind_matrix (ctx, shader,
+ _cairo_gl_shader_bind_matrix (ctx,
uniform_name,
&operand->radial.m);
strcpy (custom_part, "_circle_1");
- _cairo_gl_shader_bind_vec2 (ctx, shader,
+ _cairo_gl_shader_bind_vec2 (ctx,
uniform_name,
operand->radial.circle_1_x,
operand->radial.circle_1_y);
strcpy (custom_part, "_radius_0");
- _cairo_gl_shader_bind_float (ctx, shader,
+ _cairo_gl_shader_bind_float (ctx,
uniform_name,
operand->radial.radius_0);
strcpy (custom_part, "_radius_1");
- _cairo_gl_shader_bind_float (ctx, shader,
+ _cairo_gl_shader_bind_float (ctx,
uniform_name,
operand->radial.radius_1);
break;
@@ -603,14 +601,13 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
static void
_cairo_gl_composite_bind_to_shader (cairo_gl_context_t *ctx,
- cairo_gl_composite_t *setup,
- cairo_gl_shader_t *shader)
+ cairo_gl_composite_t *setup)
{
- if (shader == NULL)
+ if (ctx->current_shader == NULL)
return;
- _cairo_gl_operand_bind_to_shader (ctx, shader, &setup->src, "source");
- _cairo_gl_operand_bind_to_shader (ctx, shader, &setup->mask, "mask");
+ _cairo_gl_operand_bind_to_shader (ctx, &setup->src, "source");
+ _cairo_gl_operand_bind_to_shader (ctx, &setup->mask, "mask");
}
static void
@@ -1093,7 +1090,7 @@ _cairo_gl_composite_begin_component_alpha (cairo_gl_context_t *ctx,
if (unlikely (status))
return status;
_cairo_gl_set_shader (ctx, setup->pre_shader);
- _cairo_gl_composite_bind_to_shader (ctx, setup, setup->pre_shader);
+ _cairo_gl_composite_bind_to_shader (ctx, setup);
}
return CAIRO_STATUS_SUCCESS;
@@ -1138,7 +1135,7 @@ _cairo_gl_composite_begin (cairo_gl_context_t *ctx,
setup->has_component_alpha);
_cairo_gl_set_shader (ctx, setup->shader);
- _cairo_gl_composite_bind_to_shader (ctx, setup, setup->shader);
+ _cairo_gl_composite_bind_to_shader (ctx, setup);
glBindBufferARB (GL_ARRAY_BUFFER_ARB, ctx->vbo);
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 19c34c3..6f191c9 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -405,19 +405,16 @@ _cairo_gl_get_shader (cairo_gl_context_t *ctx,
cairo_private void
_cairo_gl_shader_bind_float (cairo_gl_context_t *ctx,
- cairo_gl_shader_t *shader,
const char *name,
float value);
cairo_private void
_cairo_gl_shader_bind_vec2 (cairo_gl_context_t *ctx,
- cairo_gl_shader_t *shader,
const char *name,
float value0, float value1);
cairo_private void
_cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx,
- cairo_gl_shader_t *shader,
const char *name,
float value0,
float value1,
@@ -425,20 +422,17 @@ _cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx,
cairo_private void
_cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,
- cairo_gl_shader_t *shader,
const char *name,
float value0, float value1,
float value2, float value3);
cairo_private void
_cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
- cairo_gl_shader_t *shader,
const char *name,
cairo_matrix_t* m);
cairo_private void
_cairo_gl_shader_bind_texture (cairo_gl_context_t *ctx,
- cairo_gl_shader_t *shader,
const char *name,
GLuint tex_unit);
diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c
index ccd9780..246598c 100644
--- a/src/cairo-gl-shaders.c
+++ b/src/cairo-gl-shaders.c
@@ -861,58 +861,52 @@ _cairo_gl_shader_compile (cairo_gl_context_t *ctx,
void
_cairo_gl_shader_bind_float (cairo_gl_context_t *ctx,
- cairo_gl_shader_t *shader,
const char *name,
float value)
{
- ctx->shader_impl->bind_float (shader, name, value);
+ ctx->shader_impl->bind_float (ctx->current_shader, name, value);
}
void
_cairo_gl_shader_bind_vec2 (cairo_gl_context_t *ctx,
- cairo_gl_shader_t *shader,
const char *name,
float value0,
float value1)
{
- ctx->shader_impl->bind_vec2 (shader, name, value0, value1);
+ ctx->shader_impl->bind_vec2 (ctx->current_shader, name, value0, value1);
}
void
_cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx,
- cairo_gl_shader_t *shader,
const char *name,
float value0,
float value1,
float value2)
{
- ctx->shader_impl->bind_vec3 (shader, name, value0, value1, value2);
+ ctx->shader_impl->bind_vec3 (ctx->current_shader, name, value0, value1, value2);
}
void
_cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,
- cairo_gl_shader_t *shader,
const char *name,
float value0, float value1,
float value2, float value3)
{
- ctx->shader_impl->bind_vec4 (shader, name, value0, value1, value2, value3);
+ ctx->shader_impl->bind_vec4 (ctx->current_shader, name, value0, value1, value2, value3);
}
void
_cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
- cairo_gl_shader_t *shader,
const char *name, cairo_matrix_t* m)
{
- ctx->shader_impl->bind_matrix (shader, name, m);
+ ctx->shader_impl->bind_matrix (ctx->current_shader, name, m);
}
void
_cairo_gl_shader_bind_texture (cairo_gl_context_t *ctx,
- cairo_gl_shader_t *shader,
const char *name, GLuint tex_unit)
{
- ctx->shader_impl->bind_texture (shader, name, tex_unit);
+ ctx->shader_impl->bind_texture (ctx->current_shader, name, tex_unit);
}
void
@@ -999,12 +993,12 @@ _cairo_gl_get_shader (cairo_gl_context_t *ctx,
_cairo_gl_set_shader (ctx, &entry->shader);
if (source != CAIRO_GL_OPERAND_CONSTANT) {
- _cairo_gl_shader_bind_texture (ctx, &entry->shader, "source_sampler", 0);
+ _cairo_gl_shader_bind_texture (ctx, "source_sampler", 0);
}
if (mask != CAIRO_GL_OPERAND_CONSTANT &&
mask != CAIRO_GL_OPERAND_SPANS &&
mask != CAIRO_GL_OPERAND_NONE) {
- _cairo_gl_shader_bind_texture (ctx, &entry->shader, "mask_sampler", 1);
+ _cairo_gl_shader_bind_texture (ctx, "mask_sampler", 1);
}
_cairo_gl_set_shader (ctx, NULL);
commit 065969d78f23c634ebcb2b931cbb1fe184f2cedf
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 19 18:21:06 2010 +0200
gl: Separate binding to shaders from setting operands
That way we only need to bind to shaders when creating them, but not
everytime we switch shaders on text output.
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index 61bac27..76ae6cd 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -539,31 +539,86 @@ _cairo_gl_composite_set_clip_region (cairo_gl_context_t *ctx,
}
static void
-_cairo_gl_set_tex_combine_constant_color (cairo_gl_context_t *ctx,
- cairo_gl_composite_t *setup,
- int tex_unit,
- GLfloat *color)
+_cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
+ cairo_gl_shader_t *shader,
+ cairo_gl_operand_t *operand,
+ const char *name)
{
- if (setup->shader) {
- const char *uniform_name;
+ char uniform_name[50];
+ char *custom_part;
- if (tex_unit == 0)
- uniform_name = "source_constant";
- else
- uniform_name = "mask_constant";
+ strcpy (uniform_name, name);
+ custom_part = uniform_name + strlen (name);
+ switch (operand->type) {
+ default:
+ case CAIRO_GL_OPERAND_COUNT:
+ ASSERT_NOT_REACHED;
+ case CAIRO_GL_OPERAND_NONE:
+ case CAIRO_GL_OPERAND_SPANS:
+ case CAIRO_GL_OPERAND_TEXTURE:
+ break;
+ case CAIRO_GL_OPERAND_CONSTANT:
+ strcpy (custom_part, "_constant");
_cairo_gl_shader_bind_vec4 (ctx,
- setup->shader,
- uniform_name,
- color[0],
- color[1],
- color[2],
- color[3]);
-
- return;
+ shader,
+ uniform_name,
+ operand->constant.color[0],
+ operand->constant.color[1],
+ operand->constant.color[2],
+ operand->constant.color[3]);
+ break;
+ case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
+ strcpy (custom_part, "_matrix");
+ _cairo_gl_shader_bind_matrix (ctx, shader,
+ uniform_name,
+ &operand->linear.m);
+ strcpy (custom_part, "_segment");
+ _cairo_gl_shader_bind_vec2 (ctx, shader,
+ uniform_name,
+ operand->linear.segment_x,
+ operand->linear.segment_y);
+ break;
+ case CAIRO_GL_OPERAND_RADIAL_GRADIENT:
+ strcpy (custom_part, "_matrix");
+ _cairo_gl_shader_bind_matrix (ctx, shader,
+ uniform_name,
+ &operand->radial.m);
+ strcpy (custom_part, "_circle_1");
+ _cairo_gl_shader_bind_vec2 (ctx, shader,
+ uniform_name,
+ operand->radial.circle_1_x,
+ operand->radial.circle_1_y);
+ strcpy (custom_part, "_radius_0");
+ _cairo_gl_shader_bind_float (ctx, shader,
+ uniform_name,
+ operand->radial.radius_0);
+ strcpy (custom_part, "_radius_1");
+ _cairo_gl_shader_bind_float (ctx, shader,
+ uniform_name,
+ operand->radial.radius_1);
+ break;
}
+}
+
+static void
+_cairo_gl_composite_bind_to_shader (cairo_gl_context_t *ctx,
+ cairo_gl_composite_t *setup,
+ cairo_gl_shader_t *shader)
+{
+ if (shader == NULL)
+ return;
+
+ _cairo_gl_operand_bind_to_shader (ctx, shader, &setup->src, "source");
+ _cairo_gl_operand_bind_to_shader (ctx, shader, &setup->mask, "mask");
+}
- /* Fall back to fixed function */
+static void
+_cairo_gl_set_tex_combine_constant_color (cairo_gl_context_t *ctx,
+ cairo_gl_composite_t *setup,
+ int tex_unit,
+ GLfloat *color)
+{
glActiveTexture (GL_TEXTURE0 + tex_unit);
/* Have to have a dummy texture bound in order to use the combiner unit. */
glBindTexture (ctx->tex_target, ctx->dummy_tex);
@@ -638,38 +693,12 @@ _cairo_gl_set_src_operand (cairo_gl_context_t *ctx,
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_1D, setup->src.linear.tex);
glEnable (GL_TEXTURE_1D);
-
- _cairo_gl_shader_bind_matrix (ctx, setup->shader,
- "source_matrix",
- &setup->src.linear.m);
-
- _cairo_gl_shader_bind_vec2 (ctx, setup->shader,
- "source_segment",
- setup->src.linear.segment_x,
- setup->src.linear.segment_y);
break;
case CAIRO_GL_OPERAND_RADIAL_GRADIENT:
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_1D, setup->src.linear.tex);
glEnable (GL_TEXTURE_1D);
-
- _cairo_gl_shader_bind_matrix (ctx, setup->shader,
- "source_matrix",
- &setup->src.radial.m);
-
- _cairo_gl_shader_bind_vec2 (ctx, setup->shader,
- "source_circle_1",
- setup->src.radial.circle_1_x,
- setup->src.radial.circle_1_y);
-
- _cairo_gl_shader_bind_float (ctx, setup->shader,
- "source_radius_0",
- setup->src.radial.radius_0);
-
- _cairo_gl_shader_bind_float (ctx, setup->shader,
- "source_radius_1",
- setup->src.radial.radius_1);
break;
default:
case CAIRO_GL_OPERAND_COUNT:
@@ -737,14 +766,6 @@ _cairo_gl_set_linear_gradient_mask_operand (cairo_gl_context_t *ctx,
glActiveTexture (GL_TEXTURE1);
glBindTexture (GL_TEXTURE_1D, setup->mask.linear.tex);
glEnable (GL_TEXTURE_1D);
-
- _cairo_gl_shader_bind_matrix (ctx, setup->shader,
- "mask_matrix", &setup->mask.linear.m);
-
- _cairo_gl_shader_bind_vec2 (ctx, setup->shader,
- "mask_segment",
- setup->mask.linear.segment_x,
- setup->mask.linear.segment_y);
}
static void
@@ -756,23 +777,6 @@ _cairo_gl_set_radial_gradient_mask_operand (cairo_gl_context_t *ctx,
glActiveTexture (GL_TEXTURE1);
glBindTexture (GL_TEXTURE_1D, setup->mask.radial.tex);
glEnable (GL_TEXTURE_1D);
-
- _cairo_gl_shader_bind_matrix (ctx, setup->shader,
- "mask_matrix",
- &setup->mask.radial.m);
-
- _cairo_gl_shader_bind_vec2 (ctx, setup->shader,
- "mask_circle_1",
- setup->mask.radial.circle_1_x,
- setup->mask.radial.circle_1_y);
-
- _cairo_gl_shader_bind_float (ctx, setup->shader,
- "mask_radius_0",
- setup->mask.radial.radius_0);
-
- _cairo_gl_shader_bind_float (ctx, setup->shader,
- "mask_radius_1",
- setup->mask.radial.radius_1);
}
/* This is like _cairo_gl_set_src_alpha_operand, for component alpha setup
@@ -801,14 +805,7 @@ _cairo_gl_set_component_alpha_mask_operand (cairo_gl_context_t *ctx,
switch (setup->mask.type) {
case CAIRO_GL_OPERAND_CONSTANT:
/* Have to have a dummy texture bound in order to use the combiner unit. */
- if (setup->shader) {
- _cairo_gl_shader_bind_vec4 (ctx, setup->shader,
- "mask_constant",
- setup->mask.constant.color[0],
- setup->mask.constant.color[1],
- setup->mask.constant.color[2],
- setup->mask.constant.color[3]);
- } else {
+ if (! setup->shader) {
glBindTexture (ctx->tex_target, ctx->dummy_tex);
glActiveTexture (GL_TEXTURE1);
glEnable (ctx->tex_target);
@@ -1095,6 +1092,8 @@ _cairo_gl_composite_begin_component_alpha (cairo_gl_context_t *ctx,
&setup->pre_shader);
if (unlikely (status))
return status;
+ _cairo_gl_set_shader (ctx, setup->pre_shader);
+ _cairo_gl_composite_bind_to_shader (ctx, setup, setup->pre_shader);
}
return CAIRO_STATUS_SUCCESS;
@@ -1139,6 +1138,7 @@ _cairo_gl_composite_begin (cairo_gl_context_t *ctx,
setup->has_component_alpha);
_cairo_gl_set_shader (ctx, setup->shader);
+ _cairo_gl_composite_bind_to_shader (ctx, setup, setup->shader);
glBindBufferARB (GL_ARRAY_BUFFER_ARB, ctx->vbo);
diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c
index 3484321..ccd9780 100644
--- a/src/cairo-gl-shaders.c
+++ b/src/cairo-gl-shaders.c
@@ -550,7 +550,7 @@ _cairo_gl_shader_fini (cairo_gl_context_t *ctx,
ctx->shader_impl->destroy_program (shader->program);
}
-typedef enum cairo_gl_operand_target {
+typedef enum cairo_gl_operand_name {
CAIRO_GL_OPERAND_SOURCE,
CAIRO_GL_OPERAND_MASK,
CAIRO_GL_OPERAND_DEST
commit c53f7778bcf274f64f801ef9ee1641a088842f60
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 19 16:50:57 2010 +0200
gl: Use the mask, not the source
Not that we'd ever have constant color component-alpha masks, but that's
an entirely different topic.
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index c3d65f4..61bac27 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -804,10 +804,10 @@ _cairo_gl_set_component_alpha_mask_operand (cairo_gl_context_t *ctx,
if (setup->shader) {
_cairo_gl_shader_bind_vec4 (ctx, setup->shader,
"mask_constant",
- setup->src.constant.color[0],
- setup->src.constant.color[1],
- setup->src.constant.color[2],
- setup->src.constant.color[3]);
+ setup->mask.constant.color[0],
+ setup->mask.constant.color[1],
+ setup->mask.constant.color[2],
+ setup->mask.constant.color[3]);
} else {
glBindTexture (ctx->tex_target, ctx->dummy_tex);
glActiveTexture (GL_TEXTURE1);
commit 26e8e506b66022910c262da0618ef5be8c5a080e
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 19 13:19:56 2010 +0200
gl: Add _cairo_gl_surface_is_texture()
It's more explicit then just checking surface->fb != 0
Also, it makes improving that check easier.
diff --git a/src/cairo-gl-device.c b/src/cairo-gl-device.c
index e31fc05..be4298f 100644
--- a/src/cairo-gl-device.c
+++ b/src/cairo-gl-device.c
@@ -190,7 +190,7 @@ _cairo_gl_context_set_destination (cairo_gl_context_t *ctx,
if (ctx->current_target != surface) {
ctx->current_target = surface;
- if (surface->fb) {
+ if (_cairo_gl_surface_is_texture (surface)) {
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, surface->fb);
glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
glReadBuffer (GL_COLOR_ATTACHMENT0_EXT);
@@ -206,7 +206,7 @@ _cairo_gl_context_set_destination (cairo_gl_context_t *ctx,
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
- if (surface->fb)
+ if (_cairo_gl_surface_is_texture (surface))
glOrtho (0, surface->width, 0, surface->height, -1.0, 1.0);
else
glOrtho (0, surface->width, surface->height, 0, -1.0, 1.0);
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 825dd93..19c34c3 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -228,6 +228,12 @@ _cairo_gl_surface_init (cairo_device_t *device,
cairo_content_t content,
int width, int height);
+static cairo_always_inline cairo_bool_t cairo_warn
+_cairo_gl_surface_is_texture (cairo_gl_surface_t *surface)
+{
+ return surface->fb != 0;
+}
+
cairo_private cairo_status_t
_cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
cairo_image_surface_t *src,
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index ecd30a4..992a40b 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -400,7 +400,8 @@ cairo_gl_surface_set_size (cairo_surface_t *abstract_surface,
if (unlikely (abstract_surface->status))
return;
- if (! _cairo_surface_is_gl (abstract_surface) || surface->fb) {
+ if (! _cairo_surface_is_gl (abstract_surface) ||
+ ! _cairo_gl_surface_is_texture (surface)) {
status = _cairo_surface_set_error (abstract_surface,
CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
return;
@@ -447,7 +448,7 @@ cairo_gl_surface_swapbuffers (cairo_surface_t *abstract_surface)
return;
}
- if (! surface->fb) {
+ if (! _cairo_gl_surface_is_texture (surface)) {
cairo_gl_context_t *ctx;
if (_cairo_gl_context_acquire (surface->base.device, &ctx))
@@ -536,7 +537,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 (dst->fb) {
+ if (_cairo_gl_surface_is_texture (dst)) {
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);
@@ -666,12 +667,12 @@ _cairo_gl_surface_get_image (cairo_gl_surface_t *surface,
glPixelStorei (GL_PACK_ALIGNMENT, 1);
glPixelStorei (GL_PACK_ROW_LENGTH, image->stride / cpp);
- if (surface->fb == 0 && GLEW_MESA_pack_invert)
+ if (! _cairo_gl_surface_is_texture (surface) && GLEW_MESA_pack_invert)
glPixelStorei (GL_PACK_INVERT_MESA, 1);
glReadPixels (interest->x, interest->y,
interest->width, interest->height,
format, type, image->data);
- if (surface->fb == 0 && GLEW_MESA_pack_invert)
+ if (! _cairo_gl_surface_is_texture (surface) && GLEW_MESA_pack_invert)
glPixelStorei (GL_PACK_INVERT_MESA, 0);
_cairo_gl_context_release (ctx);
commit e4cb46b50015f792b0e8c7b49f3b42f2c3c0ad00
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 19 12:10:10 2010 +0200
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.
diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c
index 55c9eb8..3484321 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 5c370b7..ecd30a4 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);
commit 7c8759e279f51ea722c07e4b0c70f4a49f34393d
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 19 11:46:12 2010 +0200
gl: cache the current shader in the context
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index b349f57..825dd93 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -139,10 +139,12 @@ typedef struct _cairo_gl_context {
cairo_gl_shader_t fill_rectangles_shader;
cairo_cache_t shaders;
- cairo_gl_surface_t *current_target;
cairo_gl_glyph_cache_t glyph_cache[2];
cairo_list_t fonts;
+ cairo_gl_surface_t *current_target;
+ cairo_gl_shader_t *current_shader;
+
void (*acquire) (void *ctx);
void (*release) (void *ctx);
diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c
index b364c71..55c9eb8 100644
--- a/src/cairo-gl-shaders.c
+++ b/src/cairo-gl-shaders.c
@@ -470,6 +470,8 @@ _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)
+ entry->ctx->current_shader = NULL;
free (entry);
}
@@ -920,7 +922,12 @@ _cairo_gl_set_shader (cairo_gl_context_t *ctx,
if (ctx->shader_impl == NULL)
return;
+ if (ctx->current_shader == shader)
+ return;
+
ctx->shader_impl->use (shader);
+
+ ctx->current_shader = shader;
}
cairo_status_t
commit 6864ca6c25aa8147a562d7f693a95025dde807a8
Author: Benjamin Otte <otte at redhat.com>
Date: Wed May 19 11:10:11 2010 +0200
gl: Move _cairo_gl_set_operator() to the file it's used in
Also make it a private function.
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index b1fe4f8..c3d65f4 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -929,6 +929,63 @@ _cairo_gl_set_mask_operand (cairo_gl_context_t *ctx,
}
}
+static void
+_cairo_gl_set_operator (cairo_gl_surface_t *dst, cairo_operator_t op,
+ cairo_bool_t component_alpha)
+{
+ struct {
+ GLenum src;
+ GLenum dst;
+ } blend_factors[] = {
+ { GL_ZERO, GL_ZERO }, /* Clear */
+ { GL_ONE, GL_ZERO }, /* Source */
+ { GL_ONE, GL_ONE_MINUS_SRC_ALPHA }, /* Over */
+ { GL_DST_ALPHA, GL_ZERO }, /* In */
+ { GL_ONE_MINUS_DST_ALPHA, GL_ZERO }, /* Out */
+ { GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, /* Atop */
+
+ { GL_ZERO, GL_ONE }, /* Dest */
+ { GL_ONE_MINUS_DST_ALPHA, GL_ONE }, /* DestOver */
+ { GL_ZERO, GL_SRC_ALPHA }, /* DestIn */
+ { GL_ZERO, GL_ONE_MINUS_SRC_ALPHA }, /* DestOut */
+ { GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA }, /* DestAtop */
+
+ { GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, /* Xor */
+ { GL_ONE, GL_ONE }, /* Add */
+ };
+ GLenum src_factor, dst_factor;
+
+ assert (op < ARRAY_LENGTH (blend_factors));
+
+ src_factor = blend_factors[op].src;
+ dst_factor = blend_factors[op].dst;
+
+ /* Even when the user requests CAIRO_CONTENT_COLOR, we use GL_RGBA
+ * due to texture filtering of GL_CLAMP_TO_BORDER. So fix those
+ * bits in that case.
+ */
+ if (dst->base.content == CAIRO_CONTENT_COLOR) {
+ if (src_factor == GL_ONE_MINUS_DST_ALPHA)
+ src_factor = GL_ZERO;
+ if (src_factor == GL_DST_ALPHA)
+ src_factor = GL_ONE;
+ }
+
+ if (component_alpha) {
+ if (dst_factor == GL_ONE_MINUS_SRC_ALPHA)
+ dst_factor = GL_ONE_MINUS_SRC_COLOR;
+ if (dst_factor == GL_SRC_ALPHA)
+ dst_factor = GL_SRC_COLOR;
+ }
+
+ glEnable (GL_BLEND);
+ if (dst->base.content == CAIRO_CONTENT_ALPHA) {
+ glBlendFuncSeparate (GL_ZERO, GL_ZERO, src_factor, dst_factor);
+ } else {
+ glBlendFunc (src_factor, dst_factor);
+ }
+}
+
static unsigned int
_cairo_gl_operand_get_vertex_size (cairo_gl_operand_type_t type)
{
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 7a43567..b349f57 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -264,10 +264,6 @@ _cairo_gl_context_set_destination (cairo_gl_context_t *ctx, cairo_gl_surface_t *
cairo_private cairo_bool_t
_cairo_gl_operator_is_supported (cairo_operator_t op);
-cairo_private void
-_cairo_gl_set_operator (cairo_gl_surface_t *dst, cairo_operator_t op,
- cairo_bool_t component_alpha);
-
cairo_private cairo_status_t
_cairo_gl_composite_init (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup,
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index dd4b35d..5c370b7 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -205,63 +205,6 @@ _cairo_gl_operator_is_supported (cairo_operator_t op)
}
void
-_cairo_gl_set_operator (cairo_gl_surface_t *dst, cairo_operator_t op,
- cairo_bool_t component_alpha)
-{
- struct {
- GLenum src;
- GLenum dst;
- } blend_factors[] = {
- { GL_ZERO, GL_ZERO }, /* Clear */
- { GL_ONE, GL_ZERO }, /* Source */
- { GL_ONE, GL_ONE_MINUS_SRC_ALPHA }, /* Over */
- { GL_DST_ALPHA, GL_ZERO }, /* In */
- { GL_ONE_MINUS_DST_ALPHA, GL_ZERO }, /* Out */
- { GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, /* Atop */
-
- { GL_ZERO, GL_ONE }, /* Dest */
- { GL_ONE_MINUS_DST_ALPHA, GL_ONE }, /* DestOver */
- { GL_ZERO, GL_SRC_ALPHA }, /* DestIn */
- { GL_ZERO, GL_ONE_MINUS_SRC_ALPHA }, /* DestOut */
- { GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA }, /* DestAtop */
-
- { GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, /* Xor */
- { GL_ONE, GL_ONE }, /* Add */
- };
- GLenum src_factor, dst_factor;
-
- assert (op < ARRAY_LENGTH (blend_factors));
-
- src_factor = blend_factors[op].src;
- dst_factor = blend_factors[op].dst;
-
- /* Even when the user requests CAIRO_CONTENT_COLOR, we use GL_RGBA
- * due to texture filtering of GL_CLAMP_TO_BORDER. So fix those
- * bits in that case.
- */
- if (dst->base.content == CAIRO_CONTENT_COLOR) {
- if (src_factor == GL_ONE_MINUS_DST_ALPHA)
- src_factor = GL_ZERO;
- if (src_factor == GL_DST_ALPHA)
- src_factor = GL_ONE;
- }
-
- if (component_alpha) {
- if (dst_factor == GL_ONE_MINUS_SRC_ALPHA)
- dst_factor = GL_ONE_MINUS_SRC_COLOR;
- if (dst_factor == GL_SRC_ALPHA)
- dst_factor = GL_SRC_COLOR;
- }
-
- glEnable (GL_BLEND);
- if (dst->base.content == CAIRO_CONTENT_ALPHA) {
- glBlendFuncSeparate (GL_ZERO, GL_ZERO, src_factor, dst_factor);
- } else {
- glBlendFunc (src_factor, dst_factor);
- }
-}
-
-void
_cairo_gl_surface_init (cairo_device_t *device,
cairo_gl_surface_t *surface,
cairo_content_t content,
commit 0d2d4c59026c31da084e6797d109a230341b396d
Author: Benjamin Otte <otte at redhat.com>
Date: Tue May 18 21:56:55 2010 +0200
gl: Detect color-pattern clears of surfaces
... and use glClear() there.
The common case here is a solid color and OPERATOR_OVER.
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 66c9165..7a43567 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -264,9 +264,6 @@ _cairo_gl_context_set_destination (cairo_gl_context_t *ctx, cairo_gl_surface_t *
cairo_private cairo_bool_t
_cairo_gl_operator_is_supported (cairo_operator_t op);
-cairo_private cairo_status_t
-_cairo_gl_surface_clear (cairo_gl_surface_t *surface);
-
cairo_private void
_cairo_gl_set_operator (cairo_gl_surface_t *dst, cairo_operator_t op,
cairo_bool_t component_alpha);
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index b823594..dd4b35d 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -350,21 +350,33 @@ _cairo_gl_surface_create_scratch (cairo_gl_context_t *ctx,
return &surface->base;
}
-cairo_status_t
-_cairo_gl_surface_clear (cairo_gl_surface_t *surface)
+static cairo_status_t
+_cairo_gl_surface_clear (cairo_gl_surface_t *surface,
+ const cairo_color_t *color)
{
cairo_gl_context_t *ctx;
cairo_status_t status;
+ double r, g, b, a;
status = _cairo_gl_context_acquire (surface->base.device, &ctx);
if (unlikely (status))
return status;
_cairo_gl_context_set_destination (ctx, surface);
- if (surface->base.content == CAIRO_CONTENT_COLOR)
- glClearColor (0.0, 0.0, 0.0, 1.0);
- else
- glClearColor (0.0, 0.0, 0.0, 0.0);
+ if (surface->base.content & CAIRO_CONTENT_COLOR) {
+ r = color->red * color->alpha;
+ g = color->green * color->alpha;
+ b = color->blue * color->alpha;
+ } else {
+ r = g = b = 0;
+ }
+ if (surface->base.content & CAIRO_CONTENT_ALPHA) {
+ a = color->alpha;
+ } else {
+ a = 1.0;
+ }
+
+ glClearColor (r, g, b, a);
glClear (GL_COLOR_BUFFER_BIT);
_cairo_gl_context_release (ctx);
@@ -406,7 +418,7 @@ cairo_gl_surface_create (cairo_device_t *abstract_device,
}
/* Cairo surfaces start out initialized to transparent (black) */
- status = _cairo_gl_surface_clear (surface);
+ status = _cairo_gl_surface_clear (surface, CAIRO_COLOR_TRANSPARENT);
if (unlikely (status)) {
cairo_surface_destroy (&surface->base);
_cairo_gl_context_release (ctx);
@@ -1385,8 +1397,16 @@ _cairo_gl_surface_paint (void *abstract_surface,
cairo_clip_t *clip)
{
/* simplify the common case of clearing the surface */
- if (op == CAIRO_OPERATOR_CLEAR && clip == NULL)
- return _cairo_gl_surface_clear (abstract_surface);
+ if (clip == NULL) {
+ if (op == CAIRO_OPERATOR_CLEAR)
+ return _cairo_gl_surface_clear (abstract_surface, CAIRO_COLOR_TRANSPARENT);
+ else if (source->type == CAIRO_PATTERN_TYPE_SOLID &&
+ (op == CAIRO_OPERATOR_SOURCE ||
+ (op == CAIRO_OPERATOR_OVER && _cairo_pattern_is_opaque_solid (source)))) {
+ return _cairo_gl_surface_clear (abstract_surface,
+ &((cairo_solid_pattern_t *) source)->color);
+ }
+ }
return CAIRO_INT_STATUS_UNSUPPORTED;
}
commit b70eb275c4aa54f7c90a985b5de67da12ac08a30
Author: Benjamin Otte <otte at redhat.com>
Date: Tue May 18 21:56:18 2010 +0200
gl: detect image uploads and fast-path them
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 531159b..b823594 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -965,6 +965,29 @@ _cairo_gl_surface_composite (cairo_operator_t op,
cairo_status_t status;
cairo_gl_composite_t setup;
cairo_rectangle_int_t rect = { dst_x, dst_y, width, height };
+ int dx, dy;
+
+ if (op == CAIRO_OPERATOR_SOURCE &&
+ mask == NULL &&
+ src->type == CAIRO_PATTERN_TYPE_SURFACE &&
+ _cairo_surface_is_image (((cairo_surface_pattern_t *) src)->surface) &&
+ _cairo_matrix_is_integer_translation (&src->matrix, &dx, &dy)) {
+ cairo_image_surface_t *image = (cairo_image_surface_t *)
+ ((cairo_surface_pattern_t *) src)->surface;
+ dx += src_x;
+ dy += src_y;
+ if (dx >= 0 &&
+ dy >= 0 &&
+ dx + width <= (unsigned int) image->width &&
+ dy + height <= (unsigned int) image->height) {
+ status = _cairo_gl_surface_draw_image (dst, image,
+ dx, dy,
+ width, height,
+ dst_x, dst_y);
+ if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+ return status;
+ }
+ }
status = _cairo_gl_context_acquire (dst->base.device, &ctx);
if (unlikely (status))
commit 8adbf3aa19fd9fb8200973ecd72cdebfd9a5364d
Author: Benjamin Otte <otte at redhat.com>
Date: Tue May 18 20:12:44 2010 +0200
gl: Use _cairo_gl_surface_draw_image() when caching glyphs
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index 7ccc7fd..4252710 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -63,33 +63,8 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
cairo_gl_surface_t *cache_surface;
cairo_gl_glyph_private_t *glyph_private;
cairo_rtree_node_t *node = NULL;
- cairo_image_surface_t *clone = NULL;
cairo_status_t status;
int width, height;
- GLenum internal_format, format, type;
- cairo_bool_t has_alpha;
-
- if (! _cairo_gl_get_image_format_and_type (glyph_surface->pixman_format,
- &internal_format,
- &format,
- &type,
- &has_alpha))
- {
- cairo_bool_t is_supported;
-
- clone = _cairo_image_surface_coerce (glyph_surface);
- if (unlikely (clone->base.status))
- return clone->base.status;
-
- is_supported =
- _cairo_gl_get_image_format_and_type (clone->pixman_format,
- &internal_format,
- &format,
- &type,
- &has_alpha);
- assert (is_supported);
- glyph_surface = clone;
- }
width = glyph_surface->width;
if (width < GLYPH_CACHE_MIN_SIZE)
@@ -114,19 +89,15 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
cache_surface = (cairo_gl_surface_t *) cache->pattern.surface;
+ /* XXX: Make sure we use the mask texture. This should work automagically somehow */
glActiveTexture (GL_TEXTURE1);
- glBindTexture (ctx->tex_target, cache_surface->tex);
-
- glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei (GL_UNPACK_ROW_LENGTH,
- glyph_surface->stride /
- (PIXMAN_FORMAT_BPP (glyph_surface->pixman_format) / 8));
- glTexSubImage2D (ctx->tex_target, 0,
- node->x, node->y,
- glyph_surface->width, glyph_surface->height,
- format, type,
- glyph_surface->data);
- glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
+ status = _cairo_gl_surface_draw_image (cache_surface,
+ glyph_surface,
+ 0, 0,
+ glyph_surface->width, glyph_surface->height,
+ node->x, node->y);
+ if (unlikely (status))
+ return status;
scaled_glyph->surface_private = node;
node->owner = &scaled_glyph->surface_private;
@@ -146,8 +117,6 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
glyph_private->p2.y /= cache_surface->height;
}
- cairo_surface_destroy (&clone->base);
-
return CAIRO_STATUS_SUCCESS;
}
commit 915aa64ef077fe3b6094d0f1c8bd87ab5acc4868
Author: Benjamin Otte <otte at redhat.com>
Date: Tue May 18 13:01:30 2010 +0200
gl: Actually check errors for _cairo_gl_composite_begin()
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index a72f93c..7ccc7fd 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -343,6 +343,8 @@ _render_glyphs (cairo_gl_surface_t *dst,
*has_component_alpha |= cache->pattern.base.has_component_alpha;
status = _cairo_gl_composite_begin (ctx, &setup);
+ if (unlikely (status))
+ goto FINISH;
}
if (scaled_glyph->surface_private == NULL) {
commit 0222cc7d76b0dc724630b660687f98a2460eb0b9
Author: Benjamin Otte <otte at redhat.com>
Date: Tue May 18 13:00:34 2010 +0200
gl: Get rid of _cairo_gl_composite_set_mask_texture()
Now that the glyph cache contains real surfaces, there's no longer a
need to have a special function for it.
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index 40efbf1..b1fe4f8 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -531,22 +531,6 @@ _cairo_gl_composite_set_mask_spans (cairo_gl_context_t *ctx,
}
void
-_cairo_gl_composite_set_mask_texture (cairo_gl_context_t *ctx,
- cairo_gl_composite_t *setup,
- GLuint tex,
- cairo_bool_t has_component_alpha)
-{
- _cairo_gl_operand_destroy (&setup->mask);
-
- setup->has_component_alpha = has_component_alpha;
-
- setup->mask.type = CAIRO_GL_OPERAND_TEXTURE;
- setup->mask.texture.tex = tex;
- setup->mask.texture.surface = NULL;
- cairo_matrix_init_identity (&setup->mask.texture.attributes.matrix);
-}
-
-void
_cairo_gl_composite_set_clip_region (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup,
cairo_region_t *clip_region)
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index b49f889..a72f93c 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -333,13 +333,14 @@ _render_glyphs (cairo_gl_surface_t *dst,
last_format = scaled_glyph->surface->format;
- _cairo_gl_composite_set_mask_texture (ctx,
- &setup,
- ((cairo_gl_surface_t *) cache->pattern.surface)->tex,
- last_format == CAIRO_FORMAT_ARGB32);
-
- if (last_format == CAIRO_FORMAT_ARGB32)
- *has_component_alpha = TRUE;
+ status = _cairo_gl_composite_set_mask (ctx,
+ &setup,
+ &cache->pattern.base,
+ 0, 0, 0, 0, 0, 0);
+ if (unlikely (status))
+ goto FINISH;
+
+ *has_component_alpha |= cache->pattern.base.has_component_alpha;
status = _cairo_gl_composite_begin (ctx, &setup);
}
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index d7298c9..66c9165 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -308,12 +308,6 @@ cairo_private void
_cairo_gl_composite_set_mask_spans (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup);
-cairo_private void
-_cairo_gl_composite_set_mask_texture (cairo_gl_context_t *ctx,
- cairo_gl_composite_t *setup,
- GLuint tex,
- cairo_bool_t has_component_alpha);
-
cairo_private cairo_status_t
_cairo_gl_composite_begin (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup);
commit 208d9f2a7e1f66ff2764c41fe67f65e27279b2ab
Author: Benjamin Otte <otte at redhat.com>
Date: Tue May 18 12:49:59 2010 +0200
gl: Make glyph cache a real surface
This has the huge advantage that we can use real surface functions on
it.
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index 7d187c5..b49f889 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -60,6 +60,7 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
cairo_scaled_glyph_t *scaled_glyph)
{
cairo_image_surface_t *glyph_surface = scaled_glyph->surface;
+ cairo_gl_surface_t *cache_surface;
cairo_gl_glyph_private_t *glyph_private;
cairo_rtree_node_t *node = NULL;
cairo_image_surface_t *clone = NULL;
@@ -111,8 +112,10 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
if (status)
return status;
+ cache_surface = (cairo_gl_surface_t *) cache->pattern.surface;
+
glActiveTexture (GL_TEXTURE1);
- glBindTexture (ctx->tex_target, cache->tex);
+ glBindTexture (ctx->tex_target, cache_surface->tex);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glPixelStorei (GL_UNPACK_ROW_LENGTH,
@@ -137,10 +140,10 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
glyph_private->p2.x = node->x + glyph_surface->width;
glyph_private->p2.y = node->y + glyph_surface->height;
if (ctx->tex_target != GL_TEXTURE_RECTANGLE_EXT) {
- glyph_private->p1.x /= cache->width;
- glyph_private->p1.y /= cache->height;
- glyph_private->p2.x /= cache->width;
- glyph_private->p2.y /= cache->height;
+ glyph_private->p1.x /= cache_surface->width;
+ glyph_private->p1.y /= cache_surface->height;
+ glyph_private->p2.x /= cache_surface->width;
+ glyph_private->p2.y /= cache_surface->height;
}
cairo_surface_destroy (&clone->base);
@@ -160,53 +163,35 @@ cairo_gl_context_get_glyph_cache (cairo_gl_context_t *ctx,
cairo_format_t format)
{
cairo_gl_glyph_cache_t *cache;
+ cairo_content_t content;
switch (format) {
case CAIRO_FORMAT_RGB16_565:
case CAIRO_FORMAT_ARGB32:
case CAIRO_FORMAT_RGB24:
cache = &ctx->glyph_cache[0];
- format = CAIRO_FORMAT_ARGB32;
+ content = CAIRO_CONTENT_COLOR_ALPHA;
break;
case CAIRO_FORMAT_A8:
case CAIRO_FORMAT_A1:
cache = &ctx->glyph_cache[1];
- format = CAIRO_FORMAT_A8;
+ content = CAIRO_CONTENT_ALPHA;
break;
case CAIRO_FORMAT_INVALID:
ASSERT_NOT_REACHED;
return NULL;
}
- if (unlikely (cache->tex == 0)) {
- GLenum internal_format;
-
- cache->width = GLYPH_CACHE_WIDTH;
- cache->height = GLYPH_CACHE_HEIGHT;
-
- switch (format) {
- case CAIRO_FORMAT_A1:
- case CAIRO_FORMAT_RGB16_565:
- case CAIRO_FORMAT_RGB24:
- ASSERT_NOT_REACHED;
- case CAIRO_FORMAT_ARGB32:
- internal_format = GL_RGBA;
- break;
- case CAIRO_FORMAT_A8:
- internal_format = GL_ALPHA;
- break;
- case CAIRO_FORMAT_INVALID:
- ASSERT_NOT_REACHED;
- return NULL;
- }
-
- glGenTextures (1, &cache->tex);
- glBindTexture (ctx->tex_target, cache->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,
- GLYPH_CACHE_WIDTH, GLYPH_CACHE_HEIGHT, 0,
- internal_format, GL_FLOAT, NULL);
+ if (unlikely (cache->pattern.surface == NULL)) {
+ cairo_surface_t *surface;
+ surface = cairo_gl_surface_create (&ctx->base,
+ content,
+ GLYPH_CACHE_WIDTH,
+ GLYPH_CACHE_HEIGHT);
+ _cairo_surface_release_device_reference (surface);
+ _cairo_pattern_init_for_surface (&cache->pattern, surface);
+ cairo_surface_destroy (surface);
+ cache->pattern.base.has_component_alpha = (content == CAIRO_CONTENT_COLOR_ALPHA);
}
return cache;
@@ -350,7 +335,7 @@ _render_glyphs (cairo_gl_surface_t *dst,
_cairo_gl_composite_set_mask_texture (ctx,
&setup,
- cache->tex,
+ ((cairo_gl_surface_t *) cache->pattern.surface)->tex,
last_format == CAIRO_FORMAT_ARGB32);
if (last_format == CAIRO_FORMAT_ARGB32)
@@ -627,8 +612,6 @@ EMPTY:
void
_cairo_gl_glyph_cache_init (cairo_gl_glyph_cache_t *cache)
{
- cache->tex = 0;
-
_cairo_rtree_init (&cache->rtree,
GLYPH_CACHE_WIDTH,
GLYPH_CACHE_HEIGHT,
@@ -642,9 +625,9 @@ _cairo_gl_glyph_cache_fini (cairo_gl_context_t *ctx,
{
_cairo_rtree_fini (&cache->rtree);
- if (cache->tex) {
- /* XXX Is this safe? */
- glDeleteTextures (1, &cache->tex);
+ if (cache->pattern.surface) {
+ _cairo_pattern_fini (&cache->pattern.base);
+ cache->pattern.surface = NULL;
}
}
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 724814a..d7298c9 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -85,8 +85,7 @@ typedef struct _cairo_gl_surface {
typedef struct cairo_gl_glyph_cache {
cairo_rtree_t rtree;
- GLuint tex;
- unsigned int width, height;
+ cairo_surface_pattern_t pattern;
} cairo_gl_glyph_cache_t;
typedef enum cairo_gl_operand_type {
commit 050117996339cfe35add1f2cd44d0e5578d4a981
Author: Benjamin Otte <otte at redhat.com>
Date: Tue May 18 12:02:54 2010 +0200
surface: Add _cairo_surface_release_device_reference() API
See the API documentation for that function about its intended purpose.
diff --git a/src/cairo-surface-private.h b/src/cairo-surface-private.h
index bc03119..19a93c2 100644
--- a/src/cairo-surface-private.h
+++ b/src/cairo-surface-private.h
@@ -65,6 +65,7 @@ struct _cairo_surface {
unsigned finished : 1;
unsigned is_clear : 1;
unsigned has_font_options : 1;
+ unsigned owns_device : 1;
cairo_user_data_array_t user_data;
cairo_user_data_array_t mime_data;
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index cf7e054..8b67e66 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -58,6 +58,7 @@ const cairo_surface_t name = { \
FALSE, /* finished */ \
TRUE, /* is_clear */ \
FALSE, /* has_font_options */ \
+ FALSE, /* owns_device */ \
{ 0, 0, 0, NULL, }, /* user_data */ \
{ 0, 0, 0, NULL, }, /* mime_data */ \
{ 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* device_transform */ \
@@ -356,6 +357,7 @@ _cairo_surface_init (cairo_surface_t *surface,
surface->unique_id = _cairo_surface_allocate_unique_id ();
surface->finished = FALSE;
surface->is_clear = FALSE;
+ surface->owns_device = (device != NULL);
_cairo_user_data_array_init (&surface->user_data);
_cairo_user_data_array_init (&surface->mime_data);
@@ -595,7 +597,8 @@ cairo_surface_destroy (cairo_surface_t *surface)
_cairo_user_data_array_fini (&surface->user_data);
_cairo_user_data_array_fini (&surface->mime_data);
- cairo_device_destroy (surface->device);
+ if (surface->owns_device)
+ cairo_device_destroy (surface->device);
free (surface);
}
@@ -673,6 +676,27 @@ cairo_surface_finish (cairo_surface_t *surface)
slim_hidden_def (cairo_surface_finish);
/**
+ * _cairo_surface_release_device_reference:
+ * @surface: a #cairo_surface_t
+ *
+ * This function makes @surface release the reference to its device. The
+ * function is intended to be used for avoiding cycling references for
+ * surfaces that are owned by their device, for example cache surfaces.
+ * Note that the @surface will still assume that the device is available.
+ * So it is the caller's responsibility to ensure the device stays around
+ * until the @surface is destroyed. Just calling cairo_surface_finish() is
+ * not enough.
+ **/
+void
+_cairo_surface_release_device_reference (cairo_surface_t *surface)
+{
+ assert (surface->owns_device);
+
+ cairo_device_destroy (surface->device);
+ surface->owns_device = FALSE;
+}
+
+/**
* cairo_surface_get_user_data:
* @surface: a #cairo_surface_t
* @key: the address of the #cairo_user_data_key_t the user data was
diff --git a/src/cairoint.h b/src/cairoint.h
index b52db6d..1f8643d 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2119,6 +2119,9 @@ _cairo_surface_set_device_scale (cairo_surface_t *surface,
cairo_private cairo_bool_t
_cairo_surface_has_device_transform (cairo_surface_t *surface) cairo_pure;
+cairo_private void
+_cairo_surface_release_device_reference (cairo_surface_t *surface);
+
/* cairo-image-surface.c */
/* XXX: In cairo 1.2.0 we added a new %CAIRO_FORMAT_RGB16_565 but
commit c489f67d1d1d6079f9b58b726ed42beea1dfc44e
Author: Benjamin Otte <otte at redhat.com>
Date: Mon May 17 20:45:42 2010 +0200
gl: Make a bunch of functions static
They are no longer used outside of cairo_gl_composite_t.
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index c21ee0e..40efbf1 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -610,7 +610,7 @@ _cairo_gl_set_tex_combine_constant_color (cairo_gl_context_t *ctx,
}
}
-void
+static void
_cairo_gl_set_src_operand (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup)
{
@@ -700,7 +700,7 @@ _cairo_gl_set_src_operand (cairo_gl_context_t *ctx,
* for creating the "source alpha" value (src.aaaa * mask.argb) required by
* component alpha rendering.
*/
-void
+static void
_cairo_gl_set_src_alpha_operand (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup)
{
@@ -794,7 +794,7 @@ _cairo_gl_set_radial_gradient_mask_operand (cairo_gl_context_t *ctx,
/* This is like _cairo_gl_set_src_alpha_operand, for component alpha setup
* of the mask part of IN to produce a "source alpha" value.
*/
-void
+static void
_cairo_gl_set_component_alpha_mask_operand (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup)
{
@@ -876,7 +876,7 @@ _cairo_gl_set_component_alpha_mask_operand (cairo_gl_context_t *ctx,
}
}
-void
+static void
_cairo_gl_set_mask_operand (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup)
{
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index d8bfcc4..724814a 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -348,22 +348,6 @@ cairo_private void
_cairo_gl_composite_end (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup);
-cairo_private void
-_cairo_gl_set_src_operand (cairo_gl_context_t *ctx,
- cairo_gl_composite_t *setup);
-
-cairo_private void
-_cairo_gl_set_src_alpha_operand (cairo_gl_context_t *ctx,
- cairo_gl_composite_t *setup);
-
-cairo_private void
-_cairo_gl_set_component_alpha_mask_operand (cairo_gl_context_t *ctx,
- cairo_gl_composite_t *setup);
-
-cairo_private void
-_cairo_gl_set_mask_operand (cairo_gl_context_t *ctx,
- cairo_gl_composite_t *setup);
-
cairo_private cairo_bool_t
_cairo_gl_get_image_format_and_type (pixman_format_code_t pixman_format,
GLenum *internal_format, GLenum *format,
commit c8008e118a54d62690d6555c9ffabf734c39e69f
Author: Benjamin Otte <otte at redhat.com>
Date: Mon May 17 19:16:20 2010 +0200
gl: Don't name the union in cairo_gl_operand_t
Gets rid of ultra-long variable names.
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index c4c30de..c21ee0e 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -263,7 +263,7 @@ _cairo_gl_pattern_texture_setup (cairo_gl_context_t *ctx,
cairo_matrix_t m;
cairo_gl_surface_t *surface;
cairo_surface_attributes_t *attributes;
- attributes = &operand->operand.texture.attributes;
+ attributes = &operand->texture.attributes;
status = _cairo_pattern_acquire_surface (src, &dst->base,
src_x, src_y,
@@ -288,8 +288,8 @@ _cairo_gl_pattern_texture_setup (cairo_gl_context_t *ctx,
assert (surface->base.backend == &_cairo_gl_surface_backend);
operand->type = CAIRO_GL_OPERAND_TEXTURE;
- operand->operand.texture.surface = surface;
- operand->operand.texture.tex = surface->tex;
+ operand->texture.surface = surface;
+ operand->texture.tex = surface->tex;
/* Translate the matrix from
* (unnormalized src -> unnormalized src) to
* (unnormalized dst -> unnormalized src)
@@ -327,10 +327,10 @@ _cairo_gl_solid_operand_init (cairo_gl_operand_t *operand,
const cairo_color_t *color)
{
operand->type = CAIRO_GL_OPERAND_CONSTANT;
- operand->operand.constant.color[0] = color->red * color->alpha;
- operand->operand.constant.color[1] = color->green * color->alpha;
- operand->operand.constant.color[2] = color->blue * color->alpha;
- operand->operand.constant.color[3] = color->alpha;
+ operand->constant.color[0] = color->red * color->alpha;
+ operand->constant.color[1] = color->green * color->alpha;
+ operand->constant.color[2] = color->blue * color->alpha;
+ operand->constant.color[3] = color->alpha;
return CAIRO_STATUS_SUCCESS;
}
@@ -360,20 +360,20 @@ _cairo_gl_gradient_operand_init (cairo_gl_context_t *ctx,
_cairo_gl_create_gradient_texture (ctx,
dst,
gradient,
- &operand->operand.linear.tex);
+ &operand->linear.tex);
/* Translation matrix from the destination fragment coordinates
* (pixels from lower left = 0,0) to the coordinates in the
*/
- cairo_matrix_init_translate (&operand->operand.linear.m, -x0, -y0);
- cairo_matrix_multiply (&operand->operand.linear.m,
+ cairo_matrix_init_translate (&operand->linear.m, -x0, -y0);
+ cairo_matrix_multiply (&operand->linear.m,
&operand->pattern->matrix,
- &operand->operand.linear.m);
- cairo_matrix_translate (&operand->operand.linear.m, 0, dst->height);
- cairo_matrix_scale (&operand->operand.linear.m, 1.0, -1.0);
+ &operand->linear.m);
+ cairo_matrix_translate (&operand->linear.m, 0, dst->height);
+ cairo_matrix_scale (&operand->linear.m, 1.0, -1.0);
- operand->operand.linear.segment_x = x1 - x0;
- operand->operand.linear.segment_y = y1 - y0;
+ operand->linear.segment_x = x1 - x0;
+ operand->linear.segment_y = y1 - y0;
operand->type = CAIRO_GL_OPERAND_LINEAR_GRADIENT;
return CAIRO_STATUS_SUCCESS;
@@ -394,22 +394,22 @@ _cairo_gl_gradient_operand_init (cairo_gl_context_t *ctx,
_cairo_gl_create_gradient_texture (ctx,
dst,
gradient,
- &operand->operand.radial.tex);
+ &operand->radial.tex);
/* Translation matrix from the destination fragment coordinates
* (pixels from lower left = 0,0) to the coordinates in the
*/
- cairo_matrix_init_translate (&operand->operand.radial.m, -x0, -y0);
- cairo_matrix_multiply (&operand->operand.radial.m,
+ cairo_matrix_init_translate (&operand->radial.m, -x0, -y0);
+ cairo_matrix_multiply (&operand->radial.m,
&operand->pattern->matrix,
- &operand->operand.radial.m);
- cairo_matrix_translate (&operand->operand.radial.m, 0, dst->height);
- cairo_matrix_scale (&operand->operand.radial.m, 1.0, -1.0);
+ &operand->radial.m);
+ cairo_matrix_translate (&operand->radial.m, 0, dst->height);
+ cairo_matrix_scale (&operand->radial.m, 1.0, -1.0);
- operand->operand.radial.circle_1_x = x1 - x0;
- operand->operand.radial.circle_1_y = y1 - y0;
- operand->operand.radial.radius_0 = r0;
- operand->operand.radial.radius_1 = r1;
+ operand->radial.circle_1_x = x1 - x0;
+ operand->radial.circle_1_y = y1 - y0;
+ operand->radial.radius_0 = r0;
+ operand->radial.radius_1 = r1;
operand->type = CAIRO_GL_OPERAND_RADIAL_GRADIENT;
return CAIRO_STATUS_SUCCESS;
@@ -425,18 +425,18 @@ _cairo_gl_operand_destroy (cairo_gl_operand_t *operand)
case CAIRO_GL_OPERAND_CONSTANT:
break;
case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
- glDeleteTextures (1, &operand->operand.linear.tex);
+ glDeleteTextures (1, &operand->linear.tex);
break;
case CAIRO_GL_OPERAND_RADIAL_GRADIENT:
- glDeleteTextures (1, &operand->operand.radial.tex);
+ glDeleteTextures (1, &operand->radial.tex);
break;
case CAIRO_GL_OPERAND_TEXTURE:
- if (operand->operand.texture.surface != NULL) {
- cairo_gl_surface_t *surface = operand->operand.texture.surface;
+ if (operand->texture.surface != NULL) {
+ cairo_gl_surface_t *surface = operand->texture.surface;
_cairo_pattern_release_surface (operand->pattern,
&surface->base,
- &operand->operand.texture.attributes);
+ &operand->texture.attributes);
}
break;
default:
@@ -541,9 +541,9 @@ _cairo_gl_composite_set_mask_texture (cairo_gl_context_t *ctx,
setup->has_component_alpha = has_component_alpha;
setup->mask.type = CAIRO_GL_OPERAND_TEXTURE;
- setup->mask.operand.texture.tex = tex;
- setup->mask.operand.texture.surface = NULL;
- cairo_matrix_init_identity (&setup->mask.operand.texture.attributes.matrix);
+ setup->mask.texture.tex = tex;
+ setup->mask.texture.surface = NULL;
+ cairo_matrix_init_identity (&setup->mask.texture.attributes.matrix);
}
void
@@ -617,15 +617,15 @@ _cairo_gl_set_src_operand (cairo_gl_context_t *ctx,
cairo_surface_attributes_t *src_attributes;
GLfloat constant_color[4] = {0.0, 0.0, 0.0, 0.0};
- src_attributes = &setup->src.operand.texture.attributes;
+ src_attributes = &setup->src.texture.attributes;
switch (setup->src.type) {
case CAIRO_GL_OPERAND_CONSTANT:
_cairo_gl_set_tex_combine_constant_color (ctx, setup, 0,
- setup->src.operand.constant.color);
+ setup->src.constant.color);
break;
case CAIRO_GL_OPERAND_TEXTURE:
- _cairo_gl_set_texture_surface (0, setup->src.operand.texture.tex,
+ _cairo_gl_set_texture_surface (0, setup->src.texture.tex,
src_attributes, ctx->tex_target);
if (!setup->shader) {
/* Set up the constant color we use to set color to 0 if needed. */
@@ -639,7 +639,7 @@ _cairo_gl_set_src_operand (cairo_gl_context_t *ctx,
* alpha-only. We may have a teximage with color bits if
* the implementation doesn't support GL_ALPHA FBOs.
*/
- if (setup->src.operand.texture.surface->base.content !=
+ if (setup->src.texture.surface->base.content !=
CAIRO_CONTENT_ALPHA)
glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE0);
else
@@ -652,40 +652,40 @@ _cairo_gl_set_src_operand (cairo_gl_context_t *ctx,
case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
glActiveTexture (GL_TEXTURE0);
- glBindTexture (GL_TEXTURE_1D, setup->src.operand.linear.tex);
+ glBindTexture (GL_TEXTURE_1D, setup->src.linear.tex);
glEnable (GL_TEXTURE_1D);
_cairo_gl_shader_bind_matrix (ctx, setup->shader,
"source_matrix",
- &setup->src.operand.linear.m);
+ &setup->src.linear.m);
_cairo_gl_shader_bind_vec2 (ctx, setup->shader,
"source_segment",
- setup->src.operand.linear.segment_x,
- setup->src.operand.linear.segment_y);
+ setup->src.linear.segment_x,
+ setup->src.linear.segment_y);
break;
case CAIRO_GL_OPERAND_RADIAL_GRADIENT:
glActiveTexture (GL_TEXTURE0);
- glBindTexture (GL_TEXTURE_1D, setup->src.operand.linear.tex);
+ glBindTexture (GL_TEXTURE_1D, setup->src.linear.tex);
glEnable (GL_TEXTURE_1D);
_cairo_gl_shader_bind_matrix (ctx, setup->shader,
"source_matrix",
- &setup->src.operand.radial.m);
+ &setup->src.radial.m);
_cairo_gl_shader_bind_vec2 (ctx, setup->shader,
"source_circle_1",
- setup->src.operand.radial.circle_1_x,
- setup->src.operand.radial.circle_1_y);
+ setup->src.radial.circle_1_x,
+ setup->src.radial.circle_1_y);
_cairo_gl_shader_bind_float (ctx, setup->shader,
"source_radius_0",
- setup->src.operand.radial.radius_0);
+ setup->src.radial.radius_0);
_cairo_gl_shader_bind_float (ctx, setup->shader,
"source_radius_1",
- setup->src.operand.radial.radius_1);
+ setup->src.radial.radius_1);
break;
default:
case CAIRO_GL_OPERAND_COUNT:
@@ -707,19 +707,19 @@ _cairo_gl_set_src_alpha_operand (cairo_gl_context_t *ctx,
GLfloat constant_color[4] = {0.0, 0.0, 0.0, 0.0};
cairo_surface_attributes_t *src_attributes;
- src_attributes = &setup->src.operand.texture.attributes;
+ src_attributes = &setup->src.texture.attributes;
switch (setup->src.type) {
case CAIRO_GL_OPERAND_CONSTANT:
- constant_color[0] = setup->src.operand.constant.color[3];
- constant_color[1] = setup->src.operand.constant.color[3];
- constant_color[2] = setup->src.operand.constant.color[3];
- constant_color[3] = setup->src.operand.constant.color[3];
+ constant_color[0] = setup->src.constant.color[3];
+ constant_color[1] = setup->src.constant.color[3];
+ constant_color[2] = setup->src.constant.color[3];
+ constant_color[3] = setup->src.constant.color[3];
_cairo_gl_set_tex_combine_constant_color (ctx, setup, 0,
constant_color);
break;
case CAIRO_GL_OPERAND_TEXTURE:
- _cairo_gl_set_texture_surface (0, setup->src.operand.texture.tex,
+ _cairo_gl_set_texture_surface (0, setup->src.texture.tex,
src_attributes, ctx->tex_target);
if (!setup->shader) {
/* Set up the combiner to just set color to the sampled texture. */
@@ -751,16 +751,16 @@ _cairo_gl_set_linear_gradient_mask_operand (cairo_gl_context_t *ctx,
assert(setup->shader);
glActiveTexture (GL_TEXTURE1);
- glBindTexture (GL_TEXTURE_1D, setup->mask.operand.linear.tex);
+ glBindTexture (GL_TEXTURE_1D, setup->mask.linear.tex);
glEnable (GL_TEXTURE_1D);
_cairo_gl_shader_bind_matrix (ctx, setup->shader,
- "mask_matrix", &setup->mask.operand.linear.m);
+ "mask_matrix", &setup->mask.linear.m);
_cairo_gl_shader_bind_vec2 (ctx, setup->shader,
"mask_segment",
- setup->mask.operand.linear.segment_x,
- setup->mask.operand.linear.segment_y);
+ setup->mask.linear.segment_x,
+ setup->mask.linear.segment_y);
}
static void
@@ -770,25 +770,25 @@ _cairo_gl_set_radial_gradient_mask_operand (cairo_gl_context_t *ctx,
assert(setup->shader);
glActiveTexture (GL_TEXTURE1);
- glBindTexture (GL_TEXTURE_1D, setup->mask.operand.radial.tex);
+ glBindTexture (GL_TEXTURE_1D, setup->mask.radial.tex);
glEnable (GL_TEXTURE_1D);
_cairo_gl_shader_bind_matrix (ctx, setup->shader,
"mask_matrix",
- &setup->mask.operand.radial.m);
+ &setup->mask.radial.m);
_cairo_gl_shader_bind_vec2 (ctx, setup->shader,
"mask_circle_1",
- setup->mask.operand.radial.circle_1_x,
- setup->mask.operand.radial.circle_1_y);
+ setup->mask.radial.circle_1_x,
+ setup->mask.radial.circle_1_y);
_cairo_gl_shader_bind_float (ctx, setup->shader,
"mask_radius_0",
- setup->mask.operand.radial.radius_0);
+ setup->mask.radial.radius_0);
_cairo_gl_shader_bind_float (ctx, setup->shader,
"mask_radius_1",
- setup->mask.operand.radial.radius_1);
+ setup->mask.radial.radius_1);
}
/* This is like _cairo_gl_set_src_alpha_operand, for component alpha setup
@@ -801,7 +801,7 @@ _cairo_gl_set_component_alpha_mask_operand (cairo_gl_context_t *ctx,
cairo_surface_attributes_t *mask_attributes;
GLfloat constant_color[4] = {0.0, 0.0, 0.0, 0.0};
- mask_attributes = &setup->mask.operand.texture.attributes;
+ mask_attributes = &setup->mask.texture.attributes;
if (!setup->shader) {
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
@@ -820,17 +820,17 @@ _cairo_gl_set_component_alpha_mask_operand (cairo_gl_context_t *ctx,
if (setup->shader) {
_cairo_gl_shader_bind_vec4 (ctx, setup->shader,
"mask_constant",
- setup->src.operand.constant.color[0],
- setup->src.operand.constant.color[1],
- setup->src.operand.constant.color[2],
- setup->src.operand.constant.color[3]);
+ setup->src.constant.color[0],
+ setup->src.constant.color[1],
+ setup->src.constant.color[2],
+ setup->src.constant.color[3]);
} else {
glBindTexture (ctx->tex_target, ctx->dummy_tex);
glActiveTexture (GL_TEXTURE1);
glEnable (ctx->tex_target);
glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,
- setup->mask.operand.constant.color);
+ setup->mask.constant.color);
glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_CONSTANT);
glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_CONSTANT);
@@ -839,7 +839,7 @@ _cairo_gl_set_component_alpha_mask_operand (cairo_gl_context_t *ctx,
}
break;
case CAIRO_GL_OPERAND_TEXTURE:
- _cairo_gl_set_texture_surface (1, setup->mask.operand.texture.tex,
+ _cairo_gl_set_texture_surface (1, setup->mask.texture.tex,
mask_attributes, ctx->tex_target);
if (!setup->shader) {
/* Set up the constant color we use to set color to 0 if needed. */
@@ -849,8 +849,8 @@ _cairo_gl_set_component_alpha_mask_operand (cairo_gl_context_t *ctx,
* alpha-only. We may have a teximage with color bits if
* the implementation doesn't support GL_ALPHA FBOs.
*/
- if (setup->mask.operand.texture.surface == NULL ||
- setup->mask.operand.texture.surface->base.content != CAIRO_CONTENT_ALPHA)
+ if (setup->mask.texture.surface == NULL ||
+ setup->mask.texture.surface->base.content != CAIRO_CONTENT_ALPHA)
glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE1);
else
glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_CONSTANT);
@@ -883,12 +883,12 @@ _cairo_gl_set_mask_operand (cairo_gl_context_t *ctx,
switch (setup->mask.type) {
case CAIRO_GL_OPERAND_CONSTANT:
_cairo_gl_set_tex_combine_constant_color (ctx, setup, 1,
- setup->mask.operand.constant.color);
+ setup->mask.constant.color);
break;
case CAIRO_GL_OPERAND_TEXTURE:
- _cairo_gl_set_texture_surface (1, setup->mask.operand.texture.tex,
- &setup->mask.operand.texture.attributes,
+ _cairo_gl_set_texture_surface (1, setup->mask.texture.tex,
+ &setup->mask.texture.attributes,
ctx->tex_target);
if (! setup->shader) {
@@ -1230,7 +1230,7 @@ _cairo_gl_operand_emit (cairo_gl_operand_t *operand,
break;
case CAIRO_GL_OPERAND_TEXTURE:
{
- cairo_surface_attributes_t *src_attributes = &operand->operand.texture.attributes;
+ cairo_surface_attributes_t *src_attributes = &operand->texture.attributes;
double s = x;
double t = y;
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 2a1007e..d8bfcc4 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -180,7 +180,7 @@ typedef struct cairo_gl_operand {
float radius_0;
float radius_1;
} radial;
- } operand;
+ };
const cairo_pattern_t *pattern;
} cairo_gl_operand_t;
More information about the cairo-commit
mailing list