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