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