1 | /* |
2 | * Copyright (C) 2015-2017 Apple Inc. All rights reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
18 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
20 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
21 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
23 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #include "config.h" |
27 | #include "WebGL2RenderingContext.h" |
28 | |
29 | #if ENABLE(WEBGL2) |
30 | |
31 | #include "CachedImage.h" |
32 | #include "EXTTextureFilterAnisotropic.h" |
33 | #include "Extensions3D.h" |
34 | #include "HTMLCanvasElement.h" |
35 | #include "HTMLImageElement.h" |
36 | #include "HTMLVideoElement.h" |
37 | #include "ImageData.h" |
38 | #include "InspectorInstrumentation.h" |
39 | #include "Logging.h" |
40 | #include "OESTextureFloat.h" |
41 | #include "OESTextureFloatLinear.h" |
42 | #include "OESTextureHalfFloat.h" |
43 | #include "OESTextureHalfFloatLinear.h" |
44 | #include "RenderBox.h" |
45 | #include "WebGLActiveInfo.h" |
46 | #include "WebGLCompressedTextureASTC.h" |
47 | #include "WebGLCompressedTextureATC.h" |
48 | #include "WebGLCompressedTexturePVRTC.h" |
49 | #include "WebGLCompressedTextureS3TC.h" |
50 | #include "WebGLDebugRendererInfo.h" |
51 | #include "WebGLDebugShaders.h" |
52 | #include "WebGLDepthTexture.h" |
53 | #include "WebGLLoseContext.h" |
54 | #include "WebGLQuery.h" |
55 | #include "WebGLSampler.h" |
56 | #include "WebGLSync.h" |
57 | #include "WebGLTransformFeedback.h" |
58 | #include "WebGLVertexArrayObject.h" |
59 | #include <JavaScriptCore/GenericTypedArrayViewInlines.h> |
60 | #include <JavaScriptCore/HeapInlines.h> |
61 | #include <JavaScriptCore/JSGenericTypedArrayViewInlines.h> |
62 | #include <wtf/IsoMallocInlines.h> |
63 | |
64 | namespace WebCore { |
65 | |
66 | WTF_MAKE_ISO_ALLOCATED_IMPL(WebGL2RenderingContext); |
67 | |
68 | std::unique_ptr<WebGL2RenderingContext> WebGL2RenderingContext::create(CanvasBase& canvas, GraphicsContext3DAttributes attributes) |
69 | { |
70 | auto renderingContext = std::unique_ptr<WebGL2RenderingContext>(new WebGL2RenderingContext(canvas, attributes)); |
71 | |
72 | InspectorInstrumentation::didCreateCanvasRenderingContext(*renderingContext); |
73 | |
74 | return renderingContext; |
75 | } |
76 | |
77 | std::unique_ptr<WebGL2RenderingContext> WebGL2RenderingContext::create(CanvasBase& canvas, Ref<GraphicsContext3D>&& context, GraphicsContext3DAttributes attributes) |
78 | { |
79 | auto renderingContext = std::unique_ptr<WebGL2RenderingContext>(new WebGL2RenderingContext(canvas, WTFMove(context), attributes)); |
80 | |
81 | InspectorInstrumentation::didCreateCanvasRenderingContext(*renderingContext); |
82 | |
83 | return renderingContext; |
84 | } |
85 | |
86 | WebGL2RenderingContext::WebGL2RenderingContext(CanvasBase& canvas, GraphicsContext3DAttributes attributes) |
87 | : WebGLRenderingContextBase(canvas, attributes) |
88 | { |
89 | } |
90 | |
91 | WebGL2RenderingContext::WebGL2RenderingContext(CanvasBase& canvas, Ref<GraphicsContext3D>&& context, GraphicsContext3DAttributes attributes) |
92 | : WebGLRenderingContextBase(canvas, WTFMove(context), attributes) |
93 | { |
94 | initializeShaderExtensions(); |
95 | initializeVertexArrayObjects(); |
96 | } |
97 | |
98 | void WebGL2RenderingContext::initializeVertexArrayObjects() |
99 | { |
100 | m_defaultVertexArrayObject = WebGLVertexArrayObject::create(*this, WebGLVertexArrayObject::Type::Default); |
101 | addContextObject(*m_defaultVertexArrayObject); |
102 | #if USE(OPENGL_ES) |
103 | m_boundVertexArrayObject = m_defaultVertexArrayObject; |
104 | #else |
105 | bindVertexArray(nullptr); // The default VAO was removed in OpenGL 3.3 but not from WebGL 2; bind the default for WebGL to use. |
106 | #endif |
107 | if (!isGLES2Compliant()) |
108 | initVertexAttrib0(); |
109 | } |
110 | |
111 | void WebGL2RenderingContext::initializeShaderExtensions() |
112 | { |
113 | m_context->getExtensions().ensureEnabled("GL_OES_standard_derivatives" ); |
114 | m_context->getExtensions().ensureEnabled("GL_EXT_draw_buffers" ); |
115 | m_context->getExtensions().ensureEnabled("GL_EXT_shader_texture_lod" ); |
116 | m_context->getExtensions().ensureEnabled("GL_EXT_frag_depth" ); |
117 | } |
118 | |
119 | inline static Optional<unsigned> arrayBufferViewElementSize(const ArrayBufferView& data) |
120 | { |
121 | switch (data.getType()) { |
122 | case JSC::NotTypedArray: |
123 | case JSC::TypeDataView: |
124 | return WTF::nullopt; |
125 | case JSC::TypeInt8: |
126 | case JSC::TypeUint8: |
127 | case JSC::TypeUint8Clamped: |
128 | case JSC::TypeInt16: |
129 | case JSC::TypeUint16: |
130 | case JSC::TypeInt32: |
131 | case JSC::TypeUint32: |
132 | case JSC::TypeFloat32: |
133 | case JSC::TypeFloat64: |
134 | return elementSize(data.getType()); |
135 | } |
136 | RELEASE_ASSERT_NOT_REACHED(); |
137 | } |
138 | |
139 | void WebGL2RenderingContext::bufferData(GC3Denum target, const ArrayBufferView& data, GC3Denum usage, GC3Duint srcOffset, GC3Duint length) |
140 | { |
141 | auto optionalElementSize = arrayBufferViewElementSize(data); |
142 | if (!optionalElementSize) { |
143 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bufferData" , "Invalid type of Array Buffer View" ); |
144 | return; |
145 | } |
146 | auto elementSize = optionalElementSize.value(); |
147 | Checked<GC3Duint, RecordOverflow> checkedElementSize(elementSize); |
148 | |
149 | Checked<GC3Duint, RecordOverflow> checkedSrcOffset(srcOffset); |
150 | Checked<GC3Duint, RecordOverflow> checkedByteSrcOffset = checkedSrcOffset * checkedElementSize; |
151 | Checked<GC3Duint, RecordOverflow> checkedlength(length); |
152 | Checked<GC3Duint, RecordOverflow> checkedByteLength = checkedlength * checkedElementSize; |
153 | |
154 | if (checkedByteSrcOffset.hasOverflowed() |
155 | || checkedByteLength.hasOverflowed() |
156 | || checkedByteSrcOffset.unsafeGet() > data.byteLength() |
157 | || checkedByteLength.unsafeGet() > data.byteLength() - checkedByteSrcOffset.unsafeGet()) { |
158 | synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData" , "srcOffset or length is out of bounds" ); |
159 | return; |
160 | } |
161 | |
162 | auto slice = Uint8Array::tryCreate(data.possiblySharedBuffer(), data.byteOffset() + checkedByteSrcOffset.unsafeGet(), checkedByteLength.unsafeGet()); |
163 | if (!slice) { |
164 | synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "bufferData" , "Could not create intermediate ArrayBufferView" ); |
165 | return; |
166 | } |
167 | WebGLRenderingContextBase::bufferData(target, BufferDataSource(slice.get()), usage); |
168 | } |
169 | |
170 | void WebGL2RenderingContext::bufferSubData(GC3Denum target, long long offset, const ArrayBufferView& data, GC3Duint srcOffset, GC3Duint length) |
171 | { |
172 | auto optionalElementSize = arrayBufferViewElementSize(data); |
173 | if (!optionalElementSize) { |
174 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bufferSubData" , "Invalid type of Array Buffer View" ); |
175 | return; |
176 | } |
177 | auto elementSize = optionalElementSize.value(); |
178 | Checked<GC3Duint, RecordOverflow> checkedElementSize(elementSize); |
179 | |
180 | Checked<GC3Duint, RecordOverflow> checkedSrcOffset(srcOffset); |
181 | Checked<GC3Duint, RecordOverflow> checkedByteSrcOffset = checkedSrcOffset * checkedElementSize; |
182 | Checked<GC3Duint, RecordOverflow> checkedlength(length); |
183 | Checked<GC3Duint, RecordOverflow> checkedByteLength = checkedlength * checkedElementSize; |
184 | |
185 | if (checkedByteSrcOffset.hasOverflowed() |
186 | || checkedByteLength.hasOverflowed() |
187 | || checkedByteSrcOffset.unsafeGet() > data.byteLength() |
188 | || checkedByteLength.unsafeGet() > data.byteLength() - checkedByteSrcOffset.unsafeGet()) { |
189 | synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData" , "srcOffset or length is out of bounds" ); |
190 | return; |
191 | } |
192 | |
193 | auto slice = Uint8Array::tryCreate(data.possiblySharedBuffer(), data.byteOffset() + checkedByteSrcOffset.unsafeGet(), checkedByteLength.unsafeGet()); |
194 | if (!slice) { |
195 | synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "bufferSubData" , "Could not create intermediate ArrayBufferView" ); |
196 | return; |
197 | } |
198 | |
199 | WebGLRenderingContextBase::bufferSubData(target, offset, BufferDataSource(slice.get())); |
200 | } |
201 | |
202 | void WebGL2RenderingContext::copyBufferSubData(GC3Denum readTarget, GC3Denum writeTarget, GC3Dint64 readOffset, GC3Dint64 writeOffset, GC3Dint64 size) |
203 | { |
204 | if (isContextLostOrPending()) |
205 | return; |
206 | if ((readTarget == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && writeTarget != GraphicsContext3D::ELEMENT_ARRAY_BUFFER) |
207 | || (writeTarget == GraphicsContext3D::ELEMENT_ARRAY_BUFFER && readTarget != GraphicsContext3D::ELEMENT_ARRAY_BUFFER)) { |
208 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyBufferSubData" , "Either both targets need to be ELEMENT_ARRAY_BUFFER or neither should be ELEMENT_ARRAY_BUFFER." ); |
209 | return; |
210 | } |
211 | if (readOffset < 0 || writeOffset < 0 || size < 0) { |
212 | synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyBufferSubData" , "offset < 0" ); |
213 | return; |
214 | } |
215 | RefPtr<WebGLBuffer> readBuffer = validateBufferDataParameters("copyBufferSubData" , readTarget, GraphicsContext3D::STATIC_DRAW); |
216 | RefPtr<WebGLBuffer> writeBuffer = validateBufferDataParameters("copyBufferSubData" , writeTarget, GraphicsContext3D::STATIC_DRAW); |
217 | if (!readBuffer || !writeBuffer) { |
218 | synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyBufferSubData" , "Invalid readTarget or writeTarget" ); |
219 | return; |
220 | } |
221 | |
222 | Checked<GC3Dintptr, RecordOverflow> checkedReadOffset(readOffset); |
223 | Checked<GC3Dintptr, RecordOverflow> checkedWriteOffset(writeOffset); |
224 | Checked<GC3Dsizeiptr, RecordOverflow> checkedSize(size); |
225 | if (checkedReadOffset.hasOverflowed() || checkedWriteOffset.hasOverflowed() || checkedSize.hasOverflowed()) { |
226 | synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyBufferSubData" , "Offset or size is too big" ); |
227 | return; |
228 | } |
229 | |
230 | if (!writeBuffer->associateCopyBufferSubData(*readBuffer, checkedReadOffset.unsafeGet(), checkedWriteOffset.unsafeGet(), checkedSize.unsafeGet())) { |
231 | this->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyBufferSubData" , "offset out of range" ); |
232 | return; |
233 | } |
234 | |
235 | m_context->moveErrorsToSyntheticErrorList(); |
236 | #if PLATFORM(COCOA) |
237 | m_context->copyBufferSubData(readTarget, writeTarget, checkedReadOffset.unsafeGet(), checkedWriteOffset.unsafeGet(), checkedSize.unsafeGet()); |
238 | #endif |
239 | if (m_context->moveErrorsToSyntheticErrorList()) { |
240 | // The bufferSubData function failed. Tell the buffer it doesn't have the data it thinks it does. |
241 | writeBuffer->disassociateBufferData(); |
242 | } |
243 | } |
244 | |
245 | void WebGL2RenderingContext::getBufferSubData(GC3Denum target, long long srcByteOffset, RefPtr<ArrayBufferView>&& dstData, GC3Duint dstOffset, GC3Duint length) |
246 | { |
247 | if (isContextLostOrPending()) |
248 | return; |
249 | RefPtr<WebGLBuffer> buffer = validateBufferDataParameters("bufferSubData" , target, GraphicsContext3D::STATIC_DRAW); |
250 | if (!buffer) { |
251 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData" , "No WebGLBuffer is bound to target" ); |
252 | return; |
253 | } |
254 | |
255 | // FIXME: Implement "If target is TRANSFORM_FEEDBACK_BUFFER, and any transform feedback object is currently active, an INVALID_OPERATION error is generated." |
256 | |
257 | if (!dstData) { |
258 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData" , "Null dstData" ); |
259 | return; |
260 | } |
261 | |
262 | auto optionalElementSize = arrayBufferViewElementSize(*dstData); |
263 | if (!optionalElementSize) { |
264 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData" , "Invalid type of Array Buffer View" ); |
265 | return; |
266 | } |
267 | auto elementSize = optionalElementSize.value(); |
268 | auto dstDataLength = dstData->byteLength() / elementSize; |
269 | |
270 | if (dstOffset > dstDataLength) { |
271 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData" , "dstOffset is larger than the length of the destination buffer." ); |
272 | return; |
273 | } |
274 | |
275 | GC3Duint copyLength = length ? length : dstDataLength - dstOffset; |
276 | |
277 | Checked<GC3Duint, RecordOverflow> checkedDstOffset(dstOffset); |
278 | Checked<GC3Duint, RecordOverflow> checkedCopyLength(copyLength); |
279 | auto checkedDestinationEnd = checkedDstOffset + checkedCopyLength; |
280 | if (checkedDestinationEnd.hasOverflowed()) { |
281 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData" , "dstOffset + copyLength is too high" ); |
282 | return; |
283 | } |
284 | |
285 | if (checkedDestinationEnd.unsafeGet() > dstDataLength) { |
286 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData" , "end of written destination is past the end of the buffer" ); |
287 | return; |
288 | } |
289 | |
290 | if (srcByteOffset < 0) { |
291 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData" , "srcByteOffset is less than 0" ); |
292 | return; |
293 | } |
294 | |
295 | Checked<GC3Dintptr, RecordOverflow> checkedSrcByteOffset(srcByteOffset); |
296 | Checked<GC3Dintptr, RecordOverflow> checkedCopyLengthPtr(copyLength); |
297 | Checked<GC3Dintptr, RecordOverflow> checkedElementSize(elementSize); |
298 | auto checkedSourceEnd = checkedSrcByteOffset + checkedCopyLengthPtr * checkedElementSize; |
299 | if (checkedSourceEnd.hasOverflowed() || checkedSourceEnd.unsafeGet() > buffer->byteLength()) { |
300 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getBufferSubData" , "Parameters would read outside the bounds of the source buffer" ); |
301 | return; |
302 | } |
303 | |
304 | m_context->moveErrorsToSyntheticErrorList(); |
305 | #if PLATFORM(COCOA) |
306 | // FIXME: Coalesce multiple getBufferSubData() calls to use a single map() call |
307 | void* ptr = m_context->mapBufferRange(target, checkedSrcByteOffset.unsafeGet(), static_cast<GC3Dsizeiptr>(checkedCopyLengthPtr.unsafeGet() * checkedElementSize.unsafeGet()), GraphicsContext3D::MAP_READ_BIT); |
308 | memcpy(static_cast<char*>(dstData->baseAddress()) + dstData->byteOffset() + dstOffset * elementSize, ptr, copyLength * elementSize); |
309 | bool success = m_context->unmapBuffer(target); |
310 | ASSERT_UNUSED(success, success); |
311 | #endif |
312 | m_context->moveErrorsToSyntheticErrorList(); |
313 | } |
314 | |
315 | void WebGL2RenderingContext::blitFramebuffer(GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dbitfield, GC3Denum) |
316 | { |
317 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] blitFramebuffer()" ); |
318 | } |
319 | |
320 | void WebGL2RenderingContext::framebufferTextureLayer(GC3Denum, GC3Denum, WebGLTexture*, GC3Dint, GC3Dint) |
321 | { |
322 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] framebufferTextureLayer()" ); |
323 | } |
324 | |
325 | #if !USE(OPENGL_ES) |
326 | static bool isRenderableInternalformat(GC3Denum internalformat) |
327 | { |
328 | // OpenGL ES 3: internalformat must be a color-renderable, depth-renderable, or stencil-renderable format, as shown in Table 1 below. |
329 | switch (internalformat) { |
330 | case GraphicsContext3D::R8: |
331 | case GraphicsContext3D::R8UI: |
332 | case GraphicsContext3D::R16UI: |
333 | case GraphicsContext3D::R16I: |
334 | case GraphicsContext3D::R32UI: |
335 | case GraphicsContext3D::R32I: |
336 | case GraphicsContext3D::RG8: |
337 | case GraphicsContext3D::RG8UI: |
338 | case GraphicsContext3D::RG8I: |
339 | case GraphicsContext3D::RG16UI: |
340 | case GraphicsContext3D::RG16I: |
341 | case GraphicsContext3D::RG32UI: |
342 | case GraphicsContext3D::RG32I: |
343 | case GraphicsContext3D::RGB8: |
344 | case GraphicsContext3D::RGB565: |
345 | case GraphicsContext3D::RGBA8: |
346 | case GraphicsContext3D::SRGB8_ALPHA8: |
347 | case GraphicsContext3D::RGB5_A1: |
348 | case GraphicsContext3D::RGBA4: |
349 | case GraphicsContext3D::RGB10_A2: |
350 | case GraphicsContext3D::RGBA8UI: |
351 | case GraphicsContext3D::RGBA8I: |
352 | case GraphicsContext3D::RGB10_A2UI: |
353 | case GraphicsContext3D::RGBA16UI: |
354 | case GraphicsContext3D::RGBA16I: |
355 | case GraphicsContext3D::RGBA32I: |
356 | case GraphicsContext3D::RGBA32UI: |
357 | case GraphicsContext3D::DEPTH_COMPONENT16: |
358 | case GraphicsContext3D::DEPTH_COMPONENT24: |
359 | case GraphicsContext3D::DEPTH_COMPONENT32F: |
360 | case GraphicsContext3D::DEPTH24_STENCIL8: |
361 | case GraphicsContext3D::DEPTH32F_STENCIL8: |
362 | case GraphicsContext3D::STENCIL_INDEX8: |
363 | return true; |
364 | } |
365 | return false; |
366 | } |
367 | #endif |
368 | |
369 | WebGLAny WebGL2RenderingContext::getInternalformatParameter(GC3Denum target, GC3Denum internalformat, GC3Denum pname) |
370 | { |
371 | if (isContextLostOrPending()) |
372 | return nullptr; |
373 | |
374 | if (pname != GraphicsContext3D::SAMPLES) { |
375 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getInternalformatParameter" , "invalid parameter name" ); |
376 | return nullptr; |
377 | } |
378 | |
379 | int numValues = 0; |
380 | #if USE(OPENGL_ES) |
381 | m_context->getInternalformativ(target, internalformat, GraphicsContext3D::NUM_SAMPLE_COUNTS, 1, &numValues); |
382 | |
383 | GC3Dint params[numValues]; |
384 | m_context->getInternalformativ(target, internalformat, pname, numValues, params); |
385 | #else |
386 | // On desktop OpenGL 4.1 or below we must emulate glGetInternalformativ. |
387 | |
388 | // GL_INVALID_ENUM is generated if target is not GL_RENDERBUFFER. |
389 | if (target != GraphicsContext3D::RENDERBUFFER) { |
390 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getInternalformatParameter" , "invalid target" ); |
391 | return nullptr; |
392 | } |
393 | |
394 | // GL_INVALID_ENUM is generated if internalformat is not color-, depth-, or stencil-renderable. |
395 | if (!isRenderableInternalformat(internalformat)) { |
396 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getInternalformatParameter" , "invalid internal format" ); |
397 | return nullptr; |
398 | } |
399 | |
400 | Vector<GC3Dint> samples; |
401 | // The way I understand this is that this will return a MINIMUM numSamples for all accepeted internalformats. |
402 | // However, the true value of this on supported GL versions is gleaned via a getInternalformativ call that depends on internalformat. |
403 | int numSamplesMask = getIntParameter(GraphicsContext3D::MAX_SAMPLES); |
404 | |
405 | while (numSamplesMask > 0) { |
406 | samples.append(numSamplesMask); |
407 | numSamplesMask = numSamplesMask >> 1; |
408 | } |
409 | |
410 | // Since multisampling is not supported for signed and unsigned integer internal formats, |
411 | // the value of GL_NUM_SAMPLE_COUNTS will be zero for such formats. |
412 | numValues = isIntegerFormat(internalformat) ? 0 : samples.size(); |
413 | GC3Dint params[numValues]; |
414 | for (size_t i = 0; i < samples.size(); ++i) |
415 | params[i] = samples[i]; |
416 | #endif |
417 | |
418 | return Int32Array::tryCreate(params, numValues); |
419 | } |
420 | |
421 | void WebGL2RenderingContext::invalidateFramebuffer(GC3Denum, const Vector<GC3Denum>&) |
422 | { |
423 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] invalidateFramebuffer()" ); |
424 | } |
425 | |
426 | void WebGL2RenderingContext::invalidateSubFramebuffer(GC3Denum, const Vector<GC3Denum>&, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei) |
427 | { |
428 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] invalidateSubFramebuffer()" ); |
429 | } |
430 | |
431 | void WebGL2RenderingContext::readBuffer(GC3Denum) |
432 | { |
433 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] readBuffer()" ); |
434 | } |
435 | |
436 | void WebGL2RenderingContext::renderbufferStorageMultisample(GC3Denum target, GC3Dsizei samples, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height) |
437 | { |
438 | // To be backward compatible with WebGL 1, also accepts internal format DEPTH_STENCIL, |
439 | // which should be mapped to DEPTH24_STENCIL8 by implementations. |
440 | if (internalformat == GraphicsContext3D::DEPTH_STENCIL) |
441 | internalformat = GraphicsContext3D::DEPTH24_STENCIL8; |
442 | |
443 | // ES 3: GL_INVALID_OPERATION is generated if internalformat is a signed or unsigned integer format and samples is greater than 0. |
444 | if (isIntegerFormat(internalformat) && samples > 0) { |
445 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "renderbufferStorageMultisample" , "multisampling not supported for this format" ); |
446 | return; |
447 | } |
448 | |
449 | switch (internalformat) { |
450 | case GraphicsContext3D::DEPTH_COMPONENT16: |
451 | case GraphicsContext3D::DEPTH_COMPONENT32F: |
452 | case GraphicsContext3D::DEPTH_COMPONENT24: |
453 | case GraphicsContext3D::RGBA32I: |
454 | case GraphicsContext3D::RGBA32UI: |
455 | case GraphicsContext3D::RGBA16I: |
456 | case GraphicsContext3D::RGBA16UI: |
457 | case GraphicsContext3D::RGBA8: |
458 | case GraphicsContext3D::RGBA8I: |
459 | case GraphicsContext3D::RGBA8UI: |
460 | case GraphicsContext3D::RGB10_A2: |
461 | case GraphicsContext3D::RGB10_A2UI: |
462 | case GraphicsContext3D::RGBA4: |
463 | case GraphicsContext3D::RG32I: |
464 | case GraphicsContext3D::RG32UI: |
465 | case GraphicsContext3D::RG16I: |
466 | case GraphicsContext3D::RG16UI: |
467 | case GraphicsContext3D::RG8: |
468 | case GraphicsContext3D::RG8I: |
469 | case GraphicsContext3D::RG8UI: |
470 | case GraphicsContext3D::R32I: |
471 | case GraphicsContext3D::R32UI: |
472 | case GraphicsContext3D::R16I: |
473 | case GraphicsContext3D::R16UI: |
474 | case GraphicsContext3D::R8: |
475 | case GraphicsContext3D::R8I: |
476 | case GraphicsContext3D::R8UI: |
477 | case GraphicsContext3D::RGB5_A1: |
478 | case GraphicsContext3D::RGB565: |
479 | case GraphicsContext3D::RGB8: |
480 | case GraphicsContext3D::STENCIL_INDEX8: |
481 | case GraphicsContext3D::SRGB8_ALPHA8: |
482 | m_context->renderbufferStorageMultisample(target, samples, internalformat, width, height); |
483 | m_renderbufferBinding->setInternalFormat(internalformat); |
484 | m_renderbufferBinding->setIsValid(true); |
485 | m_renderbufferBinding->setSize(width, height); |
486 | break; |
487 | case GraphicsContext3D::DEPTH32F_STENCIL8: |
488 | case GraphicsContext3D::DEPTH24_STENCIL8: |
489 | if (!isDepthStencilSupported()) { |
490 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage" , "invalid internalformat" ); |
491 | return; |
492 | } |
493 | m_context->renderbufferStorageMultisample(target, samples, internalformat, width, height); |
494 | m_renderbufferBinding->setSize(width, height); |
495 | m_renderbufferBinding->setIsValid(isDepthStencilSupported()); |
496 | m_renderbufferBinding->setInternalFormat(internalformat); |
497 | break; |
498 | default: |
499 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage" , "invalid internalformat" ); |
500 | return; |
501 | } |
502 | applyStencilTest(); |
503 | } |
504 | |
505 | bool WebGL2RenderingContext::validateTexStorageFuncParameters(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, const char* functionName) |
506 | { |
507 | if (width < 0 || height < 0) { |
508 | synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0" ); |
509 | return false; |
510 | } |
511 | |
512 | if (width > m_maxTextureSize || height > m_maxTextureSize) { |
513 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "texture dimensions are larger than the maximum texture size" ); |
514 | return false; |
515 | } |
516 | |
517 | if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) { |
518 | if (width != height) { |
519 | synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height for cube map" ); |
520 | return false; |
521 | } |
522 | } else if (target != GraphicsContext3D::TEXTURE_2D) { |
523 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target" ); |
524 | return false; |
525 | } |
526 | |
527 | if (levels < 0 || levels > m_maxTextureLevel) { |
528 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "number of levels is out of bounds" ); |
529 | return false; |
530 | } |
531 | |
532 | switch (internalFormat) { |
533 | case GraphicsContext3D::R8: |
534 | case GraphicsContext3D::R8_SNORM: |
535 | case GraphicsContext3D::R16F: |
536 | case GraphicsContext3D::R32F: |
537 | case GraphicsContext3D::R8UI: |
538 | case GraphicsContext3D::R8I: |
539 | case GraphicsContext3D::R16UI: |
540 | case GraphicsContext3D::R16I: |
541 | case GraphicsContext3D::R32UI: |
542 | case GraphicsContext3D::R32I: |
543 | case GraphicsContext3D::RG8: |
544 | case GraphicsContext3D::RG8_SNORM: |
545 | case GraphicsContext3D::RG16F: |
546 | case GraphicsContext3D::RG32F: |
547 | case GraphicsContext3D::RG8UI: |
548 | case GraphicsContext3D::RG8I: |
549 | case GraphicsContext3D::RG16UI: |
550 | case GraphicsContext3D::RG16I: |
551 | case GraphicsContext3D::RG32UI: |
552 | case GraphicsContext3D::RG32I: |
553 | case GraphicsContext3D::RGB8: |
554 | case GraphicsContext3D::SRGB8: |
555 | case GraphicsContext3D::RGB565: |
556 | case GraphicsContext3D::RGB8_SNORM: |
557 | case GraphicsContext3D::R11F_G11F_B10F: |
558 | case GraphicsContext3D::RGB9_E5: |
559 | case GraphicsContext3D::RGB16F: |
560 | case GraphicsContext3D::RGB32F: |
561 | case GraphicsContext3D::RGB8UI: |
562 | case GraphicsContext3D::RGB8I: |
563 | case GraphicsContext3D::RGB16UI: |
564 | case GraphicsContext3D::RGB16I: |
565 | case GraphicsContext3D::RGB32UI: |
566 | case GraphicsContext3D::RGB32I: |
567 | case GraphicsContext3D::RGBA8: |
568 | case GraphicsContext3D::SRGB8_ALPHA8: |
569 | case GraphicsContext3D::RGBA8_SNORM: |
570 | case GraphicsContext3D::RGB5_A1: |
571 | case GraphicsContext3D::RGBA4: |
572 | case GraphicsContext3D::RGB10_A2: |
573 | case GraphicsContext3D::RGBA16F: |
574 | case GraphicsContext3D::RGBA32F: |
575 | case GraphicsContext3D::RGBA8UI: |
576 | case GraphicsContext3D::RGBA8I: |
577 | case GraphicsContext3D::RGB10_A2UI: |
578 | case GraphicsContext3D::RGBA16UI: |
579 | case GraphicsContext3D::RGBA16I: |
580 | case GraphicsContext3D::RGBA32I: |
581 | case GraphicsContext3D::RGBA32UI: |
582 | case GraphicsContext3D::DEPTH_COMPONENT16: |
583 | case GraphicsContext3D::DEPTH_COMPONENT24: |
584 | case GraphicsContext3D::DEPTH_COMPONENT32F: |
585 | case GraphicsContext3D::DEPTH24_STENCIL8: |
586 | case GraphicsContext3D::DEPTH32F_STENCIL8: |
587 | break; |
588 | default: |
589 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "Unknown internalFormat" ); |
590 | return false; |
591 | } |
592 | |
593 | return true; |
594 | } |
595 | |
596 | void WebGL2RenderingContext::texStorage2D(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height) |
597 | { |
598 | if (isContextLostOrPending()) |
599 | return; |
600 | |
601 | auto texture = validateTextureBinding("texStorage2D" , target, false); |
602 | if (!texture) |
603 | return; |
604 | |
605 | if (!validateTexStorageFuncParameters(target, levels, internalFormat, width, height, "texStorage2D" )) |
606 | return; |
607 | |
608 | if (!validateNPOTTextureLevel(width, height, levels, "texStorage2D" )) |
609 | return; |
610 | |
611 | if (texture->immutable()) { |
612 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "texStorage2D" , "texStorage2D already called on this texture" ); |
613 | return; |
614 | } |
615 | texture->setImmutable(); |
616 | |
617 | m_context->texStorage2D(target, levels, internalFormat, width, height); |
618 | |
619 | { |
620 | GC3Denum format; |
621 | GC3Denum type; |
622 | if (!GraphicsContext3D::possibleFormatAndTypeForInternalFormat(internalFormat, format, type)) { |
623 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texStorage2D" , "Texture has unknown internal format" ); |
624 | return; |
625 | } |
626 | |
627 | GC3Dsizei levelWidth = width; |
628 | GC3Dsizei levelHeight = height; |
629 | |
630 | unsigned size; |
631 | GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &size, nullptr); |
632 | if (error != GraphicsContext3D::NO_ERROR) { |
633 | synthesizeGLError(error, "texStorage2D" , "bad dimensions" ); |
634 | return; |
635 | } |
636 | |
637 | Vector<char> data(size); |
638 | memset(data.data(), 0, size); |
639 | |
640 | for (GC3Dsizei level = 0; level < levels; ++level) { |
641 | if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) { |
642 | m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, level, 0, 0, levelWidth, levelHeight, format, type, data.data()); |
643 | m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, level, 0, 0, levelWidth, levelHeight, format, type, data.data()); |
644 | m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, level, 0, 0, levelWidth, levelHeight, format, type, data.data()); |
645 | m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, level, 0, 0, levelWidth, levelHeight, format, type, data.data()); |
646 | m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, level, 0, 0, levelWidth, levelHeight, format, type, data.data()); |
647 | m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, level, 0, 0, levelWidth, levelHeight, format, type, data.data()); |
648 | } else |
649 | m_context->texSubImage2D(target, level, 0, 0, levelWidth, levelHeight, format, type, data.data()); |
650 | levelWidth = std::max(1, levelWidth / 2); |
651 | levelHeight = std::max(1, levelHeight / 2); |
652 | } |
653 | } |
654 | |
655 | for (GC3Dsizei level = 0; level < levels; ++level) { |
656 | if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) { |
657 | texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE); |
658 | texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE); |
659 | texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE); |
660 | texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE); |
661 | texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE); |
662 | texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE); |
663 | } else |
664 | texture->setLevelInfo(target, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE); |
665 | } |
666 | } |
667 | |
668 | void WebGL2RenderingContext::texStorage3D(GC3Denum, GC3Dsizei, GC3Denum, GC3Dsizei, GC3Dsizei, GC3Dsizei) |
669 | { |
670 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] texStorage3D()" ); |
671 | } |
672 | |
673 | void WebGL2RenderingContext::texImage2D(GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Denum, GC3Denum, GC3Dint64) |
674 | { |
675 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] texImage2D()" ); |
676 | } |
677 | |
678 | void WebGL2RenderingContext::texImage2D(GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Denum, GC3Denum, TexImageSource&&) |
679 | { |
680 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] texImage2D()" ); |
681 | } |
682 | |
683 | void WebGL2RenderingContext::texImage2D(GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Denum, GC3Denum, RefPtr<ArrayBufferView>&&, GC3Duint) |
684 | { |
685 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] texImage2D()" ); |
686 | } |
687 | |
688 | void WebGL2RenderingContext::texImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Denum, GC3Denum, GC3Dint64) |
689 | { |
690 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] texImage3D()" ); |
691 | } |
692 | |
693 | void WebGL2RenderingContext::texImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Denum, GC3Denum, TexImageSource&&) |
694 | { |
695 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] texImage3D()" ); |
696 | } |
697 | |
698 | void WebGL2RenderingContext::texImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Denum, GC3Denum, RefPtr<ArrayBufferView>&&) |
699 | { |
700 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] texImage3D()" ); |
701 | } |
702 | |
703 | void WebGL2RenderingContext::texImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Denum, GC3Denum, RefPtr<ArrayBufferView>&&, GC3Duint) |
704 | { |
705 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] texImage3D()" ); |
706 | } |
707 | |
708 | void WebGL2RenderingContext::texSubImage2D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, GC3Dint64) |
709 | { |
710 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] texSubImage2D()" ); |
711 | } |
712 | |
713 | void WebGL2RenderingContext::texSubImage2D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, TexImageSource&&) |
714 | { |
715 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] texSubImage2D()" ); |
716 | } |
717 | |
718 | void WebGL2RenderingContext::texSubImage2D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, RefPtr<ArrayBufferView>&&, GC3Duint) |
719 | { |
720 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] texSubImage2D()" ); |
721 | } |
722 | |
723 | void WebGL2RenderingContext::texSubImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, GC3Dint64) |
724 | { |
725 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] texSubImage3D()" ); |
726 | } |
727 | |
728 | void WebGL2RenderingContext::texSubImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, RefPtr<ArrayBufferView>&&, GC3Duint) |
729 | { |
730 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] texSubImage3D()" ); |
731 | } |
732 | |
733 | void WebGL2RenderingContext::texSubImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Denum, TexImageSource&&) |
734 | { |
735 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] texSubImage3D()" ); |
736 | } |
737 | |
738 | void WebGL2RenderingContext::copyTexSubImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei) |
739 | { |
740 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] copyTexSubImage3D()" ); |
741 | } |
742 | |
743 | void WebGL2RenderingContext::compressedTexImage2D(GC3Denum, GC3Dint, GC3Denum, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Dsizei, GC3Dint64) |
744 | { |
745 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] compressedTexImage2D()" ); |
746 | } |
747 | |
748 | void WebGL2RenderingContext::compressedTexImage2D(GC3Denum, GC3Dint, GC3Denum, GC3Dsizei, GC3Dsizei, GC3Dint, ArrayBufferView&, GC3Duint, GC3Duint) |
749 | { |
750 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] compressedTexImage2D()" ); |
751 | } |
752 | |
753 | void WebGL2RenderingContext::compressedTexImage3D(GC3Denum, GC3Dint, GC3Denum, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Dint, GC3Dsizei, GC3Dint64) |
754 | { |
755 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] compressedTexImage3D()" ); |
756 | } |
757 | |
758 | void WebGL2RenderingContext::compressedTexImage3D(GC3Denum, GC3Dint, GC3Denum, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Dint, ArrayBufferView&, GC3Duint, GC3Duint) |
759 | { |
760 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] compressedTexImage3D()" ); |
761 | } |
762 | |
763 | void WebGL2RenderingContext::compressedTexSubImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Denum, GC3Dsizei, GC3Dint64) |
764 | { |
765 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] compressedTexSubImage3D()" ); |
766 | } |
767 | |
768 | void WebGL2RenderingContext::compressedTexSubImage3D(GC3Denum, GC3Dint, GC3Dint, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3Dsizei, GC3Denum, ArrayBufferView&, GC3Duint, GC3Duint) |
769 | { |
770 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] compressedTexSubImage3D()" ); |
771 | } |
772 | |
773 | GC3Dint WebGL2RenderingContext::getFragDataLocation(WebGLProgram&, const String&) |
774 | { |
775 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] getFragDataLocation()" ); |
776 | return 0; |
777 | } |
778 | |
779 | void WebGL2RenderingContext::uniform1ui(WebGLUniformLocation*, GC3Duint) |
780 | { |
781 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform1ui()" ); |
782 | } |
783 | |
784 | void WebGL2RenderingContext::uniform2ui(WebGLUniformLocation*, GC3Duint, GC3Duint) |
785 | { |
786 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform2ui()" ); |
787 | } |
788 | |
789 | void WebGL2RenderingContext::uniform3ui(WebGLUniformLocation*, GC3Duint, GC3Duint, GC3Duint) |
790 | { |
791 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform3ui()" ); |
792 | } |
793 | |
794 | void WebGL2RenderingContext::uniform4ui(WebGLUniformLocation*, GC3Duint, GC3Duint, GC3Duint, GC3Duint) |
795 | { |
796 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform4ui()" ); |
797 | } |
798 | |
799 | void WebGL2RenderingContext::uniform1uiv(WebGLUniformLocation*, Uint32List&&, GC3Duint, GC3Duint) |
800 | { |
801 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform1uiv()" ); |
802 | } |
803 | |
804 | void WebGL2RenderingContext::uniform2uiv(WebGLUniformLocation*, Uint32List&&, GC3Duint, GC3Duint) |
805 | { |
806 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform2uiv()" ); |
807 | } |
808 | |
809 | void WebGL2RenderingContext::uniform3uiv(WebGLUniformLocation*, Uint32List&&, GC3Duint, GC3Duint) |
810 | { |
811 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform3uiv()" ); |
812 | } |
813 | |
814 | void WebGL2RenderingContext::uniform4uiv(WebGLUniformLocation*, Uint32List&&, GC3Duint, GC3Duint) |
815 | { |
816 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniform4uiv()" ); |
817 | } |
818 | |
819 | void WebGL2RenderingContext::uniformMatrix2x3fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint) |
820 | { |
821 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix2x3fv()" ); |
822 | } |
823 | |
824 | void WebGL2RenderingContext::uniformMatrix3x2fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint) |
825 | { |
826 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix3x2fv()" ); |
827 | } |
828 | |
829 | void WebGL2RenderingContext::uniformMatrix2x4fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint) |
830 | { |
831 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix2x4fv()" ); |
832 | } |
833 | |
834 | void WebGL2RenderingContext::uniformMatrix4x2fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint) |
835 | { |
836 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix4x2fv()" ); |
837 | } |
838 | |
839 | void WebGL2RenderingContext::uniformMatrix3x4fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint) |
840 | { |
841 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix3x4fv()" ); |
842 | } |
843 | |
844 | void WebGL2RenderingContext::uniformMatrix4x3fv(WebGLUniformLocation*, GC3Dboolean, Float32List&&, GC3Duint, GC3Duint) |
845 | { |
846 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformMatrix4x3fv()" ); |
847 | } |
848 | |
849 | void WebGL2RenderingContext::vertexAttribI4i(GC3Duint, GC3Dint, GC3Dint, GC3Dint, GC3Dint) |
850 | { |
851 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] vertexAttribI4i()" ); |
852 | } |
853 | |
854 | void WebGL2RenderingContext::vertexAttribI4iv(GC3Duint, Int32List&&) |
855 | { |
856 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] vertexAttribI4iv()" ); |
857 | } |
858 | |
859 | void WebGL2RenderingContext::vertexAttribI4ui(GC3Duint, GC3Duint, GC3Duint, GC3Duint, GC3Duint) |
860 | { |
861 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] vertexAttribI4ui()" ); |
862 | } |
863 | |
864 | void WebGL2RenderingContext::vertexAttribI4uiv(GC3Duint, Uint32List&&) |
865 | { |
866 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] vertexAttribI4uiv()" ); |
867 | } |
868 | |
869 | void WebGL2RenderingContext::vertexAttribIPointer(GC3Duint, GC3Dint, GC3Denum, GC3Dsizei, GC3Dint64) |
870 | { |
871 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] vertexAttribIPointer()" ); |
872 | } |
873 | |
874 | void WebGL2RenderingContext::clear(GC3Dbitfield mask) |
875 | { |
876 | if (isContextLostOrPending()) |
877 | return; |
878 | if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) { |
879 | synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clear" , "invalid mask" ); |
880 | return; |
881 | } |
882 | if (m_framebufferBinding && (mask & GraphicsContext3D::COLOR_BUFFER_BIT) && isIntegerFormat(m_framebufferBinding->getColorBufferFormat())) { |
883 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clear" , "cannot clear an integer buffer" ); |
884 | return; |
885 | } |
886 | const char* reason = "framebuffer incomplete" ; |
887 | if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) { |
888 | synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "clear" , reason); |
889 | return; |
890 | } |
891 | if (!clearIfComposited(mask)) |
892 | m_context->clear(mask); |
893 | markContextChangedAndNotifyCanvasObserver(); |
894 | } |
895 | |
896 | void WebGL2RenderingContext::vertexAttribDivisor(GC3Duint index, GC3Duint divisor) |
897 | { |
898 | if (isContextLostOrPending()) |
899 | return; |
900 | |
901 | WebGLRenderingContextBase::vertexAttribDivisor(index, divisor); |
902 | } |
903 | |
904 | void WebGL2RenderingContext::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei instanceCount) |
905 | { |
906 | if (isContextLostOrPending()) |
907 | return; |
908 | |
909 | WebGLRenderingContextBase::drawArraysInstanced(mode, first, count, instanceCount); |
910 | } |
911 | |
912 | void WebGL2RenderingContext::drawElementsInstanced(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dint64 offset, GC3Dsizei instanceCount) |
913 | { |
914 | if (isContextLostOrPending()) |
915 | return; |
916 | |
917 | WebGLRenderingContextBase::drawElementsInstanced(mode, count, type, offset, instanceCount); |
918 | } |
919 | |
920 | void WebGL2RenderingContext::drawRangeElements(GC3Denum, GC3Duint, GC3Duint, GC3Dsizei, GC3Denum, GC3Dint64) |
921 | { |
922 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] drawRangeElements()" ); |
923 | } |
924 | |
925 | void WebGL2RenderingContext::drawBuffers(const Vector<GC3Denum>& buffers) |
926 | { |
927 | if (isContextLost()) |
928 | return; |
929 | GC3Dsizei n = buffers.size(); |
930 | const GC3Denum* bufs = buffers.data(); |
931 | if (!m_framebufferBinding) { |
932 | if (n != 1) { |
933 | synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffers" , "more than one buffer" ); |
934 | return; |
935 | } |
936 | if (bufs[0] != GraphicsContext3D::BACK && bufs[0] != GraphicsContext3D::NONE) { |
937 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffers" , "BACK or NONE" ); |
938 | return; |
939 | } |
940 | // Because the backbuffer is simulated on all current WebKit ports, we need to change BACK to COLOR_ATTACHMENT0. |
941 | GC3Denum value = (bufs[0] == GraphicsContext3D::BACK) ? GraphicsContext3D::COLOR_ATTACHMENT0 : GraphicsContext3D::NONE; |
942 | graphicsContext3D()->getExtensions().drawBuffersEXT(1, &value); |
943 | setBackDrawBuffer(bufs[0]); |
944 | } else { |
945 | if (n > getMaxDrawBuffers()) { |
946 | synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffers" , "more than max draw buffers" ); |
947 | return; |
948 | } |
949 | for (GC3Dsizei i = 0; i < n; ++i) { |
950 | if (bufs[i] != GraphicsContext3D::NONE && bufs[i] != static_cast<GC3Denum>(GraphicsContext3D::COLOR_ATTACHMENT0 + i)) { |
951 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffers" , "COLOR_ATTACHMENTi or NONE" ); |
952 | return; |
953 | } |
954 | } |
955 | m_framebufferBinding->drawBuffers(buffers); |
956 | } |
957 | } |
958 | |
959 | void WebGL2RenderingContext::clearBufferiv(GC3Denum buffer, GC3Dint drawbuffer, Int32List&&, GC3Duint) |
960 | { |
961 | switch (buffer) { |
962 | case GraphicsContext3D::COLOR: |
963 | if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) { |
964 | synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferiv" , "buffer index out of range" ); |
965 | return; |
966 | } |
967 | // TODO: Call clearBufferiv, requires gl3.h and ES3/gl.h |
968 | break; |
969 | case GraphicsContext3D::STENCIL: |
970 | if (drawbuffer) { |
971 | synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferiv" , "buffer index must be 0" ); |
972 | return; |
973 | } |
974 | // TODO: Call clearBufferiv, requires gl3.h and ES3/gl.h |
975 | break; |
976 | case GraphicsContext3D::DEPTH: |
977 | case GraphicsContext3D::DEPTH_STENCIL: |
978 | default: |
979 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clearBufferiv" , "buffer argument must be COLOR or STENCIL" ); |
980 | break; |
981 | } |
982 | } |
983 | |
984 | void WebGL2RenderingContext::clearBufferuiv(GC3Denum buffer, GC3Dint drawbuffer, Uint32List&&, GC3Duint) |
985 | { |
986 | switch (buffer) { |
987 | case GraphicsContext3D::COLOR: |
988 | if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) { |
989 | synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferuiv" , "buffer index out of range" ); |
990 | return; |
991 | } |
992 | // TODO: Call clearBufferuiv, requires gl3.h and ES3/gl.h |
993 | break; |
994 | case GraphicsContext3D::DEPTH: |
995 | case GraphicsContext3D::STENCIL: |
996 | case GraphicsContext3D::DEPTH_STENCIL: |
997 | default: |
998 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clearBufferuiv" , "buffer argument must be COLOR" ); |
999 | break; |
1000 | } |
1001 | } |
1002 | |
1003 | void WebGL2RenderingContext::clearBufferfv(GC3Denum buffer, GC3Dint drawbuffer, Float32List&&, GC3Duint) |
1004 | { |
1005 | switch (buffer) { |
1006 | case GraphicsContext3D::COLOR: |
1007 | if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) { |
1008 | synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferfv" , "buffer index out of range" ); |
1009 | return; |
1010 | } |
1011 | // TODO: Call clearBufferfv, requires gl3.h and ES3/gl.h |
1012 | break; |
1013 | case GraphicsContext3D::DEPTH: |
1014 | if (drawbuffer) { |
1015 | synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferfv" , "buffer index must be 0" ); |
1016 | return; |
1017 | } |
1018 | // TODO: Call clearBufferfv, requires gl3.h and ES3/gl.h |
1019 | break; |
1020 | case GraphicsContext3D::STENCIL: |
1021 | case GraphicsContext3D::DEPTH_STENCIL: |
1022 | default: |
1023 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clearBufferfv" , "buffer argument must be COLOR OR DEPTH" ); |
1024 | break; |
1025 | } |
1026 | } |
1027 | |
1028 | void WebGL2RenderingContext::clearBufferfi(GC3Denum buffer, GC3Dint drawbuffer, GC3Dfloat, GC3Dint) |
1029 | { |
1030 | switch (buffer) { |
1031 | case GraphicsContext3D::DEPTH_STENCIL: |
1032 | if (drawbuffer) { |
1033 | synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clearBufferfv" , "buffer index must be 0" ); |
1034 | return; |
1035 | } |
1036 | // TODO: Call clearBufferfi, requires gl3.h and ES3/gl.h |
1037 | break; |
1038 | case GraphicsContext3D::COLOR: |
1039 | case GraphicsContext3D::DEPTH: |
1040 | case GraphicsContext3D::STENCIL: |
1041 | default: |
1042 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "clearBufferfv" , "buffer argument must be DEPTH_STENCIL" ); |
1043 | break; |
1044 | } |
1045 | } |
1046 | |
1047 | RefPtr<WebGLQuery> WebGL2RenderingContext::createQuery() |
1048 | { |
1049 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] createQuery()" ); |
1050 | return nullptr; |
1051 | } |
1052 | |
1053 | void WebGL2RenderingContext::deleteQuery(WebGLQuery*) |
1054 | { |
1055 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] deleteQuery()" ); |
1056 | } |
1057 | |
1058 | GC3Dboolean WebGL2RenderingContext::isQuery(WebGLQuery*) |
1059 | { |
1060 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] isQuery()" ); |
1061 | return false; |
1062 | } |
1063 | |
1064 | void WebGL2RenderingContext::beginQuery(GC3Denum, WebGLQuery&) |
1065 | { |
1066 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] beginQuery()" ); |
1067 | } |
1068 | |
1069 | void WebGL2RenderingContext::endQuery(GC3Denum) |
1070 | { |
1071 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] endQuery()" ); |
1072 | } |
1073 | |
1074 | RefPtr<WebGLQuery> WebGL2RenderingContext::getQuery(GC3Denum, GC3Denum) |
1075 | { |
1076 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] getquery()" ); |
1077 | return nullptr; |
1078 | } |
1079 | |
1080 | WebGLAny WebGL2RenderingContext::getQueryParameter(WebGLQuery&, GC3Denum) |
1081 | { |
1082 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] getQueryParameter)" ); |
1083 | return nullptr; |
1084 | } |
1085 | |
1086 | RefPtr<WebGLSampler> WebGL2RenderingContext::createSampler() |
1087 | { |
1088 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] createSampler()" ); |
1089 | return nullptr; |
1090 | } |
1091 | |
1092 | void WebGL2RenderingContext::deleteSampler(WebGLSampler*) |
1093 | { |
1094 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] deleteSampler()" ); |
1095 | } |
1096 | |
1097 | GC3Dboolean WebGL2RenderingContext::isSampler(WebGLSampler*) |
1098 | { |
1099 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] isSampler()" ); |
1100 | return false; |
1101 | } |
1102 | |
1103 | void WebGL2RenderingContext::bindSampler(GC3Duint, WebGLSampler*) |
1104 | { |
1105 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] bindSampler()" ); |
1106 | } |
1107 | |
1108 | void WebGL2RenderingContext::samplerParameteri(WebGLSampler&, GC3Denum, GC3Dint) |
1109 | { |
1110 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] samplerParameteri()" ); |
1111 | } |
1112 | |
1113 | void WebGL2RenderingContext::samplerParameterf(WebGLSampler&, GC3Denum, GC3Dfloat) |
1114 | { |
1115 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] samplerParameterf()" ); |
1116 | } |
1117 | |
1118 | WebGLAny WebGL2RenderingContext::getSamplerParameter(WebGLSampler&, GC3Denum) |
1119 | { |
1120 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] getSamplerParameter()" ); |
1121 | return nullptr; |
1122 | } |
1123 | |
1124 | RefPtr<WebGLSync> WebGL2RenderingContext::fenceSync(GC3Denum, GC3Dbitfield) |
1125 | { |
1126 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] fenceSync()" ); |
1127 | return nullptr; |
1128 | } |
1129 | |
1130 | GC3Dboolean WebGL2RenderingContext::isSync(WebGLSync*) |
1131 | { |
1132 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] isSync()" ); |
1133 | return false; |
1134 | } |
1135 | |
1136 | void WebGL2RenderingContext::deleteSync(WebGLSync*) |
1137 | { |
1138 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] deleteSync()" ); |
1139 | } |
1140 | |
1141 | GC3Denum WebGL2RenderingContext::clientWaitSync(WebGLSync&, GC3Dbitfield, GC3Duint64) |
1142 | { |
1143 | // Note: Do not implement this function without consulting webkit-dev and WebGL |
1144 | // reviewers beforehand. Apple folks, see <rdar://problem/36666458>. |
1145 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] clientWaitSync()" ); |
1146 | return 0; |
1147 | } |
1148 | |
1149 | void WebGL2RenderingContext::waitSync(WebGLSync&, GC3Dbitfield, GC3Dint64) |
1150 | { |
1151 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] waitSync()" ); |
1152 | } |
1153 | |
1154 | WebGLAny WebGL2RenderingContext::getSyncParameter(WebGLSync&, GC3Denum) |
1155 | { |
1156 | // Note: Do not implement this function without consulting webkit-dev and WebGL |
1157 | // reviewers beforehand. Apple folks, see <rdar://problem/36666458>. |
1158 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] getSyncParameter()" ); |
1159 | return nullptr; |
1160 | } |
1161 | |
1162 | RefPtr<WebGLTransformFeedback> WebGL2RenderingContext::createTransformFeedback() |
1163 | { |
1164 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] createTransformFeedback()" ); |
1165 | return nullptr; |
1166 | } |
1167 | |
1168 | void WebGL2RenderingContext::deleteTransformFeedback(WebGLTransformFeedback*) |
1169 | { |
1170 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] deleteTransformFeedback()" ); |
1171 | } |
1172 | |
1173 | GC3Dboolean WebGL2RenderingContext::isTransformFeedback(WebGLTransformFeedback*) |
1174 | { |
1175 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] isTransformFeedback()" ); |
1176 | return false; |
1177 | } |
1178 | |
1179 | void WebGL2RenderingContext::bindTransformFeedback(GC3Denum, WebGLTransformFeedback*) |
1180 | { |
1181 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] bindTransformFeedback()" ); |
1182 | } |
1183 | |
1184 | void WebGL2RenderingContext::beginTransformFeedback(GC3Denum) |
1185 | { |
1186 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] beginTransformFeedback()" ); |
1187 | } |
1188 | |
1189 | void WebGL2RenderingContext::endTransformFeedback() |
1190 | { |
1191 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] endTransformFeedback()" ); |
1192 | } |
1193 | |
1194 | void WebGL2RenderingContext::transformFeedbackVaryings(WebGLProgram&, const Vector<String>&, GC3Denum) |
1195 | { |
1196 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] transformFeedbackVaryings()" ); |
1197 | } |
1198 | |
1199 | RefPtr<WebGLActiveInfo> WebGL2RenderingContext::getTransformFeedbackVarying(WebGLProgram&, GC3Duint) |
1200 | { |
1201 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] getTransformFeedbackVarying()" ); |
1202 | return nullptr; |
1203 | } |
1204 | |
1205 | void WebGL2RenderingContext::pauseTransformFeedback() |
1206 | { |
1207 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] pauseTransformFeedback()" ); |
1208 | } |
1209 | |
1210 | void WebGL2RenderingContext::resumeTransformFeedback() |
1211 | { |
1212 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] resumeTransformFeedback()" ); |
1213 | } |
1214 | |
1215 | void WebGL2RenderingContext::bindBufferBase(GC3Denum, GC3Duint, WebGLBuffer*) |
1216 | { |
1217 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] bindBufferBase()" ); |
1218 | } |
1219 | |
1220 | void WebGL2RenderingContext::bindBufferRange(GC3Denum, GC3Duint, WebGLBuffer*, GC3Dint64, GC3Dint64) |
1221 | { |
1222 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] bindBufferRange()" ); |
1223 | } |
1224 | |
1225 | WebGLAny WebGL2RenderingContext::getIndexedParameter(GC3Denum target, GC3Duint) |
1226 | { |
1227 | switch (target) { |
1228 | case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER_BINDING: |
1229 | case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER_SIZE: |
1230 | case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER_START: |
1231 | case GraphicsContext3D::UNIFORM_BUFFER_BINDING: |
1232 | case GraphicsContext3D::UNIFORM_BUFFER_SIZE: |
1233 | case GraphicsContext3D::UNIFORM_BUFFER_START: |
1234 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getIndexedParameter" , "parameter name not yet supported" ); |
1235 | return nullptr; |
1236 | default: |
1237 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getIndexedParameter" , "invalid parameter name" ); |
1238 | return nullptr; |
1239 | } |
1240 | } |
1241 | |
1242 | Optional<Vector<GC3Duint>> WebGL2RenderingContext::getUniformIndices(WebGLProgram&, const Vector<String>&) |
1243 | { |
1244 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] getUniformIndices()" ); |
1245 | return WTF::nullopt; |
1246 | } |
1247 | |
1248 | WebGLAny WebGL2RenderingContext::getActiveUniforms(WebGLProgram& program, const Vector<GC3Duint>& uniformIndices, GC3Denum pname) |
1249 | { |
1250 | if (isContextLostOrPending() || !validateWebGLObject("getActiveUniforms" , &program)) |
1251 | return nullptr; |
1252 | |
1253 | switch (pname) { |
1254 | case GraphicsContext3D::UNIFORM_TYPE: |
1255 | case GraphicsContext3D::UNIFORM_SIZE: |
1256 | case GraphicsContext3D::UNIFORM_BLOCK_INDEX: |
1257 | case GraphicsContext3D::UNIFORM_OFFSET: |
1258 | case GraphicsContext3D::UNIFORM_ARRAY_STRIDE: |
1259 | case GraphicsContext3D::UNIFORM_MATRIX_STRIDE: |
1260 | case GraphicsContext3D::UNIFORM_IS_ROW_MAJOR: |
1261 | { |
1262 | Vector<GC3Dint> params(uniformIndices.size(), 0); |
1263 | m_context->getActiveUniforms(program.object(), uniformIndices, pname, params); |
1264 | return WTFMove(params); |
1265 | } |
1266 | default: |
1267 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getActiveUniforms" , "invalid parameter name" ); |
1268 | return nullptr; |
1269 | } |
1270 | } |
1271 | |
1272 | GC3Duint WebGL2RenderingContext::getUniformBlockIndex(WebGLProgram&, const String&) |
1273 | { |
1274 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] getUniformBlockIndex()" ); |
1275 | return 0; |
1276 | } |
1277 | |
1278 | WebGLAny WebGL2RenderingContext::getActiveUniformBlockParameter(WebGLProgram&, GC3Duint, GC3Denum) |
1279 | { |
1280 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] getActiveUniformBlockParameter()" ); |
1281 | return nullptr; |
1282 | } |
1283 | |
1284 | WebGLAny WebGL2RenderingContext::getActiveUniformBlockName(WebGLProgram&, GC3Duint) |
1285 | { |
1286 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] getActiveUniformBlockName()" ); |
1287 | return nullptr; |
1288 | } |
1289 | |
1290 | void WebGL2RenderingContext::uniformBlockBinding(WebGLProgram&, GC3Duint, GC3Duint) |
1291 | { |
1292 | LOG(WebGL, "[[ NOT IMPLEMENTED ]] uniformBlockBinding()" ); |
1293 | } |
1294 | |
1295 | RefPtr<WebGLVertexArrayObject> WebGL2RenderingContext::createVertexArray() |
1296 | { |
1297 | if (isContextLost()) |
1298 | return nullptr; |
1299 | |
1300 | auto object = WebGLVertexArrayObject::create(*this, WebGLVertexArrayObject::Type::User); |
1301 | addContextObject(object.get()); |
1302 | return WTFMove(object); |
1303 | } |
1304 | |
1305 | void WebGL2RenderingContext::deleteVertexArray(WebGLVertexArrayObject* arrayObject) |
1306 | { |
1307 | if (!arrayObject || isContextLost()) |
1308 | return; |
1309 | |
1310 | if (arrayObject->isDeleted()) |
1311 | return; |
1312 | |
1313 | if (!arrayObject->isDefaultObject() && arrayObject == m_boundVertexArrayObject) |
1314 | #if USE(OPENGL_ES) |
1315 | setBoundVertexArrayObject(nullptr); |
1316 | #else |
1317 | bindVertexArray(nullptr); // The default VAO was removed in OpenGL 3.3 but not from WebGL 2; bind the default for WebGL to use. |
1318 | #endif |
1319 | |
1320 | arrayObject->deleteObject(graphicsContext3D()); |
1321 | } |
1322 | |
1323 | GC3Dboolean WebGL2RenderingContext::isVertexArray(WebGLVertexArrayObject* arrayObject) |
1324 | { |
1325 | if (!arrayObject || isContextLost()) |
1326 | return false; |
1327 | |
1328 | if (!arrayObject->hasEverBeenBound() || !arrayObject->validate(0, *this)) |
1329 | return false; |
1330 | |
1331 | return m_context->isVertexArray(arrayObject->object()); |
1332 | } |
1333 | |
1334 | void WebGL2RenderingContext::bindVertexArray(WebGLVertexArrayObject* arrayObject) |
1335 | { |
1336 | if (isContextLost()) |
1337 | return; |
1338 | |
1339 | if (arrayObject && (arrayObject->isDeleted() || !arrayObject->validate(0, *this) || !m_contextObjects.contains(arrayObject))) { |
1340 | m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION); |
1341 | return; |
1342 | } |
1343 | if (arrayObject && !arrayObject->isDefaultObject() && arrayObject->object()) { |
1344 | m_context->bindVertexArray(arrayObject->object()); |
1345 | |
1346 | arrayObject->setHasEverBeenBound(); |
1347 | setBoundVertexArrayObject(arrayObject); |
1348 | } else { |
1349 | m_context->bindVertexArray(m_defaultVertexArrayObject->object()); |
1350 | setBoundVertexArrayObject(m_defaultVertexArrayObject.get()); |
1351 | } |
1352 | } |
1353 | |
1354 | WebGLExtension* WebGL2RenderingContext::getExtension(const String& name) |
1355 | { |
1356 | if (isContextLostOrPending()) |
1357 | return nullptr; |
1358 | |
1359 | #define ENABLE_IF_REQUESTED(type, variable, nameLiteral, canEnable) \ |
1360 | if (equalIgnoringASCIICase(name, nameLiteral)) { \ |
1361 | if (!variable) { \ |
1362 | variable = (canEnable) ? 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 | |
1386 | Optional<Vector<String>> WebGL2RenderingContext::getSupportedExtensions() |
1387 | { |
1388 | if (isContextLost()) |
1389 | return WTF::nullopt; |
1390 | |
1391 | Vector<String> result; |
1392 | |
1393 | if (m_isPendingPolicyResolution) |
1394 | return result; |
1395 | |
1396 | auto& extensions = m_context->getExtensions(); |
1397 | if (extensions.supports("GL_OES_texture_float"_s )) |
1398 | result.append("OES_texture_float"_s ); |
1399 | if (extensions.supports("GL_OES_texture_float_linear"_s )) |
1400 | result.append("OES_texture_float_linear"_s ); |
1401 | if (extensions.supports("GL_OES_texture_half_float"_s )) |
1402 | result.append("OES_texture_half_float"_s ); |
1403 | if (extensions.supports("GL_OES_texture_half_float_linear"_s )) |
1404 | result.append("OES_texture_half_float_linear"_s ); |
1405 | if (extensions.supports("GL_EXT_texture_filter_anisotropic"_s )) |
1406 | result.append("WEBKIT_EXT_texture_filter_anisotropic"_s ); |
1407 | if (WebGLCompressedTextureATC::supported(*this)) |
1408 | result.append("WEBKIT_WEBGL_compressed_texture_atc"_s ); |
1409 | if (WebGLCompressedTexturePVRTC::supported(*this)) |
1410 | result.append("WEBKIT_WEBGL_compressed_texture_pvrtc"_s ); |
1411 | if (WebGLCompressedTextureS3TC::supported(*this)) |
1412 | result.append("WEBGL_compressed_texture_s3tc"_s ); |
1413 | if (WebGLCompressedTextureASTC::supported(*this)) |
1414 | result.append("WEBGL_compressed_texture_astc"_s ); |
1415 | if (WebGLDepthTexture::supported(*graphicsContext3D())) |
1416 | result.append("WEBGL_depth_texture"_s ); |
1417 | result.append("WEBGL_lose_context"_s ); |
1418 | if (extensions.supports("GL_ANGLE_translated_shader_source"_s )) |
1419 | result.append("WEBGL_debug_shaders"_s ); |
1420 | result.append("WEBGL_debug_renderer_info"_s ); |
1421 | |
1422 | return result; |
1423 | } |
1424 | |
1425 | static bool validateDefaultFramebufferAttachment(GC3Denum& attachment) |
1426 | { |
1427 | switch (attachment) { |
1428 | case GraphicsContext3D::BACK: |
1429 | // Because the backbuffer is simulated on all current WebKit ports, we need to change BACK to COLOR_ATTACHMENT0. |
1430 | attachment = GraphicsContext3D::COLOR_ATTACHMENT0; |
1431 | return true; |
1432 | case GraphicsContext3D::DEPTH: |
1433 | case GraphicsContext3D::STENCIL: |
1434 | return true; |
1435 | } |
1436 | |
1437 | return false; |
1438 | } |
1439 | |
1440 | WebGLAny WebGL2RenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname) |
1441 | { |
1442 | const char* functionName = "getFramebufferAttachmentParameter" ; |
1443 | if (isContextLostOrPending() || !validateFramebufferTarget(functionName, target)) |
1444 | return nullptr; |
1445 | |
1446 | auto targetFramebuffer = (target == GraphicsContext3D::READ_FRAMEBUFFER) ? m_readFramebufferBinding : m_framebufferBinding; |
1447 | |
1448 | if (!targetFramebuffer) { |
1449 | // OpenGL ES 3: Default framebuffer is bound. |
1450 | if (!validateDefaultFramebufferAttachment(attachment)) { |
1451 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid attachment" ); |
1452 | return nullptr; |
1453 | } |
1454 | GC3Dint value = 0; |
1455 | m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value); |
1456 | return value; |
1457 | } |
1458 | if (!validateNonDefaultFramebufferAttachment(functionName, attachment)) |
1459 | return nullptr; |
1460 | |
1461 | auto object = makeRefPtr(targetFramebuffer->getAttachmentObject(attachment)); |
1462 | if (!object) { |
1463 | if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) |
1464 | return static_cast<unsigned>(GraphicsContext3D::NONE); |
1465 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid parameter name" ); |
1466 | return nullptr; |
1467 | } |
1468 | |
1469 | switch (pname) { |
1470 | case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_RED_SIZE: |
1471 | case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: |
1472 | case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: |
1473 | case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: |
1474 | case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: |
1475 | case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: |
1476 | case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: { |
1477 | GC3Dint value = 0; |
1478 | m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value); |
1479 | return value; |
1480 | } |
1481 | } |
1482 | |
1483 | if (object->isTexture()) { |
1484 | switch (pname) { |
1485 | case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: |
1486 | return static_cast<unsigned>(GraphicsContext3D::TEXTURE); |
1487 | case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: |
1488 | return makeRefPtr(reinterpret_cast<WebGLTexture&>(*object)); |
1489 | case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: |
1490 | case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: |
1491 | case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: { |
1492 | GC3Dint value = 0; |
1493 | m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value); |
1494 | return value; |
1495 | } |
1496 | default: |
1497 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid parameter name for texture attachment" ); |
1498 | return nullptr; |
1499 | } |
1500 | } else { |
1501 | ASSERT(object->isRenderbuffer()); |
1502 | switch (pname) { |
1503 | case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: |
1504 | return static_cast<unsigned>(GraphicsContext3D::RENDERBUFFER); |
1505 | case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: |
1506 | return makeRefPtr(reinterpret_cast<WebGLRenderbuffer&>(*object)); |
1507 | case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING : { |
1508 | auto& renderBuffer = reinterpret_cast<WebGLRenderbuffer&>(*object); |
1509 | auto format = renderBuffer.getInternalFormat(); |
1510 | if (format == GraphicsContext3D::SRGB8_ALPHA8 |
1511 | || format == GraphicsContext3D::COMPRESSED_SRGB8_ETC2 |
1512 | || format == GraphicsContext3D::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC |
1513 | || format == GraphicsContext3D::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2) { |
1514 | return static_cast<unsigned>(GraphicsContext3D::SRGB); |
1515 | } |
1516 | return static_cast<unsigned>(GraphicsContext3D::LINEAR); |
1517 | } |
1518 | default: |
1519 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid parameter name for renderbuffer attachment" ); |
1520 | return nullptr; |
1521 | } |
1522 | } |
1523 | } |
1524 | |
1525 | bool WebGL2RenderingContext::validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment) |
1526 | { |
1527 | return validateFramebufferTarget(functionName, target) && validateNonDefaultFramebufferAttachment(functionName, attachment); |
1528 | } |
1529 | |
1530 | bool WebGL2RenderingContext::validateFramebufferTarget(const char* functionName, GC3Denum target) |
1531 | { |
1532 | switch (target) { |
1533 | case GraphicsContext3D::FRAMEBUFFER: |
1534 | case GraphicsContext3D::DRAW_FRAMEBUFFER: |
1535 | case GraphicsContext3D::READ_FRAMEBUFFER: |
1536 | return true; |
1537 | } |
1538 | |
1539 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target" ); |
1540 | return false; |
1541 | } |
1542 | |
1543 | bool WebGL2RenderingContext::validateNonDefaultFramebufferAttachment(const char* functionName, GC3Denum attachment) |
1544 | { |
1545 | switch (attachment) { |
1546 | case GraphicsContext3D::DEPTH_ATTACHMENT: |
1547 | case GraphicsContext3D::STENCIL_ATTACHMENT: |
1548 | case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT: |
1549 | return true; |
1550 | default: |
1551 | if (attachment >= GraphicsContext3D::COLOR_ATTACHMENT0 && attachment < static_cast<GC3Denum>(GraphicsContext3D::COLOR_ATTACHMENT0 + getMaxColorAttachments())) |
1552 | return true; |
1553 | } |
1554 | |
1555 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid attachment" ); |
1556 | return false; |
1557 | } |
1558 | |
1559 | GC3Dint WebGL2RenderingContext::getMaxDrawBuffers() |
1560 | { |
1561 | if (!m_maxDrawBuffers) |
1562 | m_context->getIntegerv(GraphicsContext3D::MAX_DRAW_BUFFERS, &m_maxDrawBuffers); |
1563 | return m_maxDrawBuffers; |
1564 | } |
1565 | |
1566 | GC3Dint WebGL2RenderingContext::getMaxColorAttachments() |
1567 | { |
1568 | // DrawBuffers requires MAX_COLOR_ATTACHMENTS == MAX_DRAW_BUFFERS |
1569 | if (!m_maxColorAttachments) |
1570 | m_context->getIntegerv(GraphicsContext3D::MAX_DRAW_BUFFERS, &m_maxColorAttachments); |
1571 | return m_maxColorAttachments; |
1572 | } |
1573 | |
1574 | void WebGL2RenderingContext::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height) |
1575 | { |
1576 | if (isContextLostOrPending()) |
1577 | return; |
1578 | if (target != GraphicsContext3D::RENDERBUFFER) { |
1579 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage" , "invalid target" ); |
1580 | return; |
1581 | } |
1582 | if (!m_renderbufferBinding || !m_renderbufferBinding->object()) { |
1583 | synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "renderbufferStorage" , "no bound renderbuffer" ); |
1584 | return; |
1585 | } |
1586 | if (!validateSize("renderbufferStorage" , width, height)) |
1587 | return; |
1588 | switch (internalformat) { |
1589 | case GraphicsContext3D::DEPTH_COMPONENT16: |
1590 | case GraphicsContext3D::DEPTH_COMPONENT32F: |
1591 | case GraphicsContext3D::DEPTH_COMPONENT24: |
1592 | case GraphicsContext3D::RGBA32I: |
1593 | case GraphicsContext3D::RGBA32UI: |
1594 | case GraphicsContext3D::RGBA16I: |
1595 | case GraphicsContext3D::RGBA16UI: |
1596 | case GraphicsContext3D::RGBA8: |
1597 | case GraphicsContext3D::RGBA8I: |
1598 | case GraphicsContext3D::RGBA8UI: |
1599 | case GraphicsContext3D::RGB10_A2: |
1600 | case GraphicsContext3D::RGB10_A2UI: |
1601 | case GraphicsContext3D::RGBA4: |
1602 | case GraphicsContext3D::RG32I: |
1603 | case GraphicsContext3D::RG32UI: |
1604 | case GraphicsContext3D::RG16I: |
1605 | case GraphicsContext3D::RG16UI: |
1606 | case GraphicsContext3D::RG8: |
1607 | case GraphicsContext3D::RG8I: |
1608 | case GraphicsContext3D::RG8UI: |
1609 | case GraphicsContext3D::R32I: |
1610 | case GraphicsContext3D::R32UI: |
1611 | case GraphicsContext3D::R16I: |
1612 | case GraphicsContext3D::R16UI: |
1613 | case GraphicsContext3D::R8: |
1614 | case GraphicsContext3D::R8I: |
1615 | case GraphicsContext3D::R8UI: |
1616 | case GraphicsContext3D::RGB5_A1: |
1617 | case GraphicsContext3D::RGB565: |
1618 | case GraphicsContext3D::RGB8: |
1619 | case GraphicsContext3D::STENCIL_INDEX8: |
1620 | case GraphicsContext3D::SRGB8_ALPHA8: |
1621 | m_context->renderbufferStorage(target, internalformat, width, height); |
1622 | m_renderbufferBinding->setInternalFormat(internalformat); |
1623 | m_renderbufferBinding->setIsValid(true); |
1624 | m_renderbufferBinding->setSize(width, height); |
1625 | break; |
1626 | case GraphicsContext3D::DEPTH32F_STENCIL8: |
1627 | case GraphicsContext3D::DEPTH24_STENCIL8: |
1628 | if (!isDepthStencilSupported()) { |
1629 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage" , "invalid internalformat" ); |
1630 | return; |
1631 | } |
1632 | m_context->renderbufferStorage(target, internalformat, width, height); |
1633 | m_renderbufferBinding->setSize(width, height); |
1634 | m_renderbufferBinding->setIsValid(isDepthStencilSupported()); |
1635 | m_renderbufferBinding->setInternalFormat(internalformat); |
1636 | break; |
1637 | default: |
1638 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage" , "invalid internalformat" ); |
1639 | return; |
1640 | } |
1641 | applyStencilTest(); |
1642 | } |
1643 | |
1644 | void WebGL2RenderingContext::hint(GC3Denum target, GC3Denum mode) |
1645 | { |
1646 | if (isContextLostOrPending()) |
1647 | return; |
1648 | bool isValid = false; |
1649 | switch (target) { |
1650 | case GraphicsContext3D::GENERATE_MIPMAP_HINT: |
1651 | case GraphicsContext3D::FRAGMENT_SHADER_DERIVATIVE_HINT: |
1652 | isValid = true; |
1653 | break; |
1654 | } |
1655 | if (!isValid) { |
1656 | synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "hint" , "invalid target" ); |
1657 | return; |
1658 | } |
1659 | m_context->hint(target, mode); |
1660 | } |
1661 | |
1662 | GC3Denum WebGL2RenderingContext::baseInternalFormatFromInternalFormat(GC3Denum internalformat) |
1663 | { |
1664 | // Handles sized, unsized, and compressed internal formats. |
1665 | switch (internalformat) { |
1666 | case GraphicsContext3D::R8: |
1667 | case GraphicsContext3D::R8_SNORM: |
1668 | case GraphicsContext3D::R16F: |
1669 | case GraphicsContext3D::R32F: |
1670 | case GraphicsContext3D::COMPRESSED_R11_EAC: |
1671 | case GraphicsContext3D::COMPRESSED_SIGNED_R11_EAC: |
1672 | return GraphicsContext3D::RED; |
1673 | case GraphicsContext3D::R8I: |
1674 | case GraphicsContext3D::R8UI: |
1675 | case GraphicsContext3D::R16I: |
1676 | case GraphicsContext3D::R16UI: |
1677 | case GraphicsContext3D::R32I: |
1678 | case GraphicsContext3D::R32UI: |
1679 | return GraphicsContext3D::RED_INTEGER; |
1680 | case GraphicsContext3D::RG8: |
1681 | case GraphicsContext3D::RG8_SNORM: |
1682 | case GraphicsContext3D::RG16F: |
1683 | case GraphicsContext3D::RG32F: |
1684 | case GraphicsContext3D::COMPRESSED_RG11_EAC: |
1685 | case GraphicsContext3D::COMPRESSED_SIGNED_RG11_EAC: |
1686 | return GraphicsContext3D::RG; |
1687 | case GraphicsContext3D::RG8I: |
1688 | case GraphicsContext3D::RG8UI: |
1689 | case GraphicsContext3D::RG16I: |
1690 | case GraphicsContext3D::RG16UI: |
1691 | case GraphicsContext3D::RG32I: |
1692 | case GraphicsContext3D::RG32UI: |
1693 | return GraphicsContext3D::RG_INTEGER; |
1694 | case GraphicsContext3D::RGB8: |
1695 | case GraphicsContext3D::RGB8_SNORM: |
1696 | case GraphicsContext3D::RGB565: |
1697 | case GraphicsContext3D::SRGB8: |
1698 | case GraphicsContext3D::RGB16F: |
1699 | case GraphicsContext3D::RGB32F: |
1700 | case GraphicsContext3D::RGB: |
1701 | case GraphicsContext3D::COMPRESSED_RGB8_ETC2: |
1702 | case GraphicsContext3D::COMPRESSED_SRGB8_ETC2: |
1703 | return GraphicsContext3D::RGB; |
1704 | case GraphicsContext3D::RGB8I: |
1705 | case GraphicsContext3D::RGB8UI: |
1706 | case GraphicsContext3D::RGB16I: |
1707 | case GraphicsContext3D::RGB16UI: |
1708 | case GraphicsContext3D::RGB32I: |
1709 | case GraphicsContext3D::RGB32UI: |
1710 | return GraphicsContext3D::RGB_INTEGER; |
1711 | case GraphicsContext3D::RGBA4: |
1712 | case GraphicsContext3D::RGB5_A1: |
1713 | case GraphicsContext3D::RGBA8: |
1714 | case GraphicsContext3D::RGBA8_SNORM: |
1715 | case GraphicsContext3D::RGB10_A2: |
1716 | case GraphicsContext3D::SRGB8_ALPHA8: |
1717 | case GraphicsContext3D::RGBA16F: |
1718 | case GraphicsContext3D::RGBA32F: |
1719 | case GraphicsContext3D::RGBA: |
1720 | case GraphicsContext3D::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: |
1721 | case GraphicsContext3D::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: |
1722 | case GraphicsContext3D::COMPRESSED_RGBA8_ETC2_EAC: |
1723 | case GraphicsContext3D::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: |
1724 | return GraphicsContext3D::RGBA; |
1725 | case GraphicsContext3D::RGBA8I: |
1726 | case GraphicsContext3D::RGBA8UI: |
1727 | case GraphicsContext3D::RGB10_A2UI: |
1728 | case GraphicsContext3D::RGBA16I: |
1729 | case GraphicsContext3D::RGBA16UI: |
1730 | case GraphicsContext3D::RGBA32I: |
1731 | case GraphicsContext3D::RGBA32UI: |
1732 | return GraphicsContext3D::RGBA_INTEGER; |
1733 | case GraphicsContext3D::DEPTH_COMPONENT16: |
1734 | case GraphicsContext3D::DEPTH_COMPONENT24: |
1735 | case GraphicsContext3D::DEPTH_COMPONENT32F: |
1736 | return GraphicsContext3D::DEPTH_COMPONENT; |
1737 | case GraphicsContext3D::DEPTH24_STENCIL8: |
1738 | case GraphicsContext3D::DEPTH32F_STENCIL8: |
1739 | return GraphicsContext3D::DEPTH_STENCIL; |
1740 | case GraphicsContext3D::LUMINANCE: |
1741 | case GraphicsContext3D::LUMINANCE_ALPHA: |
1742 | case GraphicsContext3D::ALPHA: |
1743 | return internalformat; |
1744 | default: |
1745 | ASSERT_NOT_REACHED(); |
1746 | return GraphicsContext3D::NONE; |
1747 | } |
1748 | } |
1749 | |
1750 | bool WebGL2RenderingContext::isIntegerFormat(GC3Denum internalformat) |
1751 | { |
1752 | switch (baseInternalFormatFromInternalFormat(internalformat)) { |
1753 | case GraphicsContext3D::RED_INTEGER: |
1754 | case GraphicsContext3D::RG_INTEGER: |
1755 | case GraphicsContext3D::RGB_INTEGER: |
1756 | case GraphicsContext3D::RGBA_INTEGER: |
1757 | return true; |
1758 | } |
1759 | return false; |
1760 | } |
1761 | |
1762 | WebGLAny WebGL2RenderingContext::getParameter(GC3Denum pname) |
1763 | { |
1764 | if (isContextLostOrPending()) |
1765 | return nullptr; |
1766 | switch (pname) { |
1767 | case GraphicsContext3D::ACTIVE_TEXTURE: |
1768 | return getUnsignedIntParameter(pname); |
1769 | case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE: |
1770 | return getWebGLFloatArrayParameter(pname); |
1771 | case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE: |
1772 | return getWebGLFloatArrayParameter(pname); |
1773 | case GraphicsContext3D::ALPHA_BITS: |
1774 | 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 | |
2092 | bool 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 | |
2145 | bool 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 | |
2160 | bool 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 | |