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/src/GrGLUtil.cpp b/gpu/src/GrGLUtil.cpp
new file mode 100644
index 0000000..f961194
--- /dev/null
+++ b/gpu/src/GrGLUtil.cpp
@@ -0,0 +1,256 @@
+/*

+ Copyright 2010 Google Inc.

+

+ Licensed under the Apache License, Version 2.0 (the "License");

+ you may not use this file except in compliance with the License.

+ You may obtain a copy of the License at

+

+ http://www.apache.org/licenses/LICENSE-2.0

+

+ Unless required by applicable law or agreed to in writing, software

+ distributed under the License is distributed on an "AS IS" BASIS,

+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ See the License for the specific language governing permissions and

+ limitations under the License.

+ */

+

+#include "GrGLConfig.h"

+#include <stdio.h>

+

+bool has_gl_extension(const char* ext) {

+    const char* glstr = (const char*) glGetString(GL_EXTENSIONS);

+

+    int extLength = strlen(ext);

+

+    while (true) {

+        int n = strcspn(glstr, " ");

+        if (n == extLength && 0 == strncmp(ext, glstr, n)) {

+            return true;

+        }

+        if (0 == glstr[n]) {

+            return false;

+        }

+        glstr += n+1;

+    }

+}

+

+void gl_version(int* major, int* minor) {

+    const char* v = (const char*) glGetString(GL_VERSION);

+    if (NULL == v) {

+        GrAssert(0);

+        *major = 0;

+        *minor = 0;

+        return;

+    }

+#if GR_SUPPORT_GLDESKTOP

+    int n = sscanf(v, "%d.%d", major, minor);

+    if (n != 2) {

+        GrAssert(0);

+        *major = 0;

+        *minor = 0;

+        return;

+    }

+#else

+    char profile[2];

+    int n = sscanf(v, "OpenGL ES-%c%c %d.%d", profile, profile+1, major, minor);

+    bool ok = 4 == n;

+    if (!ok) {

+        int n = sscanf(v, "OpenGL ES %d.%d", major, minor);

+        ok = 2 == n;

+    }

+    if (!ok) {

+        GrAssert(0);

+        *major = 0;

+        *minor = 0;

+        return;

+    }

+#endif

+}

+

+#if defined(GR_GL_PROC_ADDRESS_HEADER)

+    #include GR_GL_PROC_ADDRESS_HEADER

+#endif

+

+typedef void (*glProc)(void);

+

+#define GET_PROC(EXT_STRUCT, PROC_NAME) \

+    *((glProc*) &(EXT_STRUCT-> PROC_NAME)) = (glProc) GR_GL_PROC_ADDRESS((gl ## PROC_NAME)); \

+    GrAssert(NULL != EXT_STRUCT-> PROC_NAME)

+

+#define GET_SUFFIX_PROC(EXT_STRUCT, PROC_NAME, SUFFIX) \

+    *((glProc*) &(EXT_STRUCT-> PROC_NAME)) = (glProc) GR_GL_PROC_ADDRESS((gl ## PROC_NAME ## SUFFIX)); \

+    GrAssert(NULL != EXT_STRUCT-> PROC_NAME)

+

+extern void GrGLInitExtensions(GrGLExts* exts) {

+    exts->GenFramebuffers                   = NULL;

+    exts->BindFramebuffer                   = NULL;

+    exts->FramebufferTexture2D              = NULL;

+    exts->CheckFramebufferStatus            = NULL;

+    exts->DeleteFramebuffers                = NULL;

+    exts->RenderbufferStorage               = NULL;

+    exts->GenRenderbuffers                  = NULL;

+    exts->DeleteRenderbuffers               = NULL;

+    exts->FramebufferRenderbuffer           = NULL;

+    exts->BindRenderbuffer                  = NULL;

+    exts->RenderbufferStorageMultisample    = NULL;

+    exts->BlitFramebuffer                   = NULL;

+    exts->ResolveMultisampleFramebuffer     = NULL;

+    exts->FramebufferTexture2DMultisample   = NULL;

+    exts->MapBuffer                         = NULL;

+    exts->UnmapBuffer                       = NULL;

+

+    GLint major, minor;

+    gl_version(&major, &minor);

+#if GR_SUPPORT_GLDESKTOP

+

+    bool fboFound = false;

+    #if GL_VERSION_3_0

+    if (!fboFound && major >= 3) { // all of ARB_fbo is in 3.x

+        exts->GenFramebuffers                   = glGenFramebuffers;

+        exts->BindFramebuffer                   = glBindFramebuffer;

+        exts->FramebufferTexture2D              = glFramebufferTexture2D;

+        exts->CheckFramebufferStatus            = glCheckFramebufferStatus;

+        exts->DeleteFramebuffers                = glDeleteFramebuffers;

+        exts->RenderbufferStorage               = glRenderbufferStorage;

+        exts->GenRenderbuffers                  = glGenRenderbuffers;

+        exts->DeleteRenderbuffers               = glDeleteRenderbuffers;

+        exts->FramebufferRenderbuffer           = glFramebufferRenderbuffer;

+        exts->BindRenderbuffer                  = glBindRenderbuffer;

+        exts->RenderbufferStorageMultisample    = glRenderbufferStorageMultisample;

+        exts->BlitFramebuffer                   = glBlitFramebuffer;

+        fboFound = true;

+    }

+    #endif

+    #if GL_ARB_framebuffer_object

+    if (!fboFound && has_gl_extension("GL_ARB_framebuffer_object")) {

+        // GL_ARB_framebuffer_object doesn't use ARB suffix.

+        GET_PROC(exts, GenFramebuffers);

+        GET_PROC(exts, BindFramebuffer);

+        GET_PROC(exts, FramebufferTexture2D);

+        GET_PROC(exts, CheckFramebufferStatus);

+        GET_PROC(exts, DeleteFramebuffers);

+        GET_PROC(exts, RenderbufferStorage);

+        GET_PROC(exts, GenRenderbuffers);

+        GET_PROC(exts, DeleteRenderbuffers);

+        GET_PROC(exts, FramebufferRenderbuffer);

+        GET_PROC(exts, BindRenderbuffer);

+        GET_PROC(exts, RenderbufferStorageMultisample);

+        GET_PROC(exts, BlitFramebuffer);

+        fboFound = true;

+    }

+    #endif

+    // Mac doesn't declare prototypes for EXT FBO extensions

+    #if GL_EXT_framebuffer_object && !GR_MAC_BUILD

+    if (!fboFound && has_gl_extension("GL_EXT_framebuffer_object")) {

+        GET_SUFFIX_PROC(exts, GenFramebuffers, EXT);

+        GET_SUFFIX_PROC(exts, BindFramebuffer, EXT);

+        GET_SUFFIX_PROC(exts, FramebufferTexture2D, EXT);

+        GET_SUFFIX_PROC(exts, CheckFramebufferStatus, EXT);

+        GET_SUFFIX_PROC(exts, DeleteFramebuffers, EXT);

+        GET_SUFFIX_PROC(exts, RenderbufferStorage, EXT);

+        GET_SUFFIX_PROC(exts, GenRenderbuffers, EXT);

+        GET_SUFFIX_PROC(exts, DeleteRenderbuffers, EXT);

+        GET_SUFFIX_PROC(exts, FramebufferRenderbuffer, EXT);

+        GET_SUFFIX_PROC(exts, BindRenderbuffer, EXT);

+        fboFound = true;

+        // check for fbo ms and fbo blit

+        #if GL_EXT_framebuffer_multisample

+        if (has_gl_extension("GL_EXT_framebuffer_multisample")) {

+            GET_SUFFIX_PROC(exts, RenderbufferStorageMultisample, EXT);

+        }

+        #endif

+        #if GL_EXT_framebuffer_blit

+        if (has_gl_extension("GL_EXT_framebuffer_blit")) {

+            GET_SUFFIX_PROC(exts, BlitFramebuffer, EXT);

+        }

+        #endif

+    }

+    #endif

+    if (!fboFound) {

+        // we require some form of FBO

+        GrAssert(!"No FBOs supported?");

+    }

+    // we assume we have at least GL 1.5 or higher (VBOs introduced in 1.5)

+    exts->MapBuffer     = glMapBuffer;

+    exts->UnmapBuffer   = glUnmapBuffer;

+#else // !GR_SUPPORT_GLDESKTOP

+    bool foundFBO = false;

+    #if GR_SUPPORT_GLES2

+    if (!fboFound && major >= 2) {// ES 2.0 supports FBO

+        exts->GenFramebuffers                   = glGenFramebuffers;

+        exts->BindFramebuffer                   = glBindFramebuffer;

+        exts->FramebufferTexture2D              = glFramebufferTexture2D;

+        exts->CheckFramebufferStatus            = glCheckFramebufferStatus;

+        exts->DeleteFramebuffers                = glDeleteFramebuffers;

+        exts->RenderbufferStorage               = glRenderbufferStorage;

+        exts->GenRenderbuffers                  = glGenRenderbuffers;

+        exts->DeleteRenderbuffers               = glDeleteRenderbuffers;

+        exts->FramebufferRenderbuffer           = glFramebufferRenderbuffer;

+        exts->BindRenderbuffer                  = glBindRenderbuffer;

+        fboFound = true;

+    }

+    #endif

+    #if !GL_OES_framebuffer_object

+    if (!fboFound && has_gl_extension("GL_OES_framebuffer_object")) {

+        GET_SUFFIX_PROC(exts, GenFramebuffers, OES);

+        GET_SUFFIX_PROC(exts, BindFramebuffer, OES);

+        GET_SUFFIX_PROC(exts, FramebufferTexture2D, OES);

+        GET_SUFFIX_PROC(exts, CheckFramebufferStatus, OES);

+        GET_SUFFIX_PROC(exts, DeleteFramebuffers, OES);

+        GET_SUFFIX_PROC(exts, RenderbufferStorage, OES);

+        GET_SUFFIX_PROC(exts, GenRenderbuffers, OES);

+        GET_SUFFIX_PROC(exts, DeleteRenderbuffers, OES);

+        GET_SUFFIX_PROC(exts, FramebufferRenderbuffer, OES);

+        GET_SUFFIX_PROC(exts, BindRenderbuffer, OES);

+    }

+    #endif

+

+    if (!fboFound) {

+        // we require some form of FBO

+        GrAssert(!"No FBOs supported?");

+    }

+

+    #if GL_APPLE_framebuffer_multisample

+    if (has_gl_extension("GL_APPLE_framebuffer_multisample")) {

+        GET_SUFFIX_PROC(exts, ResolveMultisampleFramebuffer, APPLE);

+    }

+    #endif

+

+    #if GL_IMG_multisampled_render_to_texture

+    if (has_gl_extension("GL_IMG_multisampled_render_to_texture")) {

+        GET_SUFFIX_PROC(exts, FramebufferTexture2DMultisample, IMG);

+    }

+    #endif

+

+    #if GL_OES_mapbuffer

+    if (has_gl_extension("GL_OES_mapbuffer")) {

+        GET_SUFFIX_PROC(exts, MapBuffer, OES);

+        GET_SUFFIX_PROC(exts, UnmapBuffer, OES);

+    }

+    #endif

+#endif // !GR_SUPPORT_GLDESKTOP

+}

+

+
+///////////////////////////////////////////////////////////////////////////////
+
+void GrGLCheckErr(const char* location, const char* call) {
+    uint32_t err =  glGetError();
+    if (GL_NO_ERROR != err) {
+        GrPrintf("---- glGetError %x", err);
+        if (NULL != location) {
+            GrPrintf(" at\n\t%s", location);
+        }
+        if (NULL != call) {
+            GrPrintf("\n\t\t%s", call);
+        }
+        GrPrintf("\n");
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool gPrintGL = true;
+
+
+