mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-04 23:28:07 +02:00
gl: Remove the shader language version abstraction
Cairo only needs to support one version of the shader language API, thanks to the dispatch table. This seems unlikely to change any time soon. This makes the addition of new features, such as a uniform location cache, simpler.
This commit is contained in:
parent
5c77b4df14
commit
9741099093
2 changed files with 159 additions and 311 deletions
|
|
@ -193,8 +193,6 @@ typedef enum cairo_gl_tex {
|
|||
CAIRO_GL_TEX_TEMP = 2
|
||||
} cairo_gl_tex_t;
|
||||
|
||||
typedef struct cairo_gl_shader_impl cairo_gl_shader_impl_t;
|
||||
|
||||
typedef struct cairo_gl_shader {
|
||||
GLuint fragment_shader;
|
||||
GLuint program;
|
||||
|
|
@ -316,7 +314,7 @@ struct _cairo_gl_context {
|
|||
cairo_bool_t supports_msaa;
|
||||
char *vb;
|
||||
|
||||
const cairo_gl_shader_impl_t *shader_impl;
|
||||
cairo_bool_t has_shader_support;
|
||||
|
||||
GLuint vertex_shaders[CAIRO_GL_VAR_TYPE_MAX + 1];
|
||||
cairo_gl_shader_t fill_rectangles_shader;
|
||||
|
|
@ -419,7 +417,7 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
|
|||
static cairo_always_inline cairo_bool_t
|
||||
_cairo_gl_device_has_glsl (cairo_device_t *device)
|
||||
{
|
||||
return ((cairo_gl_context_t *) device)->shader_impl != NULL;
|
||||
return ((cairo_gl_context_t *) device)->has_shader_support;
|
||||
}
|
||||
|
||||
static cairo_always_inline cairo_bool_t
|
||||
|
|
|
|||
|
|
@ -44,270 +44,13 @@
|
|||
#include "cairo-error-private.h"
|
||||
#include "cairo-output-stream-private.h"
|
||||
|
||||
typedef struct cairo_gl_shader_impl {
|
||||
void
|
||||
(*compile_shader) (cairo_gl_context_t *ctx, GLuint *shader, GLenum type,
|
||||
const char *text);
|
||||
|
||||
void
|
||||
(*link_shader) (cairo_gl_context_t *ctx, GLuint *program, GLuint vert, GLuint frag);
|
||||
|
||||
void
|
||||
(*destroy_shader) (cairo_gl_context_t *ctx, GLuint shader);
|
||||
|
||||
void
|
||||
(*destroy_program) (cairo_gl_context_t *ctx, GLuint program);
|
||||
|
||||
void
|
||||
(*bind_float) (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
const char *name,
|
||||
float value);
|
||||
|
||||
void
|
||||
(*bind_vec2) (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
const char *name,
|
||||
float value0,
|
||||
float value1);
|
||||
|
||||
void
|
||||
(*bind_vec3) (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
const char *name,
|
||||
float value0,
|
||||
float value1,
|
||||
float value2);
|
||||
|
||||
void
|
||||
(*bind_vec4) (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
const char *name,
|
||||
float value0, float value1,
|
||||
float value2, float value3);
|
||||
|
||||
void
|
||||
(*bind_matrix) (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
const char *name,
|
||||
cairo_matrix_t* m);
|
||||
|
||||
void
|
||||
(*bind_matrix4f) (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
const char *name,
|
||||
GLfloat* gl_m);
|
||||
|
||||
void
|
||||
(*use) (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader);
|
||||
} shader_impl_t;
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_gl_shader_compile (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
cairo_gl_var_type_t src,
|
||||
cairo_gl_var_type_t mask,
|
||||
cairo_bool_t use_coverage,
|
||||
const char *fragment_text);
|
||||
|
||||
/* OpenGL Core 2.0 API. */
|
||||
static void
|
||||
compile_shader_core_2_0 (cairo_gl_context_t *ctx, GLuint *shader,
|
||||
GLenum type, const char *text)
|
||||
{
|
||||
const char* strings[1] = { text };
|
||||
GLint gl_status;
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
|
||||
*shader = dispatch->CreateShader (type);
|
||||
dispatch->ShaderSource (*shader, 1, strings, 0);
|
||||
dispatch->CompileShader (*shader);
|
||||
dispatch->GetShaderiv (*shader, GL_COMPILE_STATUS, &gl_status);
|
||||
if (gl_status == GL_FALSE) {
|
||||
GLint log_size;
|
||||
dispatch->GetShaderiv (*shader, GL_INFO_LOG_LENGTH, &log_size);
|
||||
if (0 < log_size) {
|
||||
char *log = _cairo_malloc (log_size);
|
||||
GLint chars;
|
||||
|
||||
log[log_size - 1] = '\0';
|
||||
dispatch->GetShaderInfoLog (*shader, log_size, &chars, log);
|
||||
printf ("OpenGL shader compilation failed. Shader:\n"
|
||||
"%s\n"
|
||||
"OpenGL compilation log:\n"
|
||||
"%s\n",
|
||||
text, log);
|
||||
|
||||
free (log);
|
||||
} else {
|
||||
printf ("OpenGL shader compilation failed.\n");
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
link_shader_core_2_0 (cairo_gl_context_t *ctx, GLuint *program,
|
||||
GLuint vert, GLuint frag)
|
||||
{
|
||||
GLint gl_status;
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
|
||||
*program = dispatch->CreateProgram ();
|
||||
dispatch->AttachShader (*program, vert);
|
||||
dispatch->AttachShader (*program, frag);
|
||||
|
||||
dispatch->BindAttribLocation (*program, CAIRO_GL_VERTEX_ATTRIB_INDEX,
|
||||
"Vertex");
|
||||
dispatch->BindAttribLocation (*program, CAIRO_GL_COLOR_ATTRIB_INDEX,
|
||||
"Color");
|
||||
dispatch->BindAttribLocation (*program, CAIRO_GL_TEXCOORD0_ATTRIB_INDEX,
|
||||
"MultiTexCoord0");
|
||||
dispatch->BindAttribLocation (*program, CAIRO_GL_TEXCOORD1_ATTRIB_INDEX,
|
||||
"MultiTexCoord1");
|
||||
|
||||
dispatch->LinkProgram (*program);
|
||||
dispatch->GetProgramiv (*program, GL_LINK_STATUS, &gl_status);
|
||||
if (gl_status == GL_FALSE) {
|
||||
GLint log_size;
|
||||
dispatch->GetProgramiv (*program, GL_INFO_LOG_LENGTH, &log_size);
|
||||
if (0 < log_size) {
|
||||
char *log = _cairo_malloc (log_size);
|
||||
GLint chars;
|
||||
|
||||
log[log_size - 1] = '\0';
|
||||
dispatch->GetProgramInfoLog (*program, log_size, &chars, log);
|
||||
printf ("OpenGL shader link failed:\n%s\n", log);
|
||||
|
||||
free (log);
|
||||
} else {
|
||||
printf ("OpenGL shader link failed.\n");
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_shader_core_2_0 (cairo_gl_context_t *ctx, GLuint shader)
|
||||
{
|
||||
ctx->dispatch.DeleteShader (shader);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_program_core_2_0 (cairo_gl_context_t *ctx, GLuint shader)
|
||||
{
|
||||
ctx->dispatch.DeleteProgram (shader);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_float_core_2_0 (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
const char *name,
|
||||
float value)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
GLint location = dispatch->GetUniformLocation (shader->program, name);
|
||||
assert (location != -1);
|
||||
dispatch->Uniform1f (location, value);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_vec2_core_2_0 (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
const char *name,
|
||||
float value0,
|
||||
float value1)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
GLint location = dispatch->GetUniformLocation (shader->program, name);
|
||||
assert (location != -1);
|
||||
dispatch->Uniform2f (location, value0, value1);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_vec3_core_2_0 (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
const char *name,
|
||||
float value0,
|
||||
float value1,
|
||||
float value2)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
GLint location = dispatch->GetUniformLocation (shader->program, name);
|
||||
assert (location != -1);
|
||||
dispatch->Uniform3f (location, value0, value1, value2);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_vec4_core_2_0 (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
const char *name,
|
||||
float value0,
|
||||
float value1,
|
||||
float value2,
|
||||
float value3)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
GLint location = dispatch->GetUniformLocation (shader->program, name);
|
||||
assert (location != -1);
|
||||
dispatch->Uniform4f (location, value0, value1, value2, value3);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_matrix_core_2_0 (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
const char *name,
|
||||
cairo_matrix_t* m)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
GLint location = dispatch->GetUniformLocation (shader->program, name);
|
||||
float gl_m[16] = {
|
||||
m->xx, m->xy, m->x0,
|
||||
m->yx, m->yy, m->y0,
|
||||
0, 0, 1
|
||||
};
|
||||
assert (location != -1);
|
||||
dispatch->UniformMatrix3fv (location, 1, GL_TRUE, gl_m);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_matrix4f_core_2_0 (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
const char *name,
|
||||
GLfloat* gl_m)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
GLint location = dispatch->GetUniformLocation (shader->program, name);
|
||||
assert (location != -1);
|
||||
dispatch->UniformMatrix4fv (location, 1, GL_FALSE, gl_m);
|
||||
}
|
||||
|
||||
static void
|
||||
use_program_core_2_0 (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader)
|
||||
{
|
||||
if (shader)
|
||||
ctx->dispatch.UseProgram (shader->program);
|
||||
else
|
||||
ctx->dispatch.UseProgram (0);
|
||||
}
|
||||
|
||||
static const cairo_gl_shader_impl_t shader_impl_core_2_0 = {
|
||||
compile_shader_core_2_0,
|
||||
link_shader_core_2_0,
|
||||
destroy_shader_core_2_0,
|
||||
destroy_program_core_2_0,
|
||||
bind_float_core_2_0,
|
||||
bind_vec2_core_2_0,
|
||||
bind_vec3_core_2_0,
|
||||
bind_vec4_core_2_0,
|
||||
bind_matrix_core_2_0,
|
||||
bind_matrix4f_core_2_0,
|
||||
use_program_core_2_0,
|
||||
};
|
||||
_cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
cairo_gl_var_type_t src,
|
||||
cairo_gl_var_type_t mask,
|
||||
cairo_bool_t use_coverage,
|
||||
const char *fragment_text);
|
||||
|
||||
typedef struct _cairo_shader_cache_entry {
|
||||
cairo_cache_entry_t base;
|
||||
|
|
@ -412,13 +155,10 @@ _cairo_gl_context_init_shaders (cairo_gl_context_t *ctx)
|
|||
if (_cairo_gl_get_version () >= CAIRO_GL_VERSION_ENCODE (2, 0) ||
|
||||
(_cairo_gl_has_extension ("GL_ARB_shader_objects") &&
|
||||
_cairo_gl_has_extension ("GL_ARB_fragment_shader") &&
|
||||
_cairo_gl_has_extension ("GL_ARB_vertex_shader")))
|
||||
{
|
||||
ctx->shader_impl = &shader_impl_core_2_0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->shader_impl = NULL;
|
||||
_cairo_gl_has_extension ("GL_ARB_vertex_shader"))) {
|
||||
ctx->has_shader_support = TRUE;
|
||||
} else {
|
||||
ctx->has_shader_support = FALSE;
|
||||
fprintf (stderr, "Error: The cairo gl backend requires shader support!\n");
|
||||
return CAIRO_STATUS_DEVICE_ERROR;
|
||||
}
|
||||
|
|
@ -436,12 +176,12 @@ _cairo_gl_context_init_shaders (cairo_gl_context_t *ctx)
|
|||
return status;
|
||||
|
||||
_cairo_gl_shader_init (&ctx->fill_rectangles_shader);
|
||||
status = _cairo_gl_shader_compile (ctx,
|
||||
&ctx->fill_rectangles_shader,
|
||||
CAIRO_GL_VAR_NONE,
|
||||
CAIRO_GL_VAR_NONE,
|
||||
FALSE,
|
||||
fill_fs_source);
|
||||
status = _cairo_gl_shader_compile_and_link (ctx,
|
||||
&ctx->fill_rectangles_shader,
|
||||
CAIRO_GL_VAR_NONE,
|
||||
CAIRO_GL_VAR_NONE,
|
||||
FALSE,
|
||||
fill_fs_source);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
|
|
@ -455,7 +195,7 @@ _cairo_gl_context_fini_shaders (cairo_gl_context_t *ctx)
|
|||
|
||||
for (i = 0; i <= CAIRO_GL_VAR_TYPE_MAX; i++) {
|
||||
if (ctx->vertex_shaders[i])
|
||||
ctx->shader_impl->destroy_shader (ctx, ctx->vertex_shaders[i]);
|
||||
ctx->dispatch.DeleteShader (ctx->vertex_shaders[i]);
|
||||
}
|
||||
|
||||
_cairo_cache_fini (&ctx->shaders);
|
||||
|
|
@ -466,10 +206,10 @@ _cairo_gl_shader_fini (cairo_gl_context_t *ctx,
|
|||
cairo_gl_shader_t *shader)
|
||||
{
|
||||
if (shader->fragment_shader)
|
||||
ctx->shader_impl->destroy_shader (ctx, shader->fragment_shader);
|
||||
ctx->dispatch.DeleteShader (shader->fragment_shader);
|
||||
|
||||
if (shader->program)
|
||||
ctx->shader_impl->destroy_program (ctx, shader->program);
|
||||
ctx->dispatch.DeleteProgram (shader->program);
|
||||
}
|
||||
|
||||
static const char *operand_names[] = { "source", "mask", "dest" };
|
||||
|
|
@ -966,13 +706,93 @@ cairo_gl_shader_get_fragment_source (cairo_gl_context_t *ctx,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
compile_shader (cairo_gl_context_t *ctx,
|
||||
GLuint *shader,
|
||||
GLenum type,
|
||||
const char *source)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
GLint success, log_size, num_chars;
|
||||
char *log;
|
||||
|
||||
*shader = dispatch->CreateShader (type);
|
||||
dispatch->ShaderSource (*shader, 1, &source, 0);
|
||||
dispatch->CompileShader (*shader);
|
||||
dispatch->GetShaderiv (*shader, GL_COMPILE_STATUS, &success);
|
||||
|
||||
if (success)
|
||||
return;
|
||||
|
||||
dispatch->GetShaderiv (*shader, GL_INFO_LOG_LENGTH, &log_size);
|
||||
if (log_size < 0) {
|
||||
printf ("OpenGL shader compilation failed.\n");
|
||||
ASSERT_NOT_REACHED;
|
||||
return;
|
||||
}
|
||||
|
||||
log = _cairo_malloc (log_size + 1);
|
||||
dispatch->GetShaderInfoLog (*shader, log_size, &num_chars, log);
|
||||
log[num_chars] = '\0';
|
||||
|
||||
printf ("OpenGL shader compilation failed. Shader:\n%s\n", source);
|
||||
printf ("OpenGL compilation log:\n%s\n", log);
|
||||
|
||||
free (log);
|
||||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
|
||||
static void
|
||||
link_shader_program (cairo_gl_context_t *ctx,
|
||||
GLuint *program,
|
||||
GLuint vert,
|
||||
GLuint frag)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
GLint success, log_size, num_chars;
|
||||
char *log;
|
||||
|
||||
*program = dispatch->CreateProgram ();
|
||||
dispatch->AttachShader (*program, vert);
|
||||
dispatch->AttachShader (*program, frag);
|
||||
|
||||
dispatch->BindAttribLocation (*program, CAIRO_GL_VERTEX_ATTRIB_INDEX,
|
||||
"Vertex");
|
||||
dispatch->BindAttribLocation (*program, CAIRO_GL_COLOR_ATTRIB_INDEX,
|
||||
"Color");
|
||||
dispatch->BindAttribLocation (*program, CAIRO_GL_TEXCOORD0_ATTRIB_INDEX,
|
||||
"MultiTexCoord0");
|
||||
dispatch->BindAttribLocation (*program, CAIRO_GL_TEXCOORD1_ATTRIB_INDEX,
|
||||
"MultiTexCoord1");
|
||||
|
||||
dispatch->LinkProgram (*program);
|
||||
dispatch->GetProgramiv (*program, GL_LINK_STATUS, &success);
|
||||
if (success)
|
||||
return;
|
||||
|
||||
dispatch->GetProgramiv (*program, GL_INFO_LOG_LENGTH, &log_size);
|
||||
if (log_size < 0) {
|
||||
printf ("OpenGL shader link failed.\n");
|
||||
ASSERT_NOT_REACHED;
|
||||
return;
|
||||
}
|
||||
|
||||
log = _cairo_malloc (log_size + 1);
|
||||
dispatch->GetProgramInfoLog (*program, log_size, &num_chars, log);
|
||||
log[num_chars] = '\0';
|
||||
|
||||
printf ("OpenGL shader link failed:\n%s\n", log);
|
||||
free (log);
|
||||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_gl_shader_compile (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
cairo_gl_var_type_t src,
|
||||
cairo_gl_var_type_t mask,
|
||||
cairo_bool_t use_coverage,
|
||||
const char *fragment_text)
|
||||
_cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx,
|
||||
cairo_gl_shader_t *shader,
|
||||
cairo_gl_var_type_t src,
|
||||
cairo_gl_var_type_t mask,
|
||||
cairo_bool_t use_coverage,
|
||||
const char *fragment_text)
|
||||
{
|
||||
unsigned int vertex_shader;
|
||||
cairo_status_t status;
|
||||
|
|
@ -992,19 +812,17 @@ _cairo_gl_shader_compile (cairo_gl_context_t *ctx,
|
|||
if (unlikely (status))
|
||||
goto FAILURE;
|
||||
|
||||
ctx->shader_impl->compile_shader (ctx, &ctx->vertex_shaders[vertex_shader],
|
||||
GL_VERTEX_SHADER,
|
||||
source);
|
||||
compile_shader (ctx, &ctx->vertex_shaders[vertex_shader],
|
||||
GL_VERTEX_SHADER, source);
|
||||
free (source);
|
||||
}
|
||||
|
||||
ctx->shader_impl->compile_shader (ctx, &shader->fragment_shader,
|
||||
GL_FRAGMENT_SHADER,
|
||||
fragment_text);
|
||||
compile_shader (ctx, &shader->fragment_shader,
|
||||
GL_FRAGMENT_SHADER, fragment_text);
|
||||
|
||||
ctx->shader_impl->link_shader (ctx, &shader->program,
|
||||
ctx->vertex_shaders[vertex_shader],
|
||||
shader->fragment_shader);
|
||||
link_shader_program (ctx, &shader->program,
|
||||
ctx->vertex_shaders[vertex_shader],
|
||||
shader->fragment_shader);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
|
|
@ -1053,7 +871,11 @@ _cairo_gl_shader_bind_float (cairo_gl_context_t *ctx,
|
|||
const char *name,
|
||||
float value)
|
||||
{
|
||||
ctx->shader_impl->bind_float (ctx, ctx->current_shader, name, 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
|
||||
|
|
@ -1062,7 +884,11 @@ _cairo_gl_shader_bind_vec2 (cairo_gl_context_t *ctx,
|
|||
float value0,
|
||||
float value1)
|
||||
{
|
||||
ctx->shader_impl->bind_vec2 (ctx, ctx->current_shader, name, value0, 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
|
||||
|
|
@ -1072,7 +898,11 @@ _cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx,
|
|||
float value1,
|
||||
float value2)
|
||||
{
|
||||
ctx->shader_impl->bind_vec3 (ctx, ctx->current_shader, name, value0, value1, 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
|
||||
|
|
@ -1081,21 +911,38 @@ _cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,
|
|||
float value0, float value1,
|
||||
float value2, float value3)
|
||||
{
|
||||
ctx->shader_impl->bind_vec4 (ctx, ctx->current_shader, name, value0, value1, value2, 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, cairo_matrix_t* m)
|
||||
{
|
||||
ctx->shader_impl->bind_matrix (ctx, ctx->current_shader, name, 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,
|
||||
0, 0, 1
|
||||
};
|
||||
assert (location != -1);
|
||||
dispatch->UniformMatrix3fv (location, 1, GL_TRUE, gl_m);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx,
|
||||
const char *name, GLfloat* gl_m)
|
||||
{
|
||||
ctx->shader_impl->bind_matrix4f (ctx, ctx->current_shader, name, 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);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1105,7 +952,10 @@ _cairo_gl_set_shader (cairo_gl_context_t *ctx,
|
|||
if (ctx->current_shader == shader)
|
||||
return;
|
||||
|
||||
ctx->shader_impl->use (ctx, shader);
|
||||
if (shader)
|
||||
ctx->dispatch.UseProgram (shader->program);
|
||||
else
|
||||
ctx->dispatch.UseProgram (0);
|
||||
|
||||
ctx->current_shader = shader;
|
||||
}
|
||||
|
|
@ -1164,12 +1014,12 @@ _cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx,
|
|||
|
||||
entry->ctx = ctx;
|
||||
_cairo_gl_shader_init (&entry->shader);
|
||||
status = _cairo_gl_shader_compile (ctx,
|
||||
&entry->shader,
|
||||
cairo_gl_operand_get_var_type (source->type),
|
||||
cairo_gl_operand_get_var_type (mask->type),
|
||||
use_coverage,
|
||||
fs_source);
|
||||
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),
|
||||
use_coverage,
|
||||
fs_source);
|
||||
free (fs_source);
|
||||
|
||||
if (unlikely (status)) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue