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;
+
+
+