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 12 #include <OpenGL/gl.h> 13 #include <OpenGL/glext.h> 14 15 #include <mach-o/dyld.h> 16 17 18 // This uses deprecated functions, should rewrite using dlopen, dlsym, dlclose 19 void* GetProcAddress(const char* name) { 20 NSSymbol symbol = NULL; 21 if (NSIsSymbolNameDefined(name)) { 22 symbol = NSLookupAndBindSymbol(name); 23 } 24 return NULL == symbol ? NULL : NSAddressOfSymbol(symbol); 25 } 26 27 #define GET_PROC(name) ((GrGL ## name ## Proc) GetProcAddress("_gl" #name)) 28 #define GET_PROC_SUFFIX(name, suffix) ((GrGL ## name ## Proc) GetProcAddress("_gl" #name #suffix)) 29 30 const GrGLInterface* GrGLCreateNativeInterface() { 31 // The gl functions are not context-specific so we create one global 32 // interface 33 static SkAutoTUnref<GrGLInterface> glInterface; 34 if (!glInterface.get()) { 35 GrGLInterface* interface = new GrGLInterface; 36 glInterface.reset(interface); 37 const char* verStr = (const char*) glGetString(GL_VERSION); 38 GrGLVersion ver = GrGLGetVersionFromString(verStr); 39 const char* extStr = (const char*) glGetString(GL_EXTENSIONS); 40 41 interface->fBindingsExported = kDesktop_GrGLBinding; 42 interface->fActiveTexture = glActiveTexture; 43 interface->fAttachShader = glAttachShader; 44 interface->fBeginQuery = glBeginQuery; 45 interface->fBindAttribLocation = glBindAttribLocation; 46 interface->fBindBuffer = glBindBuffer; 47 if (ver >= GR_GL_VER(3,0)) { 48 #if GL_VERSION_3_0 49 interface->fBindFragDataLocation = glBindFragDataLocation; 50 #else 51 interface->fBindFragDataLocation = GET_PROC(BindFragDataLocation); 52 #endif 53 } 54 interface->fBindTexture = glBindTexture; 55 interface->fBlendColor = glBlendColor; 56 interface->fBlendFunc = glBlendFunc; 57 interface->fBufferData = glBufferData; 58 interface->fBufferSubData = glBufferSubData; 59 interface->fClear = glClear; 60 interface->fClearColor = glClearColor; 61 interface->fClearStencil = glClearStencil; 62 interface->fColorMask = glColorMask; 63 interface->fColorPointer = glColorPointer; 64 interface->fCompileShader = glCompileShader; 65 interface->fCompressedTexImage2D = glCompressedTexImage2D; 66 interface->fCreateProgram = glCreateProgram; 67 interface->fCreateShader = glCreateShader; 68 interface->fCullFace = glCullFace; 69 interface->fDeleteBuffers = glDeleteBuffers; 70 interface->fDeleteProgram = glDeleteProgram; 71 interface->fDeleteQueries = glDeleteQueries; 72 interface->fDeleteShader = glDeleteShader; 73 interface->fDeleteTextures = glDeleteTextures; 74 interface->fDepthMask = glDepthMask; 75 interface->fDisable = glDisable; 76 interface->fDisableVertexAttribArray = 77 glDisableVertexAttribArray; 78 interface->fDrawArrays = glDrawArrays; 79 interface->fDrawBuffer = glDrawBuffer; 80 interface->fDrawBuffers = glDrawBuffers; 81 interface->fDrawElements = glDrawElements; 82 interface->fEnable = glEnable; 83 interface->fEnableVertexAttribArray = glEnableVertexAttribArray; 84 interface->fEndQuery = glEndQuery; 85 interface->fFinish = glFinish; 86 interface->fFlush = glFlush; 87 interface->fFrontFace = glFrontFace; 88 interface->fGenBuffers = glGenBuffers; 89 interface->fGenQueries = glGenQueries; 90 interface->fGetBufferParameteriv = glGetBufferParameteriv; 91 interface->fGetError = glGetError; 92 interface->fGetIntegerv = glGetIntegerv; 93 interface->fGetProgramInfoLog = glGetProgramInfoLog; 94 interface->fGetProgramiv = glGetProgramiv; 95 interface->fGetQueryiv = glGetQueryiv; 96 interface->fGetQueryObjectiv = glGetQueryObjectiv; 97 interface->fGetQueryObjectuiv = glGetQueryObjectuiv; 98 interface->fGetShaderInfoLog = glGetShaderInfoLog; 99 interface->fGetShaderiv = glGetShaderiv; 100 interface->fGetString = glGetString; 101 interface->fGetTexLevelParameteriv = glGetTexLevelParameteriv; 102 interface->fGenTextures = glGenTextures; 103 interface->fGetUniformLocation = glGetUniformLocation; 104 interface->fLineWidth = glLineWidth; 105 interface->fLinkProgram = glLinkProgram; 106 interface->fMapBuffer = glMapBuffer; 107 interface->fPixelStorei = glPixelStorei; 108 interface->fReadBuffer = glReadBuffer; 109 interface->fReadPixels = glReadPixels; 110 interface->fScissor = glScissor; 111 interface->fShaderSource = glShaderSource; 112 interface->fStencilFunc = glStencilFunc; 113 interface->fStencilFuncSeparate = glStencilFuncSeparate; 114 interface->fStencilMask = glStencilMask; 115 interface->fStencilMaskSeparate = glStencilMaskSeparate; 116 interface->fStencilOp = glStencilOp; 117 interface->fStencilOpSeparate = glStencilOpSeparate; 118 // mac uses GLenum for internalFormat param (non-standard) 119 // amounts to int vs. uint. 120 interface->fTexImage2D = (GrGLTexImage2DProc)glTexImage2D; 121 interface->fTexParameteri = glTexParameteri; 122 #if GL_ARB_texture_storage || GL_VERSION_4_2 123 interface->fTexStorage2D = glTexStorage2D 124 #elif GL_EXT_texture_storage 125 interface->fTexStorage2D = glTexStorage2DEXT; 126 #else 127 if (ver >= GR_GL_VER(4,2) || 128 GrGLHasExtensionFromString("GL_ARB_texture_storage", extStr)) { 129 GET_PROC(TexStorage2D); 130 } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", extStr)) { 131 GET_PROC_SUFFIX(TexStorage2D, EXT); 132 } 133 #endif 134 interface->fTexSubImage2D = glTexSubImage2D; 135 interface->fUniform1f = glUniform1f; 136 interface->fUniform1i = glUniform1i; 137 interface->fUniform1fv = glUniform1fv; 138 interface->fUniform1iv = glUniform1iv; 139 interface->fUniform2f = glUniform2f; 140 interface->fUniform2i = glUniform2i; 141 interface->fUniform2fv = glUniform2fv; 142 interface->fUniform2iv = glUniform2iv; 143 interface->fUniform3f = glUniform3f; 144 interface->fUniform3i = glUniform3i; 145 interface->fUniform3fv = glUniform3fv; 146 interface->fUniform3iv = glUniform3iv; 147 interface->fUniform4f = glUniform4f; 148 interface->fUniform4i = glUniform4i; 149 interface->fUniform4fv = glUniform4fv; 150 interface->fUniform4iv = glUniform4iv; 151 interface->fUniform4fv = glUniform4fv; 152 interface->fUniformMatrix2fv = glUniformMatrix2fv; 153 interface->fUniformMatrix3fv = glUniformMatrix3fv; 154 interface->fUniformMatrix4fv = glUniformMatrix4fv; 155 interface->fUnmapBuffer = glUnmapBuffer; 156 interface->fUseProgram = glUseProgram; 157 interface->fVertexAttrib4fv = glVertexAttrib4fv; 158 interface->fVertexAttribPointer = glVertexAttribPointer; 159 interface->fViewport = glViewport; 160 161 if (ver >= GR_GL_VER(3,3) || GrGLHasExtensionFromString("GL_ARB_timer_query", extStr)) { 162 // ARB extension doesn't use the ARB suffix on the function name 163 #if GL_ARB_timer_query || GL_VERSION_3_3 164 interface->fQueryCounter = glQueryCounter; 165 interface->fGetQueryObjecti64v = glGetQueryObjecti64v; 166 interface->fGetQueryObjectui64v = glGetQueryObjectui64v; 167 #else 168 interface->fQueryCounter = GET_PROC(QueryCounter); 169 interface->fGetQueryObjecti64v = GET_PROC(GetQueryObjecti64v); 170 interface->fGetQueryObjectui64v = GET_PROC(GetQueryObjectui64v); 171 #endif 172 } else if (GrGLHasExtensionFromString("GL_EXT_timer_query", extStr)) { 173 #if GL_EXT_timer_query 174 interface->fGetQueryObjecti64v = glGetQueryObjecti64vEXT; 175 interface->fGetQueryObjectui64v = glGetQueryObjectui64vEXT; 176 #else 177 interface->fGetQueryObjecti64v = GET_PROC_SUFFIX(GetQueryObjecti64v, EXT); 178 interface->fGetQueryObjectui64v = GET_PROC_SUFFIX(GetQueryObjectui64v, EXT); 179 #endif 180 } 181 182 if (ver >= GR_GL_VER(3,0) || GrGLHasExtensionFromString("GL_ARB_framebuffer_object", extStr)) { 183 // ARB extension doesn't use the ARB suffix on the function names 184 #if GL_VERSION_3_0 || GL_ARB_framebuffer_object 185 interface->fGenFramebuffers = glGenFramebuffers; 186 interface->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv; 187 interface->fGetRenderbufferParameteriv = glGetRenderbufferParameteriv; 188 interface->fBindFramebuffer = glBindFramebuffer; 189 interface->fFramebufferTexture2D = glFramebufferTexture2D; 190 interface->fCheckFramebufferStatus = glCheckFramebufferStatus; 191 interface->fDeleteFramebuffers = glDeleteFramebuffers; 192 interface->fRenderbufferStorage = glRenderbufferStorage; 193 interface->fGenRenderbuffers = glGenRenderbuffers; 194 interface->fDeleteRenderbuffers = glDeleteRenderbuffers; 195 interface->fFramebufferRenderbuffer = glFramebufferRenderbuffer; 196 interface->fBindRenderbuffer = glBindRenderbuffer; 197 interface->fRenderbufferStorageMultisample = glRenderbufferStorageMultisample; 198 interface->fBlitFramebuffer = glBlitFramebuffer; 199 #else 200 interface->fGenFramebuffers = GET_PROC(GenFramebuffers); 201 interface->fGetFramebufferAttachmentParameteriv = GET_PROC(GetFramebufferAttachmentParameteriv); 202 interface->fGetRenderbufferParameteriv = GET_PROC(GetRenderbufferParameteriv); 203 interface->fBindFramebuffer = GET_PROC(BindFramebuffer); 204 interface->fFramebufferTexture2D = GET_PROC(FramebufferTexture2D); 205 interface->fCheckFramebufferStatus = GET_PROC(CheckFramebufferStatus); 206 interface->fDeleteFramebuffers = GET_PROC(DeleteFramebuffers); 207 interface->fRenderbufferStorage = GET_PROC(RenderbufferStorage); 208 interface->fGenRenderbuffers = GET_PROC(GenRenderbuffers); 209 interface->fDeleteRenderbuffers = GET_PROC(DeleteRenderbuffers); 210 interface->fFramebufferRenderbuffer = GET_PROC(FramebufferRenderbuffer); 211 interface->fBindRenderbuffer = GET_PROC(BindRenderbuffer); 212 interface->fRenderbufferStorageMultisample = GET_PROC(RenderbufferStorageMultisample); 213 interface->fBlitFramebuffer = GET_PROC(BlitFramebuffer); 214 #endif 215 } else { 216 if (GrGLHasExtensionFromString("GL_EXT_framebuffer_object", extStr)) { 217 #if GL_EXT_framebuffer_object 218 interface->fGenFramebuffers = glGenFramebuffersEXT; 219 interface->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameterivEXT; 220 interface->fGetRenderbufferParameteriv = glGetRenderbufferParameterivEXT; 221 interface->fBindFramebuffer = glBindFramebufferEXT; 222 interface->fFramebufferTexture2D = glFramebufferTexture2DEXT; 223 interface->fCheckFramebufferStatus = glCheckFramebufferStatusEXT; 224 interface->fDeleteFramebuffers = glDeleteFramebuffersEXT; 225 interface->fRenderbufferStorage = glRenderbufferStorageEXT; 226 interface->fGenRenderbuffers = glGenRenderbuffersEXT; 227 interface->fDeleteRenderbuffers = glDeleteRenderbuffersEXT; 228 interface->fFramebufferRenderbuffer = glFramebufferRenderbufferEXT; 229 interface->fBindRenderbuffer = glBindRenderbufferEXT; 230 #else 231 interface->fGenFramebuffers = GET_PROC_SUFFIX(GenFramebuffers, EXT); 232 interface->fGetFramebufferAttachmentParameteriv = GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT); 233 interface->fGetRenderbufferParameteriv = GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT); 234 interface->fBindFramebuffer = GET_PROC_SUFFIX(BindFramebuffer, EXT); 235 interface->fFramebufferTexture2D = GET_PROC_SUFFIX(FramebufferTexture2D, EXT); 236 interface->fCheckFramebufferStatus = GET_PROC_SUFFIX(CheckFramebufferStatus, EXT); 237 interface->fDeleteFramebuffers = GET_PROC_SUFFIX(DeleteFramebuffers, EXT); 238 interface->fRenderbufferStorage = GET_PROC_SUFFIX(RenderbufferStorage, EXT); 239 interface->fGenRenderbuffers = GET_PROC_SUFFIX(GenRenderbuffers, EXT); 240 interface->fDeleteRenderbuffers = GET_PROC_SUFFIX(DeleteRenderbuffers, EXT); 241 interface->fFramebufferRenderbuffer = GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT); 242 interface->fBindRenderbuffer = GET_PROC_SUFFIX(BindRenderbuffer, EXT); 243 #endif 244 } 245 if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", extStr)) { 246 #if GL_EXT_framebuffer_multisample 247 interface->fRenderbufferStorageMultisample = glRenderbufferStorageMultisampleEXT; 248 #else 249 interface->fRenderbufferStorageMultisample = GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT); 250 #endif 251 } 252 if (GrGLHasExtensionFromString("", extStr)) { 253 #if GL_EXT_framebuffer_blit 254 interface->fBlitFramebuffer = glBlitFramebufferEXT; 255 #else 256 interface->fBlitFramebuffer = GET_PROC_SUFFIX(BlitFramebuffer, EXT); 257 #endif 258 } 259 } 260 if (ver >= GR_GL_VER(3,3) || GrGLHasExtensionFromString("GL_ARB_blend_func_extended", extStr)) { 261 // ARB extension doesn't use the ARB suffix on the function name 262 #if GL_VERSION_3_3 || GL_ARB_blend_func_extended 263 interface->fBindFragDataLocationIndexed = glBindFragDataLocationIndexed; 264 #else 265 interface->fBindFragDataLocationIndexed = GET_PROC(BindFragDataLocationIndexed); 266 #endif 267 } 268 269 interface->fBindingsExported = kDesktop_GrGLBinding; 270 } 271 glInterface.get()->ref(); 272 return glInterface.get(); 273 } 274