1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #include "gl/GrGLInterface.h" 11 #include "gl/GrGLExtensions.h" 12 #include "../GrGLUtil.h" 13 14 #include <dlfcn.h> 15 16 // We get the proc addresss of all GL functions dynamically because we sometimes link against 17 // alternative GL implementations (e.g. MESA) in addition to the native GL implementation. 18 class GLLoader { 19 public: 20 GLLoader() { 21 fLibrary = dlopen( 22 "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib", 23 RTLD_LAZY); 24 } 25 ~GLLoader() { 26 if (NULL != fLibrary) { 27 dlclose(fLibrary); 28 } 29 } 30 void* handle() { 31 return NULL == fLibrary ? RTLD_DEFAULT : fLibrary; 32 } 33 private: 34 void* fLibrary; 35 }; 36 37 static void* GetProcAddress(const char* name) { 38 static GLLoader gLoader; 39 return dlsym(gLoader.handle(), name); 40 } 41 42 #define GET_PROC(name) (interface->f ## name = ((GrGL ## name ## Proc) GetProcAddress("gl" #name))) 43 #define GET_PROC_SUFFIX(name, suffix) (interface->f ## name = ((GrGL ## name ## Proc) GetProcAddress("gl" #name #suffix))) 44 45 const GrGLInterface* GrGLCreateNativeInterface() { 46 // The gl functions are not context-specific so we create one global interface 47 static SkAutoTUnref<GrGLInterface> glInterface; 48 if (!glInterface.get()) { 49 GrGLInterface* interface = new GrGLInterface; 50 51 GrGLGetStringProc glGetString = (GrGLGetStringProc) GetProcAddress("glGetString"); 52 GrGLGetStringiProc glGetStringi = (GrGLGetStringiProc) GetProcAddress("glGetStringi"); 53 GrGLGetIntegervProc glGetIntegerv = (GrGLGetIntegervProc) GetProcAddress("glGetIntegerv"); 54 55 glInterface.reset(interface); 56 const char* verStr = (const char*) glGetString(GR_GL_VERSION); 57 GrGLVersion ver = GrGLGetVersionFromString(verStr); 58 GrGLExtensions extensions; 59 if (!extensions.init(kDesktop_GrGLBinding, glGetString, glGetStringi, glGetIntegerv)) { 60 glInterface.reset(NULL); 61 return NULL; 62 } 63 interface->fBindingsExported = kDesktop_GrGLBinding; 64 65 GET_PROC(ActiveTexture); 66 GET_PROC(AttachShader); 67 GET_PROC(BeginQuery); 68 GET_PROC(BindAttribLocation); 69 GET_PROC(BindBuffer); 70 if (ver >= GR_GL_VER(3,0)) { 71 GET_PROC(BindFragDataLocation); 72 } 73 GET_PROC(BindTexture); 74 GET_PROC(BlendFunc); 75 76 if (ver >= GR_GL_VER(1,4) || 77 extensions.has("GL_ARB_imaging") || 78 extensions.has("GL_EXT_blend_color")) { 79 GET_PROC(BlendColor); 80 } 81 82 GET_PROC(BufferData); 83 GET_PROC(BufferSubData); 84 GET_PROC(Clear); 85 GET_PROC(ClearColor); 86 GET_PROC(ClearStencil); 87 GET_PROC(ColorMask); 88 GET_PROC(CompileShader); 89 GET_PROC(CompressedTexImage2D); 90 GET_PROC(CopyTexSubImage2D); 91 GET_PROC(CreateProgram); 92 GET_PROC(CreateShader); 93 GET_PROC(CullFace); 94 GET_PROC(DeleteBuffers); 95 GET_PROC(DeleteProgram); 96 GET_PROC(DeleteQueries); 97 GET_PROC(DeleteShader); 98 GET_PROC(DeleteTextures); 99 GET_PROC(DepthMask); 100 GET_PROC(Disable); 101 GET_PROC(DisableVertexAttribArray); 102 GET_PROC(DrawArrays); 103 GET_PROC(DrawBuffer); 104 GET_PROC(DrawBuffers); 105 GET_PROC(DrawElements); 106 GET_PROC(Enable); 107 GET_PROC(EnableVertexAttribArray); 108 GET_PROC(EndQuery); 109 GET_PROC(Finish); 110 GET_PROC(Flush); 111 GET_PROC(FrontFace); 112 GET_PROC(GenBuffers); 113 GET_PROC(GenerateMipmap); 114 GET_PROC(GenQueries); 115 GET_PROC(GetBufferParameteriv); 116 GET_PROC(GetError); 117 GET_PROC(GetIntegerv); 118 GET_PROC(GetProgramInfoLog); 119 GET_PROC(GetProgramiv); 120 GET_PROC(GetQueryiv); 121 GET_PROC(GetQueryObjectiv); 122 GET_PROC(GetQueryObjectuiv); 123 GET_PROC(GetShaderInfoLog); 124 GET_PROC(GetShaderiv); 125 GET_PROC(GetString); 126 GET_PROC(GetStringi); 127 GET_PROC(GetTexLevelParameteriv); 128 GET_PROC(GenTextures); 129 GET_PROC(GetUniformLocation); 130 GET_PROC(LineWidth); 131 GET_PROC(LinkProgram); 132 GET_PROC(MapBuffer); 133 GET_PROC(PixelStorei); 134 GET_PROC(ReadBuffer); 135 GET_PROC(ReadPixels); 136 GET_PROC(Scissor); 137 GET_PROC(ShaderSource); 138 GET_PROC(StencilFunc); 139 GET_PROC(StencilFuncSeparate); 140 GET_PROC(StencilMask); 141 GET_PROC(StencilMaskSeparate); 142 GET_PROC(StencilOp); 143 GET_PROC(StencilOpSeparate); 144 GET_PROC(TexImage2D); 145 GET_PROC(TexParameteri); 146 GET_PROC(TexParameteriv); 147 if (ver >= GR_GL_VER(4,2) || extensions.has("GL_ARB_texture_storage")) { 148 GET_PROC(TexStorage2D); 149 } else if (extensions.has("GL_EXT_texture_storage")) { 150 GET_PROC_SUFFIX(TexStorage2D, EXT); 151 } 152 GET_PROC(TexSubImage2D); 153 GET_PROC(Uniform1f); 154 GET_PROC(Uniform1i); 155 GET_PROC(Uniform1fv); 156 GET_PROC(Uniform1iv); 157 GET_PROC(Uniform2f); 158 GET_PROC(Uniform2i); 159 GET_PROC(Uniform2fv); 160 GET_PROC(Uniform2iv); 161 GET_PROC(Uniform3f); 162 GET_PROC(Uniform3i); 163 GET_PROC(Uniform3fv); 164 GET_PROC(Uniform3iv); 165 GET_PROC(Uniform4f); 166 GET_PROC(Uniform4i); 167 GET_PROC(Uniform4fv); 168 GET_PROC(Uniform4iv); 169 GET_PROC(Uniform4fv); 170 GET_PROC(UniformMatrix2fv); 171 GET_PROC(UniformMatrix3fv); 172 GET_PROC(UniformMatrix4fv); 173 GET_PROC(UnmapBuffer); 174 GET_PROC(UseProgram); 175 GET_PROC(VertexAttrib4fv); 176 GET_PROC(VertexAttribPointer); 177 GET_PROC(Viewport); 178 179 if (ver >= GR_GL_VER(3,0) || extensions.has("GL_ARB_vertex_array_object")) { 180 // no ARB suffix for GL_ARB_vertex_array_object 181 GET_PROC(BindVertexArray); 182 GET_PROC(DeleteVertexArrays); 183 GET_PROC(GenVertexArrays); 184 } 185 186 if (ver >= GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) { 187 // ARB extension doesn't use the ARB suffix on the function name 188 GET_PROC(QueryCounter); 189 GET_PROC(GetQueryObjecti64v); 190 GET_PROC(GetQueryObjectui64v); 191 } else if (extensions.has("GL_EXT_timer_query")) { 192 GET_PROC_SUFFIX(GetQueryObjecti64v, EXT); 193 GET_PROC_SUFFIX(GetQueryObjectui64v, EXT); 194 } 195 196 if (ver >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) { 197 // ARB extension doesn't use the ARB suffix on the function names 198 GET_PROC(GenFramebuffers); 199 GET_PROC(GetFramebufferAttachmentParameteriv); 200 GET_PROC(GetRenderbufferParameteriv); 201 GET_PROC(BindFramebuffer); 202 GET_PROC(FramebufferTexture2D); 203 GET_PROC(CheckFramebufferStatus); 204 GET_PROC(DeleteFramebuffers); 205 GET_PROC(RenderbufferStorage); 206 GET_PROC(GenRenderbuffers); 207 GET_PROC(DeleteRenderbuffers); 208 GET_PROC(FramebufferRenderbuffer); 209 GET_PROC(BindRenderbuffer); 210 GET_PROC(RenderbufferStorageMultisample); 211 GET_PROC(BlitFramebuffer); 212 } else { 213 if (extensions.has("GL_EXT_framebuffer_object")) { 214 GET_PROC_SUFFIX(GenFramebuffers, EXT); 215 GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT); 216 GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT); 217 GET_PROC_SUFFIX(BindFramebuffer, EXT); 218 GET_PROC_SUFFIX(FramebufferTexture2D, EXT); 219 GET_PROC_SUFFIX(CheckFramebufferStatus, EXT); 220 GET_PROC_SUFFIX(DeleteFramebuffers, EXT); 221 GET_PROC_SUFFIX(RenderbufferStorage, EXT); 222 GET_PROC_SUFFIX(GenRenderbuffers, EXT); 223 GET_PROC_SUFFIX(DeleteRenderbuffers, EXT); 224 GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT); 225 GET_PROC_SUFFIX(BindRenderbuffer, EXT); 226 } 227 if (extensions.has("GL_EXT_framebuffer_multisample")) { 228 GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT); 229 } 230 if (extensions.has("GL_EXT_framebuffer_blit")) { 231 GET_PROC_SUFFIX(BlitFramebuffer, EXT); 232 } 233 } 234 if (ver >= GR_GL_VER(3,3) || extensions.has("GL_ARB_blend_func_extended")) { 235 // ARB extension doesn't use the ARB suffix on the function name 236 GET_PROC(BindFragDataLocationIndexed); 237 } 238 } 239 glInterface.get()->ref(); 240 return glInterface.get(); 241 } 242