summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cairo-gl-composite.c70
-rw-r--r--src/cairo-gl-msaa-compositor.c21
-rw-r--r--src/cairo-gl-operand.c67
-rw-r--r--src/cairo-gl-private.h24
-rw-r--r--src/cairo-gl-shaders.c31
-rw-r--r--src/cairo-gl-source.c3
-rw-r--r--src/cairo-gl-spans-compositor.c6
-rw-r--r--src/cairo-gl-traps-compositor.c3
8 files changed, 162 insertions, 63 deletions
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index d8166b83..c250e720 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -56,11 +56,12 @@ cairo_int_status_t
_cairo_gl_composite_set_source (cairo_gl_composite_t *setup,
const cairo_pattern_t *pattern,
const cairo_rectangle_int_t *sample,
- const cairo_rectangle_int_t *extents)
+ const cairo_rectangle_int_t *extents,
+ cairo_bool_t use_texgen)
{
_cairo_gl_operand_destroy (&setup->src);
return _cairo_gl_operand_init (&setup->src, pattern, setup->dst,
- sample, extents);
+ sample, extents, use_texgen);
}
void
@@ -83,14 +84,15 @@ cairo_int_status_t
_cairo_gl_composite_set_mask (cairo_gl_composite_t *setup,
const cairo_pattern_t *pattern,
const cairo_rectangle_int_t *sample,
- const cairo_rectangle_int_t *extents)
+ const cairo_rectangle_int_t *extents,
+ cairo_bool_t use_texgen)
{
_cairo_gl_operand_destroy (&setup->mask);
if (pattern == NULL)
return CAIRO_STATUS_SUCCESS;
return _cairo_gl_operand_init (&setup->mask, pattern, setup->dst,
- sample, extents);
+ sample, extents, use_texgen);
}
void
@@ -248,10 +250,12 @@ _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
_cairo_gl_texture_set_filter (ctx, ctx->tex_target,
operand->texture.attributes.filter);
- dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
- GL_FLOAT, GL_FALSE, vertex_size,
- ctx->vb + vertex_offset);
- dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
+ if (! operand->texture.texgen) {
+ dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
+ GL_FLOAT, GL_FALSE, vertex_size,
+ ctx->vb + vertex_offset);
+ dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
+ }
break;
case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
@@ -262,10 +266,12 @@ _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
_cairo_gl_texture_set_extend (ctx, ctx->tex_target, operand->gradient.extend);
_cairo_gl_texture_set_filter (ctx, ctx->tex_target, CAIRO_FILTER_BILINEAR);
- dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
- GL_FLOAT, GL_FALSE, vertex_size,
- ctx->vb + vertex_offset);
- dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
+ if (! operand->gradient.texgen) {
+ dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
+ GL_FLOAT, GL_FALSE, vertex_size,
+ ctx->vb + vertex_offset);
+ dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
+ }
break;
}
}
@@ -698,8 +704,8 @@ _cairo_gl_set_operands_and_operator (cairo_gl_composite_t *setup,
status = CAIRO_STATUS_SUCCESS;
dst_size = 2 * sizeof (GLfloat);
- src_size = _cairo_gl_operand_get_vertex_size (setup->src.type);
- mask_size = _cairo_gl_operand_get_vertex_size (setup->mask.type);
+ src_size = _cairo_gl_operand_get_vertex_size (&setup->src);
+ mask_size = _cairo_gl_operand_get_vertex_size (&setup->mask);
vertex_size = dst_size + src_size + mask_size;
if (setup->spans)
@@ -993,8 +999,29 @@ _cairo_gl_composite_emit_solid_span (cairo_gl_context_t *ctx,
cairo_gl_emit_span_t
_cairo_gl_context_choose_emit_span (cairo_gl_context_t *ctx)
{
- if (ctx->operands[CAIRO_GL_TEX_MASK].type != CAIRO_GL_OPERAND_NONE)
- return _cairo_gl_composite_emit_span;
+ if (ctx->operands[CAIRO_GL_TEX_MASK].type != CAIRO_GL_OPERAND_NONE) {
+ switch (ctx->operands[CAIRO_GL_TEX_MASK].type) {
+ default:
+ case CAIRO_GL_OPERAND_COUNT:
+ ASSERT_NOT_REACHED;
+ case CAIRO_GL_OPERAND_NONE:
+ case CAIRO_GL_OPERAND_CONSTANT:
+ break;
+
+ case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
+ case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
+ case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
+ case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
+ if (!ctx->operands[CAIRO_GL_TEX_MASK].gradient.texgen)
+ return _cairo_gl_composite_emit_span;
+ break;
+
+ case CAIRO_GL_OPERAND_TEXTURE:
+ if (!ctx->operands[CAIRO_GL_TEX_MASK].texture.texgen)
+ return _cairo_gl_composite_emit_span;
+ break;
+ }
+ }
switch (ctx->operands[CAIRO_GL_TEX_SOURCE].type) {
default:
@@ -1002,15 +1029,22 @@ _cairo_gl_context_choose_emit_span (cairo_gl_context_t *ctx)
ASSERT_NOT_REACHED;
case CAIRO_GL_OPERAND_NONE:
case CAIRO_GL_OPERAND_CONSTANT:
- return _cairo_gl_composite_emit_solid_span;
+ break;
case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
+ if (!ctx->operands[CAIRO_GL_TEX_SOURCE].gradient.texgen)
+ return _cairo_gl_composite_emit_span;
+ break;
+
case CAIRO_GL_OPERAND_TEXTURE:
- return _cairo_gl_composite_emit_span;
+ if (!ctx->operands[CAIRO_GL_TEX_SOURCE].texture.texgen)
+ return _cairo_gl_composite_emit_span;
}
+
+ return _cairo_gl_composite_emit_solid_span;
}
static inline void
diff --git a/src/cairo-gl-msaa-compositor.c b/src/cairo-gl-msaa-compositor.c
index 54772efb..a0fd9a0e 100644
--- a/src/cairo-gl-msaa-compositor.c
+++ b/src/cairo-gl-msaa-compositor.c
@@ -343,7 +343,8 @@ _cairo_gl_msaa_compositor_mask_source_operator (const cairo_compositor_t *compos
status = _cairo_gl_composite_set_source (&setup,
&composite->mask_pattern.base,
&composite->mask_sample_area,
- &composite->bounded);
+ &composite->bounded,
+ FALSE);
if (unlikely (status))
goto finish;
_cairo_gl_composite_set_multisample (&setup);
@@ -364,13 +365,15 @@ _cairo_gl_msaa_compositor_mask_source_operator (const cairo_compositor_t *compos
status = _cairo_gl_composite_set_source (&setup,
&composite->source_pattern.base,
&composite->source_sample_area,
- &composite->bounded);
+ &composite->bounded,
+ FALSE);
if (unlikely (status))
goto finish;
status = _cairo_gl_composite_set_mask (&setup,
&composite->mask_pattern.base,
&composite->source_sample_area,
- &composite->bounded);
+ &composite->bounded,
+ FALSE);
if (unlikely (status))
goto finish;
status = _cairo_gl_set_operands_and_operator (&setup, ctx);
@@ -462,7 +465,8 @@ _cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor,
status = _cairo_gl_composite_set_source (&setup,
&composite->source_pattern.base,
&composite->source_sample_area,
- &composite->bounded);
+ &composite->bounded,
+ FALSE);
if (unlikely (status))
goto finish;
@@ -470,7 +474,8 @@ _cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor,
status = _cairo_gl_composite_set_mask (&setup,
&composite->mask_pattern.base,
&composite->mask_sample_area,
- &composite->bounded);
+ &composite->bounded,
+ FALSE);
}
if (unlikely (status))
goto finish;
@@ -674,7 +679,8 @@ _cairo_gl_msaa_compositor_stroke (const cairo_compositor_t *compositor,
status = _cairo_gl_composite_set_source (&info.setup,
&composite->source_pattern.base,
&composite->source_sample_area,
- &composite->bounded);
+ &composite->bounded,
+ FALSE);
if (unlikely (status))
goto finish;
@@ -793,7 +799,8 @@ _cairo_gl_msaa_compositor_fill (const cairo_compositor_t *compositor,
status = _cairo_gl_composite_set_source (&setup,
&composite->source_pattern.base,
&composite->source_sample_area,
- &composite->bounded);
+ &composite->bounded,
+ FALSE);
if (unlikely (status))
goto cleanup_setup;
diff --git a/src/cairo-gl-operand.c b/src/cairo-gl-operand.c
index 19512668..f99400ca 100644
--- a/src/cairo-gl-operand.c
+++ b/src/cairo-gl-operand.c
@@ -107,7 +107,8 @@ _cairo_gl_subsurface_clone_operand_init (cairo_gl_operand_t *operand,
const cairo_pattern_t *_src,
cairo_gl_surface_t *dst,
const cairo_rectangle_int_t *sample,
- const cairo_rectangle_int_t *extents)
+ const cairo_rectangle_int_t *extents,
+ cairo_bool_t use_texgen)
{
const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src;
cairo_surface_pattern_t local_pattern;
@@ -185,6 +186,8 @@ _cairo_gl_subsurface_clone_operand_init (cairo_gl_operand_t *operand,
attributes->extend = src->base.extend;
attributes->filter = src->base.filter;
attributes->has_component_alpha = src->base.has_component_alpha;
+
+ operand->texture.texgen = use_texgen;
return CAIRO_STATUS_SUCCESS;
}
@@ -193,7 +196,8 @@ _cairo_gl_subsurface_operand_init (cairo_gl_operand_t *operand,
const cairo_pattern_t *_src,
cairo_gl_surface_t *dst,
const cairo_rectangle_int_t *sample,
- const cairo_rectangle_int_t *extents)
+ const cairo_rectangle_int_t *extents,
+ cairo_bool_t use_texgen)
{
const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src;
cairo_surface_subsurface_t *sub;
@@ -208,7 +212,8 @@ _cairo_gl_subsurface_operand_init (cairo_gl_operand_t *operand,
sample->y + sample->height > sub->extents.height)
{
return _cairo_gl_subsurface_clone_operand_init (operand, _src,
- dst, sample, extents);
+ dst, sample, extents,
+ use_texgen);
}
surface = (cairo_gl_surface_t *) sub->target;
@@ -239,6 +244,8 @@ _cairo_gl_subsurface_operand_init (cairo_gl_operand_t *operand,
attributes->extend = src->base.extend;
attributes->filter = src->base.filter;
attributes->has_component_alpha = src->base.has_component_alpha;
+
+ operand->texture.texgen = use_texgen;
return CAIRO_STATUS_SUCCESS;
}
@@ -247,7 +254,8 @@ _cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
const cairo_pattern_t *_src,
cairo_gl_surface_t *dst,
const cairo_rectangle_int_t *sample,
- const cairo_rectangle_int_t *extents)
+ const cairo_rectangle_int_t *extents,
+ cairo_bool_t use_texgen)
{
const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src;
cairo_gl_surface_t *surface;
@@ -261,7 +269,8 @@ _cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
if (surface->base.backend->type != CAIRO_SURFACE_TYPE_GL) {
if (_cairo_surface_is_subsurface (&surface->base))
return _cairo_gl_subsurface_operand_init (operand, _src, dst,
- sample, extents);
+ sample, extents,
+ use_texgen);
return CAIRO_INT_STATUS_UNSUPPORTED;
}
@@ -286,6 +295,8 @@ _cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
attributes->extend = src->base.extend;
attributes->filter = src->base.filter;
attributes->has_component_alpha = src->base.has_component_alpha;
+
+ operand->texture.texgen = use_texgen;
return CAIRO_STATUS_SUCCESS;
}
@@ -392,7 +403,8 @@ _cairo_gl_operand_translate (cairo_gl_operand_t *operand,
static cairo_status_t
_cairo_gl_gradient_operand_init (cairo_gl_operand_t *operand,
const cairo_pattern_t *pattern,
- cairo_gl_surface_t *dst)
+ cairo_gl_surface_t *dst,
+ cairo_bool_t use_texgen)
{
const cairo_gradient_pattern_t *gradient = (const cairo_gradient_pattern_t *)pattern;
cairo_status_t status;
@@ -475,6 +487,7 @@ _cairo_gl_gradient_operand_init (cairo_gl_operand_t *operand,
}
operand->gradient.extend = pattern->extend;
+ operand->gradient.texgen = use_texgen;
return CAIRO_STATUS_SUCCESS;
}
@@ -534,7 +547,8 @@ _cairo_gl_operand_init (cairo_gl_operand_t *operand,
const cairo_pattern_t *pattern,
cairo_gl_surface_t *dst,
const cairo_rectangle_int_t *sample,
- const cairo_rectangle_int_t *extents)
+ const cairo_rectangle_int_t *extents,
+ cairo_bool_t use_texgen)
{
cairo_int_status_t status;
@@ -546,7 +560,7 @@ _cairo_gl_operand_init (cairo_gl_operand_t *operand,
return CAIRO_STATUS_SUCCESS;
case CAIRO_PATTERN_TYPE_SURFACE:
status = _cairo_gl_surface_operand_init (operand, pattern, dst,
- sample, extents);
+ sample, extents, use_texgen);
if (status == CAIRO_INT_STATUS_UNSUPPORTED)
break;
@@ -554,7 +568,8 @@ _cairo_gl_operand_init (cairo_gl_operand_t *operand,
case CAIRO_PATTERN_TYPE_LINEAR:
case CAIRO_PATTERN_TYPE_RADIAL:
- status = _cairo_gl_gradient_operand_init (operand, pattern, dst);
+ status = _cairo_gl_gradient_operand_init (operand, pattern, dst,
+ use_texgen);
if (status == CAIRO_INT_STATUS_UNSUPPORTED)
break;
@@ -634,6 +649,7 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
char uniform_name[50];
char *custom_part;
static const char *names[] = { "source", "mask" };
+ const cairo_matrix_t *texgen = NULL;
strcpy (uniform_name, names[tex_unit]);
custom_part = uniform_name + strlen (names[tex_unit]);
@@ -643,7 +659,8 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
case CAIRO_GL_OPERAND_COUNT:
ASSERT_NOT_REACHED;
case CAIRO_GL_OPERAND_NONE:
- break;
+ return;
+
case CAIRO_GL_OPERAND_CONSTANT:
strcpy (custom_part, "_constant");
_cairo_gl_shader_bind_vec4 (ctx,
@@ -652,7 +669,8 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
operand->constant.color[1],
operand->constant.color[2],
operand->constant.color[3]);
- break;
+ return;
+
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
strcpy (custom_part, "_a");
@@ -695,7 +713,21 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
strcpy (custom_part, "_texdims");
_cairo_gl_shader_bind_vec2 (ctx, uniform_name, width, height);
}
- break;
+ break;
+ }
+
+ if (operand->type == CAIRO_GL_OPERAND_TEXTURE) {
+ if (operand->texture.texgen)
+ texgen = &operand->texture.attributes.matrix;
+ } else {
+ if (operand->gradient.texgen)
+ texgen = &operand->gradient.m;
+ }
+ if (texgen) {
+ char name[20];
+
+ sprintf (name, "%s_texgen", names[tex_unit]);
+ _cairo_gl_shader_bind_matrix(ctx, name, texgen);
}
}
@@ -738,9 +770,9 @@ _cairo_gl_operand_needs_setup (cairo_gl_operand_t *dest,
}
unsigned int
-_cairo_gl_operand_get_vertex_size (cairo_gl_operand_type_t type)
+_cairo_gl_operand_get_vertex_size (const cairo_gl_operand_t *operand)
{
- switch (type) {
+ switch (operand->type) {
default:
case CAIRO_GL_OPERAND_COUNT:
ASSERT_NOT_REACHED;
@@ -748,11 +780,12 @@ _cairo_gl_operand_get_vertex_size (cairo_gl_operand_type_t type)
case CAIRO_GL_OPERAND_CONSTANT:
return 0;
case CAIRO_GL_OPERAND_TEXTURE:
+ return operand->texture.texgen ? 0 : 2 * sizeof (GLfloat);
case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
- return 2 * sizeof (GLfloat);
+ return operand->gradient.texgen ? 0 : 2 * sizeof (GLfloat);
}
}
@@ -773,7 +806,7 @@ _cairo_gl_operand_emit (cairo_gl_operand_t *operand,
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
- {
+ if (! operand->gradient.texgen) {
double s = x;
double t = y;
@@ -784,7 +817,7 @@ _cairo_gl_operand_emit (cairo_gl_operand_t *operand,
}
break;
case CAIRO_GL_OPERAND_TEXTURE:
- {
+ if (! operand->texture.texgen) {
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 a75afa7e..2b254f98 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -136,6 +136,7 @@ typedef struct cairo_gl_operand {
cairo_gl_surface_t *surface;
cairo_gl_surface_t *owns_surface;
cairo_surface_attributes_t attributes;
+ int texgen;
} texture;
struct {
GLfloat color[4];
@@ -146,6 +147,7 @@ typedef struct cairo_gl_operand {
cairo_circle_double_t circle_d;
double radius_0, a;
cairo_extend_t extend;
+ int texgen;
} gradient;
};
unsigned int vertex_offset;
@@ -212,6 +214,7 @@ typedef enum cairo_gl_shader_in {
typedef enum cairo_gl_var_type {
CAIRO_GL_VAR_NONE,
CAIRO_GL_VAR_TEXCOORDS,
+ CAIRO_GL_VAR_TEXGEN,
} cairo_gl_var_type_t;
typedef enum cairo_gl_primitive_type {
@@ -234,8 +237,8 @@ typedef void (*cairo_gl_emit_glyph_t) (cairo_gl_context_t *ctx,
GLfloat glyph_x1, GLfloat glyph_y1,
GLfloat glyph_x2, GLfloat glyph_y2);
-#define cairo_gl_var_type_hash(src,mask,spans,dest) ((spans) << 3) | ((mask) << 2 | (src << 1) | (dest))
-#define CAIRO_GL_VAR_TYPE_MAX ((CAIRO_GL_VAR_TEXCOORDS << 3) | (CAIRO_GL_VAR_TEXCOORDS << 2) | (CAIRO_GL_VAR_TEXCOORDS << 1) | CAIRO_GL_VAR_TEXCOORDS)
+#define cairo_gl_var_type_hash(src,mask,spans,dest) ((spans) << 5) | ((mask) << 3 | (src << 1) | (dest))
+#define CAIRO_GL_VAR_TYPE_MAX (1 << 6)
typedef void (*cairo_gl_generic_func_t)(void);
typedef cairo_gl_generic_func_t (*cairo_gl_get_proc_addr_func_t)(const char *procname);
@@ -334,7 +337,7 @@ struct _cairo_gl_context {
cairo_bool_t has_shader_support;
- GLuint vertex_shaders[CAIRO_GL_VAR_TYPE_MAX + 1];
+ GLuint vertex_shaders[CAIRO_GL_VAR_TYPE_MAX];
cairo_gl_shader_t fill_rectangles_shader;
cairo_cache_t shaders;
@@ -542,9 +545,10 @@ _cairo_gl_composite_set_clip(cairo_gl_composite_t *setup,
cairo_private cairo_int_status_t
_cairo_gl_composite_set_source (cairo_gl_composite_t *setup,
- const cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
const cairo_rectangle_int_t *sample,
- const cairo_rectangle_int_t *extents);
+ const cairo_rectangle_int_t *extents,
+ cairo_bool_t use_texgen);
cairo_private void
_cairo_gl_composite_set_solid_source (cairo_gl_composite_t *setup,
@@ -558,7 +562,8 @@ cairo_private cairo_int_status_t
_cairo_gl_composite_set_mask (cairo_gl_composite_t *setup,
const cairo_pattern_t *pattern,
const cairo_rectangle_int_t *sample,
- const cairo_rectangle_int_t *extents);
+ const cairo_rectangle_int_t *extents,
+ cairo_bool_t use_texgen);
cairo_private void
_cairo_gl_composite_set_mask_operand (cairo_gl_composite_t *setup,
@@ -665,7 +670,7 @@ _cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,
cairo_private void
_cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
const char *name,
- cairo_matrix_t* m);
+ const cairo_matrix_t* m);
cairo_private void
_cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx,
@@ -697,7 +702,8 @@ _cairo_gl_operand_init (cairo_gl_operand_t *operand,
const cairo_pattern_t *pattern,
cairo_gl_surface_t *dst,
const cairo_rectangle_int_t *sample,
- const cairo_rectangle_int_t *extents);
+ const cairo_rectangle_int_t *extents,
+ cairo_bool_t use_texgen);
cairo_private void
_cairo_gl_solid_operand_init (cairo_gl_operand_t *operand,
@@ -713,7 +719,7 @@ cairo_private cairo_extend_t
_cairo_gl_operand_get_extend (cairo_gl_operand_t *operand);
cairo_private unsigned int
-_cairo_gl_operand_get_vertex_size (cairo_gl_operand_type_t type);
+_cairo_gl_operand_get_vertex_size (const cairo_gl_operand_t *operand);
cairo_private cairo_bool_t
_cairo_gl_operand_needs_setup (cairo_gl_operand_t *dest,
diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c
index 41672d62..ae2977c5 100644
--- a/src/cairo-gl-shaders.c
+++ b/src/cairo-gl-shaders.c
@@ -215,9 +215,9 @@ _cairo_gl_shader_fini (cairo_gl_context_t *ctx,
static const char *operand_names[] = { "source", "mask", "dest" };
static cairo_gl_var_type_t
-cairo_gl_operand_get_var_type (cairo_gl_operand_type_t type)
+cairo_gl_operand_get_var_type (cairo_gl_operand_t *operand)
{
- switch (type) {
+ switch (operand->type) {
default:
case CAIRO_GL_OPERAND_COUNT:
ASSERT_NOT_REACHED;
@@ -228,8 +228,9 @@ cairo_gl_operand_get_var_type (cairo_gl_operand_type_t type)
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
+ return operand->gradient.texgen ? CAIRO_GL_VAR_TEXGEN : CAIRO_GL_VAR_TEXCOORDS;
case CAIRO_GL_OPERAND_TEXTURE:
- return CAIRO_GL_VAR_TEXCOORDS;
+ return operand->texture.texgen ? CAIRO_GL_VAR_TEXGEN : CAIRO_GL_VAR_TEXCOORDS;
}
}
@@ -245,7 +246,16 @@ cairo_gl_shader_emit_variable (cairo_output_stream_t *stream,
break;
case CAIRO_GL_VAR_TEXCOORDS:
_cairo_output_stream_printf (stream,
+ "attribute vec4 MultiTexCoord%d;\n"
+ "varying vec2 %s_texcoords;\n",
+ name,
+ operand_names[name]);
+ break;
+ case CAIRO_GL_VAR_TEXGEN:
+ _cairo_output_stream_printf (stream,
+ "uniform mat3 %s_texgen;\n"
"varying vec2 %s_texcoords;\n",
+ operand_names[name],
operand_names[name]);
break;
}
@@ -266,6 +276,12 @@ cairo_gl_shader_emit_vertex (cairo_output_stream_t *stream,
" %s_texcoords = MultiTexCoord%d.xy;\n",
operand_names[name], name);
break;
+
+ case CAIRO_GL_VAR_TEXGEN:
+ _cairo_output_stream_printf (stream,
+ " %s_texcoords = (%s_texgen * Vertex.xyw).xy;\n",
+ operand_names[name], operand_names[name]);
+ break;
}
}
@@ -301,8 +317,6 @@ cairo_gl_shader_get_vertex_source (cairo_gl_var_type_t src,
_cairo_output_stream_printf (stream,
"attribute vec4 Vertex;\n"
"attribute vec4 Color;\n"
- "attribute vec4 MultiTexCoord0;\n"
- "attribute vec4 MultiTexCoord1;\n"
"uniform mat4 ModelViewProjectionMatrix;\n"
"void main()\n"
"{\n"
@@ -920,7 +934,8 @@ _cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,
void
_cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
- const char *name, cairo_matrix_t* m)
+ const char *name,
+ const cairo_matrix_t* m)
{
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
GLint location = dispatch->GetUniformLocation (ctx->current_shader->program,
@@ -1016,8 +1031,8 @@ _cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx,
_cairo_gl_shader_init (&entry->shader);
status = _cairo_gl_shader_compile_and_link (ctx,
&entry->shader,
- cairo_gl_operand_get_var_type (source->type),
- cairo_gl_operand_get_var_type (mask->type),
+ cairo_gl_operand_get_var_type (source),
+ cairo_gl_operand_get_var_type (mask),
use_coverage,
fs_source);
free (fs_source);
diff --git a/src/cairo-gl-source.c b/src/cairo-gl-source.c
index 294f6f91..12235295 100644
--- a/src/cairo-gl-source.c
+++ b/src/cairo-gl-source.c
@@ -81,7 +81,8 @@ _cairo_gl_pattern_to_source (cairo_surface_t *dst,
*src_x = *src_y = 0;
status = _cairo_gl_operand_init (&source->operand, pattern,
(cairo_gl_surface_t *)dst,
- sample, extents);
+ sample, extents,
+ FALSE);
if (unlikely (status)) {
cairo_surface_destroy (&source->base);
return _cairo_surface_create_in_error (status);
diff --git a/src/cairo-gl-spans-compositor.c b/src/cairo-gl-spans-compositor.c
index 98efd465..92e57797 100644
--- a/src/cairo-gl-spans-compositor.c
+++ b/src/cairo-gl-spans-compositor.c
@@ -454,7 +454,8 @@ _cairo_gl_span_renderer_init (cairo_abstract_span_renderer_t *_r,
status = _cairo_gl_composite_set_source (&r->setup, source,
&composite->source_sample_area,
- &composite->unbounded);
+ &composite->unbounded,
+ TRUE);
if (unlikely (status))
goto FAIL;
@@ -465,7 +466,8 @@ _cairo_gl_span_renderer_init (cairo_abstract_span_renderer_t *_r,
status = _cairo_gl_composite_set_mask (&r->setup,
&composite->mask_pattern.base,
&composite->mask_sample_area,
- &composite->unbounded);
+ &composite->unbounded,
+ TRUE);
if (unlikely (status))
goto FAIL;
}
diff --git a/src/cairo-gl-traps-compositor.c b/src/cairo-gl-traps-compositor.c
index b6c23333..9589ffcb 100644
--- a/src/cairo-gl-traps-compositor.c
+++ b/src/cairo-gl-traps-compositor.c
@@ -358,7 +358,8 @@ traps_to_operand (void *_dst,
pattern.base.extend = CAIRO_EXTEND_NONE;
status = _cairo_gl_operand_init (operand, &pattern.base, _dst,
&_cairo_unbounded_rectangle,
- &_cairo_unbounded_rectangle);
+ &_cairo_unbounded_rectangle,
+ FALSE);
_cairo_pattern_fini (&pattern.base);
if (unlikely (status))