From 97876d91d72bc70960db28f74e6862beb52f156f Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Thu, 7 Mar 2013 22:23:35 +0000 Subject: [PATCH] Always get proc address for gl functions on the mac. 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 | 316 ++++++++++------------- 1 file changed, 130 insertions(+), 186 deletions(-) diff --git a/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp b/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp index 379d0c1..a26601f 100644 --- a/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp +++ b/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp @@ -11,216 +11,188 @@ #include "gl/GrGLExtensions.h" #include "../GrGLUtil.h" -#include -#include - #include +// 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 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(); -- 2.7.4