Always get proc address for gl functions on the mac.
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 7 Mar 2013 22:23:35 +0000 (22:23 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 7 Mar 2013 22:23:35 +0000 (22:23 +0000)
Review URL: https://codereview.chromium.org/12628004

git-svn-id: http://skia.googlecode.com/svn/trunk@8032 2bbb7eff-a529-9590-31e7-b0007b416f81

src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp

index 379d0c16e6d7eb92faf895ae660609037d68cea0..a26601fe5d0d806db2597dc9ff9f877417639170 100644 (file)
 #include "gl/GrGLExtensions.h"
 #include "../GrGLUtil.h"
 
-#include <OpenGL/gl.h>
-#include <OpenGL/glext.h>
-
 #include <dlfcn.h>
 
+// We get the proc addresss of all GL functions dynamically because we sometimes link against
+// alternative GL implementations (e.g. MESA) in addition to the native GL implementation.
+class GLLoader {
+public:
+    GLLoader() {
+        fLibrary = dlopen(
+                    "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib",
+                    RTLD_LAZY);
+    }
+    ~GLLoader() {
+        if (NULL != fLibrary) {
+            dlclose(fLibrary);
+        }
+    }
+    void* handle() {
+        return NULL == fLibrary ? RTLD_DEFAULT : fLibrary;
+    }
+private:
+    void* fLibrary;
+};
+
 static void* GetProcAddress(const char* name) {
-    return dlsym(RTLD_DEFAULT, name);
+    static GLLoader gLoader;
+    return dlsym(gLoader.handle(), name);
 }
 
 #define GET_PROC(name) (interface->f ## name = ((GrGL ## name ## Proc) GetProcAddress("gl" #name)))
 #define GET_PROC_SUFFIX(name, suffix) (interface->f ## name = ((GrGL ## name ## Proc) GetProcAddress("gl" #name #suffix)))
 
 const GrGLInterface* GrGLCreateNativeInterface() {
-    // The gl functions are not context-specific so we create one global
-    // interface
+    // The gl functions are not context-specific so we create one global interface
     static SkAutoTUnref<GrGLInterface> glInterface;
     if (!glInterface.get()) {
         GrGLInterface* interface = new GrGLInterface;
+        
+        GrGLGetStringProc glGetString = (GrGLGetStringProc) GetProcAddress("glGetString");
+        GrGLGetStringiProc glGetStringi = (GrGLGetStringiProc) GetProcAddress("glGetStringi");
+        GrGLGetIntegervProc glGetIntegerv = (GrGLGetIntegervProc) GetProcAddress("glGetIntegerv");
+
         glInterface.reset(interface);
-        const char* verStr = (const char*) glGetString(GL_VERSION);
+        const char* verStr = (const char*) glGetString(GR_GL_VERSION);
         GrGLVersion ver = GrGLGetVersionFromString(verStr);
         GrGLExtensions extensions;
-        GrGLGetStringiProc glGetStringi = (GrGLGetStringiProc) GetProcAddress("glGetStringi");
         if (!extensions.init(kDesktop_GrGLBinding, glGetString, glGetStringi, glGetIntegerv)) {
             glInterface.reset(NULL);
             return NULL;
         }
         interface->fBindingsExported = kDesktop_GrGLBinding;
-        interface->fActiveTexture = glActiveTexture;
-        interface->fAttachShader = glAttachShader;
-        interface->fBeginQuery = glBeginQuery;
-        interface->fBindAttribLocation = glBindAttribLocation;
-        interface->fBindBuffer = glBindBuffer;
+        
+        GET_PROC(ActiveTexture);
+        GET_PROC(AttachShader);
+        GET_PROC(BeginQuery);
+        GET_PROC(BindAttribLocation);
+        GET_PROC(BindBuffer);
         if (ver >= GR_GL_VER(3,0)) {
-#if GL_VERSION_3_0
-            interface->fBindFragDataLocation = glBindFragDataLocation;
-#else
             GET_PROC(BindFragDataLocation);
-#endif
         }
-        interface->fBindTexture = glBindTexture;
-        interface->fBlendFunc = glBlendFunc;
+        GET_PROC(BindTexture);
+        GET_PROC(BlendFunc);
 
-        if (ver >= GR_GL_VER(1,4)) {
-            interface->fBlendColor = glBlendColor;
-        } else if (extensions.has("GL_ARB_imaging") ||
-                   extensions.has("GL_EXT_blend_color")) {
+        if (ver >= GR_GL_VER(1,4) ||
+            extensions.has("GL_ARB_imaging") ||
+            extensions.has("GL_EXT_blend_color")) {
             GET_PROC(BlendColor);
         }
 
-        interface->fBufferData = glBufferData;
-        interface->fBufferSubData = glBufferSubData;
-        interface->fClear = glClear;
-        interface->fClearColor = glClearColor;
-        interface->fClearStencil = glClearStencil;
-        interface->fColorMask = glColorMask;
-        interface->fCompileShader = glCompileShader;
-        interface->fCompressedTexImage2D = glCompressedTexImage2D;
-        interface->fCreateProgram = glCreateProgram;
-        interface->fCreateShader = glCreateShader;
-        interface->fCullFace = glCullFace;
-        interface->fDeleteBuffers = glDeleteBuffers;
-        interface->fDeleteProgram = glDeleteProgram;
-        interface->fDeleteQueries = glDeleteQueries;
-        interface->fDeleteShader = glDeleteShader;
-        interface->fDeleteTextures = glDeleteTextures;
-        interface->fDepthMask = glDepthMask;
-        interface->fDisable = glDisable;
-        interface->fDisableVertexAttribArray = glDisableVertexAttribArray;
-        interface->fDrawArrays = glDrawArrays;
-        interface->fDrawBuffer = glDrawBuffer;
-        interface->fDrawBuffers = glDrawBuffers;
-        interface->fDrawElements = glDrawElements;
-        interface->fEnable = glEnable;
-        interface->fEnableVertexAttribArray = glEnableVertexAttribArray;
-        interface->fEndQuery = glEndQuery;
-        interface->fFinish = glFinish;
-        interface->fFlush = glFlush;
-        interface->fFrontFace = glFrontFace;
-        interface->fGenBuffers = glGenBuffers;
-        interface->fGenQueries = glGenQueries;
-        interface->fGetBufferParameteriv = glGetBufferParameteriv;
-        interface->fGetError = glGetError;
-        interface->fGetIntegerv = glGetIntegerv;
-        interface->fGetProgramInfoLog = glGetProgramInfoLog;
-        interface->fGetProgramiv = glGetProgramiv;
-        interface->fGetQueryiv = glGetQueryiv;
-        interface->fGetQueryObjectiv = glGetQueryObjectiv;
-        interface->fGetQueryObjectuiv = glGetQueryObjectuiv;
-        interface->fGetShaderInfoLog = glGetShaderInfoLog;
-        interface->fGetShaderiv = glGetShaderiv;
-        interface->fGetString = glGetString;
-        interface->fGetStringi = glGetStringi;
-        interface->fGetTexLevelParameteriv = glGetTexLevelParameteriv;
-        interface->fGenTextures = glGenTextures;
-        interface->fGetUniformLocation = glGetUniformLocation;
-        interface->fLineWidth = glLineWidth;
-        interface->fLinkProgram = glLinkProgram;
-        interface->fMapBuffer = glMapBuffer;
-        interface->fPixelStorei = glPixelStorei;
-        interface->fReadBuffer = glReadBuffer;
-        interface->fReadPixels = glReadPixels;
-        interface->fScissor = glScissor;
-    // The new OpenGLES2 header has an extra "const" in it.  :(
-#if GR_GL_USE_NEW_SHADER_SOURCE_SIGNATURE
-        interface->fShaderSource = (GrGLShaderSourceProc) glShaderSource;
-#else
-        interface->fShaderSource = glShaderSource;
-#endif
-        interface->fStencilFunc = glStencilFunc;
-        interface->fStencilFuncSeparate = glStencilFuncSeparate;
-        interface->fStencilMask = glStencilMask;
-        interface->fStencilMaskSeparate = glStencilMaskSeparate;
-        interface->fStencilOp = glStencilOp;
-        interface->fStencilOpSeparate = glStencilOpSeparate;
-        // mac uses GLenum for internalFormat param (non-standard)
-        // amounts to int vs. uint.
-        interface->fTexImage2D = (GrGLTexImage2DProc)glTexImage2D;
-        interface->fTexParameteri = glTexParameteri;
-        interface->fTexParameteriv = glTexParameteriv;
-#if GL_ARB_texture_storage || GL_VERSION_4_2
-        interface->fTexStorage2D = glTexStorage2D
-#elif GL_EXT_texture_storage
-        interface->fTexStorage2D = glTexStorage2DEXT;
-#else
+        GET_PROC(BufferData);
+        GET_PROC(BufferSubData);
+        GET_PROC(Clear);
+        GET_PROC(ClearColor);
+        GET_PROC(ClearStencil);
+        GET_PROC(ColorMask);
+        GET_PROC(CompileShader);
+        GET_PROC(CompressedTexImage2D);
+        GET_PROC(CreateProgram);
+        GET_PROC(CreateShader);
+        GET_PROC(CullFace);
+        GET_PROC(DeleteBuffers);
+        GET_PROC(DeleteProgram);
+        GET_PROC(DeleteQueries);
+        GET_PROC(DeleteShader);
+        GET_PROC(DeleteTextures);
+        GET_PROC(DepthMask);
+        GET_PROC(Disable);
+        GET_PROC(DisableVertexAttribArray);
+        GET_PROC(DrawArrays);
+        GET_PROC(DrawBuffer);
+        GET_PROC(DrawBuffers);
+        GET_PROC(DrawElements);
+        GET_PROC(Enable);
+        GET_PROC(EnableVertexAttribArray);
+        GET_PROC(EndQuery);
+        GET_PROC(Finish);
+        GET_PROC(Flush);
+        GET_PROC(FrontFace);
+        GET_PROC(GenBuffers);
+        GET_PROC(GenQueries);
+        GET_PROC(GetBufferParameteriv);
+        GET_PROC(GetError);
+        GET_PROC(GetIntegerv);
+        GET_PROC(GetProgramInfoLog);
+        GET_PROC(GetProgramiv);
+        GET_PROC(GetQueryiv);
+        GET_PROC(GetQueryObjectiv);
+        GET_PROC(GetQueryObjectuiv);
+        GET_PROC(GetShaderInfoLog);
+        GET_PROC(GetShaderiv);
+        GET_PROC(GetString);
+        GET_PROC(GetStringi);
+        GET_PROC(GetTexLevelParameteriv);
+        GET_PROC(GenTextures);
+        GET_PROC(GetUniformLocation);
+        GET_PROC(LineWidth);
+        GET_PROC(LinkProgram);
+        GET_PROC(MapBuffer);
+        GET_PROC(PixelStorei);
+        GET_PROC(ReadBuffer);
+        GET_PROC(ReadPixels);
+        GET_PROC(Scissor);
+        GET_PROC(ShaderSource);
+        GET_PROC(StencilFunc);
+        GET_PROC(StencilFuncSeparate);
+        GET_PROC(StencilMask);
+        GET_PROC(StencilMaskSeparate);
+        GET_PROC(StencilOp);
+        GET_PROC(StencilOpSeparate);
+        GET_PROC(TexImage2D);
+        GET_PROC(TexParameteri);
+        GET_PROC(TexParameteriv);
         if (ver >= GR_GL_VER(4,2) || extensions.has("GL_ARB_texture_storage")) {
             GET_PROC(TexStorage2D);
         } else if (extensions.has("GL_EXT_texture_storage")) {
             GET_PROC_SUFFIX(TexStorage2D, EXT);
         }
-#endif
-        interface->fTexSubImage2D = glTexSubImage2D;
-        interface->fUniform1f = glUniform1f;
-        interface->fUniform1i = glUniform1i;
-        interface->fUniform1fv = glUniform1fv;
-        interface->fUniform1iv = glUniform1iv;
-        interface->fUniform2f = glUniform2f;
-        interface->fUniform2i = glUniform2i;
-        interface->fUniform2fv = glUniform2fv;
-        interface->fUniform2iv = glUniform2iv;
-        interface->fUniform3f = glUniform3f;
-        interface->fUniform3i = glUniform3i;
-        interface->fUniform3fv = glUniform3fv;
-        interface->fUniform3iv = glUniform3iv;
-        interface->fUniform4f = glUniform4f;
-        interface->fUniform4i = glUniform4i;
-        interface->fUniform4fv = glUniform4fv;
-        interface->fUniform4iv = glUniform4iv;
-        interface->fUniform4fv = glUniform4fv;
-        interface->fUniformMatrix2fv = glUniformMatrix2fv;
-        interface->fUniformMatrix3fv = glUniformMatrix3fv;
-        interface->fUniformMatrix4fv = glUniformMatrix4fv;
-        interface->fUnmapBuffer = glUnmapBuffer;
-        interface->fUseProgram = glUseProgram;
-        interface->fVertexAttrib4fv = glVertexAttrib4fv;
-        interface->fVertexAttribPointer = glVertexAttribPointer;
-        interface->fViewport = glViewport;
+        GET_PROC(TexSubImage2D);
+        GET_PROC(Uniform1f);
+        GET_PROC(Uniform1i);
+        GET_PROC(Uniform1fv);
+        GET_PROC(Uniform1iv);
+        GET_PROC(Uniform2f);
+        GET_PROC(Uniform2i);
+        GET_PROC(Uniform2fv);
+        GET_PROC(Uniform2iv);
+        GET_PROC(Uniform3f);
+        GET_PROC(Uniform3i);
+        GET_PROC(Uniform3fv);
+        GET_PROC(Uniform3iv);
+        GET_PROC(Uniform4f);
+        GET_PROC(Uniform4i);
+        GET_PROC(Uniform4fv);
+        GET_PROC(Uniform4iv);
+        GET_PROC(Uniform4fv);
+        GET_PROC(UniformMatrix2fv);
+        GET_PROC(UniformMatrix3fv);
+        GET_PROC(UniformMatrix4fv);
+        GET_PROC(UnmapBuffer);
+        GET_PROC(UseProgram);
+        GET_PROC(VertexAttrib4fv);
+        GET_PROC(VertexAttribPointer);
+        GET_PROC(Viewport);
 
         if (ver >= GR_GL_VER(3,0) || extensions.has("GL_ARB_vertex_array_object")) {
             // no ARB suffix for GL_ARB_vertex_array_object
-#if GL_ARB_vertex_array_object || GL_VERSION_3_0
-            interface->fBindVertexArray = glBindVertexArray;
-            interface->fDeleteVertexArrays = glDeleteVertexArrays;
-            interface->fGenVertexArrays = glGenVertexArrays;
-#else
             GET_PROC(BindVertexArray);
             GET_PROC(DeleteVertexArrays);
             GET_PROC(GenVertexArrays);
-#endif
         }
 
         if (ver >= GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) {
             // ARB extension doesn't use the ARB suffix on the function name
-#if GL_ARB_timer_query || GL_VERSION_3_3
-            interface->fQueryCounter = glQueryCounter;
-            interface->fGetQueryObjecti64v = glGetQueryObjecti64v;
-            interface->fGetQueryObjectui64v = glGetQueryObjectui64v;
-#else
             GET_PROC(QueryCounter);
             GET_PROC(GetQueryObjecti64v);
             GET_PROC(GetQueryObjectui64v);
-#endif
         } else if (extensions.has("GL_EXT_timer_query")) {
-#if GL_EXT_timer_query
-            interface->fGetQueryObjecti64v = glGetQueryObjecti64vEXT;
-            interface->fGetQueryObjectui64v = glGetQueryObjectui64vEXT;
-#else
             GET_PROC_SUFFIX(GetQueryObjecti64v, EXT);
             GET_PROC_SUFFIX(GetQueryObjectui64v, EXT);
-#endif
         }
 
         if (ver >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) {
             // ARB extension doesn't use the ARB suffix on the function names
-#if GL_VERSION_3_0 || GL_ARB_framebuffer_object
-                interface->fGenFramebuffers = glGenFramebuffers;
-                interface->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv;
-                interface->fGetRenderbufferParameteriv = glGetRenderbufferParameteriv;
-                interface->fBindFramebuffer = glBindFramebuffer;
-                interface->fFramebufferTexture2D = glFramebufferTexture2D;
-                interface->fCheckFramebufferStatus = glCheckFramebufferStatus;
-                interface->fDeleteFramebuffers = glDeleteFramebuffers;
-                interface->fRenderbufferStorage = glRenderbufferStorage;
-                interface->fGenRenderbuffers = glGenRenderbuffers;
-                interface->fDeleteRenderbuffers = glDeleteRenderbuffers;
-                interface->fFramebufferRenderbuffer = glFramebufferRenderbuffer;
-                interface->fBindRenderbuffer = glBindRenderbuffer;
-                interface->fRenderbufferStorageMultisample = glRenderbufferStorageMultisample;
-                interface->fBlitFramebuffer = glBlitFramebuffer;
-#else
                 GET_PROC(GenFramebuffers);
                 GET_PROC(GetFramebufferAttachmentParameteriv);
                 GET_PROC(GetRenderbufferParameteriv);
@@ -235,23 +207,8 @@ const GrGLInterface* GrGLCreateNativeInterface() {
                 GET_PROC(BindRenderbuffer);
                 GET_PROC(RenderbufferStorageMultisample);
                 GET_PROC(BlitFramebuffer);
-#endif
         } else {
             if (extensions.has("GL_EXT_framebuffer_object")) {
-#if GL_EXT_framebuffer_object
-                interface->fGenFramebuffers = glGenFramebuffersEXT;
-                interface->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameterivEXT;
-                interface->fGetRenderbufferParameteriv = glGetRenderbufferParameterivEXT;
-                interface->fBindFramebuffer = glBindFramebufferEXT;
-                interface->fFramebufferTexture2D = glFramebufferTexture2DEXT;
-                interface->fCheckFramebufferStatus = glCheckFramebufferStatusEXT;
-                interface->fDeleteFramebuffers = glDeleteFramebuffersEXT;
-                interface->fRenderbufferStorage = glRenderbufferStorageEXT;
-                interface->fGenRenderbuffers = glGenRenderbuffersEXT;
-                interface->fDeleteRenderbuffers = glDeleteRenderbuffersEXT;
-                interface->fFramebufferRenderbuffer = glFramebufferRenderbufferEXT;
-                interface->fBindRenderbuffer = glBindRenderbufferEXT;
-#else
                 GET_PROC_SUFFIX(GenFramebuffers, EXT);
                 GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT);
                 GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT);
@@ -264,30 +221,17 @@ const GrGLInterface* GrGLCreateNativeInterface() {
                 GET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
                 GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
                 GET_PROC_SUFFIX(BindRenderbuffer, EXT);
-#endif
             }
             if (extensions.has("GL_EXT_framebuffer_multisample")) {
-#if GL_EXT_framebuffer_multisample
-                interface->fRenderbufferStorageMultisample = glRenderbufferStorageMultisampleEXT;
-#else
                 GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
-#endif
             }
             if (extensions.has("GL_EXT_framebuffer_blit")) {
-#if GL_EXT_framebuffer_blit
-                interface->fBlitFramebuffer = glBlitFramebufferEXT;
-#else
                 GET_PROC_SUFFIX(BlitFramebuffer, EXT);
-#endif
             }
         }
         if (ver >= GR_GL_VER(3,3) || extensions.has("GL_ARB_blend_func_extended")) {
             // ARB extension doesn't use the ARB suffix on the function name
-#if GL_VERSION_3_3 || GL_ARB_blend_func_extended
-            interface->fBindFragDataLocationIndexed = glBindFragDataLocationIndexed;
-#else
             GET_PROC(BindFragDataLocationIndexed);
-#endif
         }
     }
     glInterface.get()->ref();