Use "= default" to denote default constructor or destructor
[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(IOS)
36 #include <OpenGLES/ES2/glext.h>
37 #include <OpenGLES/ES3/gl.h>
38 #else
39 #if USE(LIBEPOXY)
40 #include "EpoxyShims.h"
41 #elif USE(OPENGL_ES_2)
42 #include "OpenGLESShims.h"
43 #define GL_GLEXT_PROTOTYPES 1
44 #include <GLES2/gl2.h>
45 #include <GLES2/gl2ext.h>
46 #elif PLATFORM(MAC)
47 #define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
48 #include <OpenGL/gl.h>
49 #include <OpenGL/gl3.h>
50 #undef GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
51 #elif PLATFORM(GTK) || PLATFORM(WIN)
52 #include "OpenGLShims.h"
53 #endif
54 #endif
55
56 #include <wtf/MainThread.h>
57 #include <wtf/Vector.h>
58
59 namespace WebCore {
60
61 Extensions3DOpenGLCommon::Extensions3DOpenGLCommon(GraphicsContext3D* context, bool useIndexedGetString)
62     : m_initializedAvailableExtensions(false)
63     , m_context(context)
64     , m_isNVIDIA(false)
65     , m_isAMD(false)
66     , m_isIntel(false)
67     , m_isImagination(false)
68     , m_requiresBuiltInFunctionEmulation(false)
69     , m_requiresRestrictedMaximumTextureSize(false)
70     , m_useIndexedGetString(useIndexedGetString)
71 {
72     m_vendor = String(reinterpret_cast<const char*>(::glGetString(GL_VENDOR)));
73     m_renderer = String(reinterpret_cast<const char*>(::glGetString(GL_RENDERER)));
74
75     Vector<String> vendorComponents;
76     m_vendor.convertToASCIILowercase().split(' ', vendorComponents);
77     if (vendorComponents.contains("nvidia"))
78         m_isNVIDIA = true;
79     if (vendorComponents.contains("ati") || vendorComponents.contains("amd"))
80         m_isAMD = true;
81     if (vendorComponents.contains("intel"))
82         m_isIntel = true;
83     if (vendorComponents.contains("imagination"))
84         m_isImagination = true;
85
86 #if PLATFORM(MAC)
87     if (m_isAMD || m_isIntel)
88         m_requiresBuiltInFunctionEmulation = true;
89
90     // Intel HD 3000 devices have problems with large textures. <rdar://problem/16649140>
91     m_requiresRestrictedMaximumTextureSize = m_renderer.startsWith("Intel HD Graphics 3000");
92 #endif
93 }
94
95 Extensions3DOpenGLCommon::~Extensions3DOpenGLCommon() = default;
96
97 bool Extensions3DOpenGLCommon::supports(const String& name)
98 {
99     if (!m_initializedAvailableExtensions)
100         initializeAvailableExtensions();
101
102     // We explicitly do not support this extension until
103     // we fix the following bug:
104     // https://bugs.webkit.org/show_bug.cgi?id=149734
105     if (name == "GL_ANGLE_translated_shader_source")
106         return false;
107
108     return supportsExtension(name);
109 }
110
111 void Extensions3DOpenGLCommon::ensureEnabled(const String& name)
112 {
113     if (name == "GL_OES_standard_derivatives") {
114         // Enable support in ANGLE (if not enabled already)
115         ANGLEWebKitBridge& compiler = m_context->m_compiler;
116         ShBuiltInResources ANGLEResources = compiler.getResources();
117         if (!ANGLEResources.OES_standard_derivatives) {
118             ANGLEResources.OES_standard_derivatives = 1;
119             compiler.setResources(ANGLEResources);
120         }
121     } else if (name == "GL_EXT_draw_buffers") {
122         // Enable support in ANGLE (if not enabled already)
123         ANGLEWebKitBridge& compiler = m_context->m_compiler;
124         ShBuiltInResources ANGLEResources = compiler.getResources();
125         if (!ANGLEResources.EXT_draw_buffers) {
126             ANGLEResources.EXT_draw_buffers = 1;
127             m_context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &ANGLEResources.MaxDrawBuffers);
128             compiler.setResources(ANGLEResources);
129         }
130     } else if (name == "GL_EXT_shader_texture_lod") {
131         // Enable support in ANGLE (if not enabled already)
132         ANGLEWebKitBridge& compiler = m_context->m_compiler;
133         ShBuiltInResources ANGLEResources = compiler.getResources();
134         if (!ANGLEResources.EXT_shader_texture_lod) {
135             ANGLEResources.EXT_shader_texture_lod = 1;
136             compiler.setResources(ANGLEResources);
137         }
138     } else if (name == "GL_EXT_frag_depth") {
139         // Enable support in ANGLE (if not enabled already)
140         ANGLEWebKitBridge& compiler = m_context->m_compiler;
141         ShBuiltInResources ANGLEResources = compiler.getResources();
142         if (!ANGLEResources.EXT_frag_depth) {
143             ANGLEResources.EXT_frag_depth = 1;
144             compiler.setResources(ANGLEResources);
145         }
146     }
147 }
148
149 bool Extensions3DOpenGLCommon::isEnabled(const String& name)
150 {
151     if (name == "GL_OES_standard_derivatives") {
152         ANGLEWebKitBridge& compiler = m_context->m_compiler;
153         return compiler.getResources().OES_standard_derivatives;
154     }
155     return supports(name);
156 }
157
158 int Extensions3DOpenGLCommon::getGraphicsResetStatusARB()
159 {
160     return GraphicsContext3D::NO_ERROR;
161 }
162
163 String Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE(Platform3DObject shader)
164 {
165     ASSERT(shader);
166     int GLshaderType;
167     ANGLEShaderType shaderType;
168
169     ANGLEWebKitBridge& compiler = m_context->m_compiler;
170
171     m_context->getShaderiv(shader, GraphicsContext3D::SHADER_TYPE, &GLshaderType);
172
173     if (GLshaderType == GraphicsContext3D::VERTEX_SHADER)
174         shaderType = SHADER_TYPE_VERTEX;
175     else if (GLshaderType == GraphicsContext3D::FRAGMENT_SHADER)
176         shaderType = SHADER_TYPE_FRAGMENT;
177     else
178         return ""; // Invalid shader type.
179
180     HashMap<Platform3DObject, GraphicsContext3D::ShaderSourceEntry>::iterator result = m_context->m_shaderSourceMap.find(shader);
181
182     if (result == m_context->m_shaderSourceMap.end())
183         return "";
184
185     GraphicsContext3D::ShaderSourceEntry& entry = result->value;
186
187     String translatedShaderSource;
188     String shaderInfoLog;
189     int 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;
190
191     if (m_requiresBuiltInFunctionEmulation)
192         extraCompileOptions |= SH_EMULATE_ABS_INT_FUNCTION;
193
194     Vector<std::pair<ANGLEShaderSymbolType, sh::ShaderVariable>> symbols;
195     bool isValid = compiler.compileShaderSource(entry.source.utf8().data(), shaderType, translatedShaderSource, shaderInfoLog, symbols, extraCompileOptions);
196
197     entry.log = shaderInfoLog;
198     entry.isValid = isValid;
199
200     for (const std::pair<ANGLEShaderSymbolType, sh::ShaderVariable>& pair : symbols) {
201         const std::string& name = pair.second.name;
202         entry.symbolMap(pair.first).set(String(name.c_str(), name.length()), pair.second);
203     }
204
205     if (!isValid)
206         return "";
207
208     return translatedShaderSource;
209 }
210
211 void Extensions3DOpenGLCommon::initializeAvailableExtensions()
212 {
213 #if PLATFORM(MAC) || (PLATFORM(GTK) && !USE(OPENGL_ES_2))
214     if (m_useIndexedGetString) {
215         GLint numExtensions = 0;
216         ::glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
217         for (GLint i = 0; i < numExtensions; ++i)
218             m_availableExtensions.add(glGetStringi(GL_EXTENSIONS, i));
219
220         if (!m_availableExtensions.contains(ASCIILiteral("GL_ARB_texture_storage"))) {
221             GLint majorVersion;
222             glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
223             GLint minorVersion;
224             glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
225             if (majorVersion > 4 || (majorVersion == 4 && minorVersion >= 2))
226                 m_availableExtensions.add(ASCIILiteral("GL_ARB_texture_storage"));
227         }
228     } else
229 #endif
230     {
231         String extensionsString = getExtensions();
232         Vector<String> availableExtensions;
233         extensionsString.split(' ', availableExtensions);
234         for (size_t i = 0; i < availableExtensions.size(); ++i)
235             m_availableExtensions.add(availableExtensions[i]);
236     }
237     m_initializedAvailableExtensions = true;
238 }
239
240 void Extensions3DOpenGLCommon::readnPixelsEXT(int, int, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, GC3Dsizei, void *)
241 {
242     m_context->synthesizeGLError(GL_INVALID_OPERATION);
243 }
244
245 void Extensions3DOpenGLCommon::getnUniformfvEXT(GC3Duint, int, GC3Dsizei, float *)
246 {
247     m_context->synthesizeGLError(GL_INVALID_OPERATION);
248 }
249
250 void Extensions3DOpenGLCommon::getnUniformivEXT(GC3Duint, int, GC3Dsizei, int *)
251 {
252     m_context->synthesizeGLError(GL_INVALID_OPERATION);
253 }
254
255 } // namespace WebCore
256
257 #endif // ENABLE(GRAPHICS_CONTEXT_3D)