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