Unreviewed, rolling out r246501.
[WebKit-https.git] / Source / WebCore / platform / graphics / opengl / Extensions3DOpenGLCommon.cpp
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28
29 #if ENABLE(GRAPHICS_CONTEXT_3D)
30 #include "Extensions3DOpenGLCommon.h"
31
32 #include "ANGLEWebKitBridge.h"
33 #include "GraphicsContext3D.h"
34
35 #if PLATFORM(COCOA)
36
37 #if USE(OPENGL_ES)
38 #include <OpenGLES/ES2/glext.h>
39 #include <OpenGLES/ES3/gl.h>
40 #else
41 #define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
42 #include <OpenGL/gl.h>
43 #include <OpenGL/gl3.h>
44 #undef GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
45 #endif
46
47 #else
48
49 #if USE(LIBEPOXY)
50 #include "EpoxyShims.h"
51 #elif USE(OPENGL_ES)
52 #include "OpenGLESShims.h"
53 #include <GLES2/gl2.h>
54 #include <GLES2/gl2ext.h>
55 #elif PLATFORM(GTK) || PLATFORM(WIN)
56 #include "OpenGLShims.h"
57 #endif
58
59 #endif
60
61 #include <wtf/MainThread.h>
62 #include <wtf/Vector.h>
63
64 namespace WebCore {
65
66 Extensions3DOpenGLCommon::Extensions3DOpenGLCommon(GraphicsContext3D* context, bool useIndexedGetString)
67     : m_initializedAvailableExtensions(false)
68     , m_context(context)
69     , m_isNVIDIA(false)
70     , m_isAMD(false)
71     , m_isIntel(false)
72     , m_isImagination(false)
73     , m_requiresBuiltInFunctionEmulation(false)
74     , m_requiresRestrictedMaximumTextureSize(false)
75     , m_useIndexedGetString(useIndexedGetString)
76 {
77     m_vendor = String(reinterpret_cast<const char*>(::glGetString(GL_VENDOR)));
78     m_renderer = String(reinterpret_cast<const char*>(::glGetString(GL_RENDERER)));
79
80     Vector<String> vendorComponents = m_vendor.convertToASCIILowercase().split(' ');
81     if (vendorComponents.contains("nvidia"))
82         m_isNVIDIA = true;
83     if (vendorComponents.contains("ati") || vendorComponents.contains("amd"))
84         m_isAMD = true;
85     if (vendorComponents.contains("intel"))
86         m_isIntel = true;
87     if (vendorComponents.contains("imagination"))
88         m_isImagination = true;
89
90 #if PLATFORM(MAC)
91     if (m_isAMD || m_isIntel)
92         m_requiresBuiltInFunctionEmulation = true;
93
94     // Intel HD 3000 devices have problems with large textures. <rdar://problem/16649140>
95     m_requiresRestrictedMaximumTextureSize = m_renderer.startsWith("Intel HD Graphics 3000");
96 #endif
97 }
98
99 Extensions3DOpenGLCommon::~Extensions3DOpenGLCommon() = default;
100
101 bool Extensions3DOpenGLCommon::supports(const String& name)
102 {
103     if (!m_initializedAvailableExtensions)
104         initializeAvailableExtensions();
105
106     // We explicitly do not support this extension until
107     // we fix the following bug:
108     // https://bugs.webkit.org/show_bug.cgi?id=149734
109     if (name == "GL_ANGLE_translated_shader_source")
110         return false;
111
112     return supportsExtension(name);
113 }
114
115 void Extensions3DOpenGLCommon::ensureEnabled(const String& name)
116 {
117     if (name == "GL_OES_standard_derivatives") {
118         // Enable support in ANGLE (if not enabled already)
119         ANGLEWebKitBridge& compiler = m_context->m_compiler;
120         ShBuiltInResources ANGLEResources = compiler.getResources();
121         if (!ANGLEResources.OES_standard_derivatives) {
122             ANGLEResources.OES_standard_derivatives = 1;
123             compiler.setResources(ANGLEResources);
124         }
125     } else if (name == "GL_EXT_draw_buffers") {
126         // Enable support in ANGLE (if not enabled already)
127         ANGLEWebKitBridge& compiler = m_context->m_compiler;
128         ShBuiltInResources ANGLEResources = compiler.getResources();
129         if (!ANGLEResources.EXT_draw_buffers) {
130             ANGLEResources.EXT_draw_buffers = 1;
131             m_context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &ANGLEResources.MaxDrawBuffers);
132             compiler.setResources(ANGLEResources);
133         }
134     } else if (name == "GL_EXT_shader_texture_lod") {
135         // Enable support in ANGLE (if not enabled already)
136         ANGLEWebKitBridge& compiler = m_context->m_compiler;
137         ShBuiltInResources ANGLEResources = compiler.getResources();
138         if (!ANGLEResources.EXT_shader_texture_lod) {
139             ANGLEResources.EXT_shader_texture_lod = 1;
140             compiler.setResources(ANGLEResources);
141         }
142     } else if (name == "GL_EXT_frag_depth") {
143         // Enable support in ANGLE (if not enabled already)
144         ANGLEWebKitBridge& compiler = m_context->m_compiler;
145         ShBuiltInResources ANGLEResources = compiler.getResources();
146         if (!ANGLEResources.EXT_frag_depth) {
147             ANGLEResources.EXT_frag_depth = 1;
148             compiler.setResources(ANGLEResources);
149         }
150     }
151 }
152
153 bool Extensions3DOpenGLCommon::isEnabled(const String& name)
154 {
155     if (name == "GL_OES_standard_derivatives") {
156         ANGLEWebKitBridge& compiler = m_context->m_compiler;
157         return compiler.getResources().OES_standard_derivatives;
158     }
159     return supports(name);
160 }
161
162 int Extensions3DOpenGLCommon::getGraphicsResetStatusARB()
163 {
164     return GraphicsContext3D::NO_ERROR;
165 }
166
167 String Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE(Platform3DObject shader)
168 {
169     ASSERT(shader);
170     int GLshaderType;
171     ANGLEShaderType shaderType;
172
173     ANGLEWebKitBridge& compiler = m_context->m_compiler;
174
175     m_context->getShaderiv(shader, GraphicsContext3D::SHADER_TYPE, &GLshaderType);
176
177     if (GLshaderType == GraphicsContext3D::VERTEX_SHADER)
178         shaderType = SHADER_TYPE_VERTEX;
179     else if (GLshaderType == GraphicsContext3D::FRAGMENT_SHADER)
180         shaderType = SHADER_TYPE_FRAGMENT;
181     else
182         return ""; // Invalid shader type.
183
184     HashMap<Platform3DObject, GraphicsContext3D::ShaderSourceEntry>::iterator result = m_context->m_shaderSourceMap.find(shader);
185
186     if (result == m_context->m_shaderSourceMap.end())
187         return "";
188
189     GraphicsContext3D::ShaderSourceEntry& entry = result->value;
190
191     String translatedShaderSource;
192     String shaderInfoLog;
193     uint64_t extraCompileOptions = SH_CLAMP_INDIRECT_ARRAY_BOUNDS | SH_UNFOLD_SHORT_CIRCUIT | SH_INIT_OUTPUT_VARIABLES | SH_ENFORCE_PACKING_RESTRICTIONS | SH_LIMIT_EXPRESSION_COMPLEXITY | SH_LIMIT_CALL_STACK_DEPTH | SH_INITIALIZE_UNINITIALIZED_LOCALS;
194
195     if (m_requiresBuiltInFunctionEmulation)
196         extraCompileOptions |= SH_EMULATE_ABS_INT_FUNCTION;
197
198     Vector<std::pair<ANGLEShaderSymbolType, sh::ShaderVariable>> symbols;
199     bool isValid = compiler.compileShaderSource(entry.source.utf8().data(), shaderType, translatedShaderSource, shaderInfoLog, symbols, extraCompileOptions);
200
201     entry.log = shaderInfoLog;
202     entry.isValid = isValid;
203
204     for (const std::pair<ANGLEShaderSymbolType, sh::ShaderVariable>& pair : symbols) {
205         const std::string& name = pair.second.name;
206         entry.symbolMap(pair.first).set(String(name.c_str(), name.length()), pair.second);
207     }
208
209     if (!isValid)
210         return "";
211
212     return translatedShaderSource;
213 }
214
215 void Extensions3DOpenGLCommon::initializeAvailableExtensions()
216 {
217 #if (PLATFORM(COCOA) && USE(OPENGL)) || (PLATFORM(GTK) && !USE(OPENGL_ES))
218     if (m_useIndexedGetString) {
219         GLint numExtensions = 0;
220         ::glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
221         for (GLint i = 0; i < numExtensions; ++i)
222             m_availableExtensions.add(glGetStringi(GL_EXTENSIONS, i));
223
224         if (!m_availableExtensions.contains("GL_ARB_texture_storage"_s)) {
225             GLint majorVersion;
226             glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
227             GLint minorVersion;
228             glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
229             if (majorVersion > 4 || (majorVersion == 4 && minorVersion >= 2))
230                 m_availableExtensions.add("GL_ARB_texture_storage"_s);
231         }
232     } else
233 #endif
234     {
235         String extensionsString = getExtensions();
236         for (auto& extension : extensionsString.split(' '))
237             m_availableExtensions.add(extension);
238     }
239     m_initializedAvailableExtensions = true;
240 }
241
242 void Extensions3DOpenGLCommon::readnPixelsEXT(int, int, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, GC3Dsizei, void *)
243 {
244     m_context->synthesizeGLError(GL_INVALID_OPERATION);
245 }
246
247 void Extensions3DOpenGLCommon::getnUniformfvEXT(GC3Duint, int, GC3Dsizei, float *)
248 {
249     m_context->synthesizeGLError(GL_INVALID_OPERATION);
250 }
251
252 void Extensions3DOpenGLCommon::getnUniformivEXT(GC3Duint, int, GC3Dsizei, int *)
253 {
254     m_context->synthesizeGLError(GL_INVALID_OPERATION);
255 }
256
257 } // namespace WebCore
258
259 #endif // ENABLE(GRAPHICS_CONTEXT_3D)