Cleanup including of GL headers and provide way to include custom headers, extension getter.

git-svn-id: http://skia.googlecode.com/svn/trunk@713 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrGLConfig.h b/gpu/include/GrGLConfig.h
index 0d18db1..5c23495 100644
--- a/gpu/include/GrGLConfig.h
+++ b/gpu/include/GrGLConfig.h
@@ -20,146 +20,166 @@
 
 #include "GrTypes.h"
 
-#if GR_CHROME_BUILD // temporary build-flag, orthogonal to mac/win/linux
-    #define GR_INCLUDE_GLES2        <GLES2/gl2.h>
-    #define GR_INCLUDE_GLES2ext     <GLES2/gl2ext.h>
-    #define GR_GL_FUNC
-#elif GR_WIN32_BUILD
-    // glew has to be included before gl
-    #define GR_INCLUDE_GLDESKTOP    <GL/glew.h>
-    #define GR_INCLUDE_GLDESKTOPext <GL/gl.h>
-    #define GR_GL_FUNC __stdcall
-    // undo stupid windows defines
-    #undef near
-    #undef far
-#elif GR_MAC_BUILD
-    #define GR_INCLUDE_GLDESKTOP    <OpenGL/gl.h>
-    #define GR_INCLUDE_GLDESKTOPext <OpenGL/glext.h>
-    #define GR_GL_FUNC
-#elif GR_IOS_BUILD
-    #define GR_INCLUDE_GLES1       <OpenGLES/ES1/gl.h>
-    #define GR_INCLUDE_GLES1ext    <OpenGLES/ES1/glext.h>
-    #define GR_INCLUDE_GLES2       <OpenGLES/ES2/gl.h>
-    #define GR_INCLUDE_GLES2ext    <OpenGLES/ES2/glext.h>
-    #define GR_GL_FUNC
-#elif GR_ANDROID_BUILD
-    #ifndef GL_GLEXT_PROTOTYPES
-        #define GL_GLEXT_PROTOTYPES
+#if !defined(GR_GL_CUSTOM_SETUP)
+    #define GR_GL_CUSTOM_SETUP 0
+#endif
+/**
+ * We need to pull in the right GL headers and determine whether we are
+ * compiling for ES1, ES2, or desktop GL. (We allow ES1 and ES2 to both be
+ * supported in the same build but not ESx and desktop). We also need to know
+ * the platform-specific way to get extension function pointers (e.g.
+ * eglGetProcAddress). The port specifies this info explicitly or we will infer
+ * it from the GR_*_BUILD flag.
+ *
+ * To specify GL setup directly define GR_GL_CUSTOM_SETUP to 1 and define:
+ *      GR_SUPPORT_GLDESKTOP or (GR_SUPPORT_GLES1 and/or GR_SUPPORT_GLES2) to 1
+ *
+ *      if GR_SUPPORT_GLDESKTOP is 1 then provide:
+ *          1. The name of your GL header in GR_INCLUDE_GLDESKTOP
+ *          2. If necessary, the name of a file that includes extension
+ *             definitions in GR_INCLUDE_GLDESKTOPext.
+ *      if GR_SUPPORT_GLES1 is 1 then provide:
+ *          1. The name of your GL header in GR_INCLUDE_GLES1
+ *          2. If necessary, the name of a file that includes extension
+ *             definitions in GR_INCLUDE_GLES1ext.
+ *      if GR_SUPPORT_GLES2 is 1 then provide:
+ *          1. The name of your GL header in GR_INCLUDE_GLES2
+ *          2. If necessary, the name of a file that includes extension
+ *             definitions in GR_INCLUDE_GLES2ext.
+ *
+ *      Optionally, define GR_GL_FUNC to any qualifier needed on GL function
+ *      pointer declarations (e.g. __stdcall).
+ *
+ *      Define GR_GL_PROC_ADDRESS to take a gl function and produce a
+ *      function pointer. Two examples:
+ *          1. Your platform doesn't require a proc address function, just take
+ *             the address of the function:
+ *             #define GR_GL_PROC_ADDRESS(X) &X
+ *          2. Your platform uses eglGetProcAddress:
+ *             #define GR_GL_PROC_ADDRESS eglGetProcAddress(#X)
+ *
+ *     Optionally define GR_GL_PROC_ADDRESS_HEADER to include any additional
+ *     header necessary to use GR_GL_PROC_ADDRESS (e.g. <EGL/egl.h>)
+ *
+ * Alternatively, define GR_GL_CUSTOM_SETUP_HEADER (and not GR_GL_CUSTOM_SETUP)
+ * to a header that can be included. This file should:
+ *      1. Define the approprate GR_SUPPORT_GL* macro(s) to 1
+ *      2. Includes all necessary GL headers.
+ *      3. Optionally define GR_GL_FUNC.
+ *      4. Define GR_GL_PROC_ADDRESS.
+ *      5. Optionally define GR_GL_PROC_ADDRESS_HEADER
+ */
+
+#if GR_GL_CUSTOM_SETUP
+
+    #ifdef GR_SUPPORT_GLES1
+        #include GR_INCLUDE_GLES1
+        #if defined(GR_INCLUDE_GLES1ext)
+            #include GR_INCLUDE_GLES1ext
+        #endif
     #endif
-    #define GR_INCLUDE_GLES2        <GLES2/gl2.h>
-    #define GR_INCLUDE_GLES2ext     <GLES2/gl2ext.h>
-    #define GR_GL_FUNC
-#elif GR_LINUX_BUILD
-    // need to distinguish between ES and Deskop versions for linux
-    #ifndef GL_GLEXT_PROTOTYPES
-        #define GL_GLEXT_PROTOTYPES
+
+    #ifdef GR_SUPPORT_GLES2
+        #include GR_INCLUDE_GLES2
+        #if defined(GR_INCLUDE_GLES2ext)
+            #include GR_INCLUDE_GLES2ext
+        #endif
     #endif
-    #define GR_INCLUDE_GLDESKTOP    <GL/gl.h>
-    #define GR_INCLUDE_GLDESKTOPext <GL/glext.h>
-//    #define GR_INCLUDE_GLES1        <GLES/gl.h>
-//    #define GR_INCLUDE_GLES1ext     <GLES/glext.h>
-//    #define GR_INCLUDE_GLES2        <GLES2/gl2.h>
-//    #define GR_INCLUDE_GLES2ext     <GLES2/gl2ext.h>
-    #define GR_GL_FUNC
-#elif GR_QNX_BUILD
-    #ifndef GL_GLEXT_PROTOTYPES
-        #define GL_GLEXT_PROTOTYPES
+
+    #ifdef GR_SUPPORT_GLDESKTOP
+        #include GR_INCLUDE_GLDESKTOP
+        #if defined(GR_INCLUDE_GLDESKTOPext)
+            #include GR_INCLUDE_GLDESKTOPext
+        #endif
     #endif
-    // This is needed by the QNX GLES2 headers
-    #define GL_API_EXT
-    #define GR_INCLUDE_GLES2        <GLES2/gl2.h>
-    #define GR_INCLUDE_GLES2ext     <GLES2/gl2ext.h>
-    #define GR_INCLUDE_EGL          <EGL/egl.h>
-    #define GR_GL_FUNC
+
+#elif defined(GR_GL_CUSTOM_SETUP_HEADER)
+
+    #include GR_GL_CUSTOM_SETUP_HEADER
+
 #else
-    #error "unsupported GR_???_BUILD"
-#endif
 
-// Ensure we're at least defined
-//
-
-#ifndef GR_SUPPORT_GLES1
-    #if defined(GR_INCLUDE_GLES1)
-        #define GR_SUPPORT_GLES1        1
+    #if GR_WIN32_BUILD
+        #define GR_SUPPORT_GLDESKTOP        1
+        // glew has to be included before gl
+        #include <GL/glew.h>
+        #include <GL/gl.h>
+        // remove stupid windows defines
+        #undef near
+        #undef far
+        #define GR_GL_FUNC __stdcall
+        #define GR_GL_PROC_ADDRESS(X)       wglGetProcAddress(#X)
+        #define GR_GL_PROC_ADDRESS_HEADER   <windows.h>
+    #elif GR_MAC_BUILD
+        #define GR_SUPPORT_GLDESKTOP        1
+        #include <OpenGL/gl.h>
+        #include <OpenGL/glext.h>
+        #define GR_GL_PROC_ADDRESS(X)       &X
+    #elif GR_IOS_BUILD
+        #define GR_SUPPORT_GLES1            1
+        #include <OpenGLES/ES1/gl.h>
+        #include <OpenGLES/ES1/glext.h>
+        #define GR_SUPPORT_GLES2            1
+        #include <OpenGLES/ES2/gl.h>
+        #include <OpenGLES/ES2/glext.h>
+        #define GR_GL_PROC_ADDRESS(X)       &X
+    #elif GR_ANDROID_BUILD
+        #ifndef GL_GLEXT_PROTOTYPES
+            #define GL_GLEXT_PROTOTYPES
+        #endif
+        #define GR_SUPPORT_GLES2            1
+        #include <GLES2/gl2.h>
+        #include <GLES2/gl2ext.h>
+        #define GR_GL_PROC_ADDRESS(X)       eglGetProcAddress(#X)
+        #define GR_GL_PROC_ADDRESS_HEADER   <EGL/egl.h>
+    #elif GR_QNX_BUILD
+        #ifndef GL_GLEXT_PROTOTYPES
+            #define GL_GLEXT_PROTOTYPES
+        #endif
+         #define GR_SUPPORT_GLES2           1
+        // This is needed by the QNX GLES2 headers
+        #define GL_API_EXT
+        #include <GLES2/gl2.h>
+        #include <GLES2/gl2ext.h>
+        #define GR_GL_PROC_ADDRESS(X)       eglGetProcAddress(#X)
+        #define GR_GL_PROC_ADDRESS_HEADER   <EGL/egl.h>
+    #elif GR_LINUX_BUILD
+        #define GR_SUPPORT_GLDESKTOP        1
+        #include <GL/gl.h>
+        #include <GL/glext.h>
+        #define GR_GL_PROC_ADDRESS(X)       eglGetProcAddress(#X)
+        #define GR_GL_PROC_ADDRESS_HEADER   <EGL/egl.h>
     #else
-        #define GR_SUPPORT_GLES1        0
+        #error "unsupported GR_???_BUILD"
     #endif
+
 #endif
 
-#ifndef GR_SUPPORT_GLES2
-    #if defined(GR_INCLUDE_GLES2)
-        #define GR_SUPPORT_GLES2        1
-    #else
-        #define GR_SUPPORT_GLES2        0
-    #endif
+#if !defined(GR_SUPPORT_GLDESKTOP)
+    #define GR_SUPPORT_GLDESKTOP    0
+#endif
+#if !defined(GR_SUPPORT_GLES1)
+    #define GR_SUPPORT_GLES1        0
+#endif
+#if !defined(GR_SUPPORT_GLES2)
+    #define GR_SUPPORT_GLES2        0
 #endif
 
-#define GR_SUPPORT_GLES (GR_SUPPORT_GLES1 || GR_SUPPORT_GLES2)
+#define GR_SUPPORT_GLES ((GR_SUPPORT_GLES1) || (GR_SUPPORT_GLES2))
 
-#ifndef GR_SUPPORT_GLDESKTOP
-    #if defined(GR_INCLUDE_GLDESKTOP)
-        #define GR_SUPPORT_GLDESKTOP    1
-    #else
-        #define GR_SUPPORT_GLDESKTOP    0
-    #endif
+#if !(GR_SUPPORT_GLES) != !(GR_SUPPORT_DESKTOP)
+    #error "Either desktop of ES GL must be supported but not both"
 #endif
 
-#ifndef GR_SUPPORT_EGL
-    #if defined(GR_INCLUDE_EGL)
-        #define GR_SUPPORT_EGL          1
-    #else
-        #define GR_SUPPORT_EGL          0
-    #endif
-#endif
-// Filter the includes based on what we support
-//
-
-#if !GR_SUPPORT_GLES1
-    #undef GR_INCLUDE_GLES1
-    #undef GR_INCLUDE_GLES1ext
+#if !defined(GR_GL_FUNC)
+    #define GR_GL_FUNC
 #endif
 
-#if !GR_SUPPORT_GLES2
-    #undef GR_INCLUDE_GLES2
-    #undef GR_INCLUDE_GLES2ext
+#if !defined(GR_GL_PROC_ADDRESS)
+    #error "Must define GR_GL_PROC_ADDRESS"
 #endif
 
-#if !GR_SUPPORT_GLDESKTOP
-    #undef GR_INCLUDE_GLDESKTOP
-    #undef GR_INCLUDE_GLDESKTOPext
-#endif
-
-#if !GR_SUPPORT_EGL
-    #undef GR_INCLUDE_EGL
-#endif
-
-// Begin including GL headers
-//
-
-#ifdef GR_INCLUDE_GLES1
-    #include GR_INCLUDE_GLES1
-#endif
-#ifdef GR_INCLUDE_GLES1ext
-    #include GR_INCLUDE_GLES1ext
-#endif
-#ifdef GR_INCLUDE_GLES2
-    #include GR_INCLUDE_GLES2
-#endif
-#ifdef GR_INCLUDE_GLES2ext
-    #include GR_INCLUDE_GLES2ext
-#endif
-#ifdef GR_INCLUDE_GLDESKTOP
-    #include GR_INCLUDE_GLDESKTOP
-#endif
-#ifdef GR_INCLUDE_GLDESKTOPext
-    #include GR_INCLUDE_GLDESKTOPext
-#endif
-#ifdef GR_INCLUDE_EGL
-    #include GR_INCLUDE_EGL
-#endif
-
-//
-// End including GL headers
+////////////////////////////////////////////////////////////////////////////////
 
 #if GR_SCALAR_IS_FIXED
     #define GrGLType   GL_FIXED
@@ -193,8 +213,8 @@
 #endif
 
 ////////////////////////////////////////////////////////////////////////////////
-// setup for opengl ES/desktop extensions
-// we make a struct of function pointers so that each GL context
+// Setup for opengl ES/desktop extensions
+// We make a struct of function pointers so that each GL context
 // can have it's own struct. (Some environments may have different proc
 // addresses for different contexts).
 
@@ -289,6 +309,7 @@
 #define GR_PALETTE8_RGBA8           0x8B91
 
 extern void GrGLInitExtensions(GrGLExts* exts);
+
 ////////////////////////////////////////////////////////////////////////////////
 
 extern void GrGLCheckErr(const char* location, const char* call);