Move HTML canvas and tracks from ExceptionCode to Exception
[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 void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, ImageData* pixels)
1123 {
1124     if (isContextLostOrPending() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage, SourceImageData, target, level, GraphicsContext3D::NONE,  pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))
1125         return;
1126     
1127     Vector<uint8_t> data;
1128     bool needConversion = true;
1129     // The data from ImageData is always of format RGBA8.
1130     // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
1131     if (format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha)
1132         needConversion = false;
1133     else {
1134         if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
1135             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image data");
1136             return;
1137         }
1138     }
1139     if (m_unpackAlignment != 1)
1140         m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
1141     
1142     WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
1143     GC3Denum internalformat = tex->getInternalFormat(target, level);
1144     texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), internalformat, format, type, needConversion ? data.data() : pixels->data()->data());
1145     if (m_unpackAlignment != 1)
1146         m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
1147 }
1148
1149 ExceptionOr<void> WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLImageElement* image)
1150 {
1151     if (wouldTaintOrigin(image))
1152         return Exception { SECURITY_ERR };
1153     if (isContextLostOrPending() || !validateHTMLImageElement("texSubImage2D", image))
1154         return { };
1155
1156     RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
1157     if (!imageForRender)
1158         return { };
1159
1160     if (imageForRender->isSVGImage())
1161         imageForRender = drawImageIntoBuffer(*imageForRender, image->width(), image->height(), 1);
1162     
1163     if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLImageElement, target, level, GraphicsContext3D::NONE, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset))
1164         return { };
1165     
1166     texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha);
1167     return { };
1168 }
1169
1170 ExceptionOr<void> WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas)
1171 {
1172     if (wouldTaintOrigin(canvas))
1173         return Exception { SECURITY_ERR };
1174     if (isContextLostOrPending() || !validateHTMLCanvasElement("texSubImage2D", canvas)
1175         || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElement, target, level, GraphicsContext3D::NONE, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
1176         return { };
1177
1178     RefPtr<ImageData> imageData = canvas->getImageData();
1179     if (imageData)
1180         texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get());
1181     else
1182         texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha);
1183     return { };
1184 }
1185
1186 #if ENABLE(VIDEO)
1187
1188 ExceptionOr<void> WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLVideoElement* video)
1189 {
1190     if (wouldTaintOrigin(video))
1191         return Exception { SECURITY_ERR };
1192     if (isContextLostOrPending() || !validateHTMLVideoElement("texSubImage2D", video)
1193         || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLVideoElement, target, level, GraphicsContext3D::NONE, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))
1194         return { };
1195
1196     RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode());
1197     if (!image)
1198         return { };
1199     texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha);
1200     return { };
1201 }
1202
1203 #endif
1204
1205 bool WebGL2RenderingContext::validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType functionType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type)
1206 {
1207     if (functionType == CopyTexImage) {
1208         GC3Denum framebufferInternalFormat = 0;
1209         WebGLSharedObject* object = m_framebufferBinding->getAttachmentObject(GraphicsContext3D::COLOR_ATTACHMENT0);
1210         if (object->isTexture()) {
1211             WebGLTexture* texture = reinterpret_cast<WebGLTexture*>(object);
1212             framebufferInternalFormat = baseInternalFormatFromInternalFormat(texture->getInternalFormat(GraphicsContext3D::TEXTURE_2D, 0));
1213         } else if (object->isRenderbuffer()) {
1214             WebGLRenderbuffer* renderBuffer = reinterpret_cast<WebGLRenderbuffer*>(object);
1215             framebufferInternalFormat = baseInternalFormatFromInternalFormat(renderBuffer->getInternalFormat());
1216         }
1217         
1218         GC3Denum baseTextureInternalFormat = baseInternalFormatFromInternalFormat(internalformat);
1219         bool validFormatCombination = true;
1220         switch (framebufferInternalFormat) {
1221         case GraphicsContext3D::RED:
1222             if (baseTextureInternalFormat != GraphicsContext3D::LUMINANCE && baseTextureInternalFormat != GraphicsContext3D::RED)
1223                 validFormatCombination = false;
1224             break;
1225         case GraphicsContext3D::RG:
1226             if (baseTextureInternalFormat != GraphicsContext3D::LUMINANCE && baseTextureInternalFormat != GraphicsContext3D::RED && baseTextureInternalFormat != GraphicsContext3D::RG)
1227                 validFormatCombination = false;
1228             break;
1229         case GraphicsContext3D::RGB:
1230             if (baseTextureInternalFormat != GraphicsContext3D::LUMINANCE && baseTextureInternalFormat != GraphicsContext3D::RED && baseTextureInternalFormat != GraphicsContext3D::RG && baseTextureInternalFormat != GraphicsContext3D::RGB)
1231                 validFormatCombination = false;
1232             break;
1233         case GraphicsContext3D::RGBA:
1234             if (baseTextureInternalFormat != GraphicsContext3D::ALPHA && baseTextureInternalFormat != GraphicsContext3D::LUMINANCE && baseTextureInternalFormat != GraphicsContext3D::LUMINANCE_ALPHA && baseTextureInternalFormat != GraphicsContext3D::RED && baseTextureInternalFormat != GraphicsContext3D::RG && baseTextureInternalFormat != GraphicsContext3D::RGB && baseTextureInternalFormat != GraphicsContext3D::RGBA)
1235                 validFormatCombination = false;
1236             break;
1237         case GraphicsContext3D::DEPTH_COMPONENT:
1238             validFormatCombination = false;
1239             break;
1240         case GraphicsContext3D::DEPTH_STENCIL:
1241             validFormatCombination = false;
1242             break;
1243         }
1244         
1245         if (!validFormatCombination) {
1246             synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "copyTexImage: invalid combination of framebuffer and texture formats");
1247             return false;
1248         }
1249
1250         bool isSRGB = (getFramebufferAttachmentParameter(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING).getInt() == GraphicsContext3D::SRGB);
1251         if (isSRGB != (framebufferInternalFormat == GraphicsContext3D::SRGB8 || framebufferInternalFormat == GraphicsContext3D::SRGB8_ALPHA8)) {
1252             synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "framebuffer attachment color encoding and internal format do not match");
1253         return false;
1254         }
1255     }
1256     
1257     // We absolutely have to validate the format and type combination.
1258     // The texImage2D entry points taking HTMLImage, etc. will produce
1259     // temporary data based on this combination, so it must be legal.
1260     if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level) || !validateTexFuncLevel(functionName, target, level))
1261         return false;
1262     
1263     if (width < 0 || height < 0) {
1264         synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
1265         return false;
1266     }
1267     
1268     GC3Dint maxTextureSizeForLevel = pow(2.0, m_maxTextureLevel - 1 - level);
1269     switch (target) {
1270     case GraphicsContext3D::TEXTURE_2D:
1271         if (width > maxTextureSizeForLevel || height > maxTextureSizeForLevel) {
1272             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range");
1273             return false;
1274         }
1275         break;
1276     case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
1277     case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
1278     case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
1279     case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
1280     case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
1281     case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
1282         if (functionType != TexSubImage && width != height) {
1283             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height for cube map");
1284             return false;
1285         }
1286         // No need to check height here. For texImage width == height.
1287         // For texSubImage that will be checked when checking yoffset + height is in range.
1288         if (width > maxTextureSizeForLevel) {
1289             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range for cube map");
1290             return false;
1291         }
1292         break;
1293     default:
1294         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
1295         return false;
1296     }
1297     
1298     if (border) {
1299         synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "border != 0");
1300         return false;
1301     }
1302     
1303     return true;
1304 }
1305     
1306 bool WebGL2RenderingContext::validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level)
1307 {
1308     // Verify that a valid format has been provided.
1309     switch (format) {
1310     case GraphicsContext3D::ALPHA:
1311     case GraphicsContext3D::LUMINANCE:
1312     case GraphicsContext3D::LUMINANCE_ALPHA:
1313     case GraphicsContext3D::RGB:
1314     case GraphicsContext3D::RGBA:
1315     case GraphicsContext3D::RGBA_INTEGER:
1316     case GraphicsContext3D::RG:
1317     case GraphicsContext3D::RG_INTEGER:
1318     case GraphicsContext3D::RED_INTEGER:
1319         break;
1320     case GraphicsContext3D::DEPTH_STENCIL:
1321     case GraphicsContext3D::DEPTH_COMPONENT:
1322         if (m_webglDepthTexture)
1323             break;
1324         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "depth texture formats not enabled");
1325         return false;
1326     default:
1327         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture format");
1328         return false;
1329     }
1330     
1331     // Verify that a valid type has been provided.
1332     switch (type) {
1333     case GraphicsContext3D::UNSIGNED_BYTE:
1334     case GraphicsContext3D::BYTE:
1335     case GraphicsContext3D::UNSIGNED_SHORT:
1336     case GraphicsContext3D::SHORT:
1337     case GraphicsContext3D::UNSIGNED_INT:
1338     case GraphicsContext3D::INT:
1339     case GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV:
1340     case GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV:
1341     case GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV:
1342     case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
1343     case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
1344     case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
1345         break;
1346     case GraphicsContext3D::FLOAT:
1347         if (m_oesTextureFloat)
1348             break;
1349         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
1350         return false;
1351     case GraphicsContext3D::HALF_FLOAT:
1352     case GraphicsContext3D::HALF_FLOAT_OES:
1353         if (m_oesTextureHalfFloat)
1354             break;
1355         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
1356         return false;
1357     case GraphicsContext3D::UNSIGNED_INT_24_8:
1358     case GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV:
1359         if (isDepthStencilSupported())
1360             break;
1361         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
1362         return false;
1363     default:
1364         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
1365         return false;
1366     }
1367     
1368     // Veryify that a valid internal format has been provided.
1369     switch (internalformat) {
1370     case GraphicsContext3D::RGBA:
1371     case GraphicsContext3D::RGB:
1372     case GraphicsContext3D::LUMINANCE_ALPHA:
1373     case GraphicsContext3D::LUMINANCE:
1374     case GraphicsContext3D::ALPHA:
1375     case GraphicsContext3D::RGBA32I:
1376     case GraphicsContext3D::RGBA32UI:
1377     case GraphicsContext3D::RGBA16I:
1378     case GraphicsContext3D::RGBA16UI:
1379     case GraphicsContext3D::RGBA8:
1380     case GraphicsContext3D::RGBA8I:
1381     case GraphicsContext3D::RGBA8UI:
1382     case GraphicsContext3D::RGB10_A2:
1383     case GraphicsContext3D::RGB10_A2UI:
1384     case GraphicsContext3D::RGBA4:
1385     case GraphicsContext3D::RG32I:
1386     case GraphicsContext3D::RG32UI:
1387     case GraphicsContext3D::RG16I:
1388     case GraphicsContext3D::RG16UI:
1389     case GraphicsContext3D::RG8:
1390     case GraphicsContext3D::RG8I:
1391     case GraphicsContext3D::RG8UI:
1392     case GraphicsContext3D::R32I:
1393     case GraphicsContext3D::R32UI:
1394     case GraphicsContext3D::R16I:
1395     case GraphicsContext3D::R16UI:
1396     case GraphicsContext3D::R8:
1397     case GraphicsContext3D::R8I:
1398     case GraphicsContext3D::R8UI:
1399     case GraphicsContext3D::RGB5_A1:
1400     case GraphicsContext3D::RGB8:
1401     case GraphicsContext3D::RGB565:
1402     case GraphicsContext3D::RGBA32F:
1403     case GraphicsContext3D::RGBA16F:
1404     case GraphicsContext3D::RGBA8_SNORM:
1405     case GraphicsContext3D::RGB32F:
1406     case GraphicsContext3D::RGB32I:
1407     case GraphicsContext3D::RGB32UI:
1408     case GraphicsContext3D::RGB16F:
1409     case GraphicsContext3D::RGB16I:
1410     case GraphicsContext3D::RGB16UI:
1411     case GraphicsContext3D::RGB8_SNORM:
1412     case GraphicsContext3D::RGB8I:
1413     case GraphicsContext3D::RGB8UI:
1414     case GraphicsContext3D::SRGB8:
1415     case GraphicsContext3D::SRGB8_ALPHA8:
1416     case GraphicsContext3D::R11F_G11F_B10F:
1417     case GraphicsContext3D::RGB9_E5:
1418     case GraphicsContext3D::RG32F:
1419     case GraphicsContext3D::RG16F:
1420     case GraphicsContext3D::RG8_SNORM:
1421     case GraphicsContext3D::R32F:
1422     case GraphicsContext3D::R16F:
1423     case GraphicsContext3D::R8_SNORM:
1424     case GraphicsContext3D::STENCIL_INDEX8:
1425         break;
1426     case GraphicsContext3D::DEPTH_COMPONENT16:
1427     case GraphicsContext3D::DEPTH_COMPONENT32F:
1428     case GraphicsContext3D::DEPTH_COMPONENT24:
1429         if (m_webglDepthTexture)
1430             break;
1431         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "depth texture formats not enabled");
1432         return false;
1433     case GraphicsContext3D::DEPTH32F_STENCIL8:
1434     case GraphicsContext3D::DEPTH24_STENCIL8:
1435         if (isDepthStencilSupported())
1436             break;
1437         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture internal format");
1438         return false;
1439     case GraphicsContext3D::NONE:
1440         // When calling validateTexFuncFormatAndType with internalformat == GraphicsContext3D::NONE, the intent is
1441         // only to check for whether or not the format and type are valid types, which we have already done at this point.
1442         return true;
1443         break;
1444     default:
1445         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture internal format");
1446         return false;
1447     }
1448
1449     // Verify that the combination of format, internalformat and type is supported.
1450     switch (format) {
1451     case GraphicsContext3D::RGBA:
1452         if (type == GraphicsContext3D::UNSIGNED_BYTE
1453             && (internalformat == GraphicsContext3D::RGBA || internalformat == GraphicsContext3D::RGBA8 || internalformat == GraphicsContext3D::RGB5_A1 || internalformat == GraphicsContext3D::RGBA4 || internalformat == GraphicsContext3D::SRGB8_ALPHA8))
1454             break;
1455         if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RGBA8_SNORM)
1456             break;
1457         if (type == GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4
1458             && (internalformat == GraphicsContext3D::RGBA || internalformat == GraphicsContext3D::RGBA4))
1459             break;
1460         if (type == GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1
1461             && (internalformat == GraphicsContext3D::RGBA || internalformat == GraphicsContext3D::RGB5_A1))
1462             break;
1463         if (type == GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV
1464             && (internalformat == GraphicsContext3D::RGB10_A2 || internalformat == GraphicsContext3D::RGB5_A1))
1465             break;
1466         if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES) && internalformat == GraphicsContext3D::RGBA16F)
1467             break;
1468         if (type == GraphicsContext3D::FLOAT
1469             && (internalformat == GraphicsContext3D::RGBA32F || internalformat == GraphicsContext3D::RGBA16F))
1470             break;
1471         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
1472         return false;
1473     case GraphicsContext3D::RGBA_INTEGER:
1474         if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::RGBA8UI)
1475         break;
1476         if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RGBA8I)
1477         break;
1478         if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::RGBA16UI)
1479         break;
1480         if (type == GraphicsContext3D::SHORT && internalformat == GraphicsContext3D::RGBA16I)
1481         break;
1482         if (type == GraphicsContext3D::UNSIGNED_INT && internalformat == GraphicsContext3D::RGBA32UI)
1483         break;
1484         if (type == GraphicsContext3D::INT && internalformat == GraphicsContext3D::RGBA32I)
1485         break;
1486         if (type == GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV && internalformat == GraphicsContext3D::RGB10_A2UI)
1487             break;
1488         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
1489         return false;
1490     case GraphicsContext3D::RGB:
1491         if (type == GraphicsContext3D::UNSIGNED_BYTE
1492             && (internalformat == GraphicsContext3D::RGB || internalformat == GraphicsContext3D::RGB8 || internalformat == GraphicsContext3D::RGB565
1493             || internalformat == GraphicsContext3D::SRGB8))
1494             break;
1495         if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RGB8_SNORM)
1496             break;
1497         if (type == GraphicsContext3D::UNSIGNED_SHORT_5_6_5
1498             && (internalformat == GraphicsContext3D::RGB || internalformat == GraphicsContext3D::RGB565))
1499             break;
1500         if (type == GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV && internalformat == GraphicsContext3D::R11F_G11F_B10F)
1501             break;
1502         if (type == GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV && internalformat == GraphicsContext3D::RGB9_E5)
1503             break;
1504         if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES)
1505             && (internalformat == GraphicsContext3D::RGB16F || internalformat == GraphicsContext3D::R11F_G11F_B10F || internalformat == GraphicsContext3D::RGB9_E5))
1506             break;
1507         if (type == GraphicsContext3D::FLOAT
1508             && (internalformat == GraphicsContext3D::RGB32F || internalformat == GraphicsContext3D::RGB16F || internalformat == GraphicsContext3D::R11F_G11F_B10F || internalformat == GraphicsContext3D::RGB9_E5))
1509             break;
1510         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
1511         return false;
1512     case GraphicsContext3D::RGB_INTEGER:
1513         if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::RGB8UI)
1514             break;
1515         if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RGB8I)
1516             break;
1517         if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::RGB16UI)
1518             break;
1519         if (type == GraphicsContext3D::SHORT && internalformat == GraphicsContext3D::RGB16I)
1520             break;
1521         if (type == GraphicsContext3D::UNSIGNED_INT && internalformat == GraphicsContext3D::RGB32UI)
1522             break;
1523         if (type == GraphicsContext3D::INT && internalformat == GraphicsContext3D::RGB32I)
1524             break;
1525         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
1526         return false;
1527     case GraphicsContext3D::RG:
1528         if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::RG8)
1529             break;
1530         if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RG8_SNORM)
1531             break;
1532         if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES) && internalformat == GraphicsContext3D::RG16F)
1533             break;
1534         if (type == GraphicsContext3D::FLOAT
1535             && (internalformat == GraphicsContext3D::RG32F || internalformat == GraphicsContext3D::RG16F))
1536             break;
1537         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
1538         return false;
1539     case GraphicsContext3D::RG_INTEGER:
1540         if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::RG8UI)
1541             break;
1542         if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RG8I)
1543             break;
1544         if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::RG16UI)
1545             break;
1546         if (type == GraphicsContext3D::SHORT && internalformat == GraphicsContext3D::RG16I)
1547             break;
1548         if (type == GraphicsContext3D::UNSIGNED_INT && internalformat == GraphicsContext3D::RG32UI)
1549             break;
1550         if (type == GraphicsContext3D::INT && internalformat == GraphicsContext3D::RG32I)
1551             break;
1552         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
1553         return false;
1554     case GraphicsContext3D::RED:
1555         if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::R8)
1556             break;
1557         if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::R8_SNORM)
1558             break;
1559         if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES) && internalformat == GraphicsContext3D::R16F)
1560             break;
1561         if (type == GraphicsContext3D::FLOAT
1562             && (internalformat == GraphicsContext3D::R32F || internalformat == GraphicsContext3D::R16F))
1563             break;
1564         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
1565         return false;
1566     case GraphicsContext3D::RED_INTEGER:
1567         if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::R8UI)
1568             break;
1569         if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::R8I)
1570             break;
1571         if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::R16UI)
1572             break;
1573         if (type == GraphicsContext3D::SHORT && internalformat == GraphicsContext3D::R16I)
1574             break;
1575         if (type == GraphicsContext3D::UNSIGNED_INT && internalformat == GraphicsContext3D::R32UI)
1576             break;
1577         if (type == GraphicsContext3D::INT && internalformat == GraphicsContext3D::R32I)
1578             break;
1579         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
1580         return false;
1581     case GraphicsContext3D::DEPTH_COMPONENT:
1582         if (!m_webglDepthTexture) {
1583             synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_COMPONENT not enabled");
1584             return false;
1585         }
1586         if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::DEPTH_COMPONENT16)
1587             break;
1588         if (type == GraphicsContext3D::UNSIGNED_INT
1589             && (internalformat == GraphicsContext3D::DEPTH_COMPONENT24 || internalformat == GraphicsContext3D::DEPTH_COMPONENT16))
1590             break;
1591         if (type == GraphicsContext3D::FLOAT && internalformat == GraphicsContext3D::DEPTH_COMPONENT32F)
1592             break;
1593         if (level > 0) {
1594             synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format");
1595             return false;
1596         }
1597         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
1598         return false;
1599     case GraphicsContext3D::DEPTH_STENCIL:
1600         if (!m_webglDepthTexture || !isDepthStencilSupported()) {
1601             synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_STENCIL not enabled");
1602             return false;
1603         }
1604         if (type == GraphicsContext3D::UNSIGNED_INT_24_8 && internalformat == GraphicsContext3D::DEPTH24_STENCIL8)
1605             break;
1606         if (type == GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV && internalformat == GraphicsContext3D::DEPTH32F_STENCIL8)
1607             break;
1608         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
1609         return false;
1610     case GraphicsContext3D::ALPHA:
1611     case GraphicsContext3D::LUMINANCE:
1612     case GraphicsContext3D::LUMINANCE_ALPHA:
1613         if ((type == GraphicsContext3D::UNSIGNED_BYTE || type == GraphicsContext3D::HALF_FLOAT_OES || type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::FLOAT) && internalformat == format)
1614             break;
1615         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
1616         return false;
1617     default:
1618         ASSERT_NOT_REACHED();
1619     }
1620
1621     return true;
1622 }
1623
1624 bool WebGL2RenderingContext::validateTexFuncData(const char* functionName, GC3Dint level,
1625     GC3Dsizei width, GC3Dsizei height,
1626     GC3Denum internalformat, GC3Denum format, GC3Denum type,
1627     ArrayBufferView* pixels,
1628     NullDisposition disposition)
1629 {
1630     if (!pixels) {
1631         if (disposition == NullAllowed)
1632             return true;
1633         synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no pixels");
1634         return false;
1635     }
1636
1637     if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level))
1638         return false;
1639     if (!validateSettableTexFormat(functionName, format))
1640         return false;
1641     
1642     switch (type) {
1643     case GraphicsContext3D::BYTE:
1644         if (pixels->getType() != JSC::TypeInt8) {
1645             synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type BYTE but ArrayBufferView not Int8Array");
1646             return false;
1647         }
1648         break;
1649     case GraphicsContext3D::UNSIGNED_BYTE:
1650         if (pixels->getType() != JSC::TypeUint8) {
1651             synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array");
1652             return false;
1653         }
1654         break;
1655     case GraphicsContext3D::SHORT:
1656         if (pixels->getType() != JSC::TypeInt16) {
1657             synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type SHORT but ArrayBufferView not Int16Array");
1658             return false;
1659         }
1660         break;
1661     case GraphicsContext3D::UNSIGNED_SHORT:
1662     case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
1663     case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
1664     case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
1665         if (pixels->getType() != JSC::TypeUint16) {
1666             synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array");
1667             return false;
1668         }
1669         break;
1670     case GraphicsContext3D::INT:
1671         if (pixels->getType() != JSC::TypeInt32) {
1672             synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type INT but ArrayBufferView not Int32Array");
1673             return false;
1674         }
1675         break;
1676     case GraphicsContext3D::UNSIGNED_INT:
1677     case GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV:
1678     case GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV:
1679         if (pixels->getType() != JSC::TypeUint32) {
1680             synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_INT but ArrayBufferView not Uint32Array");
1681             return false;
1682         }
1683         break;
1684     case GraphicsContext3D::HALF_FLOAT:
1685     case GraphicsContext3D::FLOAT:
1686         if (pixels->getType() != JSC::TypeFloat32) {
1687             synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array");
1688             return false;
1689         }
1690         break;
1691     case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float
1692         // As per the specification, ArrayBufferView should be null when
1693         // OES_texture_half_float is enabled.
1694         if (pixels) {
1695             synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type HALF_FLOAT_OES but ArrayBufferView is not NULL");
1696             return false;
1697         }
1698         break;
1699     default:
1700         ASSERT_NOT_REACHED();
1701     }
1702     
1703     unsigned totalBytesRequired;
1704     GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
1705     if (error != GraphicsContext3D::NO_ERROR) {
1706         synthesizeGLError(error, functionName, "invalid texture dimensions");
1707         return false;
1708     }
1709     if (pixels->byteLength() < totalBytesRequired) {
1710         if (m_unpackAlignment != 1) {
1711             m_context->computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0);
1712             if (pixels->byteLength() == totalBytesRequired) {
1713                 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1");
1714                 return false;
1715             }
1716         }
1717         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request");
1718         return false;
1719     }
1720     return true;
1721 }
1722
1723 GC3Denum WebGL2RenderingContext::baseInternalFormatFromInternalFormat(GC3Denum internalformat)
1724 {
1725     // Handles sized, unsized, and compressed internal formats.
1726     switch (internalformat) {
1727     case GraphicsContext3D::R8:
1728     case GraphicsContext3D::R8_SNORM:
1729     case GraphicsContext3D::R16F:
1730     case GraphicsContext3D::R32F:
1731     case GraphicsContext3D::R8I:
1732     case GraphicsContext3D::R8UI:
1733     case GraphicsContext3D::R16I:
1734     case GraphicsContext3D::R16UI:
1735     case GraphicsContext3D::R32I:
1736     case GraphicsContext3D::R32UI:
1737     case GraphicsContext3D::COMPRESSED_R11_EAC:
1738     case GraphicsContext3D::COMPRESSED_SIGNED_R11_EAC:
1739         return GraphicsContext3D::RED;
1740     case GraphicsContext3D::RG8:
1741     case GraphicsContext3D::RG8_SNORM:
1742     case GraphicsContext3D::RG16F:
1743     case GraphicsContext3D::RG32F:
1744     case GraphicsContext3D::RG8I:
1745     case GraphicsContext3D::RG8UI:
1746     case GraphicsContext3D::RG16I:
1747     case GraphicsContext3D::RG16UI:
1748     case GraphicsContext3D::RG32I:
1749     case GraphicsContext3D::RG32UI:
1750     case GraphicsContext3D::COMPRESSED_RG11_EAC:
1751     case GraphicsContext3D::COMPRESSED_SIGNED_RG11_EAC:
1752         return GraphicsContext3D::RG;
1753     case GraphicsContext3D::RGB8:
1754     case GraphicsContext3D::RGB8_SNORM:
1755     case GraphicsContext3D::RGB565:
1756     case GraphicsContext3D::SRGB8:
1757     case GraphicsContext3D::RGB16F:
1758     case GraphicsContext3D::RGB32F:
1759     case GraphicsContext3D::RGB8I:
1760     case GraphicsContext3D::RGB8UI:
1761     case GraphicsContext3D::RGB16I:
1762     case GraphicsContext3D::RGB16UI:
1763     case GraphicsContext3D::RGB32I:
1764     case GraphicsContext3D::RGB32UI:
1765     case GraphicsContext3D::RGB:
1766     case GraphicsContext3D::COMPRESSED_RGB8_ETC2:
1767     case GraphicsContext3D::COMPRESSED_SRGB8_ETC2:
1768         return GraphicsContext3D::RGB;
1769     case GraphicsContext3D::RGBA4:
1770     case GraphicsContext3D::RGB5_A1:
1771     case GraphicsContext3D::RGBA8:
1772     case GraphicsContext3D::RGBA8_SNORM:
1773     case GraphicsContext3D::RGB10_A2:
1774     case GraphicsContext3D::RGB10_A2UI:
1775     case GraphicsContext3D::SRGB8_ALPHA8:
1776     case GraphicsContext3D::RGBA16F:
1777     case GraphicsContext3D::RGBA32F:
1778     case GraphicsContext3D::RGBA8I:
1779     case GraphicsContext3D::RGBA8UI:
1780     case GraphicsContext3D::RGBA16I:
1781     case GraphicsContext3D::RGBA16UI:
1782     case GraphicsContext3D::RGBA32I:
1783     case GraphicsContext3D::RGBA32UI:
1784     case GraphicsContext3D::RGBA:
1785     case GraphicsContext3D::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1786     case GraphicsContext3D::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1787     case GraphicsContext3D::COMPRESSED_RGBA8_ETC2_EAC:
1788     case GraphicsContext3D::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
1789         return GraphicsContext3D::RGBA;
1790     case GraphicsContext3D::DEPTH_COMPONENT16:
1791     case GraphicsContext3D::DEPTH_COMPONENT24:
1792     case GraphicsContext3D::DEPTH_COMPONENT32F:
1793         return GraphicsContext3D::DEPTH_COMPONENT;
1794     case GraphicsContext3D::DEPTH24_STENCIL8:
1795     case GraphicsContext3D::DEPTH32F_STENCIL8:
1796         return GraphicsContext3D::DEPTH_STENCIL;
1797     case GraphicsContext3D::LUMINANCE:
1798     case GraphicsContext3D::LUMINANCE_ALPHA:
1799     case GraphicsContext3D::ALPHA:
1800         return internalformat;
1801     default:
1802         ASSERT_NOT_REACHED();
1803         return GraphicsContext3D::NONE;
1804     }
1805 }
1806
1807 bool WebGL2RenderingContext::isIntegerFormat(GC3Denum internalformat)
1808 {
1809     switch (baseInternalFormatFromInternalFormat(internalformat)) {
1810     case GraphicsContext3D::RED_INTEGER:
1811     case GraphicsContext3D::RG_INTEGER:
1812     case GraphicsContext3D::RGB_INTEGER:
1813     case GraphicsContext3D::RGBA_INTEGER:
1814         return true;
1815     }
1816     return false;
1817 }
1818
1819 WebGLGetInfo WebGL2RenderingContext::getParameter(GC3Denum pname)
1820 {
1821     if (isContextLostOrPending())
1822         return WebGLGetInfo();
1823     const int intZero = 0;
1824     switch (pname) {
1825     case GraphicsContext3D::ACTIVE_TEXTURE:
1826         return getUnsignedIntParameter(pname);
1827     case GraphicsContext3D::ALIASED_LINE_WIDTH_RANGE:
1828         return getWebGLFloatArrayParameter(pname);
1829     case GraphicsContext3D::ALIASED_POINT_SIZE_RANGE:
1830         return getWebGLFloatArrayParameter(pname);
1831     case GraphicsContext3D::ALPHA_BITS:
1832         return getIntParameter(pname);
1833     case GraphicsContext3D::ARRAY_BUFFER_BINDING:
1834         return WebGLGetInfo(m_boundArrayBuffer.get());
1835     case GraphicsContext3D::BLEND:
1836         return getBooleanParameter(pname);
1837     case GraphicsContext3D::BLEND_COLOR:
1838         return getWebGLFloatArrayParameter(pname);
1839     case GraphicsContext3D::BLEND_DST_ALPHA:
1840         return getUnsignedIntParameter(pname);
1841     case GraphicsContext3D::BLEND_DST_RGB:
1842         return getUnsignedIntParameter(pname);
1843     case GraphicsContext3D::BLEND_EQUATION_ALPHA:
1844         return getUnsignedIntParameter(pname);
1845     case GraphicsContext3D::BLEND_EQUATION_RGB:
1846         return getUnsignedIntParameter(pname);
1847     case GraphicsContext3D::BLEND_SRC_ALPHA:
1848         return getUnsignedIntParameter(pname);
1849     case GraphicsContext3D::BLEND_SRC_RGB:
1850         return getUnsignedIntParameter(pname);
1851     case GraphicsContext3D::BLUE_BITS:
1852         return getIntParameter(pname);
1853     case GraphicsContext3D::COLOR_CLEAR_VALUE:
1854         return getWebGLFloatArrayParameter(pname);
1855     case GraphicsContext3D::COLOR_WRITEMASK:
1856         return getBooleanArrayParameter(pname);
1857     case GraphicsContext3D::COMPRESSED_TEXTURE_FORMATS:
1858         return WebGLGetInfo(PassRefPtr<Uint32Array>(Uint32Array::create(m_compressedTextureFormats.data(), m_compressedTextureFormats.size())));
1859     case GraphicsContext3D::CULL_FACE:
1860         return getBooleanParameter(pname);
1861     case GraphicsContext3D::CULL_FACE_MODE:
1862         return getUnsignedIntParameter(pname);
1863     case GraphicsContext3D::CURRENT_PROGRAM:
1864         return WebGLGetInfo(m_currentProgram.get());
1865     case GraphicsContext3D::DEPTH_BITS:
1866         if (!m_framebufferBinding && !m_attributes.depth)
1867             return WebGLGetInfo(intZero);
1868         return getIntParameter(pname);
1869     case GraphicsContext3D::DEPTH_CLEAR_VALUE:
1870         return getFloatParameter(pname);
1871     case GraphicsContext3D::DEPTH_FUNC:
1872         return getUnsignedIntParameter(pname);
1873     case GraphicsContext3D::DEPTH_RANGE:
1874         return getWebGLFloatArrayParameter(pname);
1875     case GraphicsContext3D::DEPTH_TEST:
1876         return getBooleanParameter(pname);
1877     case GraphicsContext3D::DEPTH_WRITEMASK:
1878         return getBooleanParameter(pname);
1879     case GraphicsContext3D::DITHER:
1880         return getBooleanParameter(pname);
1881     case GraphicsContext3D::ELEMENT_ARRAY_BUFFER_BINDING:
1882         return WebGLGetInfo(m_boundVertexArrayObject->getElementArrayBuffer());
1883     case GraphicsContext3D::FRAMEBUFFER_BINDING:
1884         return WebGLGetInfo(m_framebufferBinding.get());
1885     case GraphicsContext3D::FRONT_FACE:
1886         return getUnsignedIntParameter(pname);
1887     case GraphicsContext3D::GENERATE_MIPMAP_HINT:
1888         return getUnsignedIntParameter(pname);
1889     case GraphicsContext3D::GREEN_BITS:
1890         return getIntParameter(pname);
1891     case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_FORMAT:
1892         return getIntParameter(pname);
1893     case GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE:
1894         return getIntParameter(pname);
1895     case GraphicsContext3D::LINE_WIDTH:
1896         return getFloatParameter(pname);
1897     case GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1898         return getIntParameter(pname);
1899     case GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE:
1900         return getIntParameter(pname);
1901     case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS:
1902         return getIntParameter(pname);
1903     case GraphicsContext3D::MAX_RENDERBUFFER_SIZE:
1904         return getIntParameter(pname);
1905     case GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS:
1906         return getIntParameter(pname);
1907     case GraphicsContext3D::MAX_TEXTURE_SIZE:
1908         return getIntParameter(pname);
1909     case GraphicsContext3D::MAX_VARYING_VECTORS:
1910         return getIntParameter(pname);
1911     case GraphicsContext3D::MAX_VERTEX_ATTRIBS:
1912         return getIntParameter(pname);
1913     case GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1914         return getIntParameter(pname);
1915     case GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS:
1916         return getIntParameter(pname);
1917     case GraphicsContext3D::MAX_VIEWPORT_DIMS:
1918         return getWebGLIntArrayParameter(pname);
1919     case GraphicsContext3D::NUM_SHADER_BINARY_FORMATS:
1920         return getIntParameter(pname);
1921     case GraphicsContext3D::PACK_ALIGNMENT:
1922         return getIntParameter(pname);
1923     case GraphicsContext3D::POLYGON_OFFSET_FACTOR:
1924         return getFloatParameter(pname);
1925     case GraphicsContext3D::POLYGON_OFFSET_FILL:
1926         return getBooleanParameter(pname);
1927     case GraphicsContext3D::POLYGON_OFFSET_UNITS:
1928         return getFloatParameter(pname);
1929     case GraphicsContext3D::RED_BITS:
1930         return getIntParameter(pname);
1931     case GraphicsContext3D::RENDERBUFFER_BINDING:
1932         return WebGLGetInfo(m_renderbufferBinding.get());
1933     case GraphicsContext3D::RENDERER:
1934         return WebGLGetInfo(String("WebKit WebGL"));
1935     case GraphicsContext3D::SAMPLE_BUFFERS:
1936         return getIntParameter(pname);
1937     case GraphicsContext3D::SAMPLE_COVERAGE_INVERT:
1938         return getBooleanParameter(pname);
1939     case GraphicsContext3D::SAMPLE_COVERAGE_VALUE:
1940         return getFloatParameter(pname);
1941     case GraphicsContext3D::SAMPLES:
1942         return getIntParameter(pname);
1943     case GraphicsContext3D::SCISSOR_BOX:
1944         return getWebGLIntArrayParameter(pname);
1945     case GraphicsContext3D::SCISSOR_TEST:
1946         return getBooleanParameter(pname);
1947     case GraphicsContext3D::SHADING_LANGUAGE_VERSION:
1948         return WebGLGetInfo("WebGL GLSL ES 1.0 (" + m_context->getString(GraphicsContext3D::SHADING_LANGUAGE_VERSION) + ")");
1949     case GraphicsContext3D::STENCIL_BACK_FAIL:
1950         return getUnsignedIntParameter(pname);
1951     case GraphicsContext3D::STENCIL_BACK_FUNC:
1952         return getUnsignedIntParameter(pname);
1953     case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_FAIL:
1954         return getUnsignedIntParameter(pname);
1955     case GraphicsContext3D::STENCIL_BACK_PASS_DEPTH_PASS:
1956         return getUnsignedIntParameter(pname);
1957     case GraphicsContext3D::STENCIL_BACK_REF:
1958         return getIntParameter(pname);
1959     case GraphicsContext3D::STENCIL_BACK_VALUE_MASK:
1960         return getUnsignedIntParameter(pname);
1961     case GraphicsContext3D::STENCIL_BACK_WRITEMASK:
1962         return getUnsignedIntParameter(pname);
1963     case GraphicsContext3D::STENCIL_BITS:
1964         if (!m_framebufferBinding && !m_attributes.stencil)
1965             return WebGLGetInfo(intZero);
1966         return getIntParameter(pname);
1967     case GraphicsContext3D::STENCIL_CLEAR_VALUE:
1968         return getIntParameter(pname);
1969     case GraphicsContext3D::STENCIL_FAIL:
1970         return getUnsignedIntParameter(pname);
1971     case GraphicsContext3D::STENCIL_FUNC:
1972         return getUnsignedIntParameter(pname);
1973     case GraphicsContext3D::STENCIL_PASS_DEPTH_FAIL:
1974         return getUnsignedIntParameter(pname);
1975     case GraphicsContext3D::STENCIL_PASS_DEPTH_PASS:
1976         return getUnsignedIntParameter(pname);
1977     case GraphicsContext3D::STENCIL_REF:
1978         return getIntParameter(pname);
1979     case GraphicsContext3D::STENCIL_TEST:
1980         return getBooleanParameter(pname);
1981     case GraphicsContext3D::STENCIL_VALUE_MASK:
1982         return getUnsignedIntParameter(pname);
1983     case GraphicsContext3D::STENCIL_WRITEMASK:
1984         return getUnsignedIntParameter(pname);
1985     case GraphicsContext3D::SUBPIXEL_BITS:
1986         return getIntParameter(pname);
1987     case GraphicsContext3D::TEXTURE_BINDING_2D:
1988         return WebGLGetInfo(m_textureUnits[m_activeTextureUnit].texture2DBinding.get());
1989     case GraphicsContext3D::TEXTURE_BINDING_CUBE_MAP:
1990         return WebGLGetInfo(m_textureUnits[m_activeTextureUnit].textureCubeMapBinding.get());
1991     case GraphicsContext3D::UNPACK_ALIGNMENT:
1992         return getIntParameter(pname);
1993     case GraphicsContext3D::UNPACK_FLIP_Y_WEBGL:
1994         return WebGLGetInfo(m_unpackFlipY);
1995     case GraphicsContext3D::UNPACK_PREMULTIPLY_ALPHA_WEBGL:
1996         return WebGLGetInfo(m_unpackPremultiplyAlpha);
1997     case GraphicsContext3D::UNPACK_COLORSPACE_CONVERSION_WEBGL:
1998         return WebGLGetInfo(m_unpackColorspaceConversion);
1999     case GraphicsContext3D::VENDOR:
2000         return WebGLGetInfo(String("WebKit"));
2001     case GraphicsContext3D::VERSION:
2002         return WebGLGetInfo("WebGL 2.0 (" + m_context->getString(GraphicsContext3D::VERSION) + ")");
2003     case GraphicsContext3D::VIEWPORT:
2004         return getWebGLIntArrayParameter(pname);
2005     case WebGLDebugRendererInfo::UNMASKED_RENDERER_WEBGL:
2006         if (m_webglDebugRendererInfo)
2007             return WebGLGetInfo(m_context->getString(GraphicsContext3D::RENDERER));
2008         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
2009         return WebGLGetInfo();
2010     case WebGLDebugRendererInfo::UNMASKED_VENDOR_WEBGL:
2011         if (m_webglDebugRendererInfo)
2012             return WebGLGetInfo(m_context->getString(GraphicsContext3D::VENDOR));
2013         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
2014         return WebGLGetInfo();
2015     case Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
2016         if (m_extTextureFilterAnisotropic)
2017             return getUnsignedIntParameter(Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT);
2018         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
2019         return WebGLGetInfo();
2020     case GraphicsContext3D::FRAGMENT_SHADER_DERIVATIVE_HINT:
2021         return getIntParameter(pname);
2022     case GraphicsContext3D::MAX_3D_TEXTURE_SIZE:
2023         return getIntParameter(pname);
2024     case GraphicsContext3D::MAX_ARRAY_TEXTURE_LAYERS:
2025         return getIntParameter(pname);
2026     case GraphicsContext3D::MAX_COLOR_ATTACHMENTS:
2027         return getIntParameter(pname);
2028     case GraphicsContext3D::MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2029         return getInt64Parameter(pname);
2030     case GraphicsContext3D::MAX_COMBINED_UNIFORM_BLOCKS:
2031         return getIntParameter(pname);
2032     case GraphicsContext3D::MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
2033         return getInt64Parameter(pname);
2034     case GraphicsContext3D::MAX_DRAW_BUFFERS:
2035         return getIntParameter(pname);
2036     case GraphicsContext3D::MAX_ELEMENT_INDEX:
2037         return getInt64Parameter(pname);
2038     case GraphicsContext3D::MAX_ELEMENTS_INDICES:
2039         return getIntParameter(pname);
2040     case GraphicsContext3D::MAX_ELEMENTS_VERTICES:
2041         return getIntParameter(pname);
2042     case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_COMPONENTS:
2043         return getIntParameter(pname);
2044     case GraphicsContext3D::MAX_FRAGMENT_UNIFORM_BLOCKS:
2045         return getIntParameter(pname);
2046     case GraphicsContext3D::MAX_PROGRAM_TEXEL_OFFSET:
2047         return getIntParameter(pname);
2048     case GraphicsContext3D::MAX_SAMPLES:
2049         return getIntParameter(pname);
2050     case GraphicsContext3D::MAX_SERVER_WAIT_TIMEOUT:
2051         return getInt64Parameter(pname);
2052     case GraphicsContext3D::MAX_TEXTURE_LOD_BIAS:
2053         return getIntParameter(pname);
2054     case GraphicsContext3D::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
2055         return getIntParameter(pname);
2056     case GraphicsContext3D::MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
2057         return getIntParameter(pname);
2058     case GraphicsContext3D::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
2059         return getIntParameter(pname);
2060     case GraphicsContext3D::MAX_UNIFORM_BLOCK_SIZE:
2061         return getInt64Parameter(pname);
2062     case GraphicsContext3D::MAX_UNIFORM_BUFFER_BINDINGS:
2063         return getIntParameter(pname);
2064     case GraphicsContext3D::MAX_VARYING_COMPONENTS:
2065         return getIntParameter(pname);
2066     case GraphicsContext3D::MAX_VERTEX_OUTPUT_COMPONENTS:
2067         return getIntParameter(pname);
2068     case GraphicsContext3D::MAX_VERTEX_UNIFORM_BLOCKS:
2069         return getIntParameter(pname);
2070     case GraphicsContext3D::MAX_VERTEX_UNIFORM_COMPONENTS: 
2071         return getIntParameter(pname);                            
2072     case GraphicsContext3D::MIN_PROGRAM_TEXEL_OFFSET:
2073         return getIntParameter(pname);
2074     case GraphicsContext3D::PACK_ROW_LENGTH:
2075         return getIntParameter(pname);
2076     case GraphicsContext3D::PACK_SKIP_PIXELS:
2077         return getIntParameter(pname);
2078     case GraphicsContext3D::PACK_SKIP_ROWS:
2079         return getIntParameter(pname);
2080     case GraphicsContext3D::UNPACK_IMAGE_HEIGHT:
2081         return getIntParameter(pname);
2082     case GraphicsContext3D::UNPACK_ROW_LENGTH:
2083         return getIntParameter(pname);
2084     case GraphicsContext3D::UNPACK_SKIP_IMAGES:
2085         return getIntParameter(pname);
2086     case GraphicsContext3D::UNPACK_SKIP_PIXELS:
2087         return getIntParameter(pname);
2088     case GraphicsContext3D::UNPACK_SKIP_ROWS:
2089         return getIntParameter(pname);
2090     case GraphicsContext3D::RASTERIZER_DISCARD:
2091         return getBooleanParameter(pname);
2092     case GraphicsContext3D::SAMPLE_ALPHA_TO_COVERAGE:
2093         return getBooleanParameter(pname);
2094     case GraphicsContext3D::SAMPLE_COVERAGE:
2095         return getBooleanParameter(pname);
2096     case GraphicsContext3D::TRANSFORM_FEEDBACK_ACTIVE:
2097         return getBooleanParameter(pname);
2098     case GraphicsContext3D::TRANSFORM_FEEDBACK_PAUSED:
2099         return getBooleanParameter(pname);
2100     case GraphicsContext3D::UNIFORM_BUFFER_OFFSET_ALIGNMENT:
2101         return getIntParameter(pname);
2102     case GraphicsContext3D::VERTEX_ARRAY_BINDING: {
2103         if (!m_boundVertexArrayObject->isDefaultObject())
2104             return WebGLGetInfo(static_cast<WebGLVertexArrayObject*>(m_boundVertexArrayObject.get()));
2105         return WebGLGetInfo();
2106         }
2107         break;
2108     case GraphicsContext3D::DRAW_BUFFER0:
2109     case GraphicsContext3D::DRAW_BUFFER1:
2110     case GraphicsContext3D::DRAW_BUFFER2:
2111     case GraphicsContext3D::DRAW_BUFFER3:
2112     case GraphicsContext3D::DRAW_BUFFER4:
2113     case GraphicsContext3D::DRAW_BUFFER5:
2114     case GraphicsContext3D::DRAW_BUFFER6:
2115     case GraphicsContext3D::DRAW_BUFFER7:
2116     case GraphicsContext3D::DRAW_BUFFER8:
2117     case GraphicsContext3D::DRAW_BUFFER9:
2118     case GraphicsContext3D::DRAW_BUFFER10:
2119     case GraphicsContext3D::DRAW_BUFFER11:
2120     case GraphicsContext3D::DRAW_BUFFER12:
2121     case GraphicsContext3D::DRAW_BUFFER13:
2122     case GraphicsContext3D::DRAW_BUFFER14:
2123     case GraphicsContext3D::DRAW_BUFFER15: {
2124         GC3Dint value = GraphicsContext3D::NONE;
2125         if (m_framebufferBinding)
2126             value = m_framebufferBinding->getDrawBuffer(pname);
2127         else // emulated backbuffer
2128             value = m_backDrawBuffer;
2129         return WebGLGetInfo(value);
2130         }
2131     case GraphicsContext3D::COPY_READ_BUFFER:
2132     case GraphicsContext3D::COPY_WRITE_BUFFER:
2133     case GraphicsContext3D::PIXEL_PACK_BUFFER_BINDING:   
2134     case GraphicsContext3D::PIXEL_UNPACK_BUFFER_BINDING:
2135     case GraphicsContext3D::READ_BUFFER:
2136     case GraphicsContext3D::SAMPLER_BINDING:
2137     case GraphicsContext3D::TEXTURE_BINDING_2D_ARRAY:
2138     case GraphicsContext3D::TEXTURE_BINDING_3D:
2139     case GraphicsContext3D::READ_FRAMEBUFFER_BINDING:
2140     case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER_BINDING:
2141     case GraphicsContext3D::UNIFORM_BUFFER_BINDING:
2142         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "parameter name not yet supported");
2143         return WebGLGetInfo();
2144     default:
2145         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name");
2146         return WebGLGetInfo();
2147     }
2148 }
2149
2150 bool WebGL2RenderingContext::validateIndexArrayConservative(GC3Denum type, unsigned& numElementsRequired)
2151 {
2152     // Performs conservative validation by caching a maximum index of
2153     // the given type per element array buffer. If all of the bound
2154     // array buffers have enough elements to satisfy that maximum
2155     // index, skips the expensive per-draw-call iteration in
2156     // validateIndexArrayPrecise.
2157     
2158     RefPtr<WebGLBuffer> elementArrayBuffer = m_boundVertexArrayObject->getElementArrayBuffer();
2159     
2160     if (!elementArrayBuffer)
2161         return false;
2162     
2163     GC3Dsizeiptr numElements = elementArrayBuffer->byteLength();
2164     // The case count==0 is already dealt with in drawElements before validateIndexArrayConservative.
2165     if (!numElements)
2166         return false;
2167     const ArrayBuffer* buffer = elementArrayBuffer->elementArrayBuffer();
2168     ASSERT(buffer);
2169     
2170     int maxIndex = elementArrayBuffer->getCachedMaxIndex(type);
2171     if (maxIndex < 0) {
2172         // Compute the maximum index in the entire buffer for the given type of index.
2173         switch (type) {
2174         case GraphicsContext3D::UNSIGNED_BYTE: {
2175             const GC3Dubyte* p = static_cast<const GC3Dubyte*>(buffer->data());
2176             for (GC3Dsizeiptr i = 0; i < numElements; i++)
2177                 maxIndex = std::max(maxIndex, static_cast<int>(p[i]));
2178             break;
2179         }
2180         case GraphicsContext3D::UNSIGNED_SHORT: {
2181             numElements /= sizeof(GC3Dushort);
2182             const GC3Dushort* p = static_cast<const GC3Dushort*>(buffer->data());
2183             for (GC3Dsizeiptr i = 0; i < numElements; i++)
2184                 maxIndex = std::max(maxIndex, static_cast<int>(p[i]));
2185             break;
2186         }
2187         case GraphicsContext3D::UNSIGNED_INT: {
2188             numElements /= sizeof(GC3Duint);
2189             const GC3Duint* p = static_cast<const GC3Duint*>(buffer->data());
2190             for (GC3Dsizeiptr i = 0; i < numElements; i++)
2191                 maxIndex = std::max(maxIndex, static_cast<int>(p[i]));
2192             break;
2193         }
2194         default:
2195             return false;
2196         }
2197         elementArrayBuffer->setCachedMaxIndex(type, maxIndex);
2198     }
2199     
2200     if (maxIndex >= 0) {
2201         // The number of required elements is one more than the maximum
2202         // index that will be accessed.
2203         numElementsRequired = maxIndex + 1;
2204         return true;
2205     }
2206     
2207     return false;
2208 }
2209
2210 bool WebGL2RenderingContext::validateBlendEquation(const char* functionName, GC3Denum mode)
2211 {
2212     switch (mode) {
2213     case GraphicsContext3D::FUNC_ADD:
2214     case GraphicsContext3D::FUNC_SUBTRACT:
2215     case GraphicsContext3D::FUNC_REVERSE_SUBTRACT:
2216     case GraphicsContext3D::MIN:
2217     case GraphicsContext3D::MAX:
2218         return true;
2219         break;
2220     default:
2221         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid mode");
2222         return false;
2223     }
2224 }
2225
2226 bool WebGL2RenderingContext::validateCapability(const char* functionName, GC3Denum cap)
2227 {
2228     switch (cap) {
2229     case GraphicsContext3D::BLEND:
2230     case GraphicsContext3D::CULL_FACE:
2231     case GraphicsContext3D::DEPTH_TEST:
2232     case GraphicsContext3D::DITHER:
2233     case GraphicsContext3D::POLYGON_OFFSET_FILL:
2234     case GraphicsContext3D::SAMPLE_ALPHA_TO_COVERAGE:
2235     case GraphicsContext3D::SAMPLE_COVERAGE:
2236     case GraphicsContext3D::SCISSOR_TEST:
2237     case GraphicsContext3D::STENCIL_TEST:
2238     case GraphicsContext3D::RASTERIZER_DISCARD:
2239         return true;
2240     default:
2241         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid capability");
2242         return false;
2243     }
2244 }
2245
2246 } // namespace WebCore
2247
2248 #endif // ENABLE(WEBGL)