[gl] Convert fill_rectangles to the new GLSL core/arb wrapper.

This commit is contained in:
Eric Anholt 2010-02-02 11:17:43 -08:00
parent 416273db34
commit 672973caa0
3 changed files with 48 additions and 109 deletions

View file

@ -91,12 +91,13 @@ typedef struct _cairo_gl_context {
cairo_device_t base;
GLuint dummy_tex;
GLint fill_rectangles_shader;
GLint fill_rectangles_color_uniform;
GLint max_framebuffer_size;
GLint max_texture_size;
cairo_bool_t using_glsl;
cairo_bool_t using_shaders;
cairo_gl_shader_program_t fill_rectangles_shader;
cairo_gl_surface_t *current_target;
cairo_gl_surface_t *glyphs_temporary_mask;
cairo_gl_glyph_cache_t glyph_cache[2];
@ -236,10 +237,6 @@ _cairo_gl_surface_show_glyphs (void *abstract_dst,
cairo_private void
_cairo_gl_glyph_cache_fini (cairo_gl_glyph_cache_t *cache);
cairo_private cairo_status_t
_cairo_gl_load_glsl (GLint *shader,
const char *vs_source, const char *fs_source);
static inline int
_cairo_gl_y_flip (cairo_gl_surface_t *surface, int y)
{
@ -290,6 +287,9 @@ bind_matrix_to_shader (GLuint program, const char *name, cairo_matrix_t* m);
cairo_status_t
bind_texture_to_shader (GLuint program, const char *name, GLuint tex_unit);
void
_cairo_gl_use_program (cairo_gl_shader_program_t *shader);
slim_hidden_proto (cairo_gl_surface_create);
#endif /* CAIRO_GL_PRIVATE_H */

View file

@ -35,89 +35,6 @@
#include "cairo-gl-private.h"
#include "cairo-error-private.h"
static GLint
_cairo_gl_compile_glsl(GLenum type, GLint *shader_out, const char *source)
{
GLint ok;
GLint shader;
shader = glCreateShaderObjectARB (type);
glShaderSourceARB (shader, 1, (const GLchar **)&source, NULL);
glCompileShaderARB (shader);
glGetObjectParameterivARB (shader, GL_OBJECT_COMPILE_STATUS_ARB, &ok);
if (!ok) {
GLchar *info;
GLint size;
glGetObjectParameterivARB (shader, GL_OBJECT_INFO_LOG_LENGTH_ARB,
&size);
info = malloc (size);
if (info)
glGetInfoLogARB (shader, size, NULL, info);
fprintf (stderr, "Failed to compile %s: %s\n",
type == GL_FRAGMENT_SHADER ? "FS" : "VS",
info);
fprintf (stderr, "Shader source:\n%s", source);
fprintf (stderr, "GLSL compile failure\n");
glDeleteObjectARB (shader);
return CAIRO_INT_STATUS_UNSUPPORTED;
}
*shader_out = shader;
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_gl_load_glsl (GLint *shader_out,
const char *vs_source, const char *fs_source)
{
GLint ok;
GLint shader, vs, fs;
cairo_status_t status;
shader = glCreateProgramObjectARB ();
status = _cairo_gl_compile_glsl (GL_VERTEX_SHADER_ARB, &vs, vs_source);
if (_cairo_status_is_error (status))
goto fail;
status = _cairo_gl_compile_glsl (GL_FRAGMENT_SHADER_ARB, &fs, fs_source);
if (_cairo_status_is_error (status))
goto fail;
glAttachObjectARB (shader, vs);
glAttachObjectARB (shader, fs);
glLinkProgram (shader);
glGetObjectParameterivARB (shader, GL_OBJECT_LINK_STATUS_ARB, &ok);
if (!ok) {
GLchar *info;
GLint size;
glGetObjectParameterivARB (shader, GL_OBJECT_INFO_LOG_LENGTH_ARB,
&size);
info = malloc (size);
if (info)
glGetInfoLogARB (shader, size, NULL, info);
fprintf (stderr, "Failed to link: %s\n", info);
free (info);
status = CAIRO_INT_STATUS_UNSUPPORTED;
return CAIRO_INT_STATUS_UNSUPPORTED;
}
*shader_out = shader;
return CAIRO_STATUS_SUCCESS;
fail:
glDeleteObjectARB (shader);
return status;
}
typedef struct _shader_impl {
cairo_status_t
(*compile_shader) (GLuint *shader, GLenum type, const char *text);
@ -157,6 +74,9 @@ typedef struct _shader_impl {
cairo_status_t
(*bind_texture_to_shader) (GLuint program, const char *name, GLuint tex_unit);
void
(*use_program) (cairo_gl_shader_program_t *program);
} shader_impl_t;
static const shader_impl_t*
@ -394,6 +314,12 @@ bind_texture_to_shader_arb (GLuint program, const char *name, GLuint tex_unit)
return CAIRO_STATUS_SUCCESS;
}
static void
use_program_arb (cairo_gl_shader_program_t *program)
{
glUseProgramObjectARB (program->program);
}
/* OpenGL Core 2.0 API. */
static cairo_status_t
compile_shader_core_2_0 (GLuint *shader, GLenum type, const char *text)
@ -559,6 +485,12 @@ bind_texture_to_shader_core_2_0 (GLuint program, const char *name, GLuint tex_un
return CAIRO_STATUS_SUCCESS;
}
static void
use_program_core_2_0 (cairo_gl_shader_program_t *program)
{
glUseProgram (program->program);
}
static const shader_impl_t shader_impl_core_2_0 = {
compile_shader_core_2_0,
link_shader_core_2_0,
@ -571,6 +503,7 @@ static const shader_impl_t shader_impl_core_2_0 = {
bind_vec4_to_shader_core_2_0,
bind_matrix_to_shader_core_2_0,
bind_texture_to_shader_core_2_0,
use_program_core_2_0,
};
static const shader_impl_t shader_impl_arb = {
@ -585,6 +518,7 @@ static const shader_impl_t shader_impl_arb = {
bind_vec4_to_shader_arb,
bind_matrix_to_shader_arb,
bind_texture_to_shader_arb,
use_program_arb,
};
static const shader_impl_t*
@ -713,3 +647,9 @@ bind_texture_to_shader (GLuint program, const char *name, GLuint tex_unit)
{
return get_impl()->bind_texture_to_shader(program, name, tex_unit);
}
void
_cairo_gl_use_program (cairo_gl_shader_program_t *program)
{
get_impl()->use_program (program);
}

View file

@ -114,12 +114,15 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx)
return _cairo_error (CAIRO_STATUS_INVALID_FORMAT); /* XXX */
}
if (GLEW_ARB_fragment_shader &&
GLEW_ARB_vertex_shader &&
GLEW_ARB_shader_objects) {
if (GLEW_VERSION_2_0 ||
(GLEW_ARB_fragment_shader &&
GLEW_ARB_vertex_shader &&
GLEW_ARB_shader_objects)) {
ctx->using_glsl = TRUE;
}
init_shader_program (&ctx->fill_rectangles_shader);
/* Set up the dummy texture for tex_env_combine with constant color. */
glGenTextures (1, &ctx->dummy_tex);
glBindTexture (GL_TEXTURE_2D, ctx->dummy_tex);
@ -1889,7 +1892,6 @@ _cairo_gl_surface_fill_rectangles_glsl (void *abstract_surface,
#define N_STACK_RECTS 4
cairo_gl_surface_t *surface = abstract_surface;
GLfloat vertices_stack[N_STACK_RECTS*4*2];
GLfloat gl_color[4];
cairo_gl_context_t *ctx;
int i;
GLfloat *vertices;
@ -1913,16 +1915,12 @@ _cairo_gl_surface_fill_rectangles_glsl (void *abstract_surface,
if (unlikely (status))
return status;
if (ctx->fill_rectangles_shader == 0) {
status = _cairo_gl_load_glsl (&ctx->fill_rectangles_shader,
fill_vs_source, fill_fs_source);
if (_cairo_status_is_error (status)) {
_cairo_gl_context_release (ctx);
return status;
}
ctx->fill_rectangles_color_uniform =
glGetUniformLocationARB (ctx->fill_rectangles_shader, "color");
status = create_shader_program (&ctx->fill_rectangles_shader,
fill_vs_source,
fill_fs_source);
if (unlikely (status)) {
_cairo_gl_context_release (ctx);
return status;
}
if (num_rects > N_STACK_RECTS) {
@ -1936,16 +1934,17 @@ _cairo_gl_surface_fill_rectangles_glsl (void *abstract_surface,
vertices = vertices_stack;
}
glUseProgramObjectARB (ctx->fill_rectangles_shader);
_cairo_gl_use_program (&ctx->fill_rectangles_shader);
_cairo_gl_set_destination (surface);
_cairo_gl_set_operator (surface, op, FALSE);
gl_color[0] = color->red * color->alpha;
gl_color[1] = color->green * color->alpha;
gl_color[2] = color->blue * color->alpha;
gl_color[3] = color->alpha;
glUniform4fvARB (ctx->fill_rectangles_color_uniform, 1, gl_color);
bind_vec4_to_shader (ctx->fill_rectangles_shader.program,
"color",
color->red * color->alpha,
color->green * color->alpha,
color->blue * color->alpha,
color->alpha);
for (i = 0; i < num_rects; i++) {
vertices[i * 8 + 0] = rects[i].x;