[6/6] gl: Replace built-in vertex attributes with custom attributes

Message ID 1297163415-31035-7-git-send-email-alexandros.frantzis@linaro.org
State Accepted
Commit e4fdd9a1cd4c0d074dd20417e66de5856b6ba5a7
Headers show

Commit Message

alexandros.frantzis@linaro.org Feb. 8, 2011, 11:10 a.m.
From: Alexandros Frantzis <alexandros.frantzis@linaro.org>

Built-in vertex attributes like gl_Vertex and gl_Color, have been obsoleted
and removed in recent GL versions and they are not supported at all in GLES2.0.
Custom attributes are supported in all GL versions >= 2.0, in GL 1.x with
ARB shader extensions and in GLES2.0.
---
 src/cairo-gl-composite.c |   42 ++++++++++++++++++++++--------------------
 src/cairo-gl-private.h   |   10 ++++++++++
 src/cairo-gl-shaders.c   |   20 +++++++++++++++++---
 3 files changed, 49 insertions(+), 23 deletions(-)

Patch

diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index 7cbe894..d5b3c5c 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -3,6 +3,7 @@ 
  * Copyright © 2009 Eric Anholt
  * Copyright © 2009 Chris Wilson
  * Copyright © 2005,2010 Red Hat, Inc
+ * Copyright © 2011 Linaro Limited
  *
  * This library is free software; you can redistribute it and/or
  * modify it either under the terms of the GNU Lesser General Public
@@ -36,6 +37,7 @@ 
  *	Carl Worth <cworth@cworth.org>
  *	Chris Wilson <chris@chris-wilson.co.uk>
  *	Eric Anholt <eric@anholt.net>
+ *	Alexandros Frantzis <alexandros.frantzis@linaro.org>
  */
 
 #include "cairoint.h"
@@ -516,6 +518,7 @@  _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
                                  unsigned int        vertex_size,
                                  unsigned int        vertex_offset)
 {
+    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
     cairo_bool_t needs_setup;
 
     /* XXX: we need to do setup when switching from shaders
@@ -543,9 +546,10 @@  _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
     case CAIRO_GL_OPERAND_NONE:
         break;
     case CAIRO_GL_OPERAND_SPANS:
-	glColorPointer (4, GL_UNSIGNED_BYTE, vertex_size,
-                        (void *) (uintptr_t) vertex_offset);
-	glEnableClientState (GL_COLOR_ARRAY);
+	dispatch->VertexAttribPointer (CAIRO_GL_COLOR_ATTRIB_INDEX, 4,
+				       GL_UNSIGNED_BYTE, GL_TRUE, vertex_size,
+				       (void *) (uintptr_t) vertex_offset);
+	dispatch->EnableVertexAttribArray (CAIRO_GL_COLOR_ATTRIB_INDEX);
         /* fall through */
     case CAIRO_GL_OPERAND_CONSTANT:
         break;
@@ -557,10 +561,10 @@  _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
         _cairo_gl_texture_set_filter (ctx, ctx->tex_target,
                                       operand->texture.attributes.filter);
 
-	glClientActiveTexture (GL_TEXTURE0 + tex_unit);
-	glTexCoordPointer (2, GL_FLOAT, vertex_size,
-                           (void *) (uintptr_t) vertex_offset);
-	glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+	dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
+					GL_FLOAT, GL_FALSE, vertex_size,
+					(void *) (uintptr_t) 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:
@@ -572,10 +576,10 @@  _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
         _cairo_gl_texture_set_extend (ctx, GL_TEXTURE_1D, operand->gradient.extend);
         _cairo_gl_texture_set_filter (ctx, GL_TEXTURE_1D, CAIRO_FILTER_BILINEAR);
 
-	glClientActiveTexture (GL_TEXTURE0 + tex_unit);
-	glTexCoordPointer (2, GL_FLOAT, vertex_size,
-                           (void *) (uintptr_t) vertex_offset);
-	glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+	dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
+				       GL_FLOAT, GL_FALSE, vertex_size,
+				       (void *) (uintptr_t) vertex_offset);
+	dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
 	break;
     }
 }
@@ -584,6 +588,7 @@  void
 _cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx,
                                    cairo_gl_tex_t tex_unit)
 {
+    cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
     assert (_cairo_gl_context_is_flushed (ctx));
 
     switch (ctx->operands[tex_unit].type) {
@@ -593,23 +598,19 @@  _cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx,
     case CAIRO_GL_OPERAND_NONE:
         break;
     case CAIRO_GL_OPERAND_SPANS:
-        glDisableClientState (GL_COLOR_ARRAY);
+        dispatch->DisableVertexAttribArray (CAIRO_GL_COLOR_ATTRIB_INDEX);
         /* fall through */
     case CAIRO_GL_OPERAND_CONSTANT:
         break;
     case CAIRO_GL_OPERAND_TEXTURE:
-        glActiveTexture (GL_TEXTURE0 + tex_unit);
-        glClientActiveTexture (GL_TEXTURE0 + tex_unit);
-        glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+        dispatch->DisableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
         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:
         _cairo_gl_gradient_destroy (ctx->operands[tex_unit].gradient.gradient);
-        glActiveTexture (GL_TEXTURE0 + tex_unit);
-        glClientActiveTexture (GL_TEXTURE0 + tex_unit);
-        glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+        dispatch->DisableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
         break;
     }
 
@@ -862,8 +863,9 @@  _cairo_gl_composite_begin (cairo_gl_composite_t *setup,
     if (_cairo_gl_context_is_flushed (ctx)) {
         ctx->dispatch.BindBuffer (GL_ARRAY_BUFFER, ctx->vbo);
 
-        glVertexPointer (2, GL_FLOAT, vertex_size, NULL);
-        glEnableClientState (GL_VERTEX_ARRAY);
+	ctx->dispatch.VertexAttribPointer (CAIRO_GL_VERTEX_ATTRIB_INDEX, 2,
+					   GL_FLOAT, GL_FALSE, vertex_size, NULL);
+	ctx->dispatch.EnableVertexAttribArray (CAIRO_GL_VERTEX_ATTRIB_INDEX);
     }
 
     _cairo_gl_context_setup_operand (ctx, CAIRO_GL_TEX_SOURCE, &setup->src, vertex_size, dst_size);
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index fd1af87..475f14a 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -3,6 +3,7 @@ 
  * Copyright © 2009 Eric Anholt
  * Copyright © 2009 Chris Wilson
  * Copyright © 2005,2010 Red Hat, Inc
+ * Copyright © 2011 Linaro Limited
  *
  * This library is free software; you can redistribute it and/or
  * modify it either under the terms of the GNU Lesser General Public
@@ -37,6 +38,7 @@ 
  *	Chris Wilson <chris@chris-wilson.co.uk>
  *	Eric Anholt <eric@anholt.net>
  *	T. Zachary Laine <whatwasthataddress@gmail.com>
+ *	Alexandros Frantzis <alexandros.frantzis@linaro.org>
  */
 
 #ifndef CAIRO_GL_PRIVATE_H
@@ -84,6 +86,14 @@ 
 /* VBO size that we allocate, smaller size means we gotta flush more often */
 #define CAIRO_GL_VBO_SIZE 16384
 
+/* Indices for vertex attributes used by BindAttribLocation etc */
+enum {
+    CAIRO_GL_VERTEX_ATTRIB_INDEX = 0,
+    CAIRO_GL_COLOR_ATTRIB_INDEX  = 1,
+    CAIRO_GL_TEXCOORD0_ATTRIB_INDEX = 2,
+    CAIRO_GL_TEXCOORD1_ATTRIB_INDEX = CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + 1
+};
+
 typedef struct _cairo_gl_surface {
     cairo_surface_t base;
 
diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c
index 6a3a606..a17491e 100644
--- a/src/cairo-gl-shaders.c
+++ b/src/cairo-gl-shaders.c
@@ -163,6 +163,16 @@  link_shader_core_2_0 (cairo_gl_context_t *ctx, GLuint *program,
     *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) {
@@ -492,12 +502,12 @@  cairo_gl_shader_emit_vertex (cairo_output_stream_t *stream,
         break;
     case CAIRO_GL_VAR_TEXCOORDS:
         _cairo_output_stream_printf (stream, 
-                                     "    %s_texcoords = gl_MultiTexCoord%d.xy;\n",
+                                     "    %s_texcoords = MultiTexCoord%d.xy;\n",
                                      operand_names[name], name);
         break;
     case CAIRO_GL_VAR_COVERAGE:
         _cairo_output_stream_printf (stream, 
-                                     "    %s_coverage = gl_Color.a;\n",
+                                     "    %s_coverage = Color.a;\n",
                                      operand_names[name]);
         break;
     }
@@ -518,10 +528,14 @@  cairo_gl_shader_get_vertex_source (cairo_gl_var_type_t src,
     cairo_gl_shader_emit_variable (stream, mask, CAIRO_GL_TEX_MASK);
 
     _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"
-				 "    gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n");
+				 "    gl_Position = ModelViewProjectionMatrix * Vertex;\n");
 
     cairo_gl_shader_emit_vertex (stream, src, CAIRO_GL_TEX_SOURCE);
     cairo_gl_shader_emit_vertex (stream, mask, CAIRO_GL_TEX_MASK);