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