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 ENABLE(WEBGL) 21 22 #define DISABLE_SHIMS 23 #include "OpenGLShims.h" 24 25 #include <dlfcn.h> 26 #include <wtf/text/CString.h> 27 #include <wtf/text/WTFString.h> 28 29 #define ASSIGN_FUNCTION_TABLE_ENTRY(FunctionName, success) \ 30 openGLFunctionTable()->FunctionName = reinterpret_cast<FunctionName##Type>(lookupOpenGLFunctionAddress(#FunctionName, success)) 31 32 namespace WebCore { 33 34 typedef void* (*glGetProcAddressType) (const char* procName); 35 static void* getProcAddress(const char* procName) 36 { 37 static bool initialized = false; 38 static glGetProcAddressType getProcAddressFunction = 0; 39 40 if (!initialized) { 41 getProcAddressFunction = reinterpret_cast<glGetProcAddressType>(dlsym(RTLD_DEFAULT, "glXGetProcAddress")); 42 if (!getProcAddressFunction) 43 getProcAddressFunction = reinterpret_cast<glGetProcAddressType>(dlsym(RTLD_DEFAULT, "glXGetProcAddressARB")); 44 } 45 46 if (!getProcAddressFunction) 47 return dlsym(RTLD_DEFAULT, procName); 48 return getProcAddressFunction(procName); 49 } 50 51 static void* lookupOpenGLFunctionAddress(const char* functionName, bool& success) 52 { 53 if (!success) 54 return 0; 55 56 void* target = getProcAddress(functionName); 57 if (target) 58 return target; 59 60 String fullFunctionName(functionName); 61 fullFunctionName.append("ARB"); 62 target = getProcAddress(fullFunctionName.utf8().data()); 63 if (target) 64 return target; 65 66 fullFunctionName = functionName; 67 fullFunctionName.append("EXT"); 68 target = getProcAddress(fullFunctionName.utf8().data()); 69 70 // A null address is still a failure case. 71 if (!target) 72 success = false; 73 74 return target; 75 } 76 77 OpenGLFunctionTable* openGLFunctionTable() 78 { 79 static OpenGLFunctionTable table; 80 return &table; 81 } 82 83 bool initializeOpenGLShims() 84 { 85 static bool success = true; 86 static bool initialized = false; 87 if (initialized) 88 return success; 89 90 initialized = true; 91 ASSIGN_FUNCTION_TABLE_ENTRY(glActiveTexture, success); 92 ASSIGN_FUNCTION_TABLE_ENTRY(glAttachShader, success); 93 ASSIGN_FUNCTION_TABLE_ENTRY(glBindAttribLocation, success); 94 ASSIGN_FUNCTION_TABLE_ENTRY(glBindBuffer, success); 95 ASSIGN_FUNCTION_TABLE_ENTRY(glBindFramebuffer, success); 96 ASSIGN_FUNCTION_TABLE_ENTRY(glBindRenderbuffer, success); 97 ASSIGN_FUNCTION_TABLE_ENTRY(glBlendColor, success); 98 ASSIGN_FUNCTION_TABLE_ENTRY(glBlendEquation, success); 99 ASSIGN_FUNCTION_TABLE_ENTRY(glBlendEquationSeparate, success); 100 ASSIGN_FUNCTION_TABLE_ENTRY(glBlendFuncSeparate, success); 101 ASSIGN_FUNCTION_TABLE_ENTRY(glBlitFramebuffer, success); 102 ASSIGN_FUNCTION_TABLE_ENTRY(glBufferData, success); 103 ASSIGN_FUNCTION_TABLE_ENTRY(glBufferSubData, success); 104 ASSIGN_FUNCTION_TABLE_ENTRY(glCheckFramebufferStatus, success); 105 ASSIGN_FUNCTION_TABLE_ENTRY(glCompileShader, success); 106 ASSIGN_FUNCTION_TABLE_ENTRY(glCreateProgram, success); 107 ASSIGN_FUNCTION_TABLE_ENTRY(glCreateShader, success); 108 ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteBuffers, success); 109 ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteFramebuffers, success); 110 ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteProgram, success); 111 ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteRenderbuffers, success); 112 ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteShader, success); 113 ASSIGN_FUNCTION_TABLE_ENTRY(glDetachShader, success); 114 ASSIGN_FUNCTION_TABLE_ENTRY(glDisableVertexAttribArray, success); 115 ASSIGN_FUNCTION_TABLE_ENTRY(glEnableVertexAttribArray, success); 116 ASSIGN_FUNCTION_TABLE_ENTRY(glFramebufferRenderbuffer, success); 117 ASSIGN_FUNCTION_TABLE_ENTRY(glFramebufferTexture2D, success); 118 ASSIGN_FUNCTION_TABLE_ENTRY(glGenBuffers, success); 119 ASSIGN_FUNCTION_TABLE_ENTRY(glGenerateMipmap, success); 120 ASSIGN_FUNCTION_TABLE_ENTRY(glGenFramebuffers, success); 121 ASSIGN_FUNCTION_TABLE_ENTRY(glGenRenderbuffers, success); 122 ASSIGN_FUNCTION_TABLE_ENTRY(glGetActiveAttrib, success); 123 ASSIGN_FUNCTION_TABLE_ENTRY(glGetActiveUniform, success); 124 ASSIGN_FUNCTION_TABLE_ENTRY(glGetAttachedShaders, success); 125 ASSIGN_FUNCTION_TABLE_ENTRY(glGetAttribLocation, success); 126 ASSIGN_FUNCTION_TABLE_ENTRY(glGetBufferParameteriv, success); 127 ASSIGN_FUNCTION_TABLE_ENTRY(glGetFramebufferAttachmentParameteriv, success); 128 ASSIGN_FUNCTION_TABLE_ENTRY(glGetProgramInfoLog, success); 129 ASSIGN_FUNCTION_TABLE_ENTRY(glGetProgramiv, success); 130 ASSIGN_FUNCTION_TABLE_ENTRY(glGetRenderbufferParameteriv, success); 131 ASSIGN_FUNCTION_TABLE_ENTRY(glGetShaderInfoLog, success); 132 ASSIGN_FUNCTION_TABLE_ENTRY(glGetShaderiv, success); 133 ASSIGN_FUNCTION_TABLE_ENTRY(glGetShaderSource, success); 134 ASSIGN_FUNCTION_TABLE_ENTRY(glGetUniformfv, success); 135 ASSIGN_FUNCTION_TABLE_ENTRY(glGetUniformiv, success); 136 ASSIGN_FUNCTION_TABLE_ENTRY(glGetUniformLocation, success); 137 ASSIGN_FUNCTION_TABLE_ENTRY(glGetVertexAttribfv, success); 138 ASSIGN_FUNCTION_TABLE_ENTRY(glGetVertexAttribiv, success); 139 ASSIGN_FUNCTION_TABLE_ENTRY(glGetVertexAttribPointerv, success); 140 ASSIGN_FUNCTION_TABLE_ENTRY(glIsBuffer, success); 141 ASSIGN_FUNCTION_TABLE_ENTRY(glIsFramebuffer, success); 142 ASSIGN_FUNCTION_TABLE_ENTRY(glIsProgram, success); 143 ASSIGN_FUNCTION_TABLE_ENTRY(glIsRenderbuffer, success); 144 ASSIGN_FUNCTION_TABLE_ENTRY(glIsShader, success); 145 ASSIGN_FUNCTION_TABLE_ENTRY(glLinkProgram, success); 146 ASSIGN_FUNCTION_TABLE_ENTRY(glRenderbufferStorage, success); 147 ASSIGN_FUNCTION_TABLE_ENTRY(glRenderbufferStorageMultisample, success); 148 ASSIGN_FUNCTION_TABLE_ENTRY(glSampleCoverage, success); 149 ASSIGN_FUNCTION_TABLE_ENTRY(glShaderSource, success); 150 ASSIGN_FUNCTION_TABLE_ENTRY(glStencilFuncSeparate, success); 151 ASSIGN_FUNCTION_TABLE_ENTRY(glStencilMaskSeparate, success); 152 ASSIGN_FUNCTION_TABLE_ENTRY(glStencilOpSeparate, success); 153 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform1f, success); 154 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform1fv, success); 155 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform1i, success); 156 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform1iv, success); 157 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform2f, success); 158 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform2fv, success); 159 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform2i, success); 160 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform2iv, success); 161 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform3f, success); 162 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform3fv, success); 163 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform3i, success); 164 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform3iv, success); 165 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform4f, success); 166 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform4fv, success); 167 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform4i, success); 168 ASSIGN_FUNCTION_TABLE_ENTRY(glUniform4iv, success); 169 ASSIGN_FUNCTION_TABLE_ENTRY(glUniformMatrix2fv, success); 170 ASSIGN_FUNCTION_TABLE_ENTRY(glUniformMatrix3fv, success); 171 ASSIGN_FUNCTION_TABLE_ENTRY(glUniformMatrix4fv, success); 172 ASSIGN_FUNCTION_TABLE_ENTRY(glUseProgram, success); 173 ASSIGN_FUNCTION_TABLE_ENTRY(glValidateProgram, success); 174 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib1f, success); 175 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib1fv, success); 176 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib2f, success); 177 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib2fv, success); 178 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib3f, success); 179 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib3fv, success); 180 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib4f, success); 181 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib4fv, success); 182 ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttribPointer, success); 183 184 if (!success) 185 LOG_ERROR("Could not initialize OpenGL shims"); 186 return success; 187 } 188 189 } // namespace WebCore 190 191 #endif // ENABLE(WEBGL) 192