mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-11 06:20:14 +01:00
gl: Move glGetUniformLocation to shader compile time.
The lookup of the string names has significant overhead, which is why GL gives you glGetUniformLocation so that you reference uniforms by constant integers in your high performance path. Reduces cairo-perf-trace runtime of firefox-planet-gnome by 1.06767% +/- 0.289265% (n=72) on my IVB macbook air. Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
4d9439132d
commit
7b8fc77bb9
4 changed files with 70 additions and 48 deletions
|
|
@ -134,7 +134,7 @@ static void
|
|||
_cairo_gl_composite_bind_to_shader (cairo_gl_context_t *ctx,
|
||||
cairo_gl_composite_t *setup)
|
||||
{
|
||||
_cairo_gl_shader_bind_matrix4f(ctx, "ModelViewProjectionMatrix",
|
||||
_cairo_gl_shader_bind_matrix4f(ctx, ctx->current_shader->mvp_location,
|
||||
ctx->modelviewprojection_matrix);
|
||||
_cairo_gl_operand_bind_to_shader (ctx, &setup->src, CAIRO_GL_TEX_SOURCE);
|
||||
_cairo_gl_operand_bind_to_shader (ctx, &setup->mask, CAIRO_GL_TEX_MASK);
|
||||
|
|
|
|||
|
|
@ -613,14 +613,8 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
|
|||
cairo_gl_operand_t *operand,
|
||||
cairo_gl_tex_t tex_unit)
|
||||
{
|
||||
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]);
|
||||
|
||||
switch (operand->type) {
|
||||
default:
|
||||
case CAIRO_GL_OPERAND_COUNT:
|
||||
|
|
@ -629,9 +623,8 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
|
|||
return;
|
||||
|
||||
case CAIRO_GL_OPERAND_CONSTANT:
|
||||
strcpy (custom_part, "_constant");
|
||||
_cairo_gl_shader_bind_vec4 (ctx,
|
||||
uniform_name,
|
||||
ctx->current_shader->constant_location[tex_unit],
|
||||
operand->constant.color[0],
|
||||
operand->constant.color[1],
|
||||
operand->constant.color[2],
|
||||
|
|
@ -640,21 +633,18 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
|
|||
|
||||
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
|
||||
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
|
||||
strcpy (custom_part, "_a");
|
||||
_cairo_gl_shader_bind_float (ctx,
|
||||
uniform_name,
|
||||
ctx->current_shader->a_location[tex_unit],
|
||||
operand->gradient.a);
|
||||
/* fall through */
|
||||
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
|
||||
strcpy (custom_part, "_circle_d");
|
||||
_cairo_gl_shader_bind_vec3 (ctx,
|
||||
uniform_name,
|
||||
ctx->current_shader->circle_d_location[tex_unit],
|
||||
operand->gradient.circle_d.center.x,
|
||||
operand->gradient.circle_d.center.y,
|
||||
operand->gradient.circle_d.radius);
|
||||
strcpy (custom_part, "_radius_0");
|
||||
_cairo_gl_shader_bind_float (ctx,
|
||||
uniform_name,
|
||||
ctx->current_shader->radius_0_location[tex_unit],
|
||||
operand->gradient.radius_0);
|
||||
/* fall through */
|
||||
case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
|
||||
|
|
@ -677,8 +667,9 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
|
|||
width = operand->gradient.gradient->cache_entry.size,
|
||||
height = 1;
|
||||
}
|
||||
strcpy (custom_part, "_texdims");
|
||||
_cairo_gl_shader_bind_vec2 (ctx, uniform_name, width, height);
|
||||
_cairo_gl_shader_bind_vec2 (ctx,
|
||||
ctx->current_shader->texdims_location[tex_unit],
|
||||
width, height);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -691,10 +682,9 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
|
|||
texgen = &operand->gradient.m;
|
||||
}
|
||||
if (texgen) {
|
||||
char name[20];
|
||||
|
||||
sprintf (name, "%s_texgen", names[tex_unit]);
|
||||
_cairo_gl_shader_bind_matrix(ctx, name, texgen);
|
||||
_cairo_gl_shader_bind_matrix(ctx,
|
||||
ctx->current_shader->texgen_location[tex_unit],
|
||||
texgen);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -201,6 +201,13 @@ typedef enum cairo_gl_tex {
|
|||
typedef struct cairo_gl_shader {
|
||||
GLuint fragment_shader;
|
||||
GLuint program;
|
||||
GLint mvp_location;
|
||||
GLint constant_location[2];
|
||||
GLint a_location[2];
|
||||
GLint circle_d_location[2];
|
||||
GLint radius_0_location[2];
|
||||
GLint texdims_location[2];
|
||||
GLint texgen_location[2];
|
||||
} cairo_gl_shader_t;
|
||||
|
||||
typedef enum cairo_gl_shader_in {
|
||||
|
|
@ -651,35 +658,35 @@ _cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx,
|
|||
|
||||
cairo_private void
|
||||
_cairo_gl_shader_bind_float (cairo_gl_context_t *ctx,
|
||||
const char *name,
|
||||
GLint location,
|
||||
float value);
|
||||
|
||||
cairo_private void
|
||||
_cairo_gl_shader_bind_vec2 (cairo_gl_context_t *ctx,
|
||||
const char *name,
|
||||
GLint location,
|
||||
float value0, float value1);
|
||||
|
||||
cairo_private void
|
||||
_cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx,
|
||||
const char *name,
|
||||
GLint location,
|
||||
float value0,
|
||||
float value1,
|
||||
float value2);
|
||||
|
||||
cairo_private void
|
||||
_cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,
|
||||
const char *name,
|
||||
GLint location,
|
||||
float value0, float value1,
|
||||
float value2, float value3);
|
||||
|
||||
cairo_private void
|
||||
_cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
|
||||
const char *name,
|
||||
GLint location,
|
||||
const cairo_matrix_t* m);
|
||||
|
||||
cairo_private void
|
||||
_cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx,
|
||||
const char *name,
|
||||
GLint location,
|
||||
GLfloat* gl_m);
|
||||
|
||||
cairo_private void
|
||||
|
|
|
|||
|
|
@ -805,6 +805,22 @@ link_shader_program (cairo_gl_context_t *ctx,
|
|||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
|
||||
static GLint
|
||||
_cairo_gl_get_op_uniform_location(cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
cairo_gl_tex_t tex_unit,
|
||||
const char *suffix)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
char uniform_name[100];
|
||||
const char *unit_name[2] = { "source", "mask" };
|
||||
|
||||
snprintf (uniform_name, sizeof (uniform_name), "%s_%s",
|
||||
unit_name[tex_unit], suffix);
|
||||
|
||||
return dispatch->GetUniformLocation (shader->program, uniform_name);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
|
|
@ -813,8 +829,10 @@ _cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx,
|
|||
cairo_bool_t use_coverage,
|
||||
const char *fragment_text)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
unsigned int vertex_shader;
|
||||
cairo_status_t status;
|
||||
int i;
|
||||
|
||||
assert (shader->program == 0);
|
||||
|
||||
|
|
@ -828,12 +846,12 @@ _cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx,
|
|||
use_coverage,
|
||||
CAIRO_GL_VAR_NONE,
|
||||
&source);
|
||||
if (unlikely (status))
|
||||
goto FAILURE;
|
||||
if (unlikely (status))
|
||||
goto FAILURE;
|
||||
|
||||
compile_shader (ctx, &ctx->vertex_shaders[vertex_shader],
|
||||
GL_VERTEX_SHADER, source);
|
||||
free (source);
|
||||
free (source);
|
||||
}
|
||||
|
||||
compile_shader (ctx, &shader->fragment_shader,
|
||||
|
|
@ -843,6 +861,25 @@ _cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx,
|
|||
ctx->vertex_shaders[vertex_shader],
|
||||
shader->fragment_shader);
|
||||
|
||||
shader->mvp_location =
|
||||
dispatch->GetUniformLocation (shader->program,
|
||||
"ModelViewProjectionMatrix");
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
shader->constant_location[i] =
|
||||
_cairo_gl_get_op_uniform_location (ctx, shader, i, "constant");
|
||||
shader->a_location[i] =
|
||||
_cairo_gl_get_op_uniform_location (ctx, shader, i, "a");
|
||||
shader->circle_d_location[i] =
|
||||
_cairo_gl_get_op_uniform_location (ctx, shader, i, "circle_d");
|
||||
shader->radius_0_location[i] =
|
||||
_cairo_gl_get_op_uniform_location (ctx, shader, i, "radius_0");
|
||||
shader->texdims_location[i] =
|
||||
_cairo_gl_get_op_uniform_location (ctx, shader, i, "texdims");
|
||||
shader->texgen_location[i] =
|
||||
_cairo_gl_get_op_uniform_location (ctx, shader, i, "texgen");
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
FAILURE:
|
||||
|
|
@ -887,64 +924,54 @@ _cairo_gl_shader_set_samplers (cairo_gl_context_t *ctx,
|
|||
|
||||
void
|
||||
_cairo_gl_shader_bind_float (cairo_gl_context_t *ctx,
|
||||
const char *name,
|
||||
GLint location,
|
||||
float value)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
GLint location = dispatch->GetUniformLocation (ctx->current_shader->program,
|
||||
name);
|
||||
assert (location != -1);
|
||||
dispatch->Uniform1f (location, value);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_gl_shader_bind_vec2 (cairo_gl_context_t *ctx,
|
||||
const char *name,
|
||||
GLint location,
|
||||
float value0,
|
||||
float value1)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
GLint location = dispatch->GetUniformLocation (ctx->current_shader->program,
|
||||
name);
|
||||
assert (location != -1);
|
||||
dispatch->Uniform2f (location, value0, value1);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx,
|
||||
const char *name,
|
||||
GLint location,
|
||||
float value0,
|
||||
float value1,
|
||||
float value2)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
GLint location = dispatch->GetUniformLocation (ctx->current_shader->program,
|
||||
name);
|
||||
assert (location != -1);
|
||||
dispatch->Uniform3f (location, value0, value1, value2);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,
|
||||
const char *name,
|
||||
GLint location,
|
||||
float value0, float value1,
|
||||
float value2, float value3)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
GLint location = dispatch->GetUniformLocation (ctx->current_shader->program,
|
||||
name);
|
||||
assert (location != -1);
|
||||
dispatch->Uniform4f (location, value0, value1, value2, value3);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
|
||||
const char *name,
|
||||
GLint location,
|
||||
const cairo_matrix_t* m)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
GLint location = dispatch->GetUniformLocation (ctx->current_shader->program,
|
||||
name);
|
||||
float gl_m[9] = {
|
||||
m->xx, m->xy, m->x0,
|
||||
m->yx, m->yy, m->y0,
|
||||
|
|
@ -956,11 +983,9 @@ _cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
|
|||
|
||||
void
|
||||
_cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx,
|
||||
const char *name, GLfloat* gl_m)
|
||||
GLint location, GLfloat* gl_m)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
GLint location = dispatch->GetUniformLocation (ctx->current_shader->program,
|
||||
name);
|
||||
assert (location != -1);
|
||||
dispatch->UniformMatrix4fv (location, 1, GL_FALSE, gl_m);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue