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