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