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