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.
This commit is contained in:
Benjamin Otte 2010-05-19 18:21:06 +02:00
parent c53f7778bc
commit 065969d78f
2 changed files with 80 additions and 80 deletions

View file

@ -538,32 +538,87 @@ _cairo_gl_composite_set_clip_region (cairo_gl_context_t *ctx,
setup->clip_region = clip_region;
}
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)
{
char uniform_name[50];
char *custom_part;
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,
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");
}
static void
_cairo_gl_set_tex_combine_constant_color (cairo_gl_context_t *ctx,
cairo_gl_composite_t *setup,
int tex_unit,
GLfloat *color)
{
if (setup->shader) {
const char *uniform_name;
if (tex_unit == 0)
uniform_name = "source_constant";
else
uniform_name = "mask_constant";
_cairo_gl_shader_bind_vec4 (ctx,
setup->shader,
uniform_name,
color[0],
color[1],
color[2],
color[3]);
return;
}
/* Fall back to fixed function */
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);

View file

@ -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