Please support WEBGL_compressed_texture_etc1 extension (and possibly WEBGL_compressed...
[WebKit-https.git] / Source / WebCore / html / canvas / WebGL2RenderingContext.cpp
1 /*
2  * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebGL2RenderingContext.h"
28
29 #if ENABLE(WEBGL2)
30
31 #include "CachedImage.h"
32 #include "EXTTextureFilterAnisotropic.h"
33 #include "Extensions3D.h"
34 #include "HTMLCanvasElement.h"
35 #include "HTMLImageElement.h"
36 #include "HTMLVideoElement.h"
37 #include "ImageData.h"
38 #include "InspectorInstrumentation.h"
39 #include "Logging.h"
40 #include "OESTextureFloat.h"
41 #include "OESTextureFloatLinear.h"
42 #include "OESTextureHalfFloat.h"
43 #include "OESTextureHalfFloatLinear.h"
44 #include "RenderBox.h"
45 #include "WebGLActiveInfo.h"
46 #include "WebGLCompressedTextureASTC.h"
47 #include "WebGLCompressedTextureATC.h"
48 #include "WebGLCompressedTextureETC.h"
49 #include "WebGLCompressedTextureETC1.h"
50 #include "WebGLCompressedTexturePVRTC.h"
51 #include "WebGLCompressedTextureS3TC.h"
52 #include "WebGLDebugRendererInfo.h"
53 #include "WebGLDebugShaders.h"
54 #include "WebGLDepthTexture.h"
55 #include "WebGLLoseContext.h"
56 #include "WebGLQuery.h"
57 #include "WebGLSampler.h"
58 #include "WebGLSync.h"
59 #include "WebGLTransformFeedback.h"
60 #include "WebGLVertexArrayObject.h"
61 #include <JavaScriptCore/GenericTypedArrayViewInlines.h>
62 #include <JavaScriptCore/HeapInlines.h>
63 #include <JavaScriptCore/JSGenericTypedArrayViewInlines.h>
64 #include <wtf/IsoMallocInlines.h>
65
66 namespace WebCore {
67
68 WTF_MAKE_ISO_ALLOCATED_IMPL(WebGL2RenderingContext);
69
70 std::unique_ptr<WebGL2RenderingContext> WebGL2RenderingContext::create(CanvasBase& canvas, GraphicsContext3DAttributes attributes)
71 {
72     auto renderingContext = std::unique_ptr<WebGL2RenderingContext>(new WebGL2RenderingContext(canvas, attributes));
73
74     InspectorInstrumentation::didCreateCanvasRenderingContext(*renderingContext);
75
76     return renderingContext;
77 }
78
79 std::unique_ptr<WebGL2RenderingContext> WebGL2RenderingContext::create(CanvasBase& canvas, Ref<GraphicsContext3D>&& context, GraphicsContext3DAttributes attributes)
80 {
81     auto renderingContext = std::unique_ptr<WebGL2RenderingContext>(new WebGL2RenderingContext(canvas, WTFMove(context), attributes));
82
83     InspectorInstrumentation::didCreateCanvasRenderingContext(*renderingContext);
84
85     return renderingContext;
86 }
87
88 WebGL2RenderingContext::WebGL2RenderingContext(CanvasBase& canvas, GraphicsContext3DAttributes attributes)
89     : WebGLRenderingContextBase(canvas, attributes)
90 {
91 }
92
93 WebGL2RenderingContext::WebGL2RenderingContext(CanvasBase& canvas, Ref<GraphicsContext3D>&& context, GraphicsContext3DAttributes attributes)
94     : WebGLRenderingContextBase(canvas, WTFMove(context), attributes)
95 {
96     initializeShaderExtensions();
97     initializeVertexArrayObjects();
98 }
99
100 void WebGL2RenderingContext::initializeVertexArrayObjects()
101 {
102     m_defaultVertexArrayObject = WebGLVertexArrayObject::create(*this, WebGLVertexArrayObject::Type::Default);
103     addContextObject(*m_defaultVertexArrayObject);
104 #if USE(OPENGL_ES)
105     m_boundVertexArrayObject = m_defaultVertexArrayObject;
106 #else
107     bindVertexArray(nullptr); // The default VAO was removed in OpenGL 3.3 but not from WebGL 2; bind the default for WebGL to use.
108 #endif
109     if (!isGLES2Compliant())
110         initVertexAttrib0();
111 }
112
113 void WebGL2RenderingContext::initializeShaderExtensions()
114 {
115     m_context->getExtensions().ensureEnabled("GL_OES_standard_derivatives");
116     m_context->getExtensions().ensureEnabled("GL_EXT_draw_buffers");
117     m_context->getExtensions().ensureEnabled("GL_EXT_shader_texture_lod");
118     m_context->getExtensions().ensureEnabled("GL_EXT_frag_depth");
119 }
120
121 inline static Optional<unsigned> arrayBufferViewElementSize(const ArrayBufferView& data)
122 {
123     switch (data.getType()) {
124     case JSC::NotTypedArray:
125     case JSC::TypeDataView:
126         return WTF::nullopt;
127     case JSC::TypeInt8:
128     case JSC::TypeUint8:
129     case JSC::TypeUint8Clamped:
130     case JSC::TypeInt16:
131     case JSC::TypeUint16:
132     case JSC::TypeInt32:
133     case JSC::TypeUint32:
134     case JSC::TypeFloat32:
135     case JSC::TypeFloat64:
136         return elementSize(data.getType());
137     }
138     RELEASE_ASSERT_NOT_REACHED();
139 }
140
141 void WebGL2RenderingContext::bufferData(GC3Denum target, const ArrayBufferView& data, GC3Denum usage, GC3Duint srcOffset, GC3Duint length)
142 {
143     auto optionalElementSize = arrayBufferViewElementSize(data);
144     if (!optionalElementSize) {
145         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bufferData", "Invalid type of Array Buffer View");
146         return;
147     }
148     auto elementSize = optionalElementSize.value();
149     Checked<GC3Duint, RecordOverflow> checkedElementSize(elementSize);
150
151     Checked<GC3Duint, RecordOverflow> checkedSrcOffset(srcOffset);
152     Checked<GC3Duint, RecordOverflow> checkedByteSrcOffset = checkedSrcOffset * checkedElementSize;
153     Checked<GC3Duint, RecordOverflow> checkedlength(length);
154     Checked<GC3Duint, RecordOverflow> checkedByteLength = checkedlength * checkedElementSize;
155
156     if (checkedByteSrcOffset.hasOverflowed()
157         || checkedByteLength.hasOverflowed()
158         || checkedByteSrcOffset.unsafeGet() > data.byteLength()
159         || checkedByteLength.unsafeGet() > data.byteLength() - checkedByteSrcOffset.unsafeGet()) {
160         synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "srcOffset or length is out of bounds");
161         return;
162     }
163
164     auto slice = Uint8Array::tryCreate(data.possiblySharedBuffer(), data.byteOffset() + checkedByteSrcOffset.unsafeGet(), checkedByteLength.unsafeGet());
165     if (!slice) {
166         synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "bufferData", "Could not create intermediate ArrayBufferView");
167         return;
168     }
169     WebGLRenderingContextBase::bufferData(target, BufferDataSource(slice.get()), usage);
170 }
171
172 void WebGL2RenderingContext::bufferSubData(GC3Denum target, long long offset, const ArrayBufferView& data, GC3Duint srcOffset, GC3Duint length)
173 {
174     auto optionalElementSize = arrayBufferViewElementSize(data);
175     if (!optionalElementSize) {
176         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bufferSubData", "Invalid type of Array Buffer View");
177         return;
178     }
179     auto elementSize = optionalElementSize.value();
180     Checked<GC3Duint, RecordOverflow> checkedElementSize(elementSize);
181
182     Checked<GC3Duint, RecordOverflow> checkedSrcOffset(srcOffset);
183     Checked<GC3Duint, RecordOverflow> checkedByteSrcOffset = checkedSrcOffset * checkedElementSize;
184     Checked<GC3Duint, RecordOverflow> checkedlength(length);
185     Checked<GC3Duint, RecordOverflow> checkedByteLength = checkedlength * checkedElementSize;
186
187     if (checkedByteSrcOffset.hasOverflowed()
188         || checkedByteLength.hasOverflowed()
189         || checkedByteSrcOffset.unsafeGet() > data.byteLength()
190         || checkedByteLength.unsafeGet() > data.byteLength() - checkedByteSrcOffset.unsafeGet()) {
191         synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "srcOffset or length is out of bounds");
192         return;
193     }
194
195     auto slice = Uint8Array::tryCreate(data.possiblySharedBuffer(), data.byteOffset() + checkedByteSrcOffset.unsafeGet(), checkedByteLength.unsafeGet());
196     if (!slice) {
197         synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "bufferSubData", "Could not create intermediate ArrayBufferView");
198         return;
199     }
200
201     WebGLRenderingContextBase::bufferSubData(target, offset, BufferDataSource(slice.get()));
202 }
203
204 void WebGL2RenderingContext::copyBufferSubData(GC3Denum readTarget, GC3Denum writeTarget, GC3Dint64 readOffset, GC3Dint64 writeOffset, GC3Dint64 size)
205 {
206     if (isContextLostOrPending())
207         return;
208     if ((readTarget == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && writeTarget != GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
209         || (writeTarget == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && readTarget != GraphicsContext3D::ELEMENT_ARRAY_BUFFER)) {
210         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyBufferSubData", "Either both targets need to be ELEMENT_ARRAY_BUFFER or neither should be ELEMENT_ARRAY_BUFFER.");
211         return;
212     }
213     if (readOffset < 0 || writeOffset < 0 || size < 0) {
214         synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyBufferSubData", "offset < 0");
215         return;
216     }
217     RefPtr<WebGLBuffer> readBuffer = validateBufferDataParameters("copyBufferSubData", readTarget, GraphicsContext3D::STATIC_DRAW);
218     RefPtr<WebGLBuffer> writeBuffer = validateBufferDataParameters("copyBufferSubData", writeTarget, GraphicsContext3D::STATIC_DRAW);
219     if (!readBuffer || !writeBuffer) {
220         synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyBufferSubData", "Invalid readTarget or writeTarget");
221         return;
222     }
223
224     Checked<GC3Dintptr, RecordOverflow> checkedReadOffset(readOffset);
225     Checked<GC3Dintptr, RecordOverflow> checkedWriteOffset(writeOffset);
226     Checked<GC3Dsizeiptr, RecordOverflow> checkedSize(size);
227     if (checkedReadOffset.hasOverflowed() || checkedWriteOffset.hasOverflowed() || checkedSize.hasOverflowed()) {
228         synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyBufferSubData", "Offset or size is too big");
229         return;
230     }
231
232     if (!writeBuffer->associateCopyBufferSubData(*readBuffer, checkedReadOffset.unsafeGet(), checkedWriteOffset.unsafeGet(), checkedSize.unsafeGet())) {
233         this->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyBufferSubData", "offset out of range");
234         return;
235     }
236
237     m_context->moveErrorsToSyntheticErrorList();
238 #if PLATFORM(COCOA)
239     m_context->copyBufferSubData(readTarget, writeTarget, checkedReadOffset.unsafeGet(), checkedWriteOffset.unsafeGet(), checkedSize.unsafeGet());
240 #endif
241     if (m_context->moveErrorsToSyntheticErrorList()) {
242         // The bufferSubData function failed. Tell the buffer it doesn't have the data it thinks it does.
243         writeBuffer->disassociateBufferData();
244     }
245 }
246
247 void WebGL2RenderingContext::getBufferSubData(GC3Denum target, long long srcByteOffset, RefPtr<ArrayBufferView>&& dstData, GC3Duint dstOffset, GC3Duint length)
248 {
249     if (isContextLostOrPending())
250         return;
251     RefPtr<WebGLBuffer> buffer = validateBufferDataParameters("bufferSubData", target, GraphicsContext3D::STATIC_DRAW);
252     if (!buffer) {
253         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData", "No WebGLBuffer is bound to target");
254         return;
255     }
256
257     // FIXME: Implement "If target is TRANSFORM_FEEDBACK_BUFFER, and any transform feedback object is currently active, an INVALID_OPERATION error is generated."
258
259     if (!dstData) {
260         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData", "Null dstData");
261         return;
262     }
263
264     auto optionalElementSize = arrayBufferViewElementSize(*dstData);
265     if (!optionalElementSize) {
266         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData", "Invalid type of Array Buffer View");
267         return;
268     }
269     auto elementSize = optionalElementSize.value();
270     auto dstDataLength = dstData->byteLength() / elementSize;
271
272     if (dstOffset > dstDataLength) {
273         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData", "dstOffset is larger than the length of the destination buffer.");
274         return;
275     }
276
277     GC3Duint copyLength = length ? length : dstDataLength - dstOffset;
278
279     Checked<GC3Duint, RecordOverflow> checkedDstOffset(dstOffset);
280     Checked<GC3Duint, RecordOverflow> checkedCopyLength(copyLength);
281     auto checkedDestinationEnd = checkedDstOffset + checkedCopyLength;
282     if (checkedDestinationEnd.hasOverflowed()) {
283         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData", "dstOffset + copyLength is too high");
284         return;
285     }
286
287     if (checkedDestinationEnd.unsafeGet() > dstDataLength) {
288         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData", "end of written destination is past the end of the buffer");
289         return;
290     }
291
292     if (srcByteOffset < 0) {
293         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData", "srcByteOffset is less than 0");
294         return;
295     }
296
297     Checked<GC3Dintptr, RecordOverflow> checkedSrcByteOffset(srcByteOffset);
298     Checked<GC3Dintptr, RecordOverflow> checkedCopyLengthPtr(copyLength);
299     Checked<GC3Dintptr, RecordOverflow> checkedElementSize(elementSize);
300     auto checkedSourceEnd = checkedSrcByteOffset + checkedCopyLengthPtr * checkedElementSize;
301     if (checkedSourceEnd.hasOverflowed() || checkedSourceEnd.unsafeGet() > buffer->byteLength()) {
302         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData", "Parameters would read outside the bounds of the source buffer");
303         return;
304     }
305
306     m_context->moveErrorsToSyntheticErrorList();
307 #if PLATFORM(COCOA)
308     // FIXME: Coalesce multiple getBufferSubData() calls to use a single map() call
309     void* ptr = m_context->mapBufferRange(target, checkedSrcByteOffset.unsafeGet(), static_cast<GC3Dsizeiptr>(checkedCopyLengthPtr.unsafeGet() * checkedElementSize.unsafeGet()), GraphicsContext3D::MAP_READ_BIT);
310     memcpy(static_cast<char*>(dstData->baseAddress()) + dstData->byteOffset() + dstOffset * elementSize, ptr, copyLength * elementSize);
311     bool success = m_context->unmapBuffer(target);
312     ASSERT_UNUSED(success, success);
313 #endif
314     m_context->moveErrorsToSyntheticErrorList();
315 }
316
317 void WebGL2RenderingContext::blitFramebuffer(GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dbitfield, GC3Denum)
318 {
319     LOG(WebGL, "[[ NOT IMPLEMENTED ]] blitFramebuffer()");
320 }
321
322 void WebGL2RenderingContext::framebufferTextureLayer(GC3Denum, GC3Denum, WebGLTexture*, GC3Dint, GC3Dint)
323 {
324     LOG(WebGL, "[[ NOT IMPLEMENTED ]] framebufferTextureLayer()");
325 }
326
327 #if !USE(OPENGL_ES)
328 static bool isRenderableInternalformat(GC3Denum internalformat)
329 {
330     // OpenGL ES 3: internalformat must be a color-renderable, depth-renderable, or stencil-renderable format, as shown in Table 1 below.
331     switch (internalformat) {
332     case GraphicsContext3D::R8:
333     case GraphicsContext3D::R8UI:
334     case GraphicsContext3D::R16UI:
335     case GraphicsContext3D::R16I:
336     case GraphicsContext3D::R32UI:
337     case GraphicsContext3D::R32I:
338     case GraphicsContext3D::RG8:
339     case GraphicsContext3D::RG8UI:
340     case GraphicsContext3D::RG8I:
341     case GraphicsContext3D::RG16UI:
342     case GraphicsContext3D::RG16I:
343     case GraphicsContext3D::RG32UI:
344     case GraphicsContext3D::RG32I:
345     case GraphicsContext3D::RGB8:
346     case GraphicsContext3D::RGB565:
347     case GraphicsContext3D::RGBA8:
348     case GraphicsContext3D::SRGB8_ALPHA8:
349     case GraphicsContext3D::RGB5_A1:
350     case GraphicsContext3D::RGBA4:
351     case GraphicsContext3D::RGB10_A2:
352     case GraphicsContext3D::RGBA8UI:
353     case GraphicsContext3D::RGBA8I:
354     case GraphicsContext3D::RGB10_A2UI:
355     case GraphicsContext3D::RGBA16UI:
356     case GraphicsContext3D::RGBA16I:
357     case GraphicsContext3D::RGBA32I:
358     case GraphicsContext3D::RGBA32UI:
359     case GraphicsContext3D::DEPTH_COMPONENT16:
360     case GraphicsContext3D::DEPTH_COMPONENT24:
361     case GraphicsContext3D::DEPTH_COMPONENT32F:
362     case GraphicsContext3D::DEPTH24_STENCIL8:
363     case GraphicsContext3D::DEPTH32F_STENCIL8:
364     case GraphicsContext3D::STENCIL_INDEX8:
365         return true;
366     }
367     return false;
368 }
369 #endif
370
371 WebGLAny WebGL2RenderingContext::getInternalformatParameter(GC3Denum target, GC3Denum internalformat, GC3Denum pname)
372 {
373     if (isContextLostOrPending())
374         return nullptr;
375
376     if (pname != GraphicsContext3D::SAMPLES) {
377         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getInternalformatParameter", "invalid parameter name");
378         return nullptr;
379     }
380
381     int numValues = 0;
382 #if USE(OPENGL_ES)
383     m_context->getInternalformativ(target, internalformat, GraphicsContext3D::NUM_SAMPLE_COUNTS, 1, &numValues);
384
385     GC3Dint params[numValues];
386     m_context->getInternalformativ(target, internalformat, pname, numValues, params);
387 #else
388     // On desktop OpenGL 4.1 or below we must emulate glGetInternalformativ.
389
390     // GL_INVALID_ENUM is generated if target is not GL_RENDERBUFFER.
391     if (target != GraphicsContext3D::RENDERBUFFER) {
392         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getInternalformatParameter", "invalid target");
393         return nullptr;
394     }
395
396     // GL_INVALID_ENUM is generated if internalformat is not color-, depth-, or stencil-renderable.
397     if (!isRenderableInternalformat(internalformat)) {
398         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getInternalformatParameter", "invalid internal format");
399         return nullptr;
400     }
401
402     Vector<GC3Dint> samples;
403     // The way I understand this is that this will return a MINIMUM numSamples for all accepeted internalformats.
404     // However, the true value of this on supported GL versions is gleaned via a getInternalformativ call that depends on internalformat.
405     int numSamplesMask = getIntParameter(GraphicsContext3D::MAX_SAMPLES);
406
407     while (numSamplesMask > 0) {
408         samples.append(numSamplesMask);
409         numSamplesMask = numSamplesMask >> 1;
410     }
411
412     // Since multisampling is not supported for signed and unsigned integer internal formats,
413     // the value of GL_NUM_SAMPLE_COUNTS will be zero for such formats.
414     numValues = isIntegerFormat(internalformat) ? 0 : samples.size();
415     GC3Dint params[numValues];
416     for (size_t i = 0; i < samples.size(); ++i)
417         params[i] = samples[i];
418 #endif
419
420     return Int32Array::tryCreate(params, numValues);
421 }
422
423 void WebGL2RenderingContext::invalidateFramebuffer(GC3Denum, const Vector<GC3Denum>&)
424 {
425     LOG(WebGL, "[[ NOT IMPLEMENTED ]] invalidateFramebuffer()");
426 }
427
428 void WebGL2RenderingContext::invalidateSubFramebuffer(GC3Denum, const Vector<GC3Denum>&, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei)
429 {
430     LOG(WebGL, "[[ NOT IMPLEMENTED ]] invalidateSubFramebuffer()");
431 }
432
433 void WebGL2RenderingContext::readBuffer(GC3Denum)
434 {
435     LOG(WebGL, "[[ NOT IMPLEMENTED ]] readBuffer()");
436 }
437
438 void WebGL2RenderingContext::renderbufferStorageMultisample(GC3Denum target, GC3Dsizei samples, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
439 {
440     // To be backward compatible with WebGL 1, also accepts internal format DEPTH_STENCIL,
441     // which should be mapped to DEPTH24_STENCIL8 by implementations.
442     if (internalformat == GraphicsContext3D::DEPTH_STENCIL)
443         internalformat = GraphicsContext3D::DEPTH24_STENCIL8;
444
445     // ES 3: GL_INVALID_OPERATION is generated if internalformat is a signed or unsigned integer format and samples is greater than 0.
446     if (isIntegerFormat(internalformat) && samples > 0) {
447         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "renderbufferStorageMultisample", "multisampling not supported for this format");
448         return;
449     }
450
451     switch (internalformat) {
452     case GraphicsContext3D::DEPTH_COMPONENT16:
453     case GraphicsContext3D::DEPTH_COMPONENT32F:
454     case GraphicsContext3D::DEPTH_COMPONENT24:
455     case GraphicsContext3D::RGBA32I:
456     case GraphicsContext3D::RGBA32UI:
457     case GraphicsContext3D::RGBA16I:
458     case GraphicsContext3D::RGBA16UI:
459     case GraphicsContext3D::RGBA8:
460     case GraphicsContext3D::RGBA8I:
461     case GraphicsContext3D::RGBA8UI:
462     case GraphicsContext3D::RGB10_A2:
463     case GraphicsContext3D::RGB10_A2UI:
464     case GraphicsContext3D::RGBA4:
465     case GraphicsContext3D::RG32I:
466     case GraphicsContext3D::RG32UI:
467     case GraphicsContext3D::RG16I:
468     case GraphicsContext3D::RG16UI:
469     case GraphicsContext3D::RG8:
470     case GraphicsContext3D::RG8I:
471     case GraphicsContext3D::RG8UI:
472     case GraphicsContext3D::R32I:
473     case GraphicsContext3D::R32UI:
474     case GraphicsContext3D::R16I:
475     case GraphicsContext3D::R16UI:
476     case GraphicsContext3D::R8:
477     case GraphicsContext3D::R8I:
478     case GraphicsContext3D::R8UI:
479     case GraphicsContext3D::RGB5_A1:
480     case GraphicsContext3D::RGB565:
481     case GraphicsContext3D::RGB8:
482     case GraphicsContext3D::STENCIL_INDEX8:
483     case GraphicsContext3D::SRGB8_ALPHA8:
484         m_context->renderbufferStorageMultisample(target, samples, internalformat, width, height);
485         m_renderbufferBinding->setInternalFormat(internalformat);
486         m_renderbufferBinding->setIsValid(true);
487         m_renderbufferBinding->setSize(width, height);
488         break;
489     case GraphicsContext3D::DEPTH32F_STENCIL8:
490     case GraphicsContext3D::DEPTH24_STENCIL8:
491         if (!isDepthStencilSupported()) {
492             synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
493             return;
494         }
495         m_context->renderbufferStorageMultisample(target, samples, internalformat, width, height);
496         m_renderbufferBinding->setSize(width, height);
497         m_renderbufferBinding->setIsValid(isDepthStencilSupported());
498         m_renderbufferBinding->setInternalFormat(internalformat);
499         break;
500     default:
501         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
502         return;
503     }
504     applyStencilTest();
505 }
506
507 bool WebGL2RenderingContext::validateTexStorageFuncParameters(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, const char* functionName)
508 {
509     if (width < 0 || height < 0) {
510         synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
511         return false;
512     }
513
514     if (width > m_maxTextureSize || height > m_maxTextureSize) {
515         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "texture dimensions are larger than the maximum texture size");
516         return false;
517     }
518
519     if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
520         if (width != height) {
521             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height for cube map");
522             return false;
523         }
524     } else if (target != GraphicsContext3D::TEXTURE_2D) {
525         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
526         return false;
527     }
528
529     if (levels < 0 || levels > m_maxTextureLevel) {
530         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "number of levels is out of bounds");
531         return false;
532     }
533
534     switch (internalFormat) {
535     case GraphicsContext3D::R8:
536     case GraphicsContext3D::R8_SNORM:
537     case GraphicsContext3D::R16F:
538     case GraphicsContext3D::R32F:
539     case GraphicsContext3D::R8UI:
540     case GraphicsContext3D::R8I:
541     case GraphicsContext3D::R16UI:
542     case GraphicsContext3D::R16I:
543     case GraphicsContext3D::R32UI:
544     case GraphicsContext3D::R32I:
545     case GraphicsContext3D::RG8:
546     case GraphicsContext3D::RG8_SNORM:
547     case GraphicsContext3D::RG16F:
548     case GraphicsContext3D::RG32F:
549     case GraphicsContext3D::RG8UI:
550     case GraphicsContext3D::RG8I:
551     case GraphicsContext3D::RG16UI:
552     case GraphicsContext3D::RG16I:
553     case GraphicsContext3D::RG32UI:
554     case GraphicsContext3D::RG32I:
555     case GraphicsContext3D::RGB8:
556     case GraphicsContext3D::SRGB8:
557     case GraphicsContext3D::RGB565:
558     case GraphicsContext3D::RGB8_SNORM:
559     case GraphicsContext3D::R11F_G11F_B10F:
560     case GraphicsContext3D::RGB9_E5:
561     case GraphicsContext3D::RGB16F:
562     case GraphicsContext3D::RGB32F:
563     case GraphicsContext3D::RGB8UI:
564     case GraphicsContext3D::RGB8I:
565     case GraphicsContext3D::RGB16UI:
566     case GraphicsContext3D::RGB16I:
567     case GraphicsContext3D::RGB32UI:
568     case GraphicsContext3D::RGB32I:
569     case GraphicsContext3D::RGBA8:
570     case GraphicsContext3D::SRGB8_ALPHA8:
571     case GraphicsContext3D::RGBA8_SNORM:
572     case GraphicsContext3D::RGB5_A1:
573     case GraphicsContext3D::RGBA4:
574     case GraphicsContext3D::RGB10_A2:
575     case GraphicsContext3D::RGBA16F:
576     case GraphicsContext3D::RGBA32F:
577     case GraphicsContext3D::RGBA8UI:
578     case GraphicsContext3D::RGBA8I:
579     case GraphicsContext3D::RGB10_A2UI:
580     case GraphicsContext3D::RGBA16UI:
581     case GraphicsContext3D::RGBA16I:
582     case GraphicsContext3D::RGBA32I:
583     case GraphicsContext3D::RGBA32UI:
584     case GraphicsContext3D::DEPTH_COMPONENT16:
585     case GraphicsContext3D::DEPTH_COMPONENT24:
586     case GraphicsContext3D::DEPTH_COMPONENT32F:
587     case GraphicsContext3D::DEPTH24_STENCIL8:
588     case GraphicsContext3D::DEPTH32F_STENCIL8:
589         break;
590     default:
591         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "Unknown internalFormat");
592         return false;
593     }
594
595     return true;
596 }
597
598 void WebGL2RenderingContext::texStorage2D(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height)
599 {
600     if (isContextLostOrPending())
601         return;
602
603     auto texture = validateTextureBinding("texStorage2D", target, false);
604     if (!texture)
605         return;
606
607     if (!validateTexStorageFuncParameters(target, levels, internalFormat, width, height, "texStorage2D"))
608         return;
609
610     if (!validateNPOTTextureLevel(width, height, levels, "texStorage2D"))
611         return;
612
613     if (texture->immutable()) {
614         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "texStorage2D", "texStorage2D already called on this texture");
615         return;
616     }
617     texture->setImmutable();
618
619     m_context->texStorage2D(target, levels, internalFormat, width, height);
620
621     {
622         GC3Denum format;
623         GC3Denum type;
624         if (!GraphicsContext3D::possibleFormatAndTypeForInternalFormat(internalFormat, format, type)) {
625             synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texStorage2D", "Texture has unknown internal format");
626             return;
627         }
628
629         GC3Dsizei levelWidth = width;
630         GC3Dsizei levelHeight = height;
631
632         unsigned size;
633         GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &size, nullptr);
634         if (error != GraphicsContext3D::NO_ERROR) {
635             synthesizeGLError(error, "texStorage2D", "bad dimensions");
636             return;
637         }
638
639         Vector<char> data(size);
640         memset(data.data(), 0, size);
641
642         for (GC3Dsizei level = 0; level < levels; ++level) {
643             if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
644                 m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
645                 m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
646                 m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
647                 m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
648                 m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
649                 m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
650             } else
651                 m_context->texSubImage2D(target, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
652             levelWidth = std::max(1, levelWidth / 2);
653             levelHeight = std::max(1, levelHeight / 2);
654         }
655     }
656
657     for (GC3Dsizei level = 0; level < levels; ++level) {
658         if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
659             texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
660             texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
661             texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
662             texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
663             texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
664             texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
665         } else
666             texture->setLevelInfo(target, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
667     }
668 }
669
670 void WebGL2RenderingContext::texStorage3D(GC3Denum, GC3Dsizei, GC3Denum, GC3Dsizei, GC3Dsizei, GC3Dsizei)
671 {
672     LOG(WebGL, "[[ NOT IMPLEMENTED ]] texStorage3D()");
673 }
674
675 void WebGL2RenderingContext::texImage2D(GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Denum, GC3Denum, GC3Dint64)
676 {
677     LOG(WebGL, "[[ NOT IMPLEMENTED ]] texImage2D()");
678 }
679
680 void WebGL2RenderingContext::texImage2D(GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Denum, GC3Denum, TexImageSource&&)
681 {
682     LOG(WebGL, "[[ NOT IMPLEMENTED ]] texImage2D()");
683 }
684
685 void WebGL2RenderingContext::texImage2D(GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Denum, GC3Denum, RefPtr<ArrayBufferView>&&, GC3Duint)
686 {
687     LOG(WebGL, "[[ NOT IMPLEMENTED ]] texImage2D()");
688 }
689
690 void WebGL2RenderingContext::texImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Denum, GC3Denum, GC3Dint64)
691 {
692     LOG(WebGL, "[[ NOT IMPLEMENTED ]] texImage3D()");
693 }
694
695 void WebGL2RenderingContext::texImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Denum, GC3Denum, TexImageSource&&)
696 {
697     LOG(WebGL, "[[ NOT IMPLEMENTED ]] texImage3D()");
698 }
699
700 void WebGL2RenderingContext::texImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Denum, GC3Denum, RefPtr<ArrayBufferView>&&)
701 {
702     LOG(WebGL, "[[ NOT IMPLEMENTED ]] texImage3D()");
703 }
704
705 void WebGL2RenderingContext::texImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Denum, GC3Denum, RefPtr<ArrayBufferView>&&, GC3Duint)
706 {
707     LOG(WebGL, "[[ NOT IMPLEMENTED ]] texImage3D()");
708 }
709
710 void WebGL2RenderingContext::texSubImage2D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, GC3Dint64)
711 {
712     LOG(WebGL, "[[ NOT IMPLEMENTED ]] texSubImage2D()");
713 }
714
715 void WebGL2RenderingContext::texSubImage2D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, TexImageSource&&)
716 {
717     LOG(WebGL, "[[ NOT IMPLEMENTED ]] texSubImage2D()");
718 }
719
720 void WebGL2RenderingContext::texSubImage2D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, RefPtr<ArrayBufferView>&&, GC3Duint)
721 {
722     LOG(WebGL, "[[ NOT IMPLEMENTED ]] texSubImage2D()");
723 }
724
725 void WebGL2RenderingContext::texSubImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, GC3Dint64)
726 {
727     LOG(WebGL, "[[ NOT IMPLEMENTED ]] texSubImage3D()");
728 }
729
730 void WebGL2RenderingContext::texSubImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, RefPtr<ArrayBufferView>&&, GC3Duint)
731 {
732     LOG(WebGL, "[[ NOT IMPLEMENTED ]] texSubImage3D()");
733 }
734
735 void WebGL2RenderingContext::texSubImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, TexImageSource&&)
736 {
737     LOG(WebGL, "[[ NOT IMPLEMENTED ]] texSubImage3D()");
738 }
739
740 void WebGL2RenderingContext::copyTexSubImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei)
741 {
742     LOG(WebGL, "[[ NOT IMPLEMENTED ]] copyTexSubImage3D()");
743 }
744
745 void WebGL2RenderingContext::compressedTexImage2D(GC3Denum, GC3Dint, GC3Denum, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Dsizei, GC3Dint64)
746 {
747     LOG(WebGL, "[[ NOT IMPLEMENTED ]] compressedTexImage2D()");
748 }
749
750 void WebGL2RenderingContext::compressedTexImage2D(GC3Denum, GC3Dint, GC3Denum, GC3Dsizei, GC3Dsizei, GC3Dint, ArrayBufferView&, GC3Duint, GC3Duint)
751 {
752     LOG(WebGL, "[[ NOT IMPLEMENTED ]] compressedTexImage2D()");
753 }
754
755 void WebGL2RenderingContext::compressedTexImage3D(GC3Denum, GC3Dint, GC3Denum, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Dsizei, GC3Dint64)
756 {
757     LOG(WebGL, "[[ NOT IMPLEMENTED ]] compressedTexImage3D()");
758 }
759
760 void WebGL2RenderingContext::compressedTexImage3D(GC3Denum, GC3Dint, GC3Denum, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Dint, ArrayBufferView&, GC3Duint, GC3Duint)
761 {
762     LOG(WebGL, "[[ NOT IMPLEMENTED ]] compressedTexImage3D()");
763 }
764
765 void WebGL2RenderingContext::compressedTexSubImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Dsizei, GC3Dint64)
766 {
767     LOG(WebGL, "[[ NOT IMPLEMENTED ]] compressedTexSubImage3D()");
768 }
769
770 void WebGL2RenderingContext::compressedTexSubImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Denum, ArrayBufferView&, GC3Duint, GC3Duint)
771 {
772     LOG(WebGL, "[[ NOT IMPLEMENTED ]] compressedTexSubImage3D()");
773 }
774
775 GC3Dint WebGL2RenderingContext::getFragDataLocation(WebGLProgram&, const String&)
776 {
777     LOG(WebGL, "[[ NOT IMPLEMENTED ]] getFragDataLocation()");
778     return 0;
779 }
780
781 void WebGL2RenderingContext::uniform1ui(WebGLUniformLocation*, GC3Duint)
782 {
783     LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform1ui()");
784 }
785
786 void WebGL2RenderingContext::uniform2ui(WebGLUniformLocation*, GC3Duint, GC3Duint)
787 {
788     LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform2ui()");
789 }
790
791 void WebGL2RenderingContext::uniform3ui(WebGLUniformLocation*, GC3Duint, GC3Duint, GC3Duint)
792 {
793     LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform3ui()");
794 }
795
796 void WebGL2RenderingContext::uniform4ui(WebGLUniformLocation*, GC3Duint, GC3Duint, GC3Duint, GC3Duint)
797 {
798     LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform4ui()");
799 }
800
801 void WebGL2RenderingContext::uniform1uiv(WebGLUniformLocation*, Uint32List&&, GC3Duint, GC3Duint)
802 {
803     LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform1uiv()");
804 }
805
806 void WebGL2RenderingContext::uniform2uiv(WebGLUniformLocation*, Uint32List&&, GC3Duint, GC3Duint)
807 {
808     LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform2uiv()");
809 }
810
811 void WebGL2RenderingContext::uniform3uiv(WebGLUniformLocation*, Uint32List&&, GC3Duint, GC3Duint)
812 {
813     LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform3uiv()");
814 }
815
816 void WebGL2RenderingContext::uniform4uiv(WebGLUniformLocation*, Uint32List&&, GC3Duint, GC3Duint)
817 {
818     LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform4uiv()");
819 }
820
821 void WebGL2RenderingContext::uniformMatrix2x3fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint)
822 {
823     LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix2x3fv()");
824 }
825
826 void WebGL2RenderingContext::uniformMatrix3x2fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint)
827 {
828     LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix3x2fv()");
829 }
830
831 void WebGL2RenderingContext::uniformMatrix2x4fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint)
832 {
833     LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix2x4fv()");
834 }
835
836 void WebGL2RenderingContext::uniformMatrix4x2fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint)
837 {
838     LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix4x2fv()");
839 }
840
841 void WebGL2RenderingContext::uniformMatrix3x4fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint)
842 {
843     LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix3x4fv()");
844 }
845
846 void WebGL2RenderingContext::uniformMatrix4x3fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint)
847 {
848     LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix4x3fv()");
849 }
850
851 void WebGL2RenderingContext::vertexAttribI4i(GC3Duint, GC3Dint, GC3Dint, GC3Dint, GC3Dint)
852 {
853     LOG(WebGL, "[[ NOT IMPLEMENTED ]] vertexAttribI4i()");
854 }
855
856 void WebGL2RenderingContext::vertexAttribI4iv(GC3Duint, Int32List&&)
857 {
858     LOG(WebGL, "[[ NOT IMPLEMENTED ]] vertexAttribI4iv()");
859 }
860
861 void WebGL2RenderingContext::vertexAttribI4ui(GC3Duint, GC3Duint, GC3Duint, GC3Duint, GC3Duint)
862 {
863     LOG(WebGL, "[[ NOT IMPLEMENTED ]] vertexAttribI4ui()");
864 }
865
866 void WebGL2RenderingContext::vertexAttribI4uiv(GC3Duint, Uint32List&&)
867 {
868     LOG(WebGL, "[[ NOT IMPLEMENTED ]] vertexAttribI4uiv()");
869 }
870
871 void WebGL2RenderingContext::vertexAttribIPointer(GC3Duint, GC3Dint, GC3Denum, GC3Dsizei, GC3Dint64)
872 {
873     LOG(WebGL, "[[ NOT IMPLEMENTED ]] vertexAttribIPointer()");
874 }
875
876 void WebGL2RenderingContext::clear(GC3Dbitfield mask)
877 {
878     if (isContextLostOrPending())
879         return;
880     if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
881         synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clear", "invalid mask");
882         return;
883     }
884     if (m_framebufferBinding && (mask & GraphicsContext3D::COLOR_BUFFER_BIT) && isIntegerFormat(m_framebufferBinding->getColorBufferFormat())) {
885         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clear", "cannot clear an integer buffer");
886         return;
887     }
888     const char* reason = "framebuffer incomplete";
889     if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
890         synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "clear", reason);
891         return;
892     }
893     if (!clearIfComposited(mask))
894         m_context->clear(mask);
895     markContextChangedAndNotifyCanvasObserver();
896 }
897
898 void WebGL2RenderingContext::vertexAttribDivisor(GC3Duint index, GC3Duint divisor)
899 {
900     if (isContextLostOrPending())
901         return;
902     
903     WebGLRenderingContextBase::vertexAttribDivisor(index, divisor);
904 }
905
906 void WebGL2RenderingContext::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei instanceCount)
907 {
908     if (isContextLostOrPending())
909         return;
910
911     WebGLRenderingContextBase::drawArraysInstanced(mode, first, count, instanceCount);
912 }
913
914 void WebGL2RenderingContext::drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dint64 offset, GC3Dsizei instanceCount)
915 {
916     if (isContextLostOrPending())
917         return;
918
919     WebGLRenderingContextBase::drawElementsInstanced(mode, count, type, offset, instanceCount);
920 }
921
922 void WebGL2RenderingContext::drawRangeElements(GC3Denum, GC3Duint, GC3Duint, GC3Dsizei, GC3Denum, GC3Dint64)
923 {
924     LOG(WebGL, "[[ NOT IMPLEMENTED ]] drawRangeElements()");
925 }
926
927 void WebGL2RenderingContext::drawBuffers(const Vector<GC3Denum>& buffers)
928 {
929     if (isContextLost())
930         return;
931     GC3Dsizei n = buffers.size();
932     const GC3Denum* bufs = buffers.data();
933     if (!m_framebufferBinding) {
934         if (n != 1) {
935             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffers", "more than one buffer");
936             return;
937         }
938         if (bufs[0] != GraphicsContext3D::BACK && bufs[0] != GraphicsContext3D::NONE) {
939             synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffers", "BACK or NONE");
940             return;
941         }
942         // Because the backbuffer is simulated on all current WebKit ports, we need to change BACK to COLOR_ATTACHMENT0.
943         GC3Denum value = (bufs[0] == GraphicsContext3D::BACK) ? GraphicsContext3D::COLOR_ATTACHMENT0 : GraphicsContext3D::NONE;
944         graphicsContext3D()->getExtensions().drawBuffersEXT(1, &value);
945         setBackDrawBuffer(bufs[0]);
946     } else {
947         if (n > getMaxDrawBuffers()) {
948             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffers", "more than max draw buffers");
949             return;
950         }
951         for (GC3Dsizei i = 0; i < n; ++i) {
952             if (bufs[i] != GraphicsContext3D::NONE && bufs[i] != static_cast<GC3Denum>(GraphicsContext3D::COLOR_ATTACHMENT0 + i)) {
953                 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffers", "COLOR_ATTACHMENTi or NONE");
954                 return;
955             }
956         }
957         m_framebufferBinding->drawBuffers(buffers);
958     }
959 }
960
961 void WebGL2RenderingContext::clearBufferiv(GC3Denum buffer, GC3Dint drawbuffer, Int32List&&, GC3Duint)
962 {
963     switch (buffer) {
964     case GraphicsContext3D::COLOR:
965         if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) {
966             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferiv", "buffer index out of range");
967             return;
968         }
969         // TODO: Call clearBufferiv, requires gl3.h and ES3/gl.h
970         break;
971     case GraphicsContext3D::STENCIL:
972         if (drawbuffer) {
973             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferiv", "buffer index must be 0");
974             return;
975         }
976         // TODO: Call clearBufferiv, requires gl3.h and ES3/gl.h
977         break;
978     case GraphicsContext3D::DEPTH:
979     case GraphicsContext3D::DEPTH_STENCIL:
980     default:
981         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clearBufferiv", "buffer argument must be COLOR or STENCIL");
982         break;
983     }
984 }
985
986 void WebGL2RenderingContext::clearBufferuiv(GC3Denum buffer, GC3Dint drawbuffer, Uint32List&&, GC3Duint)
987 {
988     switch (buffer) {
989     case GraphicsContext3D::COLOR:
990         if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) {
991             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferuiv", "buffer index out of range");
992             return;
993         }
994         // TODO: Call clearBufferuiv, requires gl3.h and ES3/gl.h
995         break;
996     case GraphicsContext3D::DEPTH:
997     case GraphicsContext3D::STENCIL:
998     case GraphicsContext3D::DEPTH_STENCIL:
999     default:
1000         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clearBufferuiv", "buffer argument must be COLOR");
1001         break;
1002     }
1003 }
1004
1005 void WebGL2RenderingContext::clearBufferfv(GC3Denum buffer, GC3Dint drawbuffer, Float32List&&, GC3Duint)
1006 {
1007     switch (buffer) {
1008     case GraphicsContext3D::COLOR:
1009         if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) {
1010             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferfv", "buffer index out of range");
1011             return;
1012         }
1013         // TODO: Call clearBufferfv, requires gl3.h and ES3/gl.h
1014         break;
1015     case GraphicsContext3D::DEPTH:
1016         if (drawbuffer) {
1017             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferfv", "buffer index must be 0");
1018             return;
1019         }
1020         // TODO: Call clearBufferfv, requires gl3.h and ES3/gl.h
1021         break;
1022     case GraphicsContext3D::STENCIL:
1023     case GraphicsContext3D::DEPTH_STENCIL:
1024     default:
1025         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clearBufferfv", "buffer argument must be COLOR OR DEPTH");
1026         break;
1027     }
1028 }
1029
1030 void WebGL2RenderingContext::clearBufferfi(GC3Denum buffer, GC3Dint drawbuffer, GC3Dfloat, GC3Dint)
1031 {
1032     switch (buffer) {
1033     case GraphicsContext3D::DEPTH_STENCIL:
1034         if (drawbuffer) {
1035             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferfv", "buffer index must be 0");
1036             return;
1037         }
1038         // TODO: Call clearBufferfi, requires gl3.h and ES3/gl.h
1039         break;
1040     case GraphicsContext3D::COLOR:
1041     case GraphicsContext3D::DEPTH:
1042     case GraphicsContext3D::STENCIL:
1043     default:
1044         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clearBufferfv", "buffer argument must be DEPTH_STENCIL");
1045         break;
1046     }
1047 }
1048
1049 RefPtr<WebGLQuery> WebGL2RenderingContext::createQuery()
1050 {
1051     LOG(WebGL, "[[ NOT IMPLEMENTED ]] createQuery()");
1052     return nullptr;
1053 }
1054
1055 void WebGL2RenderingContext::deleteQuery(WebGLQuery*)
1056 {
1057     LOG(WebGL, "[[ NOT IMPLEMENTED ]] deleteQuery()");
1058 }
1059
1060 GC3Dboolean WebGL2RenderingContext::isQuery(WebGLQuery*)
1061 {
1062     LOG(WebGL, "[[ NOT IMPLEMENTED ]] isQuery()");
1063     return false;
1064 }
1065
1066 void WebGL2RenderingContext::beginQuery(GC3Denum, WebGLQuery&)
1067 {
1068     LOG(WebGL, "[[ NOT IMPLEMENTED ]] beginQuery()");
1069 }
1070
1071 void WebGL2RenderingContext::endQuery(GC3Denum)
1072 {
1073     LOG(WebGL, "[[ NOT IMPLEMENTED ]] endQuery()");
1074 }
1075
1076 RefPtr<WebGLQuery> WebGL2RenderingContext::getQuery(GC3Denum, GC3Denum)
1077 {
1078     LOG(WebGL, "[[ NOT IMPLEMENTED ]] getquery()");
1079     return nullptr;
1080 }
1081
1082 WebGLAny WebGL2RenderingContext::getQueryParameter(WebGLQuery&, GC3Denum)
1083 {
1084     LOG(WebGL, "[[ NOT IMPLEMENTED ]] getQueryParameter)");
1085     return nullptr;
1086 }
1087
1088 RefPtr<WebGLSampler> WebGL2RenderingContext::createSampler()
1089 {
1090     LOG(WebGL, "[[ NOT IMPLEMENTED ]] createSampler()");
1091     return nullptr;
1092 }
1093
1094 void WebGL2RenderingContext::deleteSampler(WebGLSampler*)
1095 {
1096     LOG(WebGL, "[[ NOT IMPLEMENTED ]] deleteSampler()");
1097 }
1098
1099 GC3Dboolean WebGL2RenderingContext::isSampler(WebGLSampler*)
1100 {
1101     LOG(WebGL, "[[ NOT IMPLEMENTED ]] isSampler()");
1102     return false;
1103 }
1104
1105 void WebGL2RenderingContext::bindSampler(GC3Duint, WebGLSampler*)
1106 {
1107     LOG(WebGL, "[[ NOT IMPLEMENTED ]] bindSampler()");
1108 }
1109
1110 void WebGL2RenderingContext::samplerParameteri(WebGLSampler&, GC3Denum, GC3Dint)
1111 {
1112     LOG(WebGL, "[[ NOT IMPLEMENTED ]] samplerParameteri()");
1113 }
1114
1115 void WebGL2RenderingContext::samplerParameterf(WebGLSampler&, GC3Denum, GC3Dfloat)
1116 {
1117     LOG(WebGL, "[[ NOT IMPLEMENTED ]] samplerParameterf()");
1118 }
1119
1120 WebGLAny WebGL2RenderingContext::getSamplerParameter(WebGLSampler&, GC3Denum)
1121 {
1122     LOG(WebGL, "[[ NOT IMPLEMENTED ]] getSamplerParameter()");
1123     return nullptr;
1124 }
1125
1126 RefPtr<WebGLSync> WebGL2RenderingContext::fenceSync(GC3Denum, GC3Dbitfield)
1127 {
1128     LOG(WebGL, "[[ NOT IMPLEMENTED ]] fenceSync()");
1129     return nullptr;
1130 }
1131
1132 GC3Dboolean WebGL2RenderingContext::isSync(WebGLSync*)
1133 {
1134     LOG(WebGL, "[[ NOT IMPLEMENTED ]] isSync()");
1135     return false;
1136 }
1137
1138 void WebGL2RenderingContext::deleteSync(WebGLSync*)
1139 {
1140     LOG(WebGL, "[[ NOT IMPLEMENTED ]] deleteSync()");
1141 }
1142
1143 GC3Denum WebGL2RenderingContext::clientWaitSync(WebGLSync&, GC3Dbitfield, GC3Duint64)
1144 {
1145     // Note: Do not implement this function without consulting webkit-dev and WebGL
1146     // reviewers beforehand. Apple folks, see <rdar://problem/36666458>.
1147     LOG(WebGL, "[[ NOT IMPLEMENTED ]] clientWaitSync()");
1148     return 0;
1149 }
1150
1151 void WebGL2RenderingContext::waitSync(WebGLSync&, GC3Dbitfield, GC3Dint64)
1152 {
1153     LOG(WebGL, "[[ NOT IMPLEMENTED ]] waitSync()");
1154 }
1155
1156 WebGLAny WebGL2RenderingContext::getSyncParameter(WebGLSync&, GC3Denum)
1157 {
1158     // Note: Do not implement this function without consulting webkit-dev and WebGL
1159     // reviewers beforehand. Apple folks, see <rdar://problem/36666458>.
1160     LOG(WebGL, "[[ NOT IMPLEMENTED ]] getSyncParameter()");
1161     return nullptr;
1162 }
1163
1164 RefPtr<WebGLTransformFeedback> WebGL2RenderingContext::createTransformFeedback()
1165 {
1166     LOG(WebGL, "[[ NOT IMPLEMENTED ]] createTransformFeedback()");
1167     return nullptr;
1168 }
1169
1170 void WebGL2RenderingContext::deleteTransformFeedback(WebGLTransformFeedback*)
1171 {
1172     LOG(WebGL, "[[ NOT IMPLEMENTED ]] deleteTransformFeedback()");
1173 }
1174
1175 GC3Dboolean WebGL2RenderingContext::isTransformFeedback(WebGLTransformFeedback*)
1176 {
1177     LOG(WebGL, "[[ NOT IMPLEMENTED ]] isTransformFeedback()");
1178     return false;
1179 }
1180
1181 void WebGL2RenderingContext::bindTransformFeedback(GC3Denum, WebGLTransformFeedback*)
1182 {
1183     LOG(WebGL, "[[ NOT IMPLEMENTED ]] bindTransformFeedback()");
1184 }
1185
1186 void WebGL2RenderingContext::beginTransformFeedback(GC3Denum)
1187 {
1188     LOG(WebGL, "[[ NOT IMPLEMENTED ]] beginTransformFeedback()");
1189 }
1190
1191 void WebGL2RenderingContext::endTransformFeedback()
1192 {
1193     LOG(WebGL, "[[ NOT IMPLEMENTED ]] endTransformFeedback()");
1194 }
1195
1196 void WebGL2RenderingContext::transformFeedbackVaryings(WebGLProgram&, const Vector<String>&, GC3Denum)
1197 {
1198     LOG(WebGL, "[[ NOT IMPLEMENTED ]] transformFeedbackVaryings()");
1199 }
1200
1201 RefPtr<WebGLActiveInfo> WebGL2RenderingContext::getTransformFeedbackVarying(WebGLProgram&, GC3Duint)
1202 {
1203     LOG(WebGL, "[[ NOT IMPLEMENTED ]] getTransformFeedbackVarying()");
1204     return nullptr;
1205 }
1206
1207 void WebGL2RenderingContext::pauseTransformFeedback()
1208 {
1209     LOG(WebGL, "[[ NOT IMPLEMENTED ]] pauseTransformFeedback()");
1210 }
1211
1212 void WebGL2RenderingContext::resumeTransformFeedback()
1213 {
1214     LOG(WebGL, "[[ NOT IMPLEMENTED ]] resumeTransformFeedback()");
1215 }
1216
1217 void WebGL2RenderingContext::bindBufferBase(GC3Denum, GC3Duint, WebGLBuffer*)
1218 {
1219     LOG(WebGL, "[[ NOT IMPLEMENTED ]] bindBufferBase()");
1220 }
1221
1222 void WebGL2RenderingContext::bindBufferRange(GC3Denum, GC3Duint, WebGLBuffer*, GC3Dint64, GC3Dint64)
1223 {
1224     LOG(WebGL, "[[ NOT IMPLEMENTED ]] bindBufferRange()");
1225 }
1226
1227 WebGLAny WebGL2RenderingContext::getIndexedParameter(GC3Denum target, GC3Duint)
1228 {
1229     switch (target) {
1230     case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER_BINDING:
1231     case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER_SIZE:
1232     case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER_START:
1233     case GraphicsContext3D::UNIFORM_BUFFER_BINDING:
1234     case GraphicsContext3D::UNIFORM_BUFFER_SIZE:
1235     case GraphicsContext3D::UNIFORM_BUFFER_START:
1236         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getIndexedParameter", "parameter name not yet supported");
1237         return nullptr;
1238     default:
1239         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getIndexedParameter", "invalid parameter name");
1240         return nullptr;
1241     }
1242 }
1243
1244 Optional<Vector<GC3Duint>> WebGL2RenderingContext::getUniformIndices(WebGLProgram&, const Vector<String>&)
1245 {
1246     LOG(WebGL, "[[ NOT IMPLEMENTED ]] getUniformIndices()");
1247     return WTF::nullopt;
1248 }
1249
1250 WebGLAny WebGL2RenderingContext::getActiveUniforms(WebGLProgram& program, const Vector<GC3Duint>& uniformIndices, GC3Denum pname)
1251 {
1252     if (isContextLostOrPending() || !validateWebGLObject("getActiveUniforms", &program))
1253         return nullptr;
1254
1255     switch (pname) {
1256     case GraphicsContext3D::UNIFORM_TYPE:
1257     case GraphicsContext3D::UNIFORM_SIZE:
1258     case GraphicsContext3D::UNIFORM_BLOCK_INDEX:
1259     case GraphicsContext3D::UNIFORM_OFFSET:
1260     case GraphicsContext3D::UNIFORM_ARRAY_STRIDE:
1261     case GraphicsContext3D::UNIFORM_MATRIX_STRIDE:
1262     case GraphicsContext3D::UNIFORM_IS_ROW_MAJOR:
1263         {
1264             Vector<GC3Dint> params(uniformIndices.size(), 0);
1265             m_context->getActiveUniforms(program.object(), uniformIndices, pname, params);
1266             return WTFMove(params);
1267         }
1268     default:
1269         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getActiveUniforms", "invalid parameter name");
1270         return nullptr;
1271     }
1272 }
1273
1274 GC3Duint WebGL2RenderingContext::getUniformBlockIndex(WebGLProgram&, const String&)
1275 {
1276     LOG(WebGL, "[[ NOT IMPLEMENTED ]] getUniformBlockIndex()");
1277     return 0;
1278 }
1279
1280 WebGLAny WebGL2RenderingContext::getActiveUniformBlockParameter(WebGLProgram&, GC3Duint, GC3Denum)
1281 {
1282     LOG(WebGL, "[[ NOT IMPLEMENTED ]] getActiveUniformBlockParameter()");
1283     return nullptr;
1284 }
1285
1286 WebGLAny WebGL2RenderingContext::getActiveUniformBlockName(WebGLProgram&, GC3Duint)
1287 {
1288     LOG(WebGL, "[[ NOT IMPLEMENTED ]] getActiveUniformBlockName()");
1289     return nullptr;
1290 }
1291
1292 void WebGL2RenderingContext::uniformBlockBinding(WebGLProgram&, GC3Duint, GC3Duint)
1293 {
1294     LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformBlockBinding()");
1295 }
1296
1297 RefPtr<WebGLVertexArrayObject> WebGL2RenderingContext::createVertexArray()
1298 {
1299     if (isContextLost())
1300         return nullptr;
1301     
1302     auto object = WebGLVertexArrayObject::create(*this, WebGLVertexArrayObject::Type::User);
1303     addContextObject(object.get());
1304     return WTFMove(object);
1305 }
1306
1307 void WebGL2RenderingContext::deleteVertexArray(WebGLVertexArrayObject* arrayObject)
1308 {
1309     if (!arrayObject || isContextLost())
1310         return;
1311     
1312     if (arrayObject->isDeleted())
1313         return;
1314     
1315     if (!arrayObject->isDefaultObject() && arrayObject == m_boundVertexArrayObject)
1316 #if USE(OPENGL_ES)
1317         setBoundVertexArrayObject(nullptr);
1318 #else
1319         bindVertexArray(nullptr); // The default VAO was removed in OpenGL 3.3 but not from WebGL 2; bind the default for WebGL to use.
1320 #endif
1321     
1322     arrayObject->deleteObject(graphicsContext3D());
1323 }
1324
1325 GC3Dboolean WebGL2RenderingContext::isVertexArray(WebGLVertexArrayObject* arrayObject)
1326 {
1327     if (!arrayObject || isContextLost())
1328         return false;
1329     
1330     if (!arrayObject->hasEverBeenBound() || !arrayObject->validate(0, *this))
1331         return false;
1332     
1333     return m_context->isVertexArray(arrayObject->object());
1334 }
1335
1336 void WebGL2RenderingContext::bindVertexArray(WebGLVertexArrayObject* arrayObject)
1337 {
1338     if (isContextLost())
1339         return;
1340     
1341     if (arrayObject && (arrayObject->isDeleted() || !arrayObject->validate(0, *this) || !m_contextObjects.contains(arrayObject))) {
1342         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
1343         return;
1344     }
1345     if (arrayObject && !arrayObject->isDefaultObject() && arrayObject->object()) {
1346         m_context->bindVertexArray(arrayObject->object());
1347         
1348         arrayObject->setHasEverBeenBound();
1349         setBoundVertexArrayObject(arrayObject);
1350     } else {
1351         m_context->bindVertexArray(m_defaultVertexArrayObject->object());
1352         setBoundVertexArrayObject(m_defaultVertexArrayObject.get());
1353     }
1354 }
1355
1356 WebGLExtension* WebGL2RenderingContext::getExtension(const String& name)
1357 {
1358     if (isContextLostOrPending())
1359         return nullptr;
1360
1361 #define ENABLE_IF_REQUESTED(type, variable, nameLiteral, canEnable) \
1362     if (equalIgnoringASCIICase(name, nameLiteral)) { \
1363         if (!variable) { \
1364             variable = (canEnable) ? makeUnique<type>(*this) : nullptr; \
1365             if (variable != nullptr) \
1366                 InspectorInstrumentation::didEnableExtension(*this, name); \
1367         } \
1368         return variable.get(); \
1369     }
1370
1371     ENABLE_IF_REQUESTED(EXTTextureFilterAnisotropic, m_extTextureFilterAnisotropic, "EXT_texture_filter_anisotropic", enableSupportedExtension("GL_EXT_texture_filter_anisotropic"_s));
1372     ENABLE_IF_REQUESTED(EXTTextureFilterAnisotropic, m_extTextureFilterAnisotropic, "WEBKIT_EXT_texture_filter_anisotropic", enableSupportedExtension("GL_OES_texture_float"_s));
1373     ENABLE_IF_REQUESTED(OESTextureFloat, m_oesTextureFloat, "OES_texture_float", enableSupportedExtension("GL_OES_texture_float"_s));
1374     ENABLE_IF_REQUESTED(OESTextureFloatLinear, m_oesTextureFloatLinear, "OES_texture_float_linear", enableSupportedExtension("GL_OES_texture_float_linear"_s));
1375     ENABLE_IF_REQUESTED(OESTextureHalfFloat, m_oesTextureHalfFloat, "OES_texture_half_float", enableSupportedExtension("GL_OES_texture_half_float"_s));
1376     ENABLE_IF_REQUESTED(OESTextureHalfFloatLinear, m_oesTextureHalfFloatLinear, "OES_texture_half_float_linear", enableSupportedExtension("GL_OES_texture_half_float_linear"_s));
1377     ENABLE_IF_REQUESTED(WebGLLoseContext, m_webglLoseContext, "WEBGL_lose_context", true);
1378     ENABLE_IF_REQUESTED(WebGLCompressedTextureASTC, m_webglCompressedTextureASTC, "WEBGL_compressed_texture_astc", WebGLCompressedTextureASTC::supported(*this));
1379     ENABLE_IF_REQUESTED(WebGLCompressedTextureATC, m_webglCompressedTextureATC, "WEBKIT_WEBGL_compressed_texture_atc", WebGLCompressedTextureATC::supported(*this));
1380     ENABLE_IF_REQUESTED(WebGLCompressedTextureETC, m_webglCompressedTextureETC, "WEBGL_compressed_texture_etc", WebGLCompressedTextureETC::supported(*this));
1381     ENABLE_IF_REQUESTED(WebGLCompressedTextureETC1, m_webglCompressedTextureETC1, "WEBGL_compressed_texture_etc1", WebGLCompressedTextureETC1::supported(*this));
1382     ENABLE_IF_REQUESTED(WebGLCompressedTexturePVRTC, m_webglCompressedTexturePVRTC, "WEBKIT_WEBGL_compressed_texture_pvrtc", WebGLCompressedTexturePVRTC::supported(*this));
1383     ENABLE_IF_REQUESTED(WebGLCompressedTextureS3TC, m_webglCompressedTextureS3TC, "WEBGL_compressed_texture_s3tc", WebGLCompressedTextureS3TC::supported(*this));
1384     ENABLE_IF_REQUESTED(WebGLDepthTexture, m_webglDepthTexture, "WEBGL_depth_texture", WebGLDepthTexture::supported(*graphicsContext3D()));
1385     ENABLE_IF_REQUESTED(WebGLDebugRendererInfo, m_webglDebugRendererInfo, "WEBGL_debug_renderer_info", true);
1386     ENABLE_IF_REQUESTED(WebGLDebugShaders, m_webglDebugShaders, "WEBGL_debug_shaders", m_context->getExtensions().supports("GL_ANGLE_translated_shader_source"_s));
1387     return nullptr;
1388 }
1389
1390 Optional<Vector<String>> WebGL2RenderingContext::getSupportedExtensions()
1391 {
1392     if (isContextLost())
1393         return WTF::nullopt;
1394
1395     Vector<String> result;
1396     
1397     if (m_isPendingPolicyResolution)
1398         return result;
1399
1400     auto& extensions = m_context->getExtensions();
1401     if (extensions.supports("GL_OES_texture_float"_s))
1402         result.append("OES_texture_float"_s);
1403     if (extensions.supports("GL_OES_texture_float_linear"_s))
1404         result.append("OES_texture_float_linear"_s);
1405     if (extensions.supports("GL_OES_texture_half_float"_s))
1406         result.append("OES_texture_half_float"_s);
1407     if (extensions.supports("GL_OES_texture_half_float_linear"_s))
1408         result.append("OES_texture_half_float_linear"_s);
1409     if (extensions.supports("GL_EXT_texture_filter_anisotropic"_s))
1410         result.append("WEBKIT_EXT_texture_filter_anisotropic"_s);
1411     if (WebGLCompressedTextureASTC::supported(*this))
1412         result.append("WEBGL_compressed_texture_astc"_s);
1413     if (WebGLCompressedTextureATC::supported(*this))
1414         result.append("WEBKIT_WEBGL_compressed_texture_atc"_s);
1415     if (WebGLCompressedTextureETC::supported(*this))
1416         result.append("WEBGL_compressed_texture_etc"_s);
1417     if (WebGLCompressedTextureETC1::supported(*this))
1418         result.append("WEBGL_compressed_texture_etc1"_s);
1419     if (WebGLCompressedTexturePVRTC::supported(*this))
1420         result.append("WEBKIT_WEBGL_compressed_texture_pvrtc"_s);
1421     if (WebGLCompressedTextureS3TC::supported(*this))
1422         result.append("WEBGL_compressed_texture_s3tc"_s);
1423     if (WebGLDepthTexture::supported(*graphicsContext3D()))
1424         result.append("WEBGL_depth_texture"_s);
1425     result.append("WEBGL_lose_context"_s);
1426     if (extensions.supports("GL_ANGLE_translated_shader_source"_s))
1427         result.append("WEBGL_debug_shaders"_s);
1428     result.append("WEBGL_debug_renderer_info"_s);
1429
1430     return result;
1431 }
1432
1433 static bool validateDefaultFramebufferAttachment(GC3Denum& attachment)
1434 {
1435     switch (attachment) {
1436     case GraphicsContext3D::BACK:
1437         // Because the backbuffer is simulated on all current WebKit ports, we need to change BACK to COLOR_ATTACHMENT0.
1438         attachment = GraphicsContext3D::COLOR_ATTACHMENT0;
1439         return true;
1440     case GraphicsContext3D::DEPTH:
1441     case GraphicsContext3D::STENCIL:
1442         return true;
1443     }
1444
1445     return false;
1446 }
1447
1448 WebGLAny WebGL2RenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname)
1449 {
1450     const char* functionName = "getFramebufferAttachmentParameter";
1451     if (isContextLostOrPending() || !validateFramebufferTarget(functionName, target))
1452         return nullptr;
1453
1454     auto targetFramebuffer = (target == GraphicsContext3D::READ_FRAMEBUFFER) ? m_readFramebufferBinding : m_framebufferBinding;
1455
1456     if (!targetFramebuffer) {
1457         // OpenGL ES 3: Default framebuffer is bound.
1458         if (!validateDefaultFramebufferAttachment(attachment)) {
1459             synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid attachment");
1460             return nullptr;
1461         }
1462         GC3Dint value = 0;
1463         m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
1464         return value;
1465     }
1466     if (!validateNonDefaultFramebufferAttachment(functionName, attachment))
1467         return nullptr;
1468
1469     auto object = makeRefPtr(targetFramebuffer->getAttachmentObject(attachment));
1470     if (!object) {
1471         if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
1472             return static_cast<unsigned>(GraphicsContext3D::NONE);
1473         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid parameter name");
1474         return nullptr;
1475     }
1476
1477     switch (pname) {
1478     case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_RED_SIZE:
1479     case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
1480     case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
1481     case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
1482     case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
1483     case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
1484     case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: {
1485         GC3Dint value = 0;
1486         m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
1487         return value;
1488     }
1489     }
1490     
1491     if (object->isTexture()) {
1492         switch (pname) {
1493         case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
1494             return static_cast<unsigned>(GraphicsContext3D::TEXTURE);
1495         case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
1496             return makeRefPtr(reinterpret_cast<WebGLTexture&>(*object));
1497         case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
1498         case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
1499         case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: {
1500             GC3Dint value = 0;
1501             m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
1502             return value;
1503         }
1504         default:
1505             synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid parameter name for texture attachment");
1506             return nullptr;
1507         }
1508     } else {
1509         ASSERT(object->isRenderbuffer());
1510         switch (pname) {
1511         case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
1512             return static_cast<unsigned>(GraphicsContext3D::RENDERBUFFER);
1513         case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
1514             return makeRefPtr(reinterpret_cast<WebGLRenderbuffer&>(*object));
1515         case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING : {
1516             auto& renderBuffer = reinterpret_cast<WebGLRenderbuffer&>(*object);
1517             auto format = renderBuffer.getInternalFormat();
1518             if (format == GraphicsContext3D::SRGB8_ALPHA8
1519                 || format == GraphicsContext3D::COMPRESSED_SRGB8_ETC2
1520                 || format == GraphicsContext3D::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
1521                 || format == GraphicsContext3D::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2) {
1522                 return static_cast<unsigned>(GraphicsContext3D::SRGB);
1523             }
1524             return static_cast<unsigned>(GraphicsContext3D::LINEAR);
1525         }
1526         default:
1527             synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid parameter name for renderbuffer attachment");
1528             return nullptr;
1529         }
1530     }
1531 }
1532
1533 bool WebGL2RenderingContext::validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment)
1534 {
1535     return validateFramebufferTarget(functionName, target) && validateNonDefaultFramebufferAttachment(functionName, attachment);
1536 }
1537
1538 bool WebGL2RenderingContext::validateFramebufferTarget(const char* functionName, GC3Denum target)
1539 {
1540     switch (target) {
1541     case GraphicsContext3D::FRAMEBUFFER:
1542     case GraphicsContext3D::DRAW_FRAMEBUFFER:
1543     case GraphicsContext3D::READ_FRAMEBUFFER:
1544         return true;
1545     }
1546
1547     synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
1548     return false;
1549 }
1550
1551 bool WebGL2RenderingContext::validateNonDefaultFramebufferAttachment(const char* functionName, GC3Denum attachment)
1552 {
1553     switch (attachment) {
1554     case GraphicsContext3D::DEPTH_ATTACHMENT:
1555     case GraphicsContext3D::STENCIL_ATTACHMENT:
1556     case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
1557         return true;
1558     default:
1559         if (attachment >= GraphicsContext3D::COLOR_ATTACHMENT0 && attachment < static_cast<GC3Denum>(GraphicsContext3D::COLOR_ATTACHMENT0 + getMaxColorAttachments()))
1560             return true;
1561     }
1562
1563     synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid attachment");
1564     return false;
1565 }
1566
1567 GC3Dint WebGL2RenderingContext::getMaxDrawBuffers()
1568 {
1569     if (!m_maxDrawBuffers)
1570         m_context->getIntegerv(GraphicsContext3D::MAX_DRAW_BUFFERS, &m_maxDrawBuffers);
1571     return m_maxDrawBuffers;
1572 }
1573
1574 GC3Dint WebGL2RenderingContext::getMaxColorAttachments()
1575 {
1576     // DrawBuffers requires MAX_COLOR_ATTACHMENTS == MAX_DRAW_BUFFERS
1577     if (!m_maxColorAttachments)
1578         m_context->getIntegerv(GraphicsContext3D::MAX_DRAW_BUFFERS, &m_maxColorAttachments);
1579     return m_maxColorAttachments;
1580 }
1581
1582 void WebGL2RenderingContext::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
1583 {
1584     if (isContextLostOrPending())
1585         return;
1586     if (target != GraphicsContext3D::RENDERBUFFER) {
1587         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid target");
1588         return;
1589     }
1590     if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
1591         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "renderbufferStorage", "no bound renderbuffer");
1592         return;
1593     }
1594     if (!validateSize("renderbufferStorage", width, height))
1595         return;
1596     switch (internalformat) {
1597     case GraphicsContext3D::DEPTH_COMPONENT16:
1598     case GraphicsContext3D::DEPTH_COMPONENT32F:
1599     case GraphicsContext3D::DEPTH_COMPONENT24:
1600     case GraphicsContext3D::RGBA32I:
1601     case GraphicsContext3D::RGBA32UI:
1602     case GraphicsContext3D::RGBA16I:
1603     case GraphicsContext3D::RGBA16UI:
1604     case GraphicsContext3D::RGBA8:
1605     case GraphicsContext3D::RGBA8I:
1606     case GraphicsContext3D::RGBA8UI:
1607     case GraphicsContext3D::RGB10_A2:
1608     case GraphicsContext3D::RGB10_A2UI:
1609     case GraphicsContext3D::RGBA4:
1610     case GraphicsContext3D::RG32I:
1611     case GraphicsContext3D::RG32UI:
1612     case GraphicsContext3D::RG16I:
1613     case GraphicsContext3D::RG16UI:
1614     case GraphicsContext3D::RG8:
1615     case GraphicsContext3D::RG8I:
1616     case GraphicsContext3D::RG8UI:
1617     case GraphicsContext3D::R32I:
1618     case GraphicsContext3D::R32UI:
1619     case GraphicsContext3D::R16I:
1620     case GraphicsContext3D::R16UI:
1621     case GraphicsContext3D::R8:
1622     case GraphicsContext3D::R8I:
1623     case GraphicsContext3D::R8UI:
1624     case GraphicsContext3D::RGB5_A1:
1625     case GraphicsContext3D::RGB565:
1626     case GraphicsContext3D::RGB8:
1627     case GraphicsContext3D::STENCIL_INDEX8:
1628     case GraphicsContext3D::SRGB8_ALPHA8:
1629         m_context->renderbufferStorage(target, internalformat, width, height);
1630         m_renderbufferBinding->setInternalFormat(internalformat);
1631         m_renderbufferBinding->setIsValid(true);
1632         m_renderbufferBinding->setSize(width, height);
1633         break;
1634     case GraphicsContext3D::DEPTH32F_STENCIL8:
1635     case GraphicsContext3D::DEPTH24_STENCIL8:
1636         if (!isDepthStencilSupported()) {
1637             synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
1638             return;
1639         }
1640         m_context->renderbufferStorage(target, internalformat, width, height);
1641         m_renderbufferBinding->setSize(width, height);
1642         m_renderbufferBinding->setIsValid(isDepthStencilSupported());
1643         m_renderbufferBinding->setInternalFormat(internalformat);
1644         break;
1645     default:
1646         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
1647         return;
1648     }
1649     applyStencilTest();
1650 }
1651
1652 void WebGL2RenderingContext::hint(GC3Denum target, GC3Denum mode)
1653 {
1654     if (isContextLostOrPending())
1655         return;
1656     bool isValid = false;
1657     switch (target) {
1658     case GraphicsContext3D::GENERATE_MIPMAP_HINT:
1659     case GraphicsContext3D::FRAGMENT_SHADER_DERIVATIVE_HINT:
1660         isValid = true;
1661         break;
1662     }
1663     if (!isValid) {
1664         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "hint", "invalid target");
1665         return;
1666     }
1667     m_context->hint(target, mode);
1668 }
1669
1670 GC3Denum WebGL2RenderingContext::baseInternalFormatFromInternalFormat(GC3Denum internalformat)
1671 {
1672     // Handles sized, unsized, and compressed internal formats.
1673     switch (internalformat) {
1674     case GraphicsContext3D::R8:
1675     case GraphicsContext3D::R8_SNORM:
1676     case GraphicsContext3D::R16F:
1677     case GraphicsContext3D::R32F:
1678     case GraphicsContext3D::COMPRESSED_R11_EAC:
1679     case GraphicsContext3D::COMPRESSED_SIGNED_R11_EAC:
1680         return GraphicsContext3D::RED;
1681     case GraphicsContext3D::R8I:
1682     case GraphicsContext3D::R8UI:
1683     case GraphicsContext3D::R16I:
1684     case GraphicsContext3D::R16UI:
1685     case GraphicsContext3D::R32I:
1686     case GraphicsContext3D::R32UI:
1687         return GraphicsContext3D::RED_INTEGER;
1688     case GraphicsContext3D::RG8:
1689     case GraphicsContext3D::RG8_SNORM:
1690     case GraphicsContext3D::RG16F:
1691     case GraphicsContext3D::RG32F:
1692     case GraphicsContext3D::COMPRESSED_RG11_EAC:
1693     case GraphicsContext3D::COMPRESSED_SIGNED_RG11_EAC:
1694         return GraphicsContext3D::RG;
1695     case GraphicsContext3D::RG8I:
1696     case GraphicsContext3D::RG8UI:
1697     case GraphicsContext3D::RG16I:
1698     case GraphicsContext3D::RG16UI:
1699     case GraphicsContext3D::RG32I:
1700     case GraphicsContext3D::RG32UI:
1701         return GraphicsContext3D::RG_INTEGER;
1702     case GraphicsContext3D::RGB8:
1703     case GraphicsContext3D::RGB8_SNORM:
1704     case GraphicsContext3D::RGB565:
1705     case GraphicsContext3D::SRGB8:
1706     case GraphicsContext3D::RGB16F:
1707     case GraphicsContext3D::RGB32F:
1708     case GraphicsContext3D::RGB:
1709     case GraphicsContext3D::COMPRESSED_RGB8_ETC2:
1710     case GraphicsContext3D::COMPRESSED_SRGB8_ETC2:
1711         return GraphicsContext3D::RGB;
1712     case GraphicsContext3D::RGB8I:
1713     case GraphicsContext3D::RGB8UI:
1714     case GraphicsContext3D::RGB16I:
1715     case GraphicsContext3D::RGB16UI:
1716     case GraphicsContext3D::RGB32I:
1717     case GraphicsContext3D::RGB32UI:
1718         return GraphicsContext3D::RGB_INTEGER;
1719     case GraphicsContext3D::RGBA4:
1720     case GraphicsContext3D::RGB5_A1:
1721     case GraphicsContext3D::RGBA8:
1722     case GraphicsContext3D::RGBA8_SNORM:
1723     case GraphicsContext3D::RGB10_A2:
1724     case GraphicsContext3D::SRGB8_ALPHA8:
1725     case GraphicsContext3D::RGBA16F:
1726     case GraphicsContext3D::RGBA32F:
1727     case GraphicsContext3D::RGBA:
1728     case GraphicsContext3D::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1729     case GraphicsContext3D::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1730     case GraphicsContext3D::COMPRESSED_RGBA8_ETC2_EAC:
1731     case GraphicsContext3D::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
1732         return GraphicsContext3D::RGBA;
1733     case GraphicsContext3D::RGBA8I:
1734     case GraphicsContext3D::RGBA8UI:
1735     case GraphicsContext3D::RGB10_A2UI:
1736     case GraphicsContext3D::RGBA16I:
1737     case GraphicsContext3D::RGBA16UI:
1738     case GraphicsContext3D::RGBA32I:
1739     case GraphicsContext3D::RGBA32UI:
1740         return GraphicsContext3D::RGBA_INTEGER;
1741     case GraphicsContext3D::DEPTH_COMPONENT16:
1742     case GraphicsContext3D::DEPTH_COMPONENT24:
1743     case GraphicsContext3D::DEPTH_COMPONENT32F:
1744         return GraphicsContext3D::DEPTH_COMPONENT;
1745     case GraphicsContext3D::DEPTH24_STENCIL8:
1746     case GraphicsContext3D::DEPTH32F_STENCIL8:
1747         return GraphicsContext3D::DEPTH_STENCIL;
1748     case GraphicsContext3D::LUMINANCE:
1749     case GraphicsContext3D::LUMINANCE_ALPHA:
1750     case GraphicsContext3D::ALPHA:
1751         return internalformat;
1752     default:
1753         ASSERT_NOT_REACHED();
1754         return GraphicsContext3D::NONE;
1755     }
1756 }
1757
1758 bool WebGL2RenderingContext::isIntegerFormat(GC3Denum internalformat)
1759 {
1760     switch (baseInternalFormatFromInternalFormat(internalformat)) {
1761     case GraphicsContext3D::RED_INTEGER:
1762     case GraphicsContext3D::RG_INTEGER:
1763     case GraphicsContext3D::RGB_INTEGER:
1764     case GraphicsContext3D::RGBA_INTEGER:
1765         return true;
1766     }
1767     return false;
1768 }
1769
1770 WebGLAny WebGL2RenderingContext::getParameter(GC3Denum pname)
1771 {
1772     if (isContextLostOrPending())
1773         return nullptr;
1774     switch (pname) {
1775     case GraphicsContext3D::ACTIVE_TEXTURE:
1776         return getUnsignedIntParameter(pname);
1777     case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
1778         return getWebGLFloatArrayParameter(pname);
1779     case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
1780         return getWebGLFloatArrayParameter(pname);
1781     case GraphicsContext3D::ALPHA_BITS:
1782         if (!m_framebufferBinding && !m_attributes.alpha)
1783             return 0;
1784         return getIntParameter(pname);
1785     case GraphicsContext3D::ARRAY_BUFFER_BINDING:
1786         return m_boundArrayBuffer;
1787     case GraphicsContext3D::BLEND:
1788         return getBooleanParameter(pname);
1789     case GraphicsContext3D::BLEND_COLOR:
1790         return getWebGLFloatArrayParameter(pname);
1791     case GraphicsContext3D::BLEND_DST_ALPHA:
1792         return getUnsignedIntParameter(pname);
1793     case GraphicsContext3D::BLEND_DST_RGB:
1794         return getUnsignedIntParameter(pname);
1795     case GraphicsContext3D::BLEND_EQUATION_ALPHA:
1796         return getUnsignedIntParameter(pname);
1797     case GraphicsContext3D::BLEND_EQUATION_RGB:
1798         return getUnsignedIntParameter(pname);
1799     case GraphicsContext3D::BLEND_SRC_ALPHA:
1800         return getUnsignedIntParameter(pname);
1801     case GraphicsContext3D::BLEND_SRC_RGB:
1802         return getUnsignedIntParameter(pname);
1803     case GraphicsContext3D::BLUE_BITS:
1804         return getIntParameter(pname);
1805     case GraphicsContext3D::COLOR_CLEAR_VALUE:
1806         return getWebGLFloatArrayParameter(pname);
1807     case GraphicsContext3D::COLOR_WRITEMASK:
1808         return getBooleanArrayParameter(pname);
1809     case GraphicsContext3D::COMPRESSED_TEXTURE_FORMATS:
1810         return Uint32Array::tryCreate(m_compressedTextureFormats.data(), m_compressedTextureFormats.size());
1811     case GraphicsContext3D::CULL_FACE:
1812         return getBooleanParameter(pname);
1813     case GraphicsContext3D::CULL_FACE_MODE:
1814         return getUnsignedIntParameter(pname);
1815     case GraphicsContext3D::CURRENT_PROGRAM:
1816         return m_currentProgram;
1817     case GraphicsContext3D::DEPTH_BITS:
1818         if (!m_framebufferBinding && !m_attributes.depth)
1819             return 0;
1820         return getIntParameter(pname);
1821     case GraphicsContext3D::DEPTH_CLEAR_VALUE:
1822         return getFloatParameter(pname);
1823     case GraphicsContext3D::DEPTH_FUNC:
1824         return getUnsignedIntParameter(pname);
1825     case GraphicsContext3D::DEPTH_RANGE:
1826         return getWebGLFloatArrayParameter(pname);
1827     case GraphicsContext3D::DEPTH_TEST:
1828         return getBooleanParameter(pname);
1829     case GraphicsContext3D::DEPTH_WRITEMASK:
1830         return getBooleanParameter(pname);
1831     case GraphicsContext3D::DITHER:
1832         return getBooleanParameter(pname);
1833     case GraphicsContext3D::ELEMENT_ARRAY_BUFFER_BINDING:
1834         return makeRefPtr(m_boundVertexArrayObject->getElementArrayBuffer());
1835     case GraphicsContext3D::FRAMEBUFFER_BINDING:
1836         return m_framebufferBinding;
1837     case GraphicsContext3D::FRONT_FACE:
1838         return getUnsignedIntParameter(pname);
1839     case GraphicsContext3D::GENERATE_MIPMAP_HINT:
1840         return getUnsignedIntParameter(pname);
1841     case GraphicsContext3D::GREEN_BITS:
1842         return getIntParameter(pname);
1843     case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT:
1844         return getIntParameter(pname);
1845     case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE:
1846         return getIntParameter(pname);
1847     case GraphicsContext3D::LINE_WIDTH:
1848         return getFloatParameter(pname);
1849     case GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1850         return getIntParameter(pname);
1851     case GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE:
1852         return getIntParameter(pname);
1853     case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS:
1854         return getIntParameter(pname);
1855     case GraphicsContext3D::MAX_RENDERBUFFER_SIZE:
1856         return getIntParameter(pname);
1857     case GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS:
1858         return getIntParameter(pname);
1859     case GraphicsContext3D::MAX_TEXTURE_SIZE:
1860         return getIntParameter(pname);
1861     case GraphicsContext3D::MAX_VARYING_VECTORS:
1862         return getIntParameter(pname);
1863     case GraphicsContext3D::MAX_VERTEX_ATTRIBS:
1864         return getIntParameter(pname);
1865     case GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1866         return getIntParameter(pname);
1867     case GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS:
1868         return getIntParameter(pname);
1869     case GraphicsContext3D::MAX_VIEWPORT_DIMS:
1870         return getWebGLIntArrayParameter(pname);
1871     case GraphicsContext3D::NUM_SHADER_BINARY_FORMATS:
1872         return getIntParameter(pname);
1873     case GraphicsContext3D::PACK_ALIGNMENT:
1874         return getIntParameter(pname);
1875     case GraphicsContext3D::POLYGON_OFFSET_FACTOR:
1876         return getFloatParameter(pname);
1877     case GraphicsContext3D::POLYGON_OFFSET_FILL:
1878         return getBooleanParameter(pname);
1879     case GraphicsContext3D::POLYGON_OFFSET_UNITS:
1880         return getFloatParameter(pname);
1881     case GraphicsContext3D::RED_BITS:
1882         return getIntParameter(pname);
1883     case GraphicsContext3D::RENDERBUFFER_BINDING:
1884         return m_renderbufferBinding;
1885     case GraphicsContext3D::RENDERER:
1886         return "WebKit WebGL"_str;
1887     case GraphicsContext3D::SAMPLE_BUFFERS:
1888         return getIntParameter(pname);
1889     case GraphicsContext3D::SAMPLE_COVERAGE_INVERT:
1890         return getBooleanParameter(pname);
1891     case GraphicsContext3D::SAMPLE_COVERAGE_VALUE:
1892         return getFloatParameter(pname);
1893     case GraphicsContext3D::SAMPLES:
1894         return getIntParameter(pname);
1895     case GraphicsContext3D::SCISSOR_BOX:
1896         return getWebGLIntArrayParameter(pname);
1897     case GraphicsContext3D::SCISSOR_TEST:
1898         return getBooleanParameter(pname);
1899     case GraphicsContext3D::SHADING_LANGUAGE_VERSION:
1900         return "WebGL GLSL ES 1.0 (" + m_context->getString(GraphicsContext3D::SHADING_LANGUAGE_VERSION) + ")";
1901     case GraphicsContext3D::STENCIL_BACK_FAIL:
1902         return getUnsignedIntParameter(pname);
1903     case GraphicsContext3D::STENCIL_BACK_FUNC:
1904         return getUnsignedIntParameter(pname);
1905     case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_FAIL:
1906         return getUnsignedIntParameter(pname);
1907     case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_PASS:
1908         return getUnsignedIntParameter(pname);
1909     case GraphicsContext3D::STENCIL_BACK_REF:
1910         return getIntParameter(pname);
1911     case GraphicsContext3D::STENCIL_BACK_VALUE_MASK:
1912         return getUnsignedIntParameter(pname);
1913     case GraphicsContext3D::STENCIL_BACK_WRITEMASK:
1914         return getUnsignedIntParameter(pname);
1915     case GraphicsContext3D::STENCIL_BITS:
1916         if (!m_framebufferBinding && !m_attributes.stencil)
1917             return 0;
1918         return getIntParameter(pname);
1919     case GraphicsContext3D::STENCIL_CLEAR_VALUE:
1920         return getIntParameter(pname);
1921     case GraphicsContext3D::STENCIL_FAIL:
1922         return getUnsignedIntParameter(pname);
1923     case GraphicsContext3D::STENCIL_FUNC:
1924         return getUnsignedIntParameter(pname);
1925     case GraphicsContext3D::STENCIL_PASS_DEPTH_FAIL:
1926         return getUnsignedIntParameter(pname);
1927     case GraphicsContext3D::STENCIL_PASS_DEPTH_PASS:
1928         return getUnsignedIntParameter(pname);
1929     case GraphicsContext3D::STENCIL_REF:
1930         return getIntParameter(pname);
1931     case GraphicsContext3D::STENCIL_TEST:
1932         return getBooleanParameter(pname);
1933     case GraphicsContext3D::STENCIL_VALUE_MASK:
1934         return getUnsignedIntParameter(pname);
1935     case GraphicsContext3D::STENCIL_WRITEMASK:
1936         return getUnsignedIntParameter(pname);
1937     case GraphicsContext3D::SUBPIXEL_BITS:
1938         return getIntParameter(pname);
1939     case GraphicsContext3D::TEXTURE_BINDING_2D:
1940         return m_textureUnits[m_activeTextureUnit].texture2DBinding;
1941     case GraphicsContext3D::TEXTURE_BINDING_CUBE_MAP:
1942         return m_textureUnits[m_activeTextureUnit].textureCubeMapBinding;
1943     case GraphicsContext3D::UNPACK_ALIGNMENT:
1944         return getIntParameter(pname);
1945     case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
1946         return m_unpackFlipY;
1947     case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
1948         return m_unpackPremultiplyAlpha;
1949     case GraphicsContext3D::UNPACK_COLORSPACE_CONVERSION_WEBGL:
1950         return m_unpackColorspaceConversion;
1951     case GraphicsContext3D::VENDOR:
1952         return "WebKit"_str;
1953     case GraphicsContext3D::VERSION:
1954         return "WebGL 2.0"_str;
1955     case GraphicsContext3D::VIEWPORT:
1956         return getWebGLIntArrayParameter(pname);
1957     case WebGLDebugRendererInfo::UNMASKED_RENDERER_WEBGL:
1958         if (m_webglDebugRendererInfo) {
1959 #if PLATFORM(IOS_FAMILY)
1960             return "Apple GPU"_str;
1961 #else
1962             return m_context->getString(GraphicsContext3D::RENDERER);
1963 #endif
1964         }
1965         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
1966         return nullptr;
1967     case WebGLDebugRendererInfo::UNMASKED_VENDOR_WEBGL:
1968         if (m_webglDebugRendererInfo)
1969             return m_context->getString(GraphicsContext3D::VENDOR);
1970         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
1971         return nullptr;
1972     case Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
1973         if (m_extTextureFilterAnisotropic)
1974             return getUnsignedIntParameter(Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT);
1975         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
1976         return nullptr;
1977     case GraphicsContext3D::FRAGMENT_SHADER_DERIVATIVE_HINT:
1978         return getIntParameter(pname);
1979     case GraphicsContext3D::MAX_3D_TEXTURE_SIZE:
1980         return getIntParameter(pname);
1981     case GraphicsContext3D::MAX_ARRAY_TEXTURE_LAYERS:
1982         return getIntParameter(pname);
1983     case GraphicsContext3D::MAX_COLOR_ATTACHMENTS:
1984         return getIntParameter(pname);
1985     case GraphicsContext3D::MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1986         return getInt64Parameter(pname);
1987     case GraphicsContext3D::MAX_COMBINED_UNIFORM_BLOCKS:
1988         return getIntParameter(pname);
1989     case GraphicsContext3D::MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1990         return getInt64Parameter(pname);
1991     case GraphicsContext3D::MAX_DRAW_BUFFERS:
1992         return getIntParameter(pname);
1993     case GraphicsContext3D::MAX_ELEMENT_INDEX:
1994         return getInt64Parameter(pname);
1995     case GraphicsContext3D::MAX_ELEMENTS_INDICES:
1996         return getIntParameter(pname);
1997     case GraphicsContext3D::MAX_ELEMENTS_VERTICES:
1998         return getIntParameter(pname);
1999     case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_COMPONENTS:
2000         return getIntParameter(pname);
2001     case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_BLOCKS:
2002         return getIntParameter(pname);
2003     case GraphicsContext3D::MAX_PROGRAM_TEXEL_OFFSET:
2004         return getIntParameter(pname);
2005     case GraphicsContext3D::MAX_SAMPLES:
2006         return getIntParameter(pname);
2007     case GraphicsContext3D::MAX_SERVER_WAIT_TIMEOUT:
2008         return getInt64Parameter(pname);
2009     case GraphicsContext3D::MAX_TEXTURE_LOD_BIAS:
2010         return getIntParameter(pname);
2011     case GraphicsContext3D::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
2012         return getIntParameter(pname);
2013     case GraphicsContext3D::MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
2014         return getIntParameter(pname);
2015     case GraphicsContext3D::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
2016         return getIntParameter(pname);
2017     case GraphicsContext3D::MAX_UNIFORM_BLOCK_SIZE:
2018         return getInt64Parameter(pname);
2019     case GraphicsContext3D::MAX_UNIFORM_BUFFER_BINDINGS:
2020         return getIntParameter(pname);
2021     case GraphicsContext3D::MAX_VARYING_COMPONENTS:
2022         return getIntParameter(pname);
2023     case GraphicsContext3D::MAX_VERTEX_OUTPUT_COMPONENTS:
2024         return getIntParameter(pname);
2025     case GraphicsContext3D::MAX_VERTEX_UNIFORM_BLOCKS:
2026         return getIntParameter(pname);
2027     case GraphicsContext3D::MAX_VERTEX_UNIFORM_COMPONENTS: 
2028         return getIntParameter(pname);                            
2029     case GraphicsContext3D::MIN_PROGRAM_TEXEL_OFFSET:
2030         return getIntParameter(pname);
2031     case GraphicsContext3D::PACK_ROW_LENGTH:
2032         return getIntParameter(pname);
2033     case GraphicsContext3D::PACK_SKIP_PIXELS:
2034         return getIntParameter(pname);
2035     case GraphicsContext3D::PACK_SKIP_ROWS:
2036         return getIntParameter(pname);
2037     case GraphicsContext3D::UNPACK_IMAGE_HEIGHT:
2038         return getIntParameter(pname);
2039     case GraphicsContext3D::UNPACK_ROW_LENGTH:
2040         return getIntParameter(pname);
2041     case GraphicsContext3D::UNPACK_SKIP_IMAGES:
2042         return getIntParameter(pname);
2043     case GraphicsContext3D::UNPACK_SKIP_PIXELS:
2044         return getIntParameter(pname);
2045     case GraphicsContext3D::UNPACK_SKIP_ROWS:
2046         return getIntParameter(pname);
2047     case GraphicsContext3D::RASTERIZER_DISCARD:
2048         return getBooleanParameter(pname);
2049     case GraphicsContext3D::SAMPLE_ALPHA_TO_COVERAGE:
2050         return getBooleanParameter(pname);
2051     case GraphicsContext3D::SAMPLE_COVERAGE:
2052         return getBooleanParameter(pname);
2053     case GraphicsContext3D::TRANSFORM_FEEDBACK_ACTIVE:
2054         return getBooleanParameter(pname);
2055     case GraphicsContext3D::TRANSFORM_FEEDBACK_PAUSED:
2056         return getBooleanParameter(pname);
2057     case GraphicsContext3D::UNIFORM_BUFFER_OFFSET_ALIGNMENT:
2058         return getIntParameter(pname);
2059     case GraphicsContext3D::VERTEX_ARRAY_BINDING:
2060         if (m_boundVertexArrayObject->isDefaultObject())
2061             return nullptr;
2062         return makeRefPtr(static_cast<WebGLVertexArrayObject&>(*m_boundVertexArrayObject));
2063     case GraphicsContext3D::DRAW_BUFFER0:
2064     case GraphicsContext3D::DRAW_BUFFER1:
2065     case GraphicsContext3D::DRAW_BUFFER2:
2066     case GraphicsContext3D::DRAW_BUFFER3:
2067     case GraphicsContext3D::DRAW_BUFFER4:
2068     case GraphicsContext3D::DRAW_BUFFER5:
2069     case GraphicsContext3D::DRAW_BUFFER6:
2070     case GraphicsContext3D::DRAW_BUFFER7:
2071     case GraphicsContext3D::DRAW_BUFFER8:
2072     case GraphicsContext3D::DRAW_BUFFER9:
2073     case GraphicsContext3D::DRAW_BUFFER10:
2074     case GraphicsContext3D::DRAW_BUFFER11:
2075     case GraphicsContext3D::DRAW_BUFFER12:
2076     case GraphicsContext3D::DRAW_BUFFER13:
2077     case GraphicsContext3D::DRAW_BUFFER14:
2078     case GraphicsContext3D::DRAW_BUFFER15:
2079         if (m_framebufferBinding)
2080             return m_framebufferBinding->getDrawBuffer(pname);
2081         return m_backDrawBuffer; // emulated backbuffer
2082     case GraphicsContext3D::READ_FRAMEBUFFER_BINDING:
2083         return m_readFramebufferBinding;
2084     case GraphicsContext3D::COPY_READ_BUFFER:
2085     case GraphicsContext3D::COPY_WRITE_BUFFER:
2086     case GraphicsContext3D::PIXEL_PACK_BUFFER_BINDING:   
2087     case GraphicsContext3D::PIXEL_UNPACK_BUFFER_BINDING:
2088     case GraphicsContext3D::READ_BUFFER:
2089     case GraphicsContext3D::SAMPLER_BINDING:
2090     case GraphicsContext3D::TEXTURE_BINDING_2D_ARRAY:
2091     case GraphicsContext3D::TEXTURE_BINDING_3D:
2092     case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER_BINDING:
2093     case GraphicsContext3D::UNIFORM_BUFFER_BINDING:
2094         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "parameter name not yet supported");
2095         return nullptr;
2096     default:
2097         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name");
2098         return nullptr;
2099     }
2100 }
2101
2102 bool WebGL2RenderingContext::validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired)
2103 {
2104     // Performs conservative validation by caching a maximum index of
2105     // the given type per element array buffer. If all of the bound
2106     // array buffers have enough elements to satisfy that maximum
2107     // index, skips the expensive per-draw-call iteration in
2108     // validateIndexArrayPrecise.
2109     
2110     RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
2111     
2112     if (!elementArrayBuffer)
2113         return false;
2114     
2115     GC3Dsizeiptr numElements = elementArrayBuffer->byteLength();
2116     // The case count==0 is already dealt with in drawElements before validateIndexArrayConservative.
2117     if (!numElements)
2118         return false;
2119     auto buffer = elementArrayBuffer->elementArrayBuffer();
2120     ASSERT(buffer);
2121     
2122     Optional<unsigned> maxIndex = elementArrayBuffer->getCachedMaxIndex(type);
2123     if (!maxIndex) {
2124         // Compute the maximum index in the entire buffer for the given type of index.
2125         switch (type) {
2126         case GraphicsContext3D::UNSIGNED_BYTE:
2127             maxIndex = getMaxIndex<GC3Dubyte>(buffer, 0, numElements);
2128             break;
2129         case GraphicsContext3D::UNSIGNED_SHORT:
2130             maxIndex = getMaxIndex<GC3Dushort>(buffer, 0, numElements / sizeof(GC3Dushort));
2131             break;
2132         case GraphicsContext3D::UNSIGNED_INT:
2133             maxIndex = getMaxIndex<GC3Duint>(buffer, 0, numElements / sizeof(GC3Duint));
2134             break;
2135         default:
2136             return false;
2137         }
2138         if (maxIndex)
2139             elementArrayBuffer->setCachedMaxIndex(type, maxIndex.value());
2140     }
2141     
2142     if (!maxIndex)
2143         return false;
2144
2145     // The number of required elements is one more than the maximum
2146     // index that will be accessed.
2147     auto checkedNumElementsRequired = checkedAddAndMultiply<unsigned>(maxIndex.value(), 1, 1);
2148     if (!checkedNumElementsRequired)
2149         return false;
2150     numElementsRequired = checkedNumElementsRequired.value();
2151
2152     return true;
2153 }
2154
2155 bool WebGL2RenderingContext::validateBlendEquation(const char* functionName, GC3Denum mode)
2156 {
2157     switch (mode) {
2158     case GraphicsContext3D::FUNC_ADD:
2159     case GraphicsContext3D::FUNC_SUBTRACT:
2160     case GraphicsContext3D::FUNC_REVERSE_SUBTRACT:
2161     case GraphicsContext3D::MIN:
2162     case GraphicsContext3D::MAX:
2163         return true;
2164     default:
2165         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid mode");
2166         return false;
2167     }
2168 }
2169
2170 bool WebGL2RenderingContext::validateCapability(const char* functionName, GC3Denum cap)
2171 {
2172     switch (cap) {
2173     case GraphicsContext3D::BLEND:
2174     case GraphicsContext3D::CULL_FACE:
2175     case GraphicsContext3D::DEPTH_TEST:
2176     case GraphicsContext3D::DITHER:
2177     case GraphicsContext3D::POLYGON_OFFSET_FILL:
2178     case GraphicsContext3D::SAMPLE_ALPHA_TO_COVERAGE:
2179     case GraphicsContext3D::SAMPLE_COVERAGE:
2180     case GraphicsContext3D::SCISSOR_TEST:
2181     case GraphicsContext3D::STENCIL_TEST:
2182     case GraphicsContext3D::RASTERIZER_DISCARD:
2183         return true;
2184     default:
2185         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid capability");
2186         return false;
2187     }
2188 }
2189
2190 } // namespace WebCore
2191
2192 #endif // ENABLE(WEBGL)