Home | History | Annotate | Download | only in cairo
      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