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