Use NeverDestroyed instead of DEPRECATED_DEFINE_STATIC_LOCAL
[WebKit-https.git] / Source / WebCore / platform / graphics / OpenGLShims.cpp
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(GRAPHICS_CONTEXT_3D)
21
22 #define DISABLE_SHIMS
23 #include "OpenGLShims.h"
24
25 #if !PLATFORM(WIN)
26 #include <dlfcn.h>
27 #endif
28
29 #include <wtf/text/CString.h>
30 #include <wtf/text/WTFString.h>
31
32 namespace WebCore {
33
34 OpenGLFunctionTable* openGLFunctionTable()
35 {
36     static OpenGLFunctionTable table;
37     return &table;
38 }
39
40 #if PLATFORM(WIN)
41 static void* getProcAddress(const char* procName)
42 {
43     return GetProcAddress(GetModuleHandleA("libGLESv2"), procName);
44 }
45 #else
46 typedef void* (*glGetProcAddressType) (const char* procName);
47 static 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
64 static 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     target = getProcAddress(reinterpret_cast<const char*>(makeString(functionName, "ARB").characters8()));
74     if (target)
75         return target;
76
77     // FIXME: <https://webkit.org/b/143964> OpenGLShims appears to have a dead store if GLES2
78     target = getProcAddress(reinterpret_cast<const char*>(makeString(functionName, "EXT").characters8()));
79
80 #if defined(GL_ES_VERSION_2_0)
81     target = getProcAddress(reinterpret_cast<const char*>(makeString(functionName, "ANGLE").characters8()));
82     if (target)
83         return target;
84
85     target = getProcAddress(reinterpret_cast<const char*>(makeString(functionName, "APPLE").characters8()));
86 #endif
87
88     // A null address is still a failure case.
89     if (!target && success)
90         *success = false;
91
92     return target;
93 }
94
95 #define ASSIGN_FUNCTION_TABLE_ENTRY(FunctionName, success) \
96     openGLFunctionTable()->FunctionName = reinterpret_cast<FunctionName##Type>(lookupOpenGLFunctionAddress(#FunctionName, &success))
97
98 #define ASSIGN_FUNCTION_TABLE_ENTRY_EXT(FunctionName) \
99     openGLFunctionTable()->FunctionName = reinterpret_cast<FunctionName##Type>(lookupOpenGLFunctionAddress(#FunctionName))
100
101 bool initializeOpenGLShims()
102 {
103     static bool success = true;
104     static bool initialized = false;
105     if (initialized)
106         return success;
107
108     initialized = true;
109     ASSIGN_FUNCTION_TABLE_ENTRY(glActiveTexture, success);
110     ASSIGN_FUNCTION_TABLE_ENTRY(glAttachShader, success);
111     ASSIGN_FUNCTION_TABLE_ENTRY(glBindAttribLocation, success);
112     ASSIGN_FUNCTION_TABLE_ENTRY(glBindBuffer, success);
113     ASSIGN_FUNCTION_TABLE_ENTRY(glBindFramebuffer, success);
114     ASSIGN_FUNCTION_TABLE_ENTRY(glBindRenderbuffer, success);
115     ASSIGN_FUNCTION_TABLE_ENTRY_EXT(glBindVertexArray);
116     ASSIGN_FUNCTION_TABLE_ENTRY(glBlendColor, success);
117     ASSIGN_FUNCTION_TABLE_ENTRY(glBlendEquation, success);
118     ASSIGN_FUNCTION_TABLE_ENTRY(glBlendEquationSeparate, success);
119     ASSIGN_FUNCTION_TABLE_ENTRY(glBlendFuncSeparate, success);
120     // In GLES2 there is optional an ANGLE extension for glBlitFramebuffer
121 #if defined(GL_ES_VERSION_2_0)
122     ASSIGN_FUNCTION_TABLE_ENTRY_EXT(glBlitFramebuffer);
123 #else
124     ASSIGN_FUNCTION_TABLE_ENTRY(glBlitFramebuffer, success);
125 #endif
126     ASSIGN_FUNCTION_TABLE_ENTRY(glBufferData, success);
127     ASSIGN_FUNCTION_TABLE_ENTRY(glBufferSubData, success);
128     ASSIGN_FUNCTION_TABLE_ENTRY(glCheckFramebufferStatus, success);
129     ASSIGN_FUNCTION_TABLE_ENTRY(glCompileShader, success);
130     ASSIGN_FUNCTION_TABLE_ENTRY(glCompressedTexImage2D, success);
131     ASSIGN_FUNCTION_TABLE_ENTRY(glCompressedTexSubImage2D, success);
132     ASSIGN_FUNCTION_TABLE_ENTRY(glCreateProgram, success);
133     ASSIGN_FUNCTION_TABLE_ENTRY(glCreateShader, success);
134     ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteBuffers, success);
135     ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteFramebuffers, success);
136     ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteProgram, success);
137     ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteRenderbuffers, success);
138     ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteShader, success);
139     ASSIGN_FUNCTION_TABLE_ENTRY_EXT(glDeleteVertexArrays);
140     ASSIGN_FUNCTION_TABLE_ENTRY(glDetachShader, success);
141     ASSIGN_FUNCTION_TABLE_ENTRY(glDisableVertexAttribArray, success);
142     ASSIGN_FUNCTION_TABLE_ENTRY(glDrawArraysInstanced, success);
143     ASSIGN_FUNCTION_TABLE_ENTRY(glDrawBuffers, success);
144     ASSIGN_FUNCTION_TABLE_ENTRY(glDrawElementsInstanced, success);
145     ASSIGN_FUNCTION_TABLE_ENTRY(glEnableVertexAttribArray, success);
146     ASSIGN_FUNCTION_TABLE_ENTRY(glFramebufferRenderbuffer, success);
147     ASSIGN_FUNCTION_TABLE_ENTRY(glFramebufferTexture2D, success);
148     ASSIGN_FUNCTION_TABLE_ENTRY(glGenBuffers, success);
149     ASSIGN_FUNCTION_TABLE_ENTRY(glGenerateMipmap, success);
150     ASSIGN_FUNCTION_TABLE_ENTRY(glGenFramebuffers, success);
151     ASSIGN_FUNCTION_TABLE_ENTRY(glGenRenderbuffers, success);
152     ASSIGN_FUNCTION_TABLE_ENTRY_EXT(glGenVertexArrays);
153     ASSIGN_FUNCTION_TABLE_ENTRY(glGetActiveAttrib, success);
154     ASSIGN_FUNCTION_TABLE_ENTRY(glGetActiveUniform, success);
155     ASSIGN_FUNCTION_TABLE_ENTRY(glGetAttachedShaders, success);
156     ASSIGN_FUNCTION_TABLE_ENTRY(glGetAttribLocation, success);
157     ASSIGN_FUNCTION_TABLE_ENTRY(glGetBufferParameteriv, success);
158     ASSIGN_FUNCTION_TABLE_ENTRY(glGetFramebufferAttachmentParameteriv, success);
159     ASSIGN_FUNCTION_TABLE_ENTRY(glGetProgramInfoLog, success);
160     ASSIGN_FUNCTION_TABLE_ENTRY(glGetProgramiv, success);
161     ASSIGN_FUNCTION_TABLE_ENTRY(glGetRenderbufferParameteriv, success);
162     ASSIGN_FUNCTION_TABLE_ENTRY(glGetShaderInfoLog, success);
163     ASSIGN_FUNCTION_TABLE_ENTRY(glGetShaderiv, success);
164     ASSIGN_FUNCTION_TABLE_ENTRY(glGetShaderSource, success);
165     ASSIGN_FUNCTION_TABLE_ENTRY(glGetUniformfv, success);
166     ASSIGN_FUNCTION_TABLE_ENTRY(glGetUniformiv, success);
167     ASSIGN_FUNCTION_TABLE_ENTRY(glGetUniformLocation, success);
168     ASSIGN_FUNCTION_TABLE_ENTRY(glGetVertexAttribfv, success);
169     ASSIGN_FUNCTION_TABLE_ENTRY(glGetVertexAttribiv, success);
170     ASSIGN_FUNCTION_TABLE_ENTRY(glGetVertexAttribPointerv, success);
171     ASSIGN_FUNCTION_TABLE_ENTRY(glIsBuffer, success);
172     ASSIGN_FUNCTION_TABLE_ENTRY(glIsFramebuffer, success);
173     ASSIGN_FUNCTION_TABLE_ENTRY(glIsProgram, success);
174     ASSIGN_FUNCTION_TABLE_ENTRY(glIsRenderbuffer, success);
175     ASSIGN_FUNCTION_TABLE_ENTRY(glIsShader, success);
176     ASSIGN_FUNCTION_TABLE_ENTRY_EXT(glIsVertexArray);
177     ASSIGN_FUNCTION_TABLE_ENTRY(glLinkProgram, success);
178     ASSIGN_FUNCTION_TABLE_ENTRY(glRenderbufferStorage, success);
179     // In GLES2 there are optional ANGLE and APPLE extensions for glRenderbufferStorageMultisample.
180 #if defined(GL_ES_VERSION_2_0)
181     ASSIGN_FUNCTION_TABLE_ENTRY_EXT(glRenderbufferStorageMultisample);
182 #else
183     ASSIGN_FUNCTION_TABLE_ENTRY(glRenderbufferStorageMultisample, success);
184 #endif
185     ASSIGN_FUNCTION_TABLE_ENTRY(glSampleCoverage, success);
186     ASSIGN_FUNCTION_TABLE_ENTRY(glShaderSource, success);
187     ASSIGN_FUNCTION_TABLE_ENTRY(glStencilFuncSeparate, success);
188     ASSIGN_FUNCTION_TABLE_ENTRY(glStencilMaskSeparate, success);
189     ASSIGN_FUNCTION_TABLE_ENTRY(glStencilOpSeparate, success);
190     ASSIGN_FUNCTION_TABLE_ENTRY(glUniform1f, success);
191     ASSIGN_FUNCTION_TABLE_ENTRY(glUniform1fv, success);
192     ASSIGN_FUNCTION_TABLE_ENTRY(glUniform1i, success);
193     ASSIGN_FUNCTION_TABLE_ENTRY(glUniform1iv, success);
194     ASSIGN_FUNCTION_TABLE_ENTRY(glUniform2f, success);
195     ASSIGN_FUNCTION_TABLE_ENTRY(glUniform2fv, success);
196     ASSIGN_FUNCTION_TABLE_ENTRY(glUniform2i, success);
197     ASSIGN_FUNCTION_TABLE_ENTRY(glUniform2iv, success);
198     ASSIGN_FUNCTION_TABLE_ENTRY(glUniform3f, success);
199     ASSIGN_FUNCTION_TABLE_ENTRY(glUniform3fv, success);
200     ASSIGN_FUNCTION_TABLE_ENTRY(glUniform3i, success);
201     ASSIGN_FUNCTION_TABLE_ENTRY(glUniform3iv, success);
202     ASSIGN_FUNCTION_TABLE_ENTRY(glUniform4f, success);
203     ASSIGN_FUNCTION_TABLE_ENTRY(glUniform4fv, success);
204     ASSIGN_FUNCTION_TABLE_ENTRY(glUniform4i, success);
205     ASSIGN_FUNCTION_TABLE_ENTRY(glUniform4iv, success);
206     ASSIGN_FUNCTION_TABLE_ENTRY(glUniformMatrix2fv, success);
207     ASSIGN_FUNCTION_TABLE_ENTRY(glUniformMatrix3fv, success);
208     ASSIGN_FUNCTION_TABLE_ENTRY(glUniformMatrix4fv, success);
209     ASSIGN_FUNCTION_TABLE_ENTRY(glUseProgram, success);
210     ASSIGN_FUNCTION_TABLE_ENTRY(glValidateProgram, success);
211     ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib1f, success);
212     ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib1fv, success);
213     ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib2f, success);
214     ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib2fv, success);
215     ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib3f, success);
216     ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib3fv, success);
217     ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib4f, success);
218     ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib4fv, success);
219     ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttribDivisor, success);
220     ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttribPointer, success);
221
222     if (!success)
223         LOG_ERROR("Could not initialize OpenGL shims");
224     return success;
225 }
226
227 } // namespace WebCore
228
229 #endif // ENABLE(GRAPHICS_CONTEXT_3D)