1/* 2 * Copyright (C) 2011 Igalia S.L. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19#include "config.h" 20#if USE(3D_GRAPHICS) || defined(QT_OPENGL_SHIMS) 21 22#define DISABLE_SHIMS 23#include "OpenGLShims.h" 24 25#if !PLATFORM(QT) 26#include <dlfcn.h> 27#endif 28 29#include <wtf/text/CString.h> 30#include <wtf/text/WTFString.h> 31 32namespace WebCore { 33 34OpenGLFunctionTable* openGLFunctionTable() 35{ 36 static OpenGLFunctionTable table; 37 return &table; 38} 39 40#if PLATFORM(QT) 41static void* getProcAddress(const char* procName) 42{ 43 return reinterpret_cast<void*>(QOpenGLContext::currentContext()->getProcAddress(procName)); 44} 45#else 46typedef void* (*glGetProcAddressType) (const char* procName); 47static void* getProcAddress(const char* procName) 48{ 49 static bool initialized = false; 50 static glGetProcAddressType getProcAddressFunction = 0; 51 52 if (!initialized) { 53 getProcAddressFunction = reinterpret_cast<glGetProcAddressType>(dlsym(RTLD_DEFAULT, "glXGetProcAddress")); 54 if (!getProcAddressFunction) 55 getProcAddressFunction = reinterpret_cast<glGetProcAddressType>(dlsym(RTLD_DEFAULT, "glXGetProcAddressARB")); 56 } 57 58 if (!getProcAddressFunction) 59 return dlsym(RTLD_DEFAULT, procName); 60 return getProcAddressFunction(procName); 61} 62#endif 63 64static void* lookupOpenGLFunctionAddress(const char* functionName, bool* success = 0) 65{ 66 if (success && !*success) 67 return 0; 68 69 void* target = getProcAddress(functionName); 70 if (target) 71 return target; 72 73 String fullFunctionName(functionName); 74 fullFunctionName.append("ARB"); 75 target = getProcAddress(fullFunctionName.utf8().data()); 76 if (target) 77 return target; 78 79 fullFunctionName = functionName; 80 fullFunctionName.append("EXT"); 81 target = getProcAddress(fullFunctionName.utf8().data()); 82 83#if defined(GL_ES_VERSION_2_0) 84 fullFunctionName = functionName; 85 fullFunctionName.append("ANGLE"); 86 target = getProcAddress(fullFunctionName.utf8().data()); 87 if (target) 88 return target; 89 90 fullFunctionName = functionName; 91 fullFunctionName.append("APPLE"); 92 target = getProcAddress(fullFunctionName.utf8().data()); 93#endif 94 95 // A null address is still a failure case. 96 if (!target && success) 97 *success = false; 98 99 return target; 100} 101 102#if PLATFORM(QT) && defined(QT_OPENGL_ES_2) 103 104// With Angle only EGL/GLES2 extensions are available through eglGetProcAddress, not the regular standardized functions. 105#define ASSIGN_FUNCTION_TABLE_ENTRY(FunctionName, success) \ 106 openGLFunctionTable()->FunctionName = reinterpret_cast<FunctionName##Type>(::FunctionName) 107 108#else 109 110#define ASSIGN_FUNCTION_TABLE_ENTRY(FunctionName, success) \ 111 openGLFunctionTable()->FunctionName = reinterpret_cast<FunctionName##Type>(lookupOpenGLFunctionAddress(#FunctionName, &success)) 112 113#endif 114 115#define ASSIGN_FUNCTION_TABLE_ENTRY_EXT(FunctionName) \ 116 openGLFunctionTable()->FunctionName = reinterpret_cast<FunctionName##Type>(lookupOpenGLFunctionAddress(#FunctionName)) 117 118bool initializeOpenGLShims() 119{ 120 static bool success = true; 121 static bool initialized = false; 122 if (initialized) 123 return success; 124 125 initialized = true; 126 ASSIGN_FUNCTION_TABLE_ENTRY(glActiveTexture, success); 127 ASSIGN_FUNCTION_TABLE_ENTRY(glAttachShader, success); 128 ASSIGN_FUNCTION_TABLE_ENTRY(glBindAttribLocation, success); 129 ASSIGN_FUNCTION_TABLE_ENTRY(glBindBuffer, success); 130 ASSIGN_FUNCTION_TABLE_ENTRY(glBindFramebuffer, success); 131 ASSIGN_FUNCTION_TABLE_ENTRY(glBindRenderbuffer, success); 132 ASSIGN_FUNCTION_TABLE_ENTRY_EXT(glBindVertexArray); 133 ASSIGN_FUNCTION_TABLE_ENTRY(glBlendColor, success); 134 ASSIGN_FUNCTION_TABLE_ENTRY(glBlendEquation, success); 135 ASSIGN_FUNCTION_TABLE_ENTRY(glBlendEquationSeparate, success); 136 ASSIGN_FUNCTION_TABLE_ENTRY(glBlendFuncSeparate, success); 137 // In GLES2 there is optional an ANGLE extension for glBlitFramebuffer 138#if defined(GL_ES_VERSION_2_0) 139 ASSIGN_FUNCTION_TABLE_ENTRY_EXT(glBlitFramebuffer); 140#else 141 ASSIGN_FUNCTION_TABLE_ENTRY(glBlitFramebuffer, success); 142#endif 143 ASSIGN_FUNCTION_TABLE_ENTRY(glBufferData, success); 144 ASSIGN_FUNCTION_TABLE_ENTRY(glBufferSubData, success); 145 ASSIGN_FUNCTION_TABLE_ENTRY(glCheckFramebufferStatus, success); 146 ASSIGN_FUNCTION_TABLE_ENTRY(glCompileShader, success); 147 ASSIGN_FUNCTION_TABLE_ENTRY(glCompressedTexImage2D, success); 148 ASSIGN_FUNCTION_TABLE_ENTRY(glCompressedTexSubImage2D, success); 149 ASSIGN_FUNCTION_TABLE_ENTRY(glCreateProgram, success); 150 ASSIGN_FUNCTION_TABLE_ENTRY(glCreateShader, success); 151 ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteBuffers, success); 152 ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteFramebuffers, success); 153 ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteProgram, success); 154 ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteRenderbuffers, success); 155 ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteShader, success); 156 ASSIGN_FUNCTION_TABLE_ENTRY_EXT(glDeleteVertexArrays); 157 ASSIGN_FUNCTION_TABLE_ENTRY(glDetachShader, success); 158 ASSIGN_FUNCTION_TABLE_ENTRY(glDisableVertexAttribArray, success); 159 ASSIGN_FUNCTION_TABLE_ENTRY(glEnableVertexAttribArray, success); 160 ASSIGN_FUNCTION_TABLE_ENTRY(glFramebufferRenderbuffer, success); 161 ASSIGN_FUNCTION_TABLE_ENTRY(glFramebufferTexture2D, success); 162 ASSIGN_FUNCTION_TABLE_ENTRY(glGenBuffers, success); 163 ASSIGN_FUNCTION_TABLE_ENTRY(glGenerateMipmap, success); 164 ASSIGN_FUNCTION_TABLE_ENTRY(glGenFramebuffers, success); 165 ASSIGN_FUNCTION_TABLE_ENTRY(glGenRenderbuffers, success); 166 ASSIGN_FUNCTION_TABLE_ENTRY_EXT(glGenVertexArrays); 167 ASSIGN_FUNCTION_TABLE_ENTRY(glGetActiveAttrib, success); 168 ASSIGN_FUNCTION_TABLE_ENTRY(glGetActiveUniform, success); 169 ASSIGN_FUNCTION_TABLE_ENTRY(glGetAttachedShaders, success); 170 ASSIGN_FUNCTION_TABLE_ENTRY(glGetAttribLocation, success); 171 ASSIGN_FUNCTION_TABLE_ENTRY(glGetBufferParameteriv, success); 172 ASSIGN_FUNCTION_TABLE_ENTRY(glGetFramebufferAttachmentParameteriv, success); 173 ASSIGN_FUNCTION_TABLE_ENTRY(glGetProgramInfoLog, success); 174 ASSIGN_FUNCTION_TABLE_ENTRY(glGetProgramiv, success); 175 ASSIGN_FUNCTION_TABLE_ENTRY(glGetRenderbufferParameteriv, success); 176 ASSIGN_FUNCTION_TABLE_ENTRY(glGetShaderInfoLog, success); 177 ASSIGN_FUNCTION_TABLE_ENTRY(glGetShaderiv, success); 178 ASSIGN_FUNCTION_TABLE_ENTRY(glGetShaderSource, success); 179 ASSIGN_FUNCTION_TABLE_ENTRY(glGetUniformfv, success); 180 ASSIGN_FUNCTION_TABLE_ENTRY(glGetUniformiv, success); 181 ASSIGN_FUNCTION_TABLE_ENTRY(glGetUniformLocation, success); 182 ASSIGN_FUNCTION_TABLE_ENTRY(glGetVertexAttribfv, success); 183 ASSIGN_FUNCTION_TABLE_ENTRY(glGetVertexAttribiv, success); 184 ASSIGN_FUNCTION_TABLE_ENTRY(glGetVertexAttribPointerv, success); 185 ASSIGN_FUNCTION_TABLE_ENTRY(glIsBuffer, success); 186 ASSIGN_FUNCTION_TABLE_ENTRY(glIsFramebuffer, success); 187 ASSIGN_FUNCTION_TABLE_ENTRY(glIsProgram, success); 188 ASSIGN_FUNCTION_TABLE_ENTRY(glIsRenderbuffer, success); 189 ASSIGN_FUNCTION_TABLE_ENTRY(glIsShader, success); 190 ASSIGN_FUNCTION_TABLE_ENTRY_EXT(glIsVertexArray); 191 ASSIGN_FUNCTION_TABLE_ENTRY(glLinkProgram, success); 192 ASSIGN_FUNCTION_TABLE_ENTRY(glRenderbufferStorage, success); 193 // In GLES2 there are optional ANGLE and APPLE extensions for glRenderbufferStorageMultisample. 194#if defined(GL_ES_VERSION_2_0) 195 ASSIGN_FUNCTION_TABLE_ENTRY_EXT(glRenderbufferStorageMultisample); 196#else 197 ASSIGN_FUNCTION_TABLE_ENTRY(glRenderbufferStorageMultisample, success); 198#endif 199 ASSIGN_FUNCTION_TABLE_ENTRY(glSampleCoverage, success); 200 ASSIGN_FUNCTION_TABLE_ENTRY(glShaderSource, success); 201 ASSIGN_FUNCTION_TABLE_ENTRY(glStencilFuncSeparate, success); 202 ASSIGN_FUNCTION_TABLE_ENTRY(glStencilMaskSeparate, success); 203 ASSIGN_FUNCTION_TABLE_ENTRY(glStencilOpSeparate, success); 204 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform1f, success); 205 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform1fv, success); 206 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform1i, success); 207 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform1iv, success); 208 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform2f, success); 209 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform2fv, success); 210 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform2i, success); 211 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform2iv, success); 212 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform3f, success); 213 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform3fv, success); 214 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform3i, success); 215 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform3iv, success); 216 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform4f, success); 217 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform4fv, success); 218 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform4i, success); 219 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform4iv, success); 220 ASSIGN_FUNCTION_TABLE_ENTRY(glUniformMatrix2fv, success); 221 ASSIGN_FUNCTION_TABLE_ENTRY(glUniformMatrix3fv, success); 222 ASSIGN_FUNCTION_TABLE_ENTRY(glUniformMatrix4fv, success); 223 ASSIGN_FUNCTION_TABLE_ENTRY(glUseProgram, success); 224 ASSIGN_FUNCTION_TABLE_ENTRY(glValidateProgram, success); 225 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib1f, success); 226 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib1fv, success); 227 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib2f, success); 228 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib2fv, success); 229 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib3f, success); 230 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib3fv, success); 231 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib4f, success); 232 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib4fv, success); 233 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttribPointer, success); 234 235 if (!success) 236 LOG_ERROR("Could not initialize OpenGL shims"); 237 return success; 238} 239 240} // namespace WebCore 241 242#endif // USE(3D_GRAPHICS) 243