<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[208724] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/208724">208724</a></dd>
<dt>Author</dt> <dd>mmaxfield@apple.com</dd>
<dt>Date</dt> <dd>2016-11-14 18:42:32 -0800 (Mon, 14 Nov 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[WebGL2] Teach WebGLRenderingContextBase about new texture internal formats
https://bugs.webkit.org/show_bug.cgi?id=164525

Reviewed by Dean Jackson.

Source/WebCore:

Test: fast/canvas/webgl/webgl2-texture-upload-enums.html

This patch migrates the existing WebGL calls texImage2D(), texSubImage2D(),
and readPixels() to understand the new WebGL 2 texture types. In WebGL1, the
format and the internalFormat were required to be the same, and we had this
assumption baked into many places in these functions. In WebGL 2, those two
values are often different, which means I had to fix all of these assumptions
in our code. Also, rather than have two completely separate parallel
implementations of these functions, a more forward-looking approach is to
have one implementation which has a few checks to isWebGL1() in strategic
places. (This way, bugs only have to be fixed in a single place). Therefore,
this patch deletes the WebGL 2 versions of these functions.

* html/canvas/WebGL2RenderingContext.cpp: These functions are moved to
WebGLRenderingContextBase.
(WebCore::WebGL2RenderingContext::isIntegerFormat):
(WebCore::WebGL2RenderingContext::copyTexImage2D): Deleted.
(WebCore::WebGL2RenderingContext::texSubImage2DBase): Deleted.
(WebCore::WebGL2RenderingContext::texSubImage2DImpl): Deleted.
(WebCore::WebGL2RenderingContext::texSubImage2D): Deleted.
(WebCore::WebGL2RenderingContext::validateTexFuncParameters): Deleted.
(WebCore::WebGL2RenderingContext::validateTexFuncFormatAndType): Deleted.
(WebCore::WebGL2RenderingContext::validateTexFuncData): Deleted.
* html/canvas/WebGL2RenderingContext.h: Moved function implementations to
WebGLRenderingContextBase.
* html/canvas/WebGLRenderingContext.cpp: Ditto.
(WebCore::WebGLRenderingContext::copyTexImage2D): Deleted.
(WebCore::WebGLRenderingContext::texSubImage2DBase): Deleted.
(WebCore::WebGLRenderingContext::texSubImage2DImpl): Deleted.
(WebCore::WebGLRenderingContext::texSubImage2D): Deleted.
(WebCore::WebGLRenderingContext::validateTexFuncParameters): Deleted.
(WebCore::WebGLRenderingContext::validateTexFuncFormatAndType): Deleted.
(WebCore::WebGLRenderingContext::validateTexFuncData): Deleted.
* html/canvas/WebGLRenderingContext.h: Moved function implementations to
WebGLRenderingContextBase.
* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::validateSettableTexInternalFormat):
Teach about new depth texture formats.
(WebCore::WebGLRenderingContextBase::copyTexSubImage2D): Rename
&quot;internalformat&quot; to &quot;internalFormat&quot;. Teach about the distinction between
format and internalFormat. When pre-filling textures with 0s to work around
buggy drivers, we need a new way of knowing which format/type arguments to
pass to texSubImage2D() which are compatible with the texture's internal
format. The implementation of this function was added to GraphicsContext3D
and is called here.
(WebCore::WebGLRenderingContextBase::generateMipmap): Teach about the
distinction between format and internalFormat.
(WebCore::internalFormatTheme): This is used so readPixels() knows what
kind of format/type arguments are compatible with the texture's internal
format.
(WebCore::numberOfComponentsForFormat): Ditto.
(WebCore::numberOfComponentsForInternalFormat): Ditto.
(WebCore::WebGLRenderingContextBase::readPixels): Many more format/type
combinations are required in order to test the various new kinds of
textures.
(WebCore::WebGLRenderingContextBase::texImage2DBase): Rename internalformat
to internalFormat, and teach about the distinction between format and
internalFormat.
(WebCore::WebGLRenderingContextBase::validateTexFunc): Ditto.
(WebCore::WebGLRenderingContextBase::texImage2D): Ditto.
(WebCore::WebGLRenderingContextBase::texSubImage2DImpl): Moved from
WebGLRenderingContext.
(WebCore::WebGLRenderingContextBase::texSubImage2D): Ditto.
(WebCore::WebGLRenderingContextBase::validateArrayBufferType): Ditto.
(WebCore::WebGLRenderingContextBase::validateTexFuncData): Ditto.
(WebCore::WebGLRenderingContextBase::validateTexFuncParameters): Ditto.
(WebCore::WebGLRenderingContextBase::validateTexFuncFormatAndType): Ditto.
This is the main function where the new internalFormats are dealt with.
The OpenGL ES spec lists a table of all the internalFormats and all their
compatible format/type values. This table is entered into this function to
check that the combinations are correct.
(WebCore::WebGLRenderingContextBase::texSubImage2DBase): Moved from
WebGLRenderingContext.
(WebCore::WebGLRenderingContextBase::copyTexImage2D): Ditto.
(WebCore::WebGLRenderingContextBase::validateSettableTexFormat): Deleted.
* html/canvas/WebGLRenderingContextBase.h: No longer overrides virtual
functions.
* platform/graphics/GraphicsContext3D.cpp:
(WebCore::GraphicsContext3D::computeFormatAndTypeParameters): Because
this is inside GraphicsContext3D, it doesn't need any isWebGL1() checks.
Teach about new enums.
(WebCore::GraphicsContext3D::possibleFormatAndTypeForInternalFormat):
Ditto.
(WebCore::GraphicsContext3D::packImageData):
(WebCore::GraphicsContext3D::packPixels): It is possible to try to
copy data from a video into one of these new formats. Currently, we
implement this by swizzling on the CPU. Rather than implementing all the
swizzling functions in this patch (which would make this patch much
larger), simply bail in this case. We will implement this later.
(WebCore::GraphicsContext3D::getClearBitsByFormat): Update.
* platform/graphics/GraphicsContext3D.h:
(WebCore::GraphicsContext3D::hasAlpha): Ditto.
(WebCore::GraphicsContext3D::hasColor): Ditto.

LayoutTests:

Test texture types without drawing. Instead, attach a texture to a framebuffer and
use readPixels() to make sure the texture retains its data.

* fast/canvas/webgl/webgl2-texture-upload-enums-expected.txt: Added.
* fast/canvas/webgl/webgl2-texture-upload-enums.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGL2RenderingContextcpp">trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGL2RenderingContexth">trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGLRenderingContextcpp">trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGLRenderingContexth">trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGLRenderingContextBasecpp">trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGLRenderingContextBaseh">trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsContext3Dcpp">trunk/Source/WebCore/platform/graphics/GraphicsContext3D.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsContext3Dh">trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastcanvaswebglwebgl2textureuploadenumsexpectedtxt">trunk/LayoutTests/fast/canvas/webgl/webgl2-texture-upload-enums-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcanvaswebglwebgl2textureuploadenumshtml">trunk/LayoutTests/fast/canvas/webgl/webgl2-texture-upload-enums.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (208723 => 208724)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-11-15 02:20:54 UTC (rev 208723)
+++ trunk/LayoutTests/ChangeLog        2016-11-15 02:42:32 UTC (rev 208724)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2016-11-14  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        [WebGL2] Teach WebGLRenderingContextBase about new texture internal formats
+        https://bugs.webkit.org/show_bug.cgi?id=164525
+
+        Reviewed by Dean Jackson.
+
+        Test texture types without drawing. Instead, attach a texture to a framebuffer and
+        use readPixels() to make sure the texture retains its data.
+
+        * fast/canvas/webgl/webgl2-texture-upload-enums-expected.txt: Added.
+        * fast/canvas/webgl/webgl2-texture-upload-enums.html: Added.
+
</ins><span class="cx"> 2016-11-14  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         document.createElementNS doesn't construct a custom element
</span></span></pre></div>
<a id="trunkLayoutTestsfastcanvaswebglwebgl2textureuploadenumsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/canvas/webgl/webgl2-texture-upload-enums-expected.txt (0 => 208724)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/canvas/webgl/webgl2-texture-upload-enums-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/webgl2-texture-upload-enums-expected.txt        2016-11-15 02:42:32 UTC (rev 208724)
</span><span class="lines">@@ -0,0 +1,2072 @@
</span><ins>+Test that glTexImage2D and glTexSubImage2D accept new WebGL 2 enum values
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_COMPLETE
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS receiver[index] is expected
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS arrayBuffer[i] is receiver[i]
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins><span class="cx">Property changes on: trunk/LayoutTests/fast/canvas/webgl/webgl2-texture-upload-enums-expected.txt
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<ins>+native
</ins><span class="cx">\ No newline at end of property
</span><a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<ins>+Author Date Id Rev URL
</ins><span class="cx">\ No newline at end of property
</span><a id="trunkLayoutTestsfastcanvaswebglwebgl2textureuploadenumshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/canvas/webgl/webgl2-texture-upload-enums.html (0 => 208724)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/canvas/webgl/webgl2-texture-upload-enums.html                                (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/webgl2-texture-upload-enums.html        2016-11-15 02:42:32 UTC (rev 208724)
</span><span class="lines">@@ -0,0 +1,296 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;canvas id=&quot;canvas&quot; width=&quot;40&quot; height=&quot;40&quot;&gt;&lt;/canvas&gt;
+&lt;script&gt;
+description(&quot;Test that glTexImage2D and glTexSubImage2D accept new WebGL 2 enum values&quot;);
+
+if (window.internals)
+        internals.setWebGL2Enabled(true);
+
+var canvas = document.getElementById(&quot;canvas&quot;);
+var width = canvas.width;
+var height = canvas.height;
+var gl = canvas.getContext(&quot;webgl2&quot;);
+shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+
+var texture = gl.createTexture();
+shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+gl.bindTexture(gl.TEXTURE_2D, texture);
+shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+
+var arrayBuffer = new Uint8Array(width * height * 1);
+var count = 0;
+for (var i = 0; i &lt; height; ++i) {
+        for (var j = 0; j &lt; width; ++j) {
+                arrayBuffer[(width * i + j) * 1 + 0] = count++;
+        }
+}
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.R8, width, height, 0, gl.RED, gl.UNSIGNED_BYTE, arrayBuffer);
+shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+
+var framebuffer = gl.createFramebuffer();
+shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
+shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+shouldBe(&quot;gl.checkFramebufferStatus(gl.FRAMEBUFFER)&quot;, &quot;gl.FRAMEBUFFER_COMPLETE&quot;);
+
+
+var count;
+var offset = 0;
+var index;
+var expected;
+function test(uploadArrayFunction, downloadArrayFunction, components, internalFormat, format, uploadType, downloadType) {
+        var width = 4;
+        var height = 4;
+        arrayBuffer = new uploadArrayFunction(2 * width * height * components);
+        var count = 0;
+        for (var i = 0; i &lt; height; ++i) {
+                for (var j = 0; j &lt; width; ++j) {
+                        for (var k = 0; k &lt; components; ++k) {
+                                arrayBuffer[(width * i + j) * components + k] = offset + count++;
+                        }
+                }
+        }
+        gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, width, height, 0, format, uploadType, arrayBuffer);
+        shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+        gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, format, uploadType, arrayBuffer);
+        shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+        receiver = new downloadArrayFunction(2 * width * height * components);
+        gl.readPixels(0, 0, width, height, format, downloadType, receiver);
+        shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+        count = 0;
+        for (var i = 0; i &lt; height; ++i) {
+                for (var j = 0; j &lt; width; ++j) {
+                        for (var k = 0; k &lt; components; ++k) {
+                                expected = offset + count++;
+                                index = (width * i + j) * components + k;
+                                shouldBe(&quot;receiver[index]&quot;, &quot;expected&quot;);
+                        }
+                }
+        }
+
+        if (offset == 0)
+                offset = 50;
+        else
+                offset = 0;
+}
+
+// FIXME: Read from the textures in shaders
+
+test(Uint8Array, Uint8Array, 3, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, gl.UNSIGNED_BYTE);
+test(Uint8Array, Uint8Array, 4, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, gl.UNSIGNED_BYTE);
+//test(Uint8Array, Uint8Array, 2, gl.LUMINANCE_ALPHA, gl.LUMINANCE_ALPHA, gl.UNSIGNED_BYTE, gl.UNSIGNED_BYTE);
+//test(Uint8Array, Uint8Array, 1, gl.LUMINANCE, gl.LUMINANCE, gl.UNSIGNED_BYTE, gl.UNSIGNED_BYTE);
+//test(Uint8Array, Uint8Array, 1, gl.ALPHA, gl.ALPHA, gl.UNSIGNED_BYTE, gl.UNSIGNED_BYTE);
+
+test(Uint8Array, Uint8Array, 1, gl.R8, gl.RED, gl.UNSIGNED_BYTE, gl.UNSIGNED_BYTE);
+test(Int8Array, Int8Array, 1, gl.R8_SNORM, gl.RED, gl.BYTE, gl.BYTE);
+test(Float32Array, Float32Array, 1, gl.R16F, gl.RED, gl.FLOAT, gl.FLOAT);
+test(Float32Array, Float32Array, 1, gl.R32F, gl.RED, gl.FLOAT, gl.FLOAT);
+test(Uint8Array, Uint32Array, 1, gl.R8UI, gl.RED_INTEGER, gl.UNSIGNED_BYTE, gl.UNSIGNED_INT);
+test(Int8Array, Int32Array, 1, gl.R8I, gl.RED_INTEGER, gl.BYTE, gl.INT);
+test(Uint16Array, Uint32Array, 1, gl.R16UI, gl.RED_INTEGER, gl.UNSIGNED_SHORT, gl.UNSIGNED_INT);
+test(Int16Array, Int32Array, 1, gl.R16I, gl.RED_INTEGER, gl.SHORT, gl.INT);
+test(Uint32Array, Uint32Array, 1, gl.R32UI, gl.RED_INTEGER, gl.UNSIGNED_INT, gl.UNSIGNED_INT);
+test(Int32Array, Int32Array, 1, gl.R32I, gl.RED_INTEGER, gl.INT, gl.INT);
+
+test(Uint8Array, Uint8Array, 2, gl.RG8, gl.RG, gl.UNSIGNED_BYTE, gl.UNSIGNED_BYTE);
+test(Int8Array, Int8Array, 2, gl.RG8_SNORM, gl.RG, gl.BYTE, gl.BYTE);
+test(Float32Array, Float32Array, 2, gl.RG16F, gl.RG, gl.FLOAT, gl.FLOAT);
+test(Float32Array, Float32Array, 2, gl.RG32F, gl.RG, gl.FLOAT, gl.FLOAT);
+test(Uint8Array, Uint32Array, 2, gl.RG8UI, gl.RG_INTEGER, gl.UNSIGNED_BYTE, gl.UNSIGNED_INT);
+test(Int8Array, Int32Array, 2, gl.RG8I, gl.RG_INTEGER, gl.BYTE, gl.INT);
+test(Uint16Array, Uint32Array, 2, gl.RG16UI, gl.RG_INTEGER, gl.UNSIGNED_SHORT, gl.UNSIGNED_INT);
+test(Int16Array, Int32Array, 2, gl.RG16I, gl.RG_INTEGER, gl.SHORT, gl.INT);
+test(Uint32Array, Uint32Array, 2, gl.RG32UI, gl.RG_INTEGER, gl.UNSIGNED_INT, gl.UNSIGNED_INT);
+test(Int32Array, Int32Array, 2, gl.RG32I, gl.RG_INTEGER, gl.INT, gl.INT);
+
+test(Uint8Array, Uint8Array, 3, gl.RGB8, gl.RGB, gl.UNSIGNED_BYTE, gl.UNSIGNED_BYTE);
+test(Uint8Array, Uint8Array, 3, gl.SRGB8, gl.RGB, gl.UNSIGNED_BYTE, gl.UNSIGNED_BYTE);
+test(Int8Array, Int8Array, 3, gl.RGB8_SNORM, gl.RGB, gl.BYTE, gl.BYTE);
+test(Float32Array, Float32Array, 3, gl.RGB16F, gl.RGB, gl.FLOAT, gl.FLOAT);
+test(Float32Array, Float32Array, 3, gl.RGB32F, gl.RGB, gl.FLOAT, gl.FLOAT);
+test(Uint8Array, Uint32Array, 3, gl.RGB8UI, gl.RGB_INTEGER, gl.UNSIGNED_BYTE, gl.UNSIGNED_INT);
+test(Int8Array, Int32Array, 3, gl.RGB8I, gl.RGB_INTEGER, gl.BYTE, gl.INT);
+test(Uint16Array, Uint32Array, 3, gl.RGB16UI, gl.RGB_INTEGER, gl.UNSIGNED_SHORT, gl.UNSIGNED_INT);
+test(Int16Array, Int32Array, 3, gl.RGB16I, gl.RGB_INTEGER, gl.SHORT, gl.INT);
+test(Uint32Array, Uint32Array, 3, gl.RGB32UI, gl.RGB_INTEGER, gl.UNSIGNED_INT, gl.UNSIGNED_INT);
+test(Int32Array, Int32Array, 3, gl.RGB32I, gl.RGB_INTEGER, gl.INT, gl.INT);
+
+test(Uint8Array, Uint8Array, 4, gl.RGBA8, gl.RGBA, gl.UNSIGNED_BYTE, gl.UNSIGNED_BYTE);
+test(Uint8Array, Uint8Array, 3, gl.SRGB8_ALPHA8, gl.RGBA, gl.UNSIGNED_BYTE, gl.UNSIGNED_BYTE);
+test(Int8Array, Int8Array, 4, gl.RGBA8_SNORM, gl.RGBA, gl.BYTE, gl.BYTE);
+test(Float32Array, Float32Array, 4, gl.RGBA16F, gl.RGBA, gl.FLOAT, gl.FLOAT);
+test(Float32Array, Float32Array, 4, gl.RGBA32F, gl.RGBA, gl.FLOAT, gl.FLOAT);
+test(Uint8Array, Uint32Array, 4, gl.RGBA8UI, gl.RGBA_INTEGER, gl.UNSIGNED_BYTE, gl.UNSIGNED_INT);
+test(Int8Array, Int32Array, 4, gl.RGBA8I, gl.RGBA_INTEGER, gl.BYTE, gl.INT);
+test(Uint16Array, Uint32Array, 4, gl.RGBA16UI, gl.RGBA_INTEGER, gl.UNSIGNED_SHORT, gl.UNSIGNED_INT);
+test(Int16Array, Int32Array, 4, gl.RGBA16I, gl.RGBA_INTEGER, gl.SHORT, gl.INT);
+test(Uint32Array, Uint32Array, 4, gl.RGBA32UI, gl.RGBA_INTEGER, gl.UNSIGNED_INT, gl.UNSIGNED_INT);
+test(Int32Array, Int32Array, 4, gl.RGBA32I, gl.RGBA_INTEGER, gl.INT, gl.INT);
+
+var i;
+function test565() {
+        var width = 4;
+        var height = 4;
+        arrayBuffer = new Uint16Array(width * height);
+        for (var i = 0; i &lt; height; ++i) {
+                for (var j = 0; j &lt; width; ++j) {
+                        arrayBuffer[width * i + j] = (i &lt;&lt; 11) | ((i + j) &lt;&lt; 5) | j;
+                }
+        }
+        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB565, width, height, 0, gl.RGB, gl.UNSIGNED_SHORT_5_6_5, arrayBuffer);
+        shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+        receiver = new Uint16Array(width * height);
+        gl.readPixels(0, 0, width, height, gl.RGB, gl.UNSIGNED_SHORT_5_6_5, receiver);
+        shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+
+        for (i = 0; i &lt; width * height; ++i) {
+                shouldBe(&quot;arrayBuffer[i]&quot;, &quot;receiver[i]&quot;);
+        }
+}
+
+function test5551() {
+        var width = 4;
+        var height = 4;
+        arrayBuffer = new Uint16Array(width * height);
+        for (var i = 0; i &lt; height; ++i) {
+                for (var j = 0; j &lt; width; ++j) {
+                        arrayBuffer[width * i + j] = (i &lt;&lt; 11) | ((i + j) &lt;&lt; 6) | (j &lt;&lt; 1);
+                }
+        }
+        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB5_A1, width, height, 0, gl.RGBA, gl.UNSIGNED_SHORT_5_5_5_1, arrayBuffer);
+        shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+        receiver = new Uint16Array(width * height);
+        gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_SHORT_5_5_5_1, receiver);
+        shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+
+        for (i = 0; i &lt; width * height; ++i) {
+                shouldBe(&quot;arrayBuffer[i]&quot;, &quot;receiver[i]&quot;);
+        }
+}
+
+function test4444() {
+        var width = 4;
+        var height = 4;
+        arrayBuffer = new Uint16Array(width * height);
+        for (var i = 0; i &lt; height; ++i) {
+                for (var j = 0; j &lt; width; ++j) {
+                        arrayBuffer[width * i + j] = (i &lt;&lt; 12) | ((i + j) &lt;&lt; 8) | (j &lt;&lt; 4);
+                }
+        }
+        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA4, width, height, 0, gl.RGBA, gl.UNSIGNED_SHORT_4_4_4_4, arrayBuffer);
+        shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+        receiver = new Uint16Array(width * height);
+        gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_SHORT_4_4_4_4, receiver);
+        shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+
+        for (i = 0; i &lt; width * height; ++i) {
+                shouldBe(&quot;arrayBuffer[i]&quot;, &quot;receiver[i]&quot;);
+        }
+}
+
+function test9995() {
+        var width = 4;
+        var height = 4;
+        arrayBuffer = new Uint32Array(width * height);
+        for (var i = 0; i &lt; height; ++i) {
+                for (var j = 0; j &lt; width; ++j) {
+                        arrayBuffer[width * i + j] = (i &lt;&lt; 23) | ((i + j) &lt;&lt; 14) | (j &lt;&lt; 5);
+                }
+        }
+        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB9_E5, width, height, 0, gl.RGB, gl.UNSIGNED_INT_5_9_9_9_REV, arrayBuffer);
+        shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+}
+
+function test1010102() {
+        var width = 4;
+        var height = 4;
+        arrayBuffer = new Uint32Array(width * height);
+        for (var i = 0; i &lt; height; ++i) {
+                for (var j = 0; j &lt; width; ++j) {
+                        arrayBuffer[width * i + j] = (i &lt;&lt; 22) | ((i + j) &lt;&lt; 12) | (j &lt;&lt; 2);
+                }
+        }
+        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB10_A2, width, height, 0, gl.RGBA, gl.UNSIGNED_INT_2_10_10_10_REV, arrayBuffer);
+        shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+        receiver = new Uint32Array(width * height);
+        gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_INT_2_10_10_10_REV, receiver);
+        shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+
+        for (i = 0; i &lt; width * height; ++i) {
+                shouldBe(&quot;arrayBuffer[i]&quot;, &quot;receiver[i]&quot;);
+        }
+}
+
+function test111110() {
+        var width = 4;
+        var height = 4;
+        arrayBuffer = new Uint32Array(width * height);
+        for (var i = 0; i &lt; height; ++i) {
+                for (var j = 0; j &lt; width; ++j) {
+                        arrayBuffer[width * i + j] = (i &lt;&lt; 21) | ((i + j) &lt;&lt; 10) | j;
+                }
+        }
+        gl.texImage2D(gl.TEXTURE_2D, 0, gl.R11F_G11F_B10F, width, height, 0, gl.RGB, gl.UNSIGNED_INT_10F_11F_11F_REV, arrayBuffer);
+        shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+        receiver = new Uint32Array(width * height);
+        gl.readPixels(0, 0, width, height, gl.RGB, gl.UNSIGNED_INT_10F_11F_11F_REV, receiver);
+        shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+
+        for (i = 0; i &lt; width * height; ++i) {
+                shouldBe(&quot;arrayBuffer[i]&quot;, &quot;receiver[i]&quot;);
+        }
+}
+
+function test1010102UI() {
+        var width = 4;
+        var height = 4;
+        arrayBuffer = new Uint32Array(width * height);
+        for (var i = 0; i &lt; height; ++i) {
+                for (var j = 0; j &lt; width; ++j) {
+                        arrayBuffer[width * i + j] = (i &lt;&lt; 22) | ((i + j) &lt;&lt; 12) | (j &lt;&lt; 2);
+                }
+        }
+        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB10_A2UI, width, height, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT_2_10_10_10_REV, arrayBuffer);
+        shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+        receiver = new Uint32Array(width * height);
+        gl.readPixels(0, 0, width, height, gl.RGBA_INTEGER, gl.UNSIGNED_INT_2_10_10_10_REV, receiver);
+        shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+
+        for (i = 0; i &lt; width * height; ++i) {
+                shouldBe(&quot;arrayBuffer[i]&quot;, &quot;receiver[i]&quot;);
+        }
+}
+
+test565();
+test5551();
+test4444();
+test9995();
+test1010102();
+test111110();
+test1010102UI()
+
+gl.deleteFramebuffer(framebuffer);
+shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+
+gl.deleteTexture(texture);
+shouldBe(&quot;gl.getError()&quot;, &quot;gl.NO_ERROR&quot;);
+&lt;/script&gt;
+&lt;script src=&quot;../../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (208723 => 208724)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-11-15 02:20:54 UTC (rev 208723)
+++ trunk/Source/WebCore/ChangeLog        2016-11-15 02:42:32 UTC (rev 208724)
</span><span class="lines">@@ -1,3 +1,104 @@
</span><ins>+2016-11-14  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        [WebGL2] Teach WebGLRenderingContextBase about new texture internal formats
+        https://bugs.webkit.org/show_bug.cgi?id=164525
+
+        Reviewed by Dean Jackson.
+
+        Test: fast/canvas/webgl/webgl2-texture-upload-enums.html
+
+        This patch migrates the existing WebGL calls texImage2D(), texSubImage2D(),
+        and readPixels() to understand the new WebGL 2 texture types. In WebGL1, the
+        format and the internalFormat were required to be the same, and we had this
+        assumption baked into many places in these functions. In WebGL 2, those two
+        values are often different, which means I had to fix all of these assumptions
+        in our code. Also, rather than have two completely separate parallel
+        implementations of these functions, a more forward-looking approach is to
+        have one implementation which has a few checks to isWebGL1() in strategic
+        places. (This way, bugs only have to be fixed in a single place). Therefore,
+        this patch deletes the WebGL 2 versions of these functions.
+
+        * html/canvas/WebGL2RenderingContext.cpp: These functions are moved to
+        WebGLRenderingContextBase.
+        (WebCore::WebGL2RenderingContext::isIntegerFormat):
+        (WebCore::WebGL2RenderingContext::copyTexImage2D): Deleted.
+        (WebCore::WebGL2RenderingContext::texSubImage2DBase): Deleted.
+        (WebCore::WebGL2RenderingContext::texSubImage2DImpl): Deleted.
+        (WebCore::WebGL2RenderingContext::texSubImage2D): Deleted.
+        (WebCore::WebGL2RenderingContext::validateTexFuncParameters): Deleted.
+        (WebCore::WebGL2RenderingContext::validateTexFuncFormatAndType): Deleted.
+        (WebCore::WebGL2RenderingContext::validateTexFuncData): Deleted.
+        * html/canvas/WebGL2RenderingContext.h: Moved function implementations to
+        WebGLRenderingContextBase.
+        * html/canvas/WebGLRenderingContext.cpp: Ditto.
+        (WebCore::WebGLRenderingContext::copyTexImage2D): Deleted.
+        (WebCore::WebGLRenderingContext::texSubImage2DBase): Deleted.
+        (WebCore::WebGLRenderingContext::texSubImage2DImpl): Deleted.
+        (WebCore::WebGLRenderingContext::texSubImage2D): Deleted.
+        (WebCore::WebGLRenderingContext::validateTexFuncParameters): Deleted.
+        (WebCore::WebGLRenderingContext::validateTexFuncFormatAndType): Deleted.
+        (WebCore::WebGLRenderingContext::validateTexFuncData): Deleted.
+        * html/canvas/WebGLRenderingContext.h: Moved function implementations to
+        WebGLRenderingContextBase.
+        * html/canvas/WebGLRenderingContextBase.cpp:
+        (WebCore::WebGLRenderingContextBase::validateSettableTexInternalFormat):
+        Teach about new depth texture formats.
+        (WebCore::WebGLRenderingContextBase::copyTexSubImage2D): Rename
+        &quot;internalformat&quot; to &quot;internalFormat&quot;. Teach about the distinction between
+        format and internalFormat. When pre-filling textures with 0s to work around
+        buggy drivers, we need a new way of knowing which format/type arguments to
+        pass to texSubImage2D() which are compatible with the texture's internal
+        format. The implementation of this function was added to GraphicsContext3D
+        and is called here.
+        (WebCore::WebGLRenderingContextBase::generateMipmap): Teach about the
+        distinction between format and internalFormat.
+        (WebCore::internalFormatTheme): This is used so readPixels() knows what
+        kind of format/type arguments are compatible with the texture's internal
+        format.
+        (WebCore::numberOfComponentsForFormat): Ditto.
+        (WebCore::numberOfComponentsForInternalFormat): Ditto.
+        (WebCore::WebGLRenderingContextBase::readPixels): Many more format/type
+        combinations are required in order to test the various new kinds of
+        textures.
+        (WebCore::WebGLRenderingContextBase::texImage2DBase): Rename internalformat
+        to internalFormat, and teach about the distinction between format and
+        internalFormat.
+        (WebCore::WebGLRenderingContextBase::validateTexFunc): Ditto.
+        (WebCore::WebGLRenderingContextBase::texImage2D): Ditto.
+        (WebCore::WebGLRenderingContextBase::texSubImage2DImpl): Moved from
+        WebGLRenderingContext.
+        (WebCore::WebGLRenderingContextBase::texSubImage2D): Ditto.
+        (WebCore::WebGLRenderingContextBase::validateArrayBufferType): Ditto.
+        (WebCore::WebGLRenderingContextBase::validateTexFuncData): Ditto.
+        (WebCore::WebGLRenderingContextBase::validateTexFuncParameters): Ditto.
+        (WebCore::WebGLRenderingContextBase::validateTexFuncFormatAndType): Ditto.
+        This is the main function where the new internalFormats are dealt with.
+        The OpenGL ES spec lists a table of all the internalFormats and all their
+        compatible format/type values. This table is entered into this function to
+        check that the combinations are correct.
+        (WebCore::WebGLRenderingContextBase::texSubImage2DBase): Moved from
+        WebGLRenderingContext.
+        (WebCore::WebGLRenderingContextBase::copyTexImage2D): Ditto.
+        (WebCore::WebGLRenderingContextBase::validateSettableTexFormat): Deleted.
+        * html/canvas/WebGLRenderingContextBase.h: No longer overrides virtual
+        functions.
+        * platform/graphics/GraphicsContext3D.cpp:
+        (WebCore::GraphicsContext3D::computeFormatAndTypeParameters): Because
+        this is inside GraphicsContext3D, it doesn't need any isWebGL1() checks.
+        Teach about new enums.
+        (WebCore::GraphicsContext3D::possibleFormatAndTypeForInternalFormat):
+        Ditto.
+        (WebCore::GraphicsContext3D::packImageData):
+        (WebCore::GraphicsContext3D::packPixels): It is possible to try to
+        copy data from a video into one of these new formats. Currently, we
+        implement this by swizzling on the CPU. Rather than implementing all the
+        swizzling functions in this patch (which would make this patch much
+        larger), simply bail in this case. We will implement this later.
+        (WebCore::GraphicsContext3D::getClearBitsByFormat): Update.
+        * platform/graphics/GraphicsContext3D.h:
+        (WebCore::GraphicsContext3D::hasAlpha): Ditto.
+        (WebCore::GraphicsContext3D::hasColor): Ditto.
+
</ins><span class="cx"> 2016-11-14  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Scrolling when zoomed doesn't always use the correct layout viewport
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGL2RenderingContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp (208723 => 208724)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp        2016-11-15 02:20:54 UTC (rev 208723)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp        2016-11-15 02:42:32 UTC (rev 208724)
</span><span class="lines">@@ -1154,731 +1154,6 @@
</span><span class="cx">     m_context-&gt;hint(target, mode);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebGL2RenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
-{
-    if (isContextLostOrPending())
-        return;
-    RefPtr&lt;WebGLContextAttributes&gt; attributes = getContextAttributes();
-    GC3Denum bufferFormat = attributes-&gt;alpha() ? GraphicsContext3D::RGBA : GraphicsContext3D::RGB;
-    if (!validateTexFuncParameters(&quot;copyTexImage2D&quot;, CopyTexImage, target, level, internalformat, width, height, border, bufferFormat, GraphicsContext3D::UNSIGNED_BYTE))
-        return;
-    if (!validateSettableTexFormat(&quot;copyTexImage2D&quot;, internalformat))
-        return;
-    WebGLTexture* tex = validateTextureBinding(&quot;copyTexImage2D&quot;, target, true);
-    if (!tex)
-        return;
-    if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, &quot;copyTexImage2D&quot;, &quot;framebuffer is incompatible format&quot;);
-        return;
-    }
-    if (!isGLES2NPOTStrict() &amp;&amp; level &amp;&amp; WebGLTexture::isNPOT(width, height)) {
-        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;copyTexImage2D&quot;, &quot;level &gt; 0 not power of 2&quot;);
-        return;
-    }
-    const char* reason = &quot;framebuffer incomplete&quot;;
-    if (m_framebufferBinding &amp;&amp; !m_framebufferBinding-&gt;onAccess(graphicsContext3D(), !isResourceSafe(), &amp;reason)) {
-        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, &quot;copyTexImage2D&quot;, reason);
-        return;
-    }
-    clearIfComposited();
-    if (isResourceSafe())
-        m_context-&gt;copyTexImage2D(target, level, internalformat, x, y, width, height, border);
-    else {
-        GC3Dint clippedX, clippedY;
-        GC3Dsizei clippedWidth, clippedHeight;
-        if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &amp;clippedX, &amp;clippedY, &amp;clippedWidth, &amp;clippedHeight)) {
-            m_context-&gt;texImage2DResourceSafe(target, level, internalformat, width, height, border,
-                internalformat, GraphicsContext3D::UNSIGNED_BYTE, m_unpackAlignment);
-            if (clippedWidth &gt; 0 &amp;&amp; clippedHeight &gt; 0) {
-                m_context-&gt;copyTexSubImage2D(target, level, clippedX - x, clippedY - y,
-                    clippedX, clippedY, clippedWidth, clippedHeight);
-            }
-        } else
-            m_context-&gt;copyTexImage2D(target, level, internalformat, x, y, width, height, border);
-    }
-    // FIXME: if the framebuffer is not complete, none of the below should be executed.
-    tex-&gt;setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
-}
-
-void WebGL2RenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels)
-{
-    ASSERT(!isContextLost());
-    if (!validateTexFuncParameters(&quot;texSubImage2D&quot;, TexSubImage, target, level, internalformat, width, height, 0, format, type))
-        return;
-    ASSERT(validateSize(&quot;texSubImage2D&quot;, xoffset, yoffset));
-    ASSERT(validateSettableTexFormat(&quot;texSubImage2D&quot;, format));
-    WebGLTexture* tex = validateTextureBinding(&quot;texSubImage2D&quot;, target, true);
-    if (!tex) {
-        ASSERT_NOT_REACHED();
-        return;
-    }
-    ASSERT((xoffset + width) &gt;= 0);
-    ASSERT((yoffset + height) &gt;= 0);
-    ASSERT(tex-&gt;getWidth(target, level) &gt;= (xoffset + width));
-    ASSERT(tex-&gt;getHeight(target, level) &gt;= (yoffset + height));
-    ASSERT(tex-&gt;getInternalFormat(target, level) == format);
-    ASSERT(tex-&gt;getType(target, level) == type);
-    m_context-&gt;texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
-}
-
-void WebGL2RenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha)
-{
-    Vector&lt;uint8_t&gt; data;
-    GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
-    if (!imageExtractor.extractSucceeded()) {
-        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texSubImage2D&quot;, &quot;bad image&quot;);
-        return;
-    }
-    GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
-    GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
-    const void* imagePixelData = imageExtractor.imagePixelData();
-    
-    bool needConversion = true;
-    if (type == GraphicsContext3D::UNSIGNED_BYTE &amp;&amp; sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 &amp;&amp; format == GraphicsContext3D::RGBA &amp;&amp; alphaOp == GraphicsContext3D::AlphaDoNothing &amp;&amp; !flipY)
-        needConversion = false;
-    else {
-        if (!m_context-&gt;packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
-            synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texImage2D&quot;, &quot;bad image data&quot;);
-            return;
-        }
-    }
-    
-    if (m_unpackAlignment != 1)
-        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
-    
-    WebGLTexture* tex = validateTextureBinding(&quot;texSubImage2D&quot;, target, true);
-    GC3Denum internalformat = tex-&gt;getInternalFormat(target, level);
-    texSubImage2DBase(target, level, xoffset, yoffset, image-&gt;width(), image-&gt;height(), internalformat, format, type,  needConversion ? data.data() : imagePixelData);
-    if (m_unpackAlignment != 1)
-        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, RefPtr&lt;ArrayBufferView&gt;&amp;&amp; pixels)
-{
-    if (isContextLostOrPending() || !validateTexFuncData(&quot;texSubImage2D&quot;, level, width, height, GraphicsContext3D::NONE, format, type, pixels.get(), NullNotAllowed) || !validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage, SourceArrayBufferView, target, level, GraphicsContext3D::NONE, width, height, 0, format, type, xoffset, yoffset))
-        return;
-    
-    void* data = pixels-&gt;baseAddress();
-    Vector&lt;uint8_t&gt; tempData;
-    bool changeUnpackAlignment = false;
-    if (data &amp;&amp; (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
-        if (!m_context-&gt;extractTextureData(width, height, format, type,
-            m_unpackAlignment,
-            m_unpackFlipY, m_unpackPremultiplyAlpha,
-            data,
-            tempData))
-            return;
-        data = tempData.data();
-        changeUnpackAlignment = true;
-    }
-    if (changeUnpackAlignment)
-        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
-    WebGLTexture* tex = validateTextureBinding(&quot;texSubImage2D&quot;, target, true);
-    GC3Denum internalformat = tex-&gt;getInternalFormat(target, level);
-    texSubImage2DBase(target, level, xoffset, yoffset, width, height, internalformat, format, type, data);
-    if (changeUnpackAlignment)
-        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-ExceptionOr&lt;void&gt; WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Optional&lt;TexImageSource&gt;&amp;&amp; source)
-{
-    if (!source) {
-        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texSubImage2D&quot;, &quot;source is null&quot;);
-        return { };
-    }
-
-    auto visitor = WTF::makeVisitor([&amp;](const RefPtr&lt;ImageData&gt;&amp; pixels) -&gt; ExceptionOr&lt;void&gt; {
-        if (isContextLostOrPending() || !pixels || !validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage, SourceImageData, target, level, GraphicsContext3D::NONE,  pixels-&gt;width(), pixels-&gt;height(), 0, format, type, xoffset, yoffset))
-            return { };
-
-        Vector&lt;uint8_t&gt; data;
-        bool needConversion = true;
-        // The data from ImageData is always of format RGBA8.
-        // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
-        if (format == GraphicsContext3D::RGBA &amp;&amp; type == GraphicsContext3D::UNSIGNED_BYTE &amp;&amp; !m_unpackFlipY &amp;&amp; !m_unpackPremultiplyAlpha)
-            needConversion = false;
-        else {
-            if (!m_context-&gt;extractImageData(pixels.get(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
-                synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texSubImage2D&quot;, &quot;bad image data&quot;);
-                return { };
-            }
-        }
-        if (m_unpackAlignment != 1)
-            m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
-
-        WebGLTexture* tex = validateTextureBinding(&quot;texSubImage2D&quot;, target, true);
-        GC3Denum internalformat = tex-&gt;getInternalFormat(target, level);
-        texSubImage2DBase(target, level, xoffset, yoffset, pixels-&gt;width(), pixels-&gt;height(), internalformat, format, type, needConversion ? data.data() : pixels-&gt;data()-&gt;data());
-        if (m_unpackAlignment != 1)
-            m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-
-        return { };
-    }, [&amp;](const RefPtr&lt;HTMLImageElement&gt;&amp; image) -&gt; ExceptionOr&lt;void&gt; {
-        if (wouldTaintOrigin(image.get()))
-            return Exception { SECURITY_ERR };
-        if (isContextLostOrPending() || !validateHTMLImageElement(&quot;texSubImage2D&quot;, image.get()))
-            return { };
-
-        RefPtr&lt;Image&gt; imageForRender = image-&gt;cachedImage()-&gt;imageForRenderer(image-&gt;renderer());
-        if (!imageForRender)
-            return { };
-
-        if (imageForRender-&gt;isSVGImage())
-            imageForRender = drawImageIntoBuffer(*imageForRender, image-&gt;width(), image-&gt;height(), 1);
-
-        if (!imageForRender || !validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage, SourceHTMLImageElement, target, level, GraphicsContext3D::NONE, imageForRender-&gt;width(), imageForRender-&gt;height(), 0, format, type, xoffset, yoffset))
-            return { };
-
-        texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha);
-        return { };
-    }, [&amp;](const RefPtr&lt;HTMLCanvasElement&gt;&amp; canvas) -&gt; ExceptionOr&lt;void&gt; {
-        if (wouldTaintOrigin(canvas.get()))
-            return Exception { SECURITY_ERR };
-        if (isContextLostOrPending() || !validateHTMLCanvasElement(&quot;texSubImage2D&quot;, canvas.get())
-            || !validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage, SourceHTMLCanvasElement, target, level, GraphicsContext3D::NONE, canvas-&gt;width(), canvas-&gt;height(), 0, format, type, xoffset, yoffset))
-            return { };
-
-        RefPtr&lt;ImageData&gt; imageData = canvas-&gt;getImageData();
-        if (imageData)
-            texSubImage2D(target, level, xoffset, yoffset, format, type, TexImageSource(imageData.get()));
-        else
-            texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas-&gt;copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha);
-        return { };
-    }, [&amp;](const RefPtr&lt;HTMLVideoElement&gt;&amp; video) -&gt; ExceptionOr&lt;void&gt; {
-        if (wouldTaintOrigin(video.get()))
-            return Exception { SECURITY_ERR };
-        if (isContextLostOrPending() || !validateHTMLVideoElement(&quot;texSubImage2D&quot;, video.get())
-            || !validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage, SourceHTMLVideoElement, target, level, GraphicsContext3D::NONE, video-&gt;videoWidth(), video-&gt;videoHeight(), 0, format, type, xoffset, yoffset))
-            return { };
-
-        RefPtr&lt;Image&gt; image = videoFrameToImage(video.get(), ImageBuffer::fastCopyImageMode());
-        if (!image)
-            return { };
-        texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha);
-        return { };
-    });
-
-    return WTF::visit(visitor, source.value());
-}
-
-bool WebGL2RenderingContext::validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType functionType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type)
-{
-    if (functionType == CopyTexImage) {
-        GC3Denum framebufferInternalFormat = 0;
-        WebGLSharedObject* object = m_framebufferBinding-&gt;getAttachmentObject(GraphicsContext3D::COLOR_ATTACHMENT0);
-        if (object-&gt;isTexture()) {
-            WebGLTexture* texture = reinterpret_cast&lt;WebGLTexture*&gt;(object);
-            framebufferInternalFormat = baseInternalFormatFromInternalFormat(texture-&gt;getInternalFormat(GraphicsContext3D::TEXTURE_2D, 0));
-        } else if (object-&gt;isRenderbuffer()) {
-            WebGLRenderbuffer* renderBuffer = reinterpret_cast&lt;WebGLRenderbuffer*&gt;(object);
-            framebufferInternalFormat = baseInternalFormatFromInternalFormat(renderBuffer-&gt;getInternalFormat());
-        }
-        
-        GC3Denum baseTextureInternalFormat = baseInternalFormatFromInternalFormat(internalformat);
-        bool validFormatCombination = true;
-        switch (framebufferInternalFormat) {
-        case GraphicsContext3D::RED:
-            if (baseTextureInternalFormat != GraphicsContext3D::LUMINANCE &amp;&amp; baseTextureInternalFormat != GraphicsContext3D::RED)
-                validFormatCombination = false;
-            break;
-        case GraphicsContext3D::RG:
-            if (baseTextureInternalFormat != GraphicsContext3D::LUMINANCE &amp;&amp; baseTextureInternalFormat != GraphicsContext3D::RED &amp;&amp; baseTextureInternalFormat != GraphicsContext3D::RG)
-                validFormatCombination = false;
-            break;
-        case GraphicsContext3D::RGB:
-            if (baseTextureInternalFormat != GraphicsContext3D::LUMINANCE &amp;&amp; baseTextureInternalFormat != GraphicsContext3D::RED &amp;&amp; baseTextureInternalFormat != GraphicsContext3D::RG &amp;&amp; baseTextureInternalFormat != GraphicsContext3D::RGB)
-                validFormatCombination = false;
-            break;
-        case GraphicsContext3D::RGBA:
-            if (baseTextureInternalFormat != GraphicsContext3D::ALPHA &amp;&amp; baseTextureInternalFormat != GraphicsContext3D::LUMINANCE &amp;&amp; baseTextureInternalFormat != GraphicsContext3D::LUMINANCE_ALPHA &amp;&amp; baseTextureInternalFormat != GraphicsContext3D::RED &amp;&amp; baseTextureInternalFormat != GraphicsContext3D::RG &amp;&amp; baseTextureInternalFormat != GraphicsContext3D::RGB &amp;&amp; baseTextureInternalFormat != GraphicsContext3D::RGBA)
-                validFormatCombination = false;
-            break;
-        case GraphicsContext3D::DEPTH_COMPONENT:
-            validFormatCombination = false;
-            break;
-        case GraphicsContext3D::DEPTH_STENCIL:
-            validFormatCombination = false;
-            break;
-        }
-        
-        if (!validFormatCombination) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;copyTexImage: invalid combination of framebuffer and texture formats&quot;);
-            return false;
-        }
-
-        bool isSRGB = (getFramebufferAttachmentParameter(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING).getInt() == GraphicsContext3D::SRGB);
-        if (isSRGB != (framebufferInternalFormat == GraphicsContext3D::SRGB8 || framebufferInternalFormat == GraphicsContext3D::SRGB8_ALPHA8)) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;framebuffer attachment color encoding and internal format do not match&quot;);
-        return false;
-        }
-    }
-    
-    // We absolutely have to validate the format and type combination.
-    // The texImage2D entry points taking HTMLImage, etc. will produce
-    // temporary data based on this combination, so it must be legal.
-    if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level) || !validateTexFuncLevel(functionName, target, level))
-        return false;
-    
-    if (width &lt; 0 || height &lt; 0) {
-        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;width or height &lt; 0&quot;);
-        return false;
-    }
-    
-    GC3Dint maxTextureSizeForLevel = pow(2.0, m_maxTextureLevel - 1 - level);
-    switch (target) {
-    case GraphicsContext3D::TEXTURE_2D:
-        if (width &gt; maxTextureSizeForLevel || height &gt; maxTextureSizeForLevel) {
-            synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;width or height out of range&quot;);
-            return false;
-        }
-        break;
-    case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
-    case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
-    case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
-    case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
-    case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
-    case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
-        if (functionType != TexSubImage &amp;&amp; width != height) {
-            synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;width != height for cube map&quot;);
-            return false;
-        }
-        // No need to check height here. For texImage width == height.
-        // For texSubImage that will be checked when checking yoffset + height is in range.
-        if (width &gt; maxTextureSizeForLevel) {
-            synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;width or height out of range for cube map&quot;);
-            return false;
-        }
-        break;
-    default:
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid target&quot;);
-        return false;
-    }
-    
-    if (border) {
-        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;border != 0&quot;);
-        return false;
-    }
-    
-    return true;
-}
-    
-bool WebGL2RenderingContext::validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level)
-{
-    // Verify that a valid format has been provided.
-    switch (format) {
-    case GraphicsContext3D::ALPHA:
-    case GraphicsContext3D::LUMINANCE:
-    case GraphicsContext3D::LUMINANCE_ALPHA:
-    case GraphicsContext3D::RGB:
-    case GraphicsContext3D::RGBA:
-    case GraphicsContext3D::RGBA_INTEGER:
-    case GraphicsContext3D::RG:
-    case GraphicsContext3D::RG_INTEGER:
-    case GraphicsContext3D::RED_INTEGER:
-        break;
-    case GraphicsContext3D::DEPTH_STENCIL:
-    case GraphicsContext3D::DEPTH_COMPONENT:
-        if (m_webglDepthTexture)
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;depth texture formats not enabled&quot;);
-        return false;
-    default:
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture format&quot;);
-        return false;
-    }
-    
-    // Verify that a valid type has been provided.
-    switch (type) {
-    case GraphicsContext3D::UNSIGNED_BYTE:
-    case GraphicsContext3D::BYTE:
-    case GraphicsContext3D::UNSIGNED_SHORT:
-    case GraphicsContext3D::SHORT:
-    case GraphicsContext3D::UNSIGNED_INT:
-    case GraphicsContext3D::INT:
-    case GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV:
-    case GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV:
-    case GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV:
-    case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
-    case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
-    case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
-        break;
-    case GraphicsContext3D::FLOAT:
-        if (m_oesTextureFloat)
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture type&quot;);
-        return false;
-    case GraphicsContext3D::HALF_FLOAT:
-    case GraphicsContext3D::HALF_FLOAT_OES:
-        if (m_oesTextureHalfFloat)
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture type&quot;);
-        return false;
-    case GraphicsContext3D::UNSIGNED_INT_24_8:
-    case GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV:
-        if (isDepthStencilSupported())
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture type&quot;);
-        return false;
-    default:
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture type&quot;);
-        return false;
-    }
-    
-    // Veryify that a valid internal format has been provided.
-    switch (internalformat) {
-    case GraphicsContext3D::RGBA:
-    case GraphicsContext3D::RGB:
-    case GraphicsContext3D::LUMINANCE_ALPHA:
-    case GraphicsContext3D::LUMINANCE:
-    case GraphicsContext3D::ALPHA:
-    case GraphicsContext3D::RGBA32I:
-    case GraphicsContext3D::RGBA32UI:
-    case GraphicsContext3D::RGBA16I:
-    case GraphicsContext3D::RGBA16UI:
-    case GraphicsContext3D::RGBA8:
-    case GraphicsContext3D::RGBA8I:
-    case GraphicsContext3D::RGBA8UI:
-    case GraphicsContext3D::RGB10_A2:
-    case GraphicsContext3D::RGB10_A2UI:
-    case GraphicsContext3D::RGBA4:
-    case GraphicsContext3D::RG32I:
-    case GraphicsContext3D::RG32UI:
-    case GraphicsContext3D::RG16I:
-    case GraphicsContext3D::RG16UI:
-    case GraphicsContext3D::RG8:
-    case GraphicsContext3D::RG8I:
-    case GraphicsContext3D::RG8UI:
-    case GraphicsContext3D::R32I:
-    case GraphicsContext3D::R32UI:
-    case GraphicsContext3D::R16I:
-    case GraphicsContext3D::R16UI:
-    case GraphicsContext3D::R8:
-    case GraphicsContext3D::R8I:
-    case GraphicsContext3D::R8UI:
-    case GraphicsContext3D::RGB5_A1:
-    case GraphicsContext3D::RGB8:
-    case GraphicsContext3D::RGB565:
-    case GraphicsContext3D::RGBA32F:
-    case GraphicsContext3D::RGBA16F:
-    case GraphicsContext3D::RGBA8_SNORM:
-    case GraphicsContext3D::RGB32F:
-    case GraphicsContext3D::RGB32I:
-    case GraphicsContext3D::RGB32UI:
-    case GraphicsContext3D::RGB16F:
-    case GraphicsContext3D::RGB16I:
-    case GraphicsContext3D::RGB16UI:
-    case GraphicsContext3D::RGB8_SNORM:
-    case GraphicsContext3D::RGB8I:
-    case GraphicsContext3D::RGB8UI:
-    case GraphicsContext3D::SRGB8:
-    case GraphicsContext3D::SRGB8_ALPHA8:
-    case GraphicsContext3D::R11F_G11F_B10F:
-    case GraphicsContext3D::RGB9_E5:
-    case GraphicsContext3D::RG32F:
-    case GraphicsContext3D::RG16F:
-    case GraphicsContext3D::RG8_SNORM:
-    case GraphicsContext3D::R32F:
-    case GraphicsContext3D::R16F:
-    case GraphicsContext3D::R8_SNORM:
-    case GraphicsContext3D::STENCIL_INDEX8:
-        break;
-    case GraphicsContext3D::DEPTH_COMPONENT16:
-    case GraphicsContext3D::DEPTH_COMPONENT32F:
-    case GraphicsContext3D::DEPTH_COMPONENT24:
-        if (m_webglDepthTexture)
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;depth texture formats not enabled&quot;);
-        return false;
-    case GraphicsContext3D::DEPTH32F_STENCIL8:
-    case GraphicsContext3D::DEPTH24_STENCIL8:
-        if (isDepthStencilSupported())
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture internal format&quot;);
-        return false;
-    case GraphicsContext3D::NONE:
-        // When calling validateTexFuncFormatAndType with internalformat == GraphicsContext3D::NONE, the intent is
-        // only to check for whether or not the format and type are valid types, which we have already done at this point.
-        return true;
-        break;
-    default:
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture internal format&quot;);
-        return false;
-    }
-
-    // Verify that the combination of format, internalformat and type is supported.
-    switch (format) {
-    case GraphicsContext3D::RGBA:
-        if (type == GraphicsContext3D::UNSIGNED_BYTE
-            &amp;&amp; (internalformat == GraphicsContext3D::RGBA || internalformat == GraphicsContext3D::RGBA8 || internalformat == GraphicsContext3D::RGB5_A1 || internalformat == GraphicsContext3D::RGBA4 || internalformat == GraphicsContext3D::SRGB8_ALPHA8))
-            break;
-        if (type == GraphicsContext3D::BYTE &amp;&amp; internalformat == GraphicsContext3D::RGBA8_SNORM)
-            break;
-        if (type == GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4
-            &amp;&amp; (internalformat == GraphicsContext3D::RGBA || internalformat == GraphicsContext3D::RGBA4))
-            break;
-        if (type == GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1
-            &amp;&amp; (internalformat == GraphicsContext3D::RGBA || internalformat == GraphicsContext3D::RGB5_A1))
-            break;
-        if (type == GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV
-            &amp;&amp; (internalformat == GraphicsContext3D::RGB10_A2 || internalformat == GraphicsContext3D::RGB5_A1))
-            break;
-        if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES) &amp;&amp; internalformat == GraphicsContext3D::RGBA16F)
-            break;
-        if (type == GraphicsContext3D::FLOAT
-            &amp;&amp; (internalformat == GraphicsContext3D::RGBA32F || internalformat == GraphicsContext3D::RGBA16F))
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid format, internalformat, and type combination&quot;);
-        return false;
-    case GraphicsContext3D::RGBA_INTEGER:
-        if (type == GraphicsContext3D::UNSIGNED_BYTE &amp;&amp; internalformat == GraphicsContext3D::RGBA8UI)
-        break;
-        if (type == GraphicsContext3D::BYTE &amp;&amp; internalformat == GraphicsContext3D::RGBA8I)
-        break;
-        if (type == GraphicsContext3D::UNSIGNED_SHORT &amp;&amp; internalformat == GraphicsContext3D::RGBA16UI)
-        break;
-        if (type == GraphicsContext3D::SHORT &amp;&amp; internalformat == GraphicsContext3D::RGBA16I)
-        break;
-        if (type == GraphicsContext3D::UNSIGNED_INT &amp;&amp; internalformat == GraphicsContext3D::RGBA32UI)
-        break;
-        if (type == GraphicsContext3D::INT &amp;&amp; internalformat == GraphicsContext3D::RGBA32I)
-        break;
-        if (type == GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV &amp;&amp; internalformat == GraphicsContext3D::RGB10_A2UI)
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid format, internalformat, and type combination&quot;);
-        return false;
-    case GraphicsContext3D::RGB:
-        if (type == GraphicsContext3D::UNSIGNED_BYTE
-            &amp;&amp; (internalformat == GraphicsContext3D::RGB || internalformat == GraphicsContext3D::RGB8 || internalformat == GraphicsContext3D::RGB565
-            || internalformat == GraphicsContext3D::SRGB8))
-            break;
-        if (type == GraphicsContext3D::BYTE &amp;&amp; internalformat == GraphicsContext3D::RGB8_SNORM)
-            break;
-        if (type == GraphicsContext3D::UNSIGNED_SHORT_5_6_5
-            &amp;&amp; (internalformat == GraphicsContext3D::RGB || internalformat == GraphicsContext3D::RGB565))
-            break;
-        if (type == GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV &amp;&amp; internalformat == GraphicsContext3D::R11F_G11F_B10F)
-            break;
-        if (type == GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV &amp;&amp; internalformat == GraphicsContext3D::RGB9_E5)
-            break;
-        if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES)
-            &amp;&amp; (internalformat == GraphicsContext3D::RGB16F || internalformat == GraphicsContext3D::R11F_G11F_B10F || internalformat == GraphicsContext3D::RGB9_E5))
-            break;
-        if (type == GraphicsContext3D::FLOAT
-            &amp;&amp; (internalformat == GraphicsContext3D::RGB32F || internalformat == GraphicsContext3D::RGB16F || internalformat == GraphicsContext3D::R11F_G11F_B10F || internalformat == GraphicsContext3D::RGB9_E5))
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid format, internalformat, and type combination&quot;);
-        return false;
-    case GraphicsContext3D::RGB_INTEGER:
-        if (type == GraphicsContext3D::UNSIGNED_BYTE &amp;&amp; internalformat == GraphicsContext3D::RGB8UI)
-            break;
-        if (type == GraphicsContext3D::BYTE &amp;&amp; internalformat == GraphicsContext3D::RGB8I)
-            break;
-        if (type == GraphicsContext3D::UNSIGNED_SHORT &amp;&amp; internalformat == GraphicsContext3D::RGB16UI)
-            break;
-        if (type == GraphicsContext3D::SHORT &amp;&amp; internalformat == GraphicsContext3D::RGB16I)
-            break;
-        if (type == GraphicsContext3D::UNSIGNED_INT &amp;&amp; internalformat == GraphicsContext3D::RGB32UI)
-            break;
-        if (type == GraphicsContext3D::INT &amp;&amp; internalformat == GraphicsContext3D::RGB32I)
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid format, internalformat, and type combination&quot;);
-        return false;
-    case GraphicsContext3D::RG:
-        if (type == GraphicsContext3D::UNSIGNED_BYTE &amp;&amp; internalformat == GraphicsContext3D::RG8)
-            break;
-        if (type == GraphicsContext3D::BYTE &amp;&amp; internalformat == GraphicsContext3D::RG8_SNORM)
-            break;
-        if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES) &amp;&amp; internalformat == GraphicsContext3D::RG16F)
-            break;
-        if (type == GraphicsContext3D::FLOAT
-            &amp;&amp; (internalformat == GraphicsContext3D::RG32F || internalformat == GraphicsContext3D::RG16F))
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid format, internalformat, and type combination&quot;);
-        return false;
-    case GraphicsContext3D::RG_INTEGER:
-        if (type == GraphicsContext3D::UNSIGNED_BYTE &amp;&amp; internalformat == GraphicsContext3D::RG8UI)
-            break;
-        if (type == GraphicsContext3D::BYTE &amp;&amp; internalformat == GraphicsContext3D::RG8I)
-            break;
-        if (type == GraphicsContext3D::UNSIGNED_SHORT &amp;&amp; internalformat == GraphicsContext3D::RG16UI)
-            break;
-        if (type == GraphicsContext3D::SHORT &amp;&amp; internalformat == GraphicsContext3D::RG16I)
-            break;
-        if (type == GraphicsContext3D::UNSIGNED_INT &amp;&amp; internalformat == GraphicsContext3D::RG32UI)
-            break;
-        if (type == GraphicsContext3D::INT &amp;&amp; internalformat == GraphicsContext3D::RG32I)
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid format, internalformat, and type combination&quot;);
-        return false;
-    case GraphicsContext3D::RED:
-        if (type == GraphicsContext3D::UNSIGNED_BYTE &amp;&amp; internalformat == GraphicsContext3D::R8)
-            break;
-        if (type == GraphicsContext3D::BYTE &amp;&amp; internalformat == GraphicsContext3D::R8_SNORM)
-            break;
-        if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES) &amp;&amp; internalformat == GraphicsContext3D::R16F)
-            break;
-        if (type == GraphicsContext3D::FLOAT
-            &amp;&amp; (internalformat == GraphicsContext3D::R32F || internalformat == GraphicsContext3D::R16F))
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid format, internalformat, and type combination&quot;);
-        return false;
-    case GraphicsContext3D::RED_INTEGER:
-        if (type == GraphicsContext3D::UNSIGNED_BYTE &amp;&amp; internalformat == GraphicsContext3D::R8UI)
-            break;
-        if (type == GraphicsContext3D::BYTE &amp;&amp; internalformat == GraphicsContext3D::R8I)
-            break;
-        if (type == GraphicsContext3D::UNSIGNED_SHORT &amp;&amp; internalformat == GraphicsContext3D::R16UI)
-            break;
-        if (type == GraphicsContext3D::SHORT &amp;&amp; internalformat == GraphicsContext3D::R16I)
-            break;
-        if (type == GraphicsContext3D::UNSIGNED_INT &amp;&amp; internalformat == GraphicsContext3D::R32UI)
-            break;
-        if (type == GraphicsContext3D::INT &amp;&amp; internalformat == GraphicsContext3D::R32I)
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid format, internalformat, and type combination&quot;);
-        return false;
-    case GraphicsContext3D::DEPTH_COMPONENT:
-        if (!m_webglDepthTexture) {
-            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid format. DEPTH_COMPONENT not enabled&quot;);
-            return false;
-        }
-        if (type == GraphicsContext3D::UNSIGNED_SHORT &amp;&amp; internalformat == GraphicsContext3D::DEPTH_COMPONENT16)
-            break;
-        if (type == GraphicsContext3D::UNSIGNED_INT
-            &amp;&amp; (internalformat == GraphicsContext3D::DEPTH_COMPONENT24 || internalformat == GraphicsContext3D::DEPTH_COMPONENT16))
-            break;
-        if (type == GraphicsContext3D::FLOAT &amp;&amp; internalformat == GraphicsContext3D::DEPTH_COMPONENT32F)
-            break;
-        if (level &gt; 0) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;level must be 0 for DEPTH_COMPONENT format&quot;);
-            return false;
-        }
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid format, internalformat, and type combination&quot;);
-        return false;
-    case GraphicsContext3D::DEPTH_STENCIL:
-        if (!m_webglDepthTexture || !isDepthStencilSupported()) {
-            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid format. DEPTH_STENCIL not enabled&quot;);
-            return false;
-        }
-        if (type == GraphicsContext3D::UNSIGNED_INT_24_8 &amp;&amp; internalformat == GraphicsContext3D::DEPTH24_STENCIL8)
-            break;
-        if (type == GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV &amp;&amp; internalformat == GraphicsContext3D::DEPTH32F_STENCIL8)
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid format, internalformat, and type combination&quot;);
-        return false;
-    case GraphicsContext3D::ALPHA:
-    case GraphicsContext3D::LUMINANCE:
-    case GraphicsContext3D::LUMINANCE_ALPHA:
-        if ((type == GraphicsContext3D::UNSIGNED_BYTE || type == GraphicsContext3D::HALF_FLOAT_OES || type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::FLOAT) &amp;&amp; internalformat == format)
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid format, internalformat, and type combination&quot;);
-        return false;
-    default:
-        ASSERT_NOT_REACHED();
-    }
-
-    return true;
-}
-
-bool WebGL2RenderingContext::validateTexFuncData(const char* functionName, GC3Dint level,
-    GC3Dsizei width, GC3Dsizei height,
-    GC3Denum internalformat, GC3Denum format, GC3Denum type,
-    ArrayBufferView* pixels,
-    NullDisposition disposition)
-{
-    if (!pixels) {
-        if (disposition == NullAllowed)
-            return true;
-        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;no pixels&quot;);
-        return false;
-    }
-
-    if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level))
-        return false;
-    if (!validateSettableTexFormat(functionName, format))
-        return false;
-    
-    switch (type) {
-    case GraphicsContext3D::BYTE:
-        if (pixels-&gt;getType() != JSC::TypeInt8) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;type BYTE but ArrayBufferView not Int8Array&quot;);
-            return false;
-        }
-        break;
-    case GraphicsContext3D::UNSIGNED_BYTE:
-        if (pixels-&gt;getType() != JSC::TypeUint8) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;type UNSIGNED_BYTE but ArrayBufferView not Uint8Array&quot;);
-            return false;
-        }
-        break;
-    case GraphicsContext3D::SHORT:
-        if (pixels-&gt;getType() != JSC::TypeInt16) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;type SHORT but ArrayBufferView not Int16Array&quot;);
-            return false;
-        }
-        break;
-    case GraphicsContext3D::UNSIGNED_SHORT:
-    case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
-    case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
-    case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
-        if (pixels-&gt;getType() != JSC::TypeUint16) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;type UNSIGNED_SHORT but ArrayBufferView not Uint16Array&quot;);
-            return false;
-        }
-        break;
-    case GraphicsContext3D::INT:
-        if (pixels-&gt;getType() != JSC::TypeInt32) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;type INT but ArrayBufferView not Int32Array&quot;);
-            return false;
-        }
-        break;
-    case GraphicsContext3D::UNSIGNED_INT:
-    case GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV:
-    case GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV:
-        if (pixels-&gt;getType() != JSC::TypeUint32) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;type UNSIGNED_INT but ArrayBufferView not Uint32Array&quot;);
-            return false;
-        }
-        break;
-    case GraphicsContext3D::HALF_FLOAT:
-    case GraphicsContext3D::FLOAT:
-        if (pixels-&gt;getType() != JSC::TypeFloat32) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;type FLOAT but ArrayBufferView not Float32Array&quot;);
-            return false;
-        }
-        break;
-    case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float
-        // As per the specification, ArrayBufferView should be null when
-        // OES_texture_half_float is enabled.
-        if (pixels) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;type HALF_FLOAT_OES but ArrayBufferView is not NULL&quot;);
-            return false;
-        }
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-    }
-    
-    unsigned totalBytesRequired;
-    GC3Denum error = m_context-&gt;computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &amp;totalBytesRequired, 0);
-    if (error != GraphicsContext3D::NO_ERROR) {
-        synthesizeGLError(error, functionName, &quot;invalid texture dimensions&quot;);
-        return false;
-    }
-    if (pixels-&gt;byteLength() &lt; totalBytesRequired) {
-        if (m_unpackAlignment != 1) {
-            m_context-&gt;computeImageSizeInBytes(format, type, width, height, 1, &amp;totalBytesRequired, 0);
-            if (pixels-&gt;byteLength() == totalBytesRequired) {
-                synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;ArrayBufferView not big enough for request with UNPACK_ALIGNMENT &gt; 1&quot;);
-                return false;
-            }
-        }
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;ArrayBufferView not big enough for request&quot;);
-        return false;
-    }
-    return true;
-}
-
</del><span class="cx"> GC3Denum WebGL2RenderingContext::baseInternalFormatFromInternalFormat(GC3Denum internalformat)
</span><span class="cx"> {
</span><span class="cx">     // Handles sized, unsized, and compressed internal formats.
</span><span class="lines">@@ -1965,6 +1240,8 @@
</span><span class="cx"> 
</span><span class="cx"> bool WebGL2RenderingContext::isIntegerFormat(GC3Denum internalformat)
</span><span class="cx"> {
</span><ins>+    // FIXME: baseInternalFormatFromInternalFormat() never returns any of these enums.
+    // Currently, This function erroneously always returns false.
</ins><span class="cx">     switch (baseInternalFormatFromInternalFormat(internalformat)) {
</span><span class="cx">     case GraphicsContext3D::RED_INTEGER:
</span><span class="cx">     case GraphicsContext3D::RG_INTEGER:
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGL2RenderingContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h (208723 => 208724)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h        2016-11-15 02:20:54 UTC (rev 208723)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h        2016-11-15 02:42:32 UTC (rev 208724)
</span><span class="lines">@@ -179,11 +179,6 @@
</span><span class="cx"> 
</span><span class="cx">     void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height) final;
</span><span class="cx">     void hint(GC3Denum target, GC3Denum mode) final;
</span><del>-    void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) final;
-    void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels) final;
-    void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha) final;
-    void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, RefPtr&lt;ArrayBufferView&gt;&amp;&amp;) final;
-    ExceptionOr&lt;void&gt; texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Optional&lt;TexImageSource&gt;&amp;&amp;) final;
</del><span class="cx"> 
</span><span class="cx">     void initializeVertexArrayObjects() final;
</span><span class="cx">     GC3Dint getMaxDrawBuffers() final;
</span><span class="lines">@@ -190,18 +185,6 @@
</span><span class="cx">     GC3Dint getMaxColorAttachments() final;
</span><span class="cx">     bool validateIndexArrayConservative(GC3Denum type, unsigned&amp; numElementsRequired) final;
</span><span class="cx">     bool validateBlendEquation(const char* functionName, GC3Denum mode) final;
</span><del>-    bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) final;
-    bool validateTexFuncParameters(const char* functionName,
-        TexFuncValidationFunctionType,
-        GC3Denum target, GC3Dint level,
-        GC3Denum internalformat,
-        GC3Dsizei width, GC3Dsizei height, GC3Dint border,
-        GC3Denum format, GC3Denum type) final;
-    bool validateTexFuncData(const char* functionName, GC3Dint level,
-        GC3Dsizei width, GC3Dsizei height,
-        GC3Denum internalformat, GC3Denum format, GC3Denum type,
-        ArrayBufferView* pixels,
-        NullDisposition) final;
</del><span class="cx">     bool validateCapability(const char* functionName, GC3Denum cap) final;
</span><span class="cx">     bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment) final;
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp (208723 => 208724)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp        2016-11-15 02:20:54 UTC (rev 208723)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp        2016-11-15 02:42:32 UTC (rev 208724)
</span><span class="lines">@@ -465,457 +465,6 @@
</span><span class="cx">     markContextChanged();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
-{
-    if (isContextLostOrPending())
-        return;
-    if (!validateTexFuncParameters(&quot;copyTexImage2D&quot;, CopyTexImage, target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE))
-        return;
-    if (!validateSettableTexFormat(&quot;copyTexImage2D&quot;, internalformat))
-        return;
-    WebGLTexture* tex = validateTextureBinding(&quot;copyTexImage2D&quot;, target, true);
-    if (!tex)
-        return;
-    if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, &quot;copyTexImage2D&quot;, &quot;framebuffer is incompatible format&quot;);
-        return;
-    }
-    if (!isGLES2NPOTStrict() &amp;&amp; level &amp;&amp; WebGLTexture::isNPOT(width, height)) {
-        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;copyTexImage2D&quot;, &quot;level &gt; 0 not power of 2&quot;);
-        return;
-    }
-    const char* reason = &quot;framebuffer incomplete&quot;;
-    if (m_framebufferBinding &amp;&amp; !m_framebufferBinding-&gt;onAccess(graphicsContext3D(), !isResourceSafe(), &amp;reason)) {
-        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, &quot;copyTexImage2D&quot;, reason);
-        return;
-    }
-    clearIfComposited();
-    if (isResourceSafe())
-        m_context-&gt;copyTexImage2D(target, level, internalformat, x, y, width, height, border);
-    else {
-        GC3Dint clippedX, clippedY;
-        GC3Dsizei clippedWidth, clippedHeight;
-        if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &amp;clippedX, &amp;clippedY, &amp;clippedWidth, &amp;clippedHeight)) {
-            m_context-&gt;texImage2DResourceSafe(target, level, internalformat, width, height, border,
-                internalformat, GraphicsContext3D::UNSIGNED_BYTE, m_unpackAlignment);
-            if (clippedWidth &gt; 0 &amp;&amp; clippedHeight &gt; 0) {
-                m_context-&gt;copyTexSubImage2D(target, level, clippedX - x, clippedY - y,
-                    clippedX, clippedY, clippedWidth, clippedHeight);
-            }
-        } else
-            m_context-&gt;copyTexImage2D(target, level, internalformat, x, y, width, height, border);
-    }
-    // FIXME: if the framebuffer is not complete, none of the below should be executed.
-    tex-&gt;setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
-}
-
-void WebGLRenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels)
-{
-    UNUSED_PARAM(internalformat);
-    ASSERT(!isContextLost());
-    ASSERT(validateTexFuncParameters(&quot;texSubImage2D&quot;, TexSubImage, target, level, format, width, height, 0, format, type));
-    ASSERT(validateSize(&quot;texSubImage2D&quot;, xoffset, yoffset));
-    ASSERT(validateSettableTexFormat(&quot;texSubImage2D&quot;, format));
-    WebGLTexture* tex = validateTextureBinding(&quot;texSubImage2D&quot;, target, true);
-    if (!tex) {
-        ASSERT_NOT_REACHED();
-        return;
-    }
-    ASSERT((xoffset + width) &gt;= 0);
-    ASSERT((yoffset + height) &gt;= 0);
-    ASSERT(tex-&gt;getWidth(target, level) &gt;= (xoffset + width));
-    ASSERT(tex-&gt;getHeight(target, level) &gt;= (yoffset + height));
-    ASSERT(tex-&gt;getInternalFormat(target, level) == format);
-    ASSERT(tex-&gt;getType(target, level) == type);
-    m_context-&gt;texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
-}
-
-void WebGLRenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha)
-{
-    Vector&lt;uint8_t&gt; data;
-    GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
-    if (!imageExtractor.extractSucceeded()) {
-        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texSubImage2D&quot;, &quot;bad image&quot;);
-        return;
-    }
-    GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
-    GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
-    const void* imagePixelData = imageExtractor.imagePixelData();
-    
-    bool needConversion = true;
-    if (type == GraphicsContext3D::UNSIGNED_BYTE &amp;&amp; sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 &amp;&amp; format == GraphicsContext3D::RGBA &amp;&amp; alphaOp == GraphicsContext3D::AlphaDoNothing &amp;&amp; !flipY)
-        needConversion = false;
-    else {
-        if (!m_context-&gt;packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
-            synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texImage2D&quot;, &quot;bad image data&quot;);
-            return;
-        }
-    }
-    
-    if (m_unpackAlignment != 1)
-        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
-
-    texSubImage2DBase(target, level, xoffset, yoffset, image-&gt;width(), image-&gt;height(), format, format, type, needConversion ? data.data() : imagePixelData);
-    if (m_unpackAlignment != 1)
-        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, RefPtr&lt;ArrayBufferView&gt;&amp;&amp; pixels)
-{
-    if (isContextLostOrPending() || !validateTexFuncData(&quot;texSubImage2D&quot;, level, width, height, format, format, type, pixels.get(), NullNotAllowed) || !validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage, SourceArrayBufferView, target, level, format, width, height, 0, format, type, xoffset, yoffset))
-        return;
-    
-    void* data = pixels-&gt;baseAddress();
-    Vector&lt;uint8_t&gt; tempData;
-    bool changeUnpackAlignment = false;
-    if (data &amp;&amp; (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
-        if (!m_context-&gt;extractTextureData(width, height, format, type,
-            m_unpackAlignment,
-            m_unpackFlipY, m_unpackPremultiplyAlpha,
-            data,
-            tempData))
-            return;
-        data = tempData.data();
-        changeUnpackAlignment = true;
-    }
-    if (changeUnpackAlignment)
-        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
-
-    texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, format, type, data);
-    if (changeUnpackAlignment)
-        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-ExceptionOr&lt;void&gt; WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Optional&lt;TexImageSource&gt;&amp;&amp; source)
-{
-    if (!source) {
-        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texSubImage2D&quot;, &quot;source is null&quot;);
-        return { };
-    }
-
-    auto visitor = WTF::makeVisitor([&amp;](const RefPtr&lt;ImageData&gt;&amp; pixels) -&gt; ExceptionOr&lt;void&gt; {
-        if (isContextLostOrPending() || !validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage, SourceImageData, target, level, format,  pixels-&gt;width(), pixels-&gt;height(), 0, format, type, xoffset, yoffset))
-            return { };
-
-        Vector&lt;uint8_t&gt; data;
-        bool needConversion = true;
-        // The data from ImageData is always of format RGBA8.
-        // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
-        if (format == GraphicsContext3D::RGBA &amp;&amp; type == GraphicsContext3D::UNSIGNED_BYTE &amp;&amp; !m_unpackFlipY &amp;&amp; !m_unpackPremultiplyAlpha)
-            needConversion = false;
-        else {
-            if (!m_context-&gt;extractImageData(pixels.get(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
-                synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texSubImage2D&quot;, &quot;bad image data&quot;);
-                return { };
-            }
-        }
-        if (m_unpackAlignment != 1)
-            m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
-
-        texSubImage2DBase(target, level, xoffset, yoffset, pixels-&gt;width(), pixels-&gt;height(), format, format, type, needConversion ? data.data() : pixels-&gt;data()-&gt;data());
-        if (m_unpackAlignment != 1)
-            m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-
-        return { };
-    } , [&amp;](const RefPtr&lt;HTMLImageElement&gt;&amp; image) -&gt; ExceptionOr&lt;void&gt; {
-        if (wouldTaintOrigin(image.get()))
-            return Exception { SECURITY_ERR };
-        if (isContextLostOrPending() || !validateHTMLImageElement(&quot;texSubImage2D&quot;, image.get()))
-            return { };
-
-        RefPtr&lt;Image&gt; imageForRender = image-&gt;cachedImage()-&gt;imageForRenderer(image-&gt;renderer());
-        if (!imageForRender)
-            return { };
-
-        if (imageForRender-&gt;isSVGImage())
-            imageForRender = drawImageIntoBuffer(*imageForRender, image-&gt;width(), image-&gt;height(), 1);
-
-        if (!imageForRender || !validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage, SourceHTMLImageElement, target, level, format, imageForRender-&gt;width(), imageForRender-&gt;height(), 0, format, type, xoffset, yoffset))
-            return { };
-
-        texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha);
-        return { };
-    }, [&amp;](const RefPtr&lt;HTMLCanvasElement&gt;&amp; canvas) -&gt; ExceptionOr&lt;void&gt; {
-        if (wouldTaintOrigin(canvas.get()))
-            return Exception { SECURITY_ERR };
-        if (isContextLostOrPending() || !validateHTMLCanvasElement(&quot;texSubImage2D&quot;, canvas.get())
-            || !validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage, SourceHTMLCanvasElement, target, level, format, canvas-&gt;width(), canvas-&gt;height(), 0, format, type, xoffset, yoffset))
-            return { };
-
-        RefPtr&lt;ImageData&gt; imageData = canvas-&gt;getImageData();
-        if (imageData)
-            texSubImage2D(target, level, xoffset, yoffset, format, type, TexImageSource(imageData.get()));
-        else
-            texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas-&gt;copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha);
-        return { };
-    }, [&amp;](const RefPtr&lt;HTMLVideoElement&gt;&amp; video) -&gt; ExceptionOr&lt;void&gt; {
-        if (wouldTaintOrigin(video.get()))
-            return Exception { SECURITY_ERR };
-        if (isContextLostOrPending() || !validateHTMLVideoElement(&quot;texSubImage2D&quot;, video.get())
-            || !validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage, SourceHTMLVideoElement, target, level, format, video-&gt;videoWidth(), video-&gt;videoHeight(), 0, format, type, xoffset, yoffset))
-            return { };
-
-        RefPtr&lt;Image&gt; image = videoFrameToImage(video.get(), ImageBuffer::fastCopyImageMode());
-        if (!image)
-            return { };
-        texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha);
-        return { };
-    });
-
-    return WTF::visit(visitor, source.value());
-}
-
-bool WebGLRenderingContext::validateTexFuncParameters(const char* functionName,
-    TexFuncValidationFunctionType functionType,
-    GC3Denum target, GC3Dint level,
-    GC3Denum internalformat,
-    GC3Dsizei width, GC3Dsizei height, GC3Dint border,
-    GC3Denum format, GC3Denum type)
-{
-    // We absolutely have to validate the format and type combination.
-    // The texImage2D entry points taking HTMLImage, etc. will produce
-    // temporary data based on this combination, so it must be legal.
-    if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level) || !validateTexFuncLevel(functionName, target, level))
-        return false;
-    
-    if (width &lt; 0 || height &lt; 0) {
-        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;width or height &lt; 0&quot;);
-        return false;
-    }
-    
-    GC3Dint maxTextureSizeForLevel = pow(2.0, m_maxTextureLevel - 1 - level);
-    switch (target) {
-    case GraphicsContext3D::TEXTURE_2D:
-        if (width &gt; maxTextureSizeForLevel || height &gt; maxTextureSizeForLevel) {
-            synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;width or height out of range&quot;);
-            return false;
-        }
-        break;
-    case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
-    case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
-    case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
-    case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
-    case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
-    case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
-        if (functionType != TexSubImage &amp;&amp; width != height) {
-            synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;width != height for cube map&quot;);
-            return false;
-        }
-        // No need to check height here. For texImage width == height.
-        // For texSubImage that will be checked when checking yoffset + height is in range.
-        if (width &gt; maxTextureSizeForLevel) {
-            synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;width or height out of range for cube map&quot;);
-            return false;
-        }
-        break;
-    default:
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid target&quot;);
-        return false;
-    }
-
-    if (format != internalformat) {
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;format != internalformat&quot;);
-        return false;
-    }
-    
-    if (border) {
-        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;border != 0&quot;);
-        return false;
-    }
-    
-    return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level)
-{
-    UNUSED_PARAM(internalformat);
-    switch (format) {
-    case GraphicsContext3D::ALPHA:
-    case GraphicsContext3D::LUMINANCE:
-    case GraphicsContext3D::LUMINANCE_ALPHA:
-    case GraphicsContext3D::RGB:
-    case GraphicsContext3D::RGBA:
-        break;
-    case GraphicsContext3D::DEPTH_STENCIL:
-    case GraphicsContext3D::DEPTH_COMPONENT:
-        if (m_webglDepthTexture)
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;depth texture formats not enabled&quot;);
-        return false;
-    case Extensions3D::SRGB_EXT:
-    case Extensions3D::SRGB_ALPHA_EXT:
-    default:
-        if ((format == Extensions3D::SRGB_EXT || format == Extensions3D::SRGB_ALPHA_EXT)
-            &amp;&amp; m_extsRGB)
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture format&quot;);
-        return false;
-    }
-    
-    switch (type) {
-    case GraphicsContext3D::UNSIGNED_BYTE:
-    case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
-    case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
-    case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
-        break;
-    case GraphicsContext3D::FLOAT:
-        if (m_oesTextureFloat)
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture type&quot;);
-        return false;
-    case GraphicsContext3D::HALF_FLOAT_OES:
-        if (m_oesTextureHalfFloat)
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture type&quot;);
-        return false;
-    case GraphicsContext3D::UNSIGNED_INT:
-    case GraphicsContext3D::UNSIGNED_INT_24_8:
-    case GraphicsContext3D::UNSIGNED_SHORT:
-        if (m_webglDepthTexture)
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture type&quot;);
-        return false;
-    default:
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture type&quot;);
-        return false;
-    }
-    
-    // Verify that the combination of format and type is supported.
-    switch (format) {
-    case GraphicsContext3D::ALPHA:
-    case GraphicsContext3D::LUMINANCE:
-    case GraphicsContext3D::LUMINANCE_ALPHA:
-        if (type != GraphicsContext3D::UNSIGNED_BYTE
-            &amp;&amp; type != GraphicsContext3D::FLOAT
-            &amp;&amp; type != GraphicsContext3D::HALF_FLOAT_OES) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid type for format&quot;);
-            return false;
-        }
-        break;
-    case GraphicsContext3D::RGB:
-    case Extensions3D::SRGB_EXT:
-        if (type != GraphicsContext3D::UNSIGNED_BYTE
-            &amp;&amp; type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5
-            &amp;&amp; type != GraphicsContext3D::FLOAT
-            &amp;&amp; type != GraphicsContext3D::HALF_FLOAT_OES) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid type for RGB format&quot;);
-            return false;
-        }
-        break;
-    case GraphicsContext3D::RGBA:
-    case Extensions3D::SRGB_ALPHA_EXT:
-        if (type != GraphicsContext3D::UNSIGNED_BYTE
-            &amp;&amp; type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4
-            &amp;&amp; type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1
-            &amp;&amp; type != GraphicsContext3D::FLOAT
-            &amp;&amp; type != GraphicsContext3D::HALF_FLOAT_OES) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid type for RGBA format&quot;);
-            return false;
-        }
-        break;
-    case GraphicsContext3D::DEPTH_COMPONENT:
-        if (!m_webglDepthTexture) {
-            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid format. DEPTH_COMPONENT not enabled&quot;);
-            return false;
-        }
-        if (type != GraphicsContext3D::UNSIGNED_SHORT
-            &amp;&amp; type != GraphicsContext3D::UNSIGNED_INT) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid type for DEPTH_COMPONENT format&quot;);
-            return false;
-        }
-        if (level &gt; 0) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;level must be 0 for DEPTH_COMPONENT format&quot;);
-            return false;
-        }
-        break;
-    case GraphicsContext3D::DEPTH_STENCIL:
-        if (!m_webglDepthTexture) {
-            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid format. DEPTH_STENCIL not enabled&quot;);
-            return false;
-        }
-        if (type != GraphicsContext3D::UNSIGNED_INT_24_8) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid type for DEPTH_STENCIL format&quot;);
-            return false;
-        }
-        if (level &gt; 0) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;level must be 0 for DEPTH_STENCIL format&quot;);
-            return false;
-        }
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-    }
-    
-    return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncData(const char* functionName, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, NullDisposition disposition)
-{
-    if (!pixels) {
-        if (disposition == NullAllowed)
-            return true;
-        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;no pixels&quot;);
-        return false;
-    }
-
-    if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level))
-        return false;
-    if (!validateSettableTexFormat(functionName, format))
-        return false;
-    
-    switch (type) {
-    case GraphicsContext3D::UNSIGNED_BYTE:
-        if (pixels-&gt;getType() != JSC::TypeUint8) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;type UNSIGNED_BYTE but ArrayBufferView not Uint8Array&quot;);
-            return false;
-        }
-        break;
-    case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
-    case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
-    case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
-        if (pixels-&gt;getType() != JSC::TypeUint16) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;type UNSIGNED_SHORT but ArrayBufferView not Uint16Array&quot;);
-            return false;
-        }
-        break;
-    case GraphicsContext3D::FLOAT: // OES_texture_float
-        if (pixels-&gt;getType() != JSC::TypeFloat32) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;type FLOAT but ArrayBufferView not Float32Array&quot;);
-            return false;
-        }
-        break;
-    case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float
-        // As per the specification, ArrayBufferView should be null when
-        // OES_texture_half_float is enabled.
-        if (pixels) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;type HALF_FLOAT_OES but ArrayBufferView is not NULL&quot;);
-            return false;
-        }
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-    }
-    
-    unsigned totalBytesRequired;
-    GC3Denum error = m_context-&gt;computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &amp;totalBytesRequired, 0);
-    if (error != GraphicsContext3D::NO_ERROR) {
-        synthesizeGLError(error, functionName, &quot;invalid texture dimensions&quot;);
-        return false;
-    }
-    if (pixels-&gt;byteLength() &lt; totalBytesRequired) {
-        if (m_unpackAlignment != 1) {
-            m_context-&gt;computeImageSizeInBytes(format, type, width, height, 1, &amp;totalBytesRequired, 0);
-            if (pixels-&gt;byteLength() == totalBytesRequired) {
-                synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;ArrayBufferView not big enough for request with UNPACK_ALIGNMENT &gt; 1&quot;);
-                return false;
-            }
-        }
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;ArrayBufferView not big enough for request&quot;);
-        return false;
-    }
-    return true;
-}
-
</del><span class="cx"> WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname)
</span><span class="cx"> {
</span><span class="cx">     if (isContextLostOrPending())
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h (208723 => 208724)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h        2016-11-15 02:20:54 UTC (rev 208723)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h        2016-11-15 02:42:32 UTC (rev 208724)
</span><span class="lines">@@ -46,11 +46,6 @@
</span><span class="cx">     bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment) final;
</span><span class="cx">     void hint(GC3Denum target, GC3Denum mode) final;
</span><span class="cx">     void clear(GC3Dbitfield mask) final;
</span><del>-    void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) final;
-    void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels) final;
-    void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha) final;
-    void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, RefPtr&lt;ArrayBufferView&gt;&amp;&amp;) final;
-    ExceptionOr&lt;void&gt; texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Optional&lt;TexImageSource&gt;&amp;&amp;) final;
</del><span class="cx"> 
</span><span class="cx">     GC3Dint getMaxDrawBuffers() final;
</span><span class="cx">     GC3Dint getMaxColorAttachments() final;
</span><span class="lines">@@ -57,9 +52,6 @@
</span><span class="cx">     void initializeVertexArrayObjects() final;
</span><span class="cx">     bool validateIndexArrayConservative(GC3Denum type, unsigned&amp; numElementsRequired) final;
</span><span class="cx">     bool validateBlendEquation(const char* functionName, GC3Denum mode) final;
</span><del>-    bool validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type) final;
-    bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) final;
-    bool validateTexFuncData(const char* functionName, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, NullDisposition) final;
</del><span class="cx">     bool validateCapability(const char* functionName, GC3Denum cap) final;
</span><span class="cx"> };
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContextBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (208723 => 208724)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp        2016-11-15 02:20:54 UTC (rev 208723)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp        2016-11-15 02:42:32 UTC (rev 208724)
</span><span class="lines">@@ -1309,13 +1309,22 @@
</span><span class="cx">     tex-&gt;setCompressed();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool WebGLRenderingContextBase::validateSettableTexFormat(const char* functionName, GC3Denum format)
</del><ins>+bool WebGLRenderingContextBase::validateSettableTexInternalFormat(const char* functionName, GC3Denum internalFormat)
</ins><span class="cx"> {
</span><del>-    if (GraphicsContext3D::getClearBitsByFormat(format) &amp; (GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
</del><ins>+    switch (internalFormat) {
+    case GraphicsContext3D::DEPTH_COMPONENT:
+    case GraphicsContext3D::DEPTH_STENCIL:
+    case GraphicsContext3D::DEPTH_COMPONENT16:
+    case GraphicsContext3D::DEPTH_COMPONENT24:
+    case GraphicsContext3D::DEPTH_COMPONENT32F:
+    case GraphicsContext3D::DEPTH24_STENCIL8:
+    case GraphicsContext3D::DEPTH32F_STENCIL8:
+    case GraphicsContext3D::STENCIL_INDEX8:
</ins><span class="cx">         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;format can not be set, only rendered to&quot;);
</span><span class="cx">         return false;
</span><ins>+    default:
+        return true;
</ins><span class="cx">     }
</span><del>-    return true;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebGLRenderingContextBase::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
</span><span class="lines">@@ -1338,10 +1347,10 @@
</span><span class="cx">         synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;copyTexSubImage2D&quot;, &quot;rectangle out of range&quot;);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><del>-    GC3Denum internalformat = tex-&gt;getInternalFormat(target, level);
-    if (!validateSettableTexFormat(&quot;copyTexSubImage2D&quot;, internalformat))
</del><ins>+    GC3Denum internalFormat = tex-&gt;getInternalFormat(target, level);
+    if (!validateSettableTexInternalFormat(&quot;copyTexSubImage2D&quot;, internalFormat))
</ins><span class="cx">         return;
</span><del>-    if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
</del><ins>+    if (!isTexInternalFormatColorBufferCombinationValid(internalFormat, getBoundFramebufferColorFormat())) {
</ins><span class="cx">         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, &quot;copyTexSubImage2D&quot;, &quot;framebuffer is incompatible format&quot;);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="lines">@@ -1357,8 +1366,12 @@
</span><span class="cx">         GC3Dint clippedX, clippedY;
</span><span class="cx">         GC3Dsizei clippedWidth, clippedHeight;
</span><span class="cx">         if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &amp;clippedX, &amp;clippedY, &amp;clippedWidth, &amp;clippedHeight)) {
</span><del>-            GC3Denum format = tex-&gt;getInternalFormat(target, level);
-            GC3Denum type = tex-&gt;getType(target, level);
</del><ins>+            GC3Denum format;
+            GC3Denum type;
+            if (!GraphicsContext3D::possibleFormatAndTypeForInternalFormat(tex-&gt;getInternalFormat(target, level), format, type)) {
+                synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;copyTexSubImage2D&quot;, &quot;Texture has unknown internal format&quot;);
+                return;
+            }
</ins><span class="cx">             std::unique_ptr&lt;unsigned char[]&gt; zero;
</span><span class="cx">             if (width &amp;&amp; height) {
</span><span class="cx">                 unsigned int size;
</span><span class="lines">@@ -2108,7 +2121,7 @@
</span><span class="cx">         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, &quot;generateMipmap&quot;, &quot;trying to generate mipmaps from compressed texture&quot;);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><del>-    if (!validateSettableTexFormat(&quot;generateMipmap&quot;, tex-&gt;getInternalFormat(target, 0)))
</del><ins>+    if (!validateSettableTexInternalFormat(&quot;generateMipmap&quot;, tex-&gt;getInternalFormat(target, 0)))
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     // generateMipmap won't work properly if minFilter is not NEAREST_MIPMAP_LINEAR
</span><span class="lines">@@ -2819,47 +2832,305 @@
</span><span class="cx">     m_context-&gt;polygonOffset(factor, units);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebGLRenderingContextBase::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView&amp; pixels)
</del><ins>+enum class InternalFormatTheme {
+    None,
+    NormalizedFixedPoint,
+    Packed,
+    SignedNormalizedFixedPoint,
+    FloatingPoint,
+    SignedInteger,
+    UnsignedInteger
+};
+
+static InternalFormatTheme internalFormatTheme(GC3Denum internalFormat)
</ins><span class="cx"> {
</span><del>-    if (isContextLostOrPending())
-        return;
-    // Due to WebGL's same-origin restrictions, it is not possible to
-    // taint the origin using the WebGL API.
-    ASSERT(canvas().originClean());
-    // Validate input parameters.
</del><ins>+    switch (internalFormat) {
+    case GraphicsContext3D::RGB:
+    case GraphicsContext3D::RGBA:
+    case GraphicsContext3D::LUMINANCE_ALPHA:
+    case GraphicsContext3D::LUMINANCE:
+    case GraphicsContext3D::ALPHA:
+    case GraphicsContext3D::R8:
+    case GraphicsContext3D::RG8:
+    case GraphicsContext3D::RGB8:
+    case GraphicsContext3D::SRGB8:
+    case GraphicsContext3D::RGBA8:
+    case GraphicsContext3D::SRGB8_ALPHA8:
+    case GraphicsContext3D::SRGB_ALPHA:
+        return InternalFormatTheme::NormalizedFixedPoint;
+    case GraphicsContext3D::RGB565:
+    case GraphicsContext3D::RGB5_A1:
+    case GraphicsContext3D::RGBA4:
+    case GraphicsContext3D::RGB9_E5:
+    case GraphicsContext3D::RGB10_A2:
+    case GraphicsContext3D::R11F_G11F_B10F:
+    case GraphicsContext3D::RGB10_A2UI:
+        return InternalFormatTheme::Packed;
+    case GraphicsContext3D::R8_SNORM:
+    case GraphicsContext3D::RG8_SNORM:
+    case GraphicsContext3D::RGB8_SNORM:
+    case GraphicsContext3D::RGBA8_SNORM:
+        return InternalFormatTheme::SignedNormalizedFixedPoint;
+    case GraphicsContext3D::R16F:
+    case GraphicsContext3D::R32F:
+    case GraphicsContext3D::RG16F:
+    case GraphicsContext3D::RG32F:
+    case GraphicsContext3D::RGB16F:
+    case GraphicsContext3D::RGB32F:
+    case GraphicsContext3D::RGBA16F:
+    case GraphicsContext3D::RGBA32F:
+        return InternalFormatTheme::FloatingPoint;
+    case GraphicsContext3D::R8I:
+    case GraphicsContext3D::R16I:
+    case GraphicsContext3D::R32I:
+    case GraphicsContext3D::RG8I:
+    case GraphicsContext3D::RG16I:
+    case GraphicsContext3D::RG32I:
+    case GraphicsContext3D::RGB8I:
+    case GraphicsContext3D::RGB16I:
+    case GraphicsContext3D::RGB32I:
+    case GraphicsContext3D::RGBA8I:
+    case GraphicsContext3D::RGBA16I:
+    case GraphicsContext3D::RGBA32I:
+        return InternalFormatTheme::SignedInteger;
+    case GraphicsContext3D::R8UI:
+    case GraphicsContext3D::R16UI:
+    case GraphicsContext3D::R32UI:
+    case GraphicsContext3D::RG8UI:
+    case GraphicsContext3D::RG16UI:
+    case GraphicsContext3D::RG32UI:
+    case GraphicsContext3D::RGB8UI:
+    case GraphicsContext3D::RGB16UI:
+    case GraphicsContext3D::RGB32UI:
+    case GraphicsContext3D::RGBA8UI:
+    case GraphicsContext3D::RGBA16UI:
+    case GraphicsContext3D::RGBA32UI:
+        return InternalFormatTheme::UnsignedInteger;
+    default:
+        return InternalFormatTheme::None;
+    }
+}
+
+static int numberOfComponentsForFormat(GC3Denum format)
+{
</ins><span class="cx">     switch (format) {
</span><del>-    case GraphicsContext3D::ALPHA:
</del><ins>+    case GraphicsContext3D::RED:
+    case GraphicsContext3D::RED_INTEGER:
+        return 1;
+    case GraphicsContext3D::RG:
+    case GraphicsContext3D::RG_INTEGER:
+        return 2;
</ins><span class="cx">     case GraphicsContext3D::RGB:
</span><ins>+    case GraphicsContext3D::RGB_INTEGER:
+        return 3;
</ins><span class="cx">     case GraphicsContext3D::RGBA:
</span><del>-        break;
</del><ins>+    case GraphicsContext3D::RGBA_INTEGER:
+        return 4;
</ins><span class="cx">     default:
</span><del>-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;readPixels&quot;, &quot;invalid format&quot;);
-        return;
</del><ins>+        return 0;
</ins><span class="cx">     }
</span><del>-    switch (type) {
-    case GraphicsContext3D::UNSIGNED_BYTE:
-    case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
-    case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
-    case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
-        break;
</del><ins>+}
+
+static int numberOfComponentsForInternalFormat(GC3Denum internalFormat)
+{
+    switch (internalFormat) {
+    case GraphicsContext3D::LUMINANCE:
+    case GraphicsContext3D::ALPHA:
+    case GraphicsContext3D::R8:
+    case GraphicsContext3D::R8_SNORM:
+    case GraphicsContext3D::R16F:
+    case GraphicsContext3D::R32F:
+    case GraphicsContext3D::R8UI:
+    case GraphicsContext3D::R8I:
+    case GraphicsContext3D::R16UI:
+    case GraphicsContext3D::R16I:
+    case GraphicsContext3D::R32UI:
+    case GraphicsContext3D::R32I:
+    case GraphicsContext3D::DEPTH_COMPONENT16:
+    case GraphicsContext3D::DEPTH_COMPONENT24:
+    case GraphicsContext3D::DEPTH_COMPONENT32F:
+        return 1;
+    case GraphicsContext3D::RG8:
+    case GraphicsContext3D::LUMINANCE_ALPHA:
+    case GraphicsContext3D::RG8_SNORM:
+    case GraphicsContext3D::RG16F:
+    case GraphicsContext3D::RG32F:
+    case GraphicsContext3D::RG8UI:
+    case GraphicsContext3D::RG8I:
+    case GraphicsContext3D::RG16UI:
+    case GraphicsContext3D::RG16I:
+    case GraphicsContext3D::RG32UI:
+    case GraphicsContext3D::RG32I:
+    case GraphicsContext3D::DEPTH24_STENCIL8:
+    case GraphicsContext3D::DEPTH32F_STENCIL8:
+        return 2;
+    case GraphicsContext3D::RGB:
+    case GraphicsContext3D::RGB8:
+    case GraphicsContext3D::SRGB8:
+    case GraphicsContext3D::RGB565:
+    case GraphicsContext3D::RGB8_SNORM:
+    case GraphicsContext3D::R11F_G11F_B10F:
+    case GraphicsContext3D::RGB9_E5:
+    case GraphicsContext3D::RGB16F:
+    case GraphicsContext3D::RGB32F:
+    case GraphicsContext3D::RGB8UI:
+    case GraphicsContext3D::RGB8I:
+    case GraphicsContext3D::RGB16UI:
+    case GraphicsContext3D::RGB16I:
+    case GraphicsContext3D::RGB32UI:
+    case GraphicsContext3D::RGB32I:
+        return 3;
+    case GraphicsContext3D::RGBA:
+    case GraphicsContext3D::RGBA8:
+    case GraphicsContext3D::SRGB_ALPHA:
+    case GraphicsContext3D::SRGB8_ALPHA8:
+    case GraphicsContext3D::RGBA8_SNORM:
+    case GraphicsContext3D::RGB5_A1:
+    case GraphicsContext3D::RGBA4:
+    case GraphicsContext3D::RGB10_A2:
+    case GraphicsContext3D::RGBA16F:
+    case GraphicsContext3D::RGBA32F:
+    case GraphicsContext3D::RGBA8UI:
+    case GraphicsContext3D::RGBA8I:
+    case GraphicsContext3D::RGB10_A2UI:
+    case GraphicsContext3D::RGBA16UI:
+    case GraphicsContext3D::RGBA16I:
+    case GraphicsContext3D::RGBA32UI:
+    case GraphicsContext3D::RGBA32I:
+        return 4;
</ins><span class="cx">     default:
</span><del>-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;readPixels&quot;, &quot;invalid type&quot;);
-        return;
</del><ins>+        return 0;
</ins><span class="cx">     }
</span><del>-    if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) {
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, &quot;readPixels&quot;, &quot;format not RGBA or type not UNSIGNED_BYTE&quot;);
</del><ins>+}
+
+void WebGLRenderingContextBase::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView&amp; pixels)
+{
+    if (isContextLostOrPending())
</ins><span class="cx">         return;
</span><ins>+    // Due to WebGL's same-origin restrictions, it is not possible to
+    // taint the origin using the WebGL API.
+    ASSERT(canvas().originClean());
+
+    GC3Denum internalFormat = 0;
+    if (m_framebufferBinding) {
+        const char* reason = &quot;framebuffer incomplete&quot;;
+        if (!m_framebufferBinding-&gt;onAccess(graphicsContext3D(), !isResourceSafe(), &amp;reason)) {
+            synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, &quot;readPixels&quot;, reason);
+            return;
+        }
+        // FIXME: readBuffer() should affect this
+        internalFormat = m_framebufferBinding-&gt;getColorBufferFormat();
+    } else {
+        if (m_attributes.alpha)
+            internalFormat = GraphicsContext3D::RGB8;
+        else
+            internalFormat = GraphicsContext3D::RGBA8;
</ins><span class="cx">     }
</span><del>-    // Validate array type against pixel type.
-    if (pixels.getType() != JSC::TypeUint8) {
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, &quot;readPixels&quot;, &quot;ArrayBufferView not Uint8Array&quot;);
</del><ins>+
+    if (!internalFormat) {
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;readPixels&quot;, &quot;Incorrect internal format&quot;);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><del>-    const char* reason = &quot;framebuffer incomplete&quot;;
-    if (m_framebufferBinding &amp;&amp; !m_framebufferBinding-&gt;onAccess(graphicsContext3D(), !isResourceSafe(), &amp;reason)) {
-        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, &quot;readPixels&quot;, reason);
</del><ins>+
+    if (isWebGL1()) {
+        switch (format) {
+        case GraphicsContext3D::ALPHA:
+        case GraphicsContext3D::RGB:
+        case GraphicsContext3D::RGBA:
+            break;
+        default:
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;readPixels&quot;, &quot;invalid format&quot;);
+            return;
+        }
+        switch (type) {
+        case GraphicsContext3D::UNSIGNED_BYTE:
+        case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
+        case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
+        case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
+            break;
+        default:
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;readPixels&quot;, &quot;invalid type&quot;);
+            return;
+        }
+        if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) {
+            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, &quot;readPixels&quot;, &quot;format not RGBA or type not UNSIGNED_BYTE&quot;);
+            return;
+        }
+    }
+
+    InternalFormatTheme internalFormatTheme = WebCore::internalFormatTheme(internalFormat);
+    int internalFormatComponentCount = numberOfComponentsForInternalFormat(internalFormat);
+    if (internalFormatTheme == InternalFormatTheme::None || !internalFormatComponentCount) {
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;readPixels&quot;, &quot;Incorrect internal format&quot;);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><ins>+
+#define INTERNAL_FORMAT_CHECK(themeMacro, typeMacro, pixelTypeMacro) case InternalFormatTheme::themeMacro: \
+        if (type != GraphicsContext3D::typeMacro || pixels.getType() != JSC::pixelTypeMacro) { \
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;readPixels&quot;, &quot;type does not match internal format&quot;); \
+            return; \
+        } \
+        if (format != GraphicsContext3D::RED &amp;&amp; format != GraphicsContext3D::RG &amp;&amp; format != GraphicsContext3D::RGB &amp;&amp; format != GraphicsContext3D::RGBA) { \
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;readPixels&quot;, &quot;Unknown format&quot;); \
+            return; \
+        } \
+        if (numberOfComponentsForFormat(format) &lt; internalFormatComponentCount) { \
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;readPixels&quot;, &quot;Not enough components in format&quot;); \
+            return; \
+        } \
+        break;
+
+#define INTERNAL_FORMAT_INTEGER_CHECK(themeMacro, typeMacro, pixelTypeMacro) case InternalFormatTheme::themeMacro: \
+        if (type != GraphicsContext3D::typeMacro || pixels.getType() != JSC::pixelTypeMacro) { \
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;readPixels&quot;, &quot;type does not match internal format&quot;); \
+            return; \
+        } \
+        if (format != GraphicsContext3D::RED_INTEGER &amp;&amp; format != GraphicsContext3D::RG_INTEGER &amp;&amp; format != GraphicsContext3D::RGB_INTEGER &amp;&amp; format != GraphicsContext3D::RGBA_INTEGER) { \
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;readPixels&quot;, &quot;Unknown format&quot;); \
+            return; \
+        } \
+        if (numberOfComponentsForFormat(format) &lt; internalFormatComponentCount) { \
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;readPixels&quot;, &quot;Not enough components in format&quot;); \
+            return; \
+        } \
+        break;
+
+#define PACKED_INTERNAL_FORMAT_CHECK(internalFormatMacro, formatMacro, type0Macro, pixelType0Macro, type1Macro, pixelType1Macro) case GraphicsContext3D::internalFormatMacro: \
+        if (!(type == GraphicsContext3D::type0Macro &amp;&amp; pixels.getType() == JSC::pixelType0Macro) \
+            &amp;&amp; !(type == GraphicsContext3D::type1Macro &amp;&amp; pixels.getType() == JSC::pixelType1Macro)) { \
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;readPixels&quot;, &quot;type does not match internal format&quot;); \
+            return; \
+        } \
+        if (format != GraphicsContext3D::formatMacro) { \
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;readPixels&quot;, &quot;Invalid format&quot;); \
+            return; \
+        } \
+        break;
+
+    switch (internalFormatTheme) {
+    INTERNAL_FORMAT_CHECK        (NormalizedFixedPoint      , UNSIGNED_BYTE, TypeUint8  );
+    INTERNAL_FORMAT_CHECK        (SignedNormalizedFixedPoint, BYTE         , TypeInt8   );
+    INTERNAL_FORMAT_CHECK        (FloatingPoint             , FLOAT        , TypeFloat32);
+    INTERNAL_FORMAT_INTEGER_CHECK(SignedInteger             , INT          , TypeInt32  );
+    INTERNAL_FORMAT_INTEGER_CHECK(UnsignedInteger           , UNSIGNED_INT , TypeUint32 );
+    case InternalFormatTheme::Packed:
+        switch (internalFormat) {
+        PACKED_INTERNAL_FORMAT_CHECK(RGB565        , RGB         , UNSIGNED_SHORT_5_6_5        , TypeUint16, UNSIGNED_BYTE              , TypeUint8  );
+        PACKED_INTERNAL_FORMAT_CHECK(RGB5_A1       , RGBA        , UNSIGNED_SHORT_5_5_5_1      , TypeUint16, UNSIGNED_BYTE              , TypeUint8  );
+        PACKED_INTERNAL_FORMAT_CHECK(RGBA4         , RGBA        , UNSIGNED_SHORT_4_4_4_4      , TypeUint16, UNSIGNED_BYTE              , TypeUint8  );
+        PACKED_INTERNAL_FORMAT_CHECK(RGB9_E5       , RGB         , UNSIGNED_INT_5_9_9_9_REV    , TypeUint32, UNSIGNED_INT_5_9_9_9_REV   , TypeUint32 );
+        PACKED_INTERNAL_FORMAT_CHECK(RGB10_A2      , RGBA        , UNSIGNED_INT_2_10_10_10_REV , TypeUint32, UNSIGNED_INT_2_10_10_10_REV, TypeUint32 );
+        PACKED_INTERNAL_FORMAT_CHECK(R11F_G11F_B10F, RGB         , UNSIGNED_INT_10F_11F_11F_REV, TypeUint32, FLOAT                      , TypeFloat32);
+        PACKED_INTERNAL_FORMAT_CHECK(RGB10_A2UI    , RGBA_INTEGER, UNSIGNED_INT_2_10_10_10_REV , TypeUint32, UNSIGNED_INT_2_10_10_10_REV, TypeUint32 );
+        }
+        break;
+    case InternalFormatTheme::None:
+        ASSERT_NOT_REACHED();
+    }
+#undef INTERNAL_FORMAT_CHECK
+#undef INTERNAL_FORMAT_INTEGER_CHECK
+#undef PACKED_INTERNAL_FORMAT_CHECK
+
</ins><span class="cx">     // Calculate array size, taking into consideration of PACK_ALIGNMENT.
</span><span class="cx">     unsigned int totalBytesRequired = 0;
</span><span class="cx">     unsigned int padding = 0;
</span><span class="lines">@@ -2878,30 +3149,10 @@
</span><span class="cx">     clearIfComposited();
</span><span class="cx">     void* data = pixels.baseAddress();
</span><span class="cx"> 
</span><del>-    {
-        if (m_isRobustnessEXTSupported)
-            m_context-&gt;getExtensions()-&gt;readnPixelsEXT(x, y, width, height, format, type, pixels.byteLength(), data);
-        else
-            m_context-&gt;readPixels(x, y, width, height, format, type, data);
-    }
-
-#if OS(DARWIN)
-    if (m_isRobustnessEXTSupported) // we haven't computed padding
-        m_context-&gt;computeImageSizeInBytes(format, type, width, height, m_packAlignment, &amp;totalBytesRequired, &amp;padding);
-    // FIXME: remove this section when GL driver bug on Mac AND the GLES driver bug
-    // on QC is fixed, i.e., when alpha is off, readPixels should
-    // set alpha to 255 instead of 0.
-    if (!m_framebufferBinding &amp;&amp; !m_context-&gt;getContextAttributes().alpha) {
-        unsigned char* pixels = reinterpret_cast&lt;unsigned char*&gt;(data);
-        for (GC3Dsizei iy = 0; iy &lt; height; ++iy) {
-            for (GC3Dsizei ix = 0; ix &lt; width; ++ix) {
-                pixels[3] = 255;
-                pixels += 4;
-            }
-            pixels += padding;
-        }
-    }
-#endif
</del><ins>+    if (m_isRobustnessEXTSupported)
+        m_context-&gt;getExtensions()-&gt;readnPixelsEXT(x, y, width, height, format, type, pixels.byteLength(), data);
+    else
+        m_context-&gt;readPixels(x, y, width, height, format, type, data);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebGLRenderingContextBase::releaseShaderCompiler()
</span><span class="lines">@@ -3024,11 +3275,11 @@
</span><span class="cx">     m_context-&gt;stencilOpSeparate(face, fail, zfail, zpass);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebGLRenderingContextBase::texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels)
</del><ins>+void WebGLRenderingContextBase::texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels)
</ins><span class="cx"> {
</span><span class="cx">     // FIXME: For now we ignore any errors returned.
</span><span class="cx">     WebGLTexture* tex = validateTextureBinding(&quot;texImage2D&quot;, target, true);
</span><del>-    ASSERT(validateTexFuncParameters(&quot;texImage2D&quot;, TexImage, target, level, internalformat, width, height, border, format, type));
</del><ins>+    ASSERT(validateTexFuncParameters(&quot;texImage2D&quot;, TexImage, target, level, internalFormat, width, height, border, format, type));
</ins><span class="cx">     ASSERT(tex);
</span><span class="cx">     ASSERT(validateNPOTTextureLevel(width, height, level, &quot;texImage2D&quot;));
</span><span class="cx">     if (!pixels) {
</span><span class="lines">@@ -3037,17 +3288,17 @@
</span><span class="cx">         // can not be cleared with texImage2D and must be cleared by binding to an fbo and calling
</span><span class="cx">         // clear.
</span><span class="cx">         if (isResourceSafe())
</span><del>-            m_context-&gt;texImage2D(target, level, internalformat, width, height, border, format, type, nullptr);
</del><ins>+            m_context-&gt;texImage2D(target, level, internalFormat, width, height, border, format, type, nullptr);
</ins><span class="cx">         else {
</span><del>-            bool succeed = m_context-&gt;texImage2DResourceSafe(target, level, internalformat, width, height,
</del><ins>+            bool succeed = m_context-&gt;texImage2DResourceSafe(target, level, internalFormat, width, height,
</ins><span class="cx">                                                              border, format, type, m_unpackAlignment);
</span><span class="cx">             if (!succeed)
</span><span class="cx">                 return;
</span><span class="cx">         }
</span><span class="cx">     } else {
</span><del>-        ASSERT(validateSettableTexFormat(&quot;texImage2D&quot;, internalformat));
</del><ins>+        ASSERT(validateSettableTexInternalFormat(&quot;texImage2D&quot;, internalFormat));
</ins><span class="cx">         m_context-&gt;moveErrorsToSyntheticErrorList();
</span><del>-        m_context-&gt;texImage2D(target, level, internalformat, width, height,
</del><ins>+        m_context-&gt;texImage2D(target, level, internalFormat, width, height,
</ins><span class="cx">                               border, format, type, pixels);
</span><span class="cx">         if (m_context-&gt;moveErrorsToSyntheticErrorList()) {
</span><span class="cx">             // The texImage2D function failed. Tell the WebGLTexture it doesn't have the data for this level.
</span><span class="lines">@@ -3055,7 +3306,7 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">     }
</span><del>-    tex-&gt;setLevelInfo(target, level, internalformat, width, height, type);
</del><ins>+    tex-&gt;setLevelInfo(target, level, internalFormat, width, height, type);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebGLRenderingContextBase::texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha)
</span><span class="lines">@@ -3087,9 +3338,9 @@
</span><span class="cx">         m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool WebGLRenderingContextBase::validateTexFunc(const char* functionName, TexFuncValidationFunctionType functionType, TexFuncValidationSourceType sourceType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset)
</del><ins>+bool WebGLRenderingContextBase::validateTexFunc(const char* functionName, TexFuncValidationFunctionType functionType, TexFuncValidationSourceType sourceType, GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset)
</ins><span class="cx"> {
</span><del>-    if (!validateTexFuncParameters(functionName, functionType, target, level, internalformat, width, height, border, format, type))
</del><ins>+    if (!validateTexFuncParameters(functionName, functionType, target, level, internalFormat, width, height, border, format, type))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     WebGLTexture* texture = validateTextureBinding(functionName, target, true);
</span><span class="lines">@@ -3102,11 +3353,11 @@
</span><span class="cx">         // For SourceArrayBufferView, function validateTexFuncData() would handle whether to validate the SettableTexFormat
</span><span class="cx">         // by checking if the ArrayBufferView is null or not.
</span><span class="cx">         if (sourceType != SourceArrayBufferView) {
</span><del>-            if (!validateSettableTexFormat(functionName, format))
</del><ins>+            if (!validateSettableTexInternalFormat(functionName, internalFormat))
</ins><span class="cx">                 return false;
</span><span class="cx">         }
</span><span class="cx">     } else {
</span><del>-        if (!validateSettableTexFormat(functionName, format))
</del><ins>+        if (!validateSettableTexInternalFormat(functionName, internalFormat))
</ins><span class="cx">             return false;
</span><span class="cx">         if (!validateSize(functionName, xoffset, yoffset))
</span><span class="cx">             return false;
</span><span class="lines">@@ -3119,7 +3370,7 @@
</span><span class="cx">             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;dimensions out of range&quot;);
</span><span class="cx">             return false;
</span><span class="cx">         }
</span><del>-        if (texture-&gt;getInternalFormat(target, level) != format || texture-&gt;getType(target, level) != type) {
</del><ins>+        if (texture-&gt;getInternalFormat(target, level) != internalFormat || texture-&gt;getType(target, level) != type) {
</ins><span class="cx">             synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;type and format do not match texture&quot;);
</span><span class="cx">             return false;
</span><span class="cx">         }
</span><span class="lines">@@ -3128,10 +3379,10 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, RefPtr&lt;ArrayBufferView&gt;&amp;&amp; pixels)
</del><ins>+void WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, RefPtr&lt;ArrayBufferView&gt;&amp;&amp; pixels)
</ins><span class="cx"> {
</span><del>-    if (isContextLostOrPending() || !validateTexFuncData(&quot;texImage2D&quot;, level, width, height, internalformat, format, type, pixels.get(), NullAllowed)
-        || !validateTexFunc(&quot;texImage2D&quot;, TexImage, SourceArrayBufferView, target, level, internalformat, width, height, border, format, type, 0, 0))
</del><ins>+    if (isContextLostOrPending() || !validateTexFuncData(&quot;texImage2D&quot;, level, width, height, internalFormat, format, type, pixels.get(), NullAllowed)
+        || !validateTexFunc(&quot;texImage2D&quot;, TexImage, SourceArrayBufferView, target, level, internalFormat, width, height, border, format, type, 0, 0))
</ins><span class="cx">         return;
</span><span class="cx">     void* data = pixels ? pixels-&gt;baseAddress() : 0;
</span><span class="cx">     Vector&lt;uint8_t&gt; tempData;
</span><span class="lines">@@ -3148,11 +3399,609 @@
</span><span class="cx">     }
</span><span class="cx">     if (changeUnpackAlignment)
</span><span class="cx">         m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
</span><del>-    texImage2DBase(target, level, internalformat, width, height, border, format, type, data);
</del><ins>+    texImage2DBase(target, level, internalFormat, width, height, border, format, type, data);
</ins><span class="cx">     if (changeUnpackAlignment)
</span><span class="cx">         m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebGLRenderingContextBase::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha)
+{
+    Vector&lt;uint8_t&gt; data;
+    GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
+    if (!imageExtractor.extractSucceeded()) {
+        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texSubImage2D&quot;, &quot;bad image&quot;);
+        return;
+    }
+    GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
+    GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
+    const void* imagePixelData = imageExtractor.imagePixelData();
+    
+    bool needConversion = true;
+    if (type == GraphicsContext3D::UNSIGNED_BYTE &amp;&amp; sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 &amp;&amp; format == GraphicsContext3D::RGBA &amp;&amp; alphaOp == GraphicsContext3D::AlphaDoNothing &amp;&amp; !flipY)
+        needConversion = false;
+    else {
+        if (!m_context-&gt;packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
+            synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texImage2D&quot;, &quot;bad image data&quot;);
+            return;
+        }
+    }
+    
+    if (m_unpackAlignment != 1)
+        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+
+    texSubImage2DBase(target, level, xoffset, yoffset, image-&gt;width(), image-&gt;height(), format, format, type, needConversion ? data.data() : imagePixelData);
+
+    if (m_unpackAlignment != 1)
+        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, RefPtr&lt;ArrayBufferView&gt;&amp;&amp; pixels)
+{
+    if (isContextLostOrPending())
+        return;
+
+    WebGLTexture* texture = validateTextureBinding(&quot;texSubImage2D&quot;, target, true);
+    if (!texture)
+        return;
+
+    GC3Denum internalFormat = texture-&gt;getInternalFormat(target, level);
+    if (!internalFormat) {
+        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texSubImage2D&quot;, &quot;invalid texture target or level&quot;);
+        return;
+    }
+
+    if (!validateTexFuncData(&quot;texSubImage2D&quot;, level, width, height, internalFormat, format, type, pixels.get(), NullNotAllowed))
+        return;
+
+    if (!validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage, SourceArrayBufferView, target, level, internalFormat, width, height, 0, format, type, xoffset, yoffset))
+        return;
+    
+    void* data = pixels-&gt;baseAddress();
+    Vector&lt;uint8_t&gt; tempData;
+    bool changeUnpackAlignment = false;
+    if (data &amp;&amp; (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
+        if (!m_context-&gt;extractTextureData(width, height, format, type, m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, tempData))
+            return;
+        data = tempData.data();
+        changeUnpackAlignment = true;
+    }
+    if (changeUnpackAlignment)
+        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+
+    texSubImage2DBase(target, level, xoffset, yoffset, width, height, internalFormat, format, type, data);
+
+    if (changeUnpackAlignment)
+        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+ExceptionOr&lt;void&gt; WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Optional&lt;TexImageSource&gt;&amp;&amp; source)
+{
+    if (!source) {
+        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texSubImage2D&quot;, &quot;source is null&quot;);
+        return { };
+    }
+
+    if (isContextLostOrPending())
+        return { };
+
+    auto visitor = WTF::makeVisitor([&amp;](const RefPtr&lt;ImageData&gt;&amp; pixels) -&gt; ExceptionOr&lt;void&gt; {
+        WebGLTexture* texture = validateTextureBinding(&quot;texSubImage2D&quot;, target, true);
+        if (!texture)
+            return { };
+
+        GC3Denum internalFormat = texture-&gt;getInternalFormat(target, level);
+        if (!internalFormat) {
+            synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texSubImage2D&quot;, &quot;invalid texture target or level&quot;);
+            return { };
+        }
+
+        if (!validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage, SourceImageData, target, level, internalFormat, pixels-&gt;width(), pixels-&gt;height(), 0, format, type, xoffset, yoffset))
+            return { };
+
+        Vector&lt;uint8_t&gt; data;
+        bool needConversion = true;
+        // The data from ImageData is always of format RGBA8.
+        // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
+        if (format == GraphicsContext3D::RGBA &amp;&amp; type == GraphicsContext3D::UNSIGNED_BYTE &amp;&amp; !m_unpackFlipY &amp;&amp; !m_unpackPremultiplyAlpha)
+            needConversion = false;
+        else {
+            if (!m_context-&gt;extractImageData(pixels.get(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
+                synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texSubImage2D&quot;, &quot;bad image data&quot;);
+                return { };
+            }
+        }
+        if (m_unpackAlignment != 1)
+            m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+
+        texSubImage2DBase(target, level, xoffset, yoffset, pixels-&gt;width(), pixels-&gt;height(), format, format, type, needConversion ? data.data() : pixels-&gt;data()-&gt;data());
+
+        if (m_unpackAlignment != 1)
+            m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+
+        return { };
+    } , [&amp;](const RefPtr&lt;HTMLImageElement&gt;&amp; image) -&gt; ExceptionOr&lt;void&gt; {
+        if (wouldTaintOrigin(image.get()))
+            return Exception { SECURITY_ERR };
+        if (isContextLostOrPending() || !validateHTMLImageElement(&quot;texSubImage2D&quot;, image.get()))
+            return { };
+
+        RefPtr&lt;Image&gt; imageForRender = image-&gt;cachedImage()-&gt;imageForRenderer(image-&gt;renderer());
+        if (!imageForRender)
+            return { };
+
+        if (imageForRender-&gt;isSVGImage())
+            imageForRender = drawImageIntoBuffer(*imageForRender, image-&gt;width(), image-&gt;height(), 1);
+
+        WebGLTexture* texture = validateTextureBinding(&quot;texSubImage2D&quot;, target, true);
+        if (!texture)
+            return { };
+
+        GC3Denum internalFormat = texture-&gt;getInternalFormat(target, level);
+        if (!internalFormat) {
+            synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texSubImage2D&quot;, &quot;invalid texture target or level&quot;);
+            return { };
+        }
+
+        if (!imageForRender || !validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage, SourceHTMLImageElement, target, level, internalFormat, imageForRender-&gt;width(), imageForRender-&gt;height(), 0, format, type, xoffset, yoffset))
+            return { };
+
+        texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha);
+        return { };
+    }, [&amp;](const RefPtr&lt;HTMLCanvasElement&gt;&amp; canvas) -&gt; ExceptionOr&lt;void&gt; {
+        if (wouldTaintOrigin(canvas.get()))
+            return Exception { SECURITY_ERR };
+        if (isContextLostOrPending() || !validateHTMLCanvasElement(&quot;texSubImage2D&quot;, canvas.get()))
+            return { };
+
+        WebGLTexture* texture = validateTextureBinding(&quot;texSubImage2D&quot;, target, true);
+        if (!texture)
+            return { };
+
+        GC3Denum internalFormat = texture-&gt;getInternalFormat(target, level);
+        if (!internalFormat) {
+            synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texSubImage2D&quot;, &quot;invalid texture target or level&quot;);
+            return { };
+        }
+
+        if (!validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage, SourceHTMLCanvasElement, target, level, internalFormat, canvas-&gt;width(), canvas-&gt;height(), 0, format, type, xoffset, yoffset))
+            return { };
+
+        RefPtr&lt;ImageData&gt; imageData = canvas-&gt;getImageData();
+        if (imageData)
+            texSubImage2D(target, level, xoffset, yoffset, format, type, TexImageSource(imageData.get()));
+        else
+            texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas-&gt;copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha);
+        return { };
+    }, [&amp;](const RefPtr&lt;HTMLVideoElement&gt;&amp; video) -&gt; ExceptionOr&lt;void&gt; {
+        if (wouldTaintOrigin(video.get()))
+            return Exception { SECURITY_ERR };
+        if (isContextLostOrPending() || !validateHTMLVideoElement(&quot;texSubImage2D&quot;, video.get()))
+            return { };
+
+        WebGLTexture* texture = validateTextureBinding(&quot;texSubImage2D&quot;, target, true);
+        if (!texture)
+            return { };
+
+        GC3Denum internalFormat = texture-&gt;getInternalFormat(target, level);
+        if (!internalFormat) {
+            synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;texSubImage2D&quot;, &quot;invalid texture target or level&quot;);
+            return { };
+        }
+
+        if (!validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage, SourceHTMLVideoElement, target, level, internalFormat, video-&gt;videoWidth(), video-&gt;videoHeight(), 0, format, type, xoffset, yoffset))
+            return { };
+
+        RefPtr&lt;Image&gt; image = videoFrameToImage(video.get(), ImageBuffer::fastCopyImageMode());
+        if (!image)
+            return { };
+        texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha);
+        return { };
+    });
+
+    return WTF::visit(visitor, source.value());
+}
+
+bool WebGLRenderingContextBase::validateArrayBufferType(const char* functionName, GC3Denum type, Optional&lt;JSC::TypedArrayType&gt; arrayType)
+{
+#define TYPE_VALIDATION_CASE(arrayTypeMacro) if (arrayType &amp;&amp; arrayType.value() != JSC::arrayTypeMacro) { \
+            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;ArrayBufferView not &quot; #arrayTypeMacro); \
+            return false; \
+        } \
+        break;
+
+    switch (type) {
+    case GraphicsContext3D::UNSIGNED_BYTE:
+        TYPE_VALIDATION_CASE(TypeUint8);
+    case GraphicsContext3D::BYTE:
+        TYPE_VALIDATION_CASE(TypeInt8);
+    case GraphicsContext3D::UNSIGNED_SHORT:
+    case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
+    case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
+    case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
+        TYPE_VALIDATION_CASE(TypeUint16);
+    case GraphicsContext3D::SHORT:
+        TYPE_VALIDATION_CASE(TypeInt16);
+    case GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV:
+    case GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV:
+    case GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV:
+    case GraphicsContext3D::UNSIGNED_INT_24_8:
+    case GraphicsContext3D::UNSIGNED_INT:
+        TYPE_VALIDATION_CASE(TypeUint32);
+    case GraphicsContext3D::INT:
+        TYPE_VALIDATION_CASE(TypeInt32);
+    case GraphicsContext3D::FLOAT: // OES_texture_float
+        TYPE_VALIDATION_CASE(TypeFloat32);
+    case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float
+    case GraphicsContext3D::HALF_FLOAT:
+    case GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV:
+        // As per the specification, ArrayBufferView should be null when
+        // OES_texture_half_float is enabled.
+        if (arrayType) {
+            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;type HALF_FLOAT_OES but ArrayBufferView is not NULL&quot;);
+            return false;
+        }
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+#undef TYPE_VALIDATION_CASE
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncData(const char* functionName, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum internalFormat, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, NullDisposition disposition)
+{
+    if (!pixels) {
+        if (disposition == NullAllowed)
+            return true;
+        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;no pixels&quot;);
+        return false;
+    }
+
+    if (!validateTexFuncFormatAndType(functionName, internalFormat, format, type, level))
+        return false;
+    if (!validateSettableTexInternalFormat(functionName, internalFormat))
+        return false;
+    if (!validateArrayBufferType(functionName, type, pixels ? Optional&lt;JSC::TypedArrayType&gt;(pixels-&gt;getType()) : Nullopt))
+        return false;
+    
+    unsigned totalBytesRequired;
+    GC3Denum error = m_context-&gt;computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &amp;totalBytesRequired, 0);
+    if (error != GraphicsContext3D::NO_ERROR) {
+        synthesizeGLError(error, functionName, &quot;invalid texture dimensions&quot;);
+        return false;
+    }
+    if (pixels-&gt;byteLength() &lt; totalBytesRequired) {
+        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;ArrayBufferView not big enough for request&quot;);
+        return false;
+    }
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncParameters(const char* functionName,
+    TexFuncValidationFunctionType functionType,
+    GC3Denum target, GC3Dint level,
+    GC3Denum internalformat,
+    GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+    GC3Denum format, GC3Denum type)
+{
+    // We absolutely have to validate the format and type combination.
+    // The texImage2D entry points taking HTMLImage, etc. will produce
+    // temporary data based on this combination, so it must be legal.
+    if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level) || !validateTexFuncLevel(functionName, target, level))
+        return false;
+    
+    if (width &lt; 0 || height &lt; 0) {
+        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;width or height &lt; 0&quot;);
+        return false;
+    }
+    
+    GC3Dint maxTextureSizeForLevel = pow(2.0, m_maxTextureLevel - 1 - level);
+    switch (target) {
+    case GraphicsContext3D::TEXTURE_2D:
+        if (width &gt; maxTextureSizeForLevel || height &gt; maxTextureSizeForLevel) {
+            synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;width or height out of range&quot;);
+            return false;
+        }
+        break;
+    case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
+    case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
+    case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
+    case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
+    case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
+    case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
+        if (functionType != TexSubImage &amp;&amp; width != height) {
+            synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;width != height for cube map&quot;);
+            return false;
+        }
+        // No need to check height here. For texImage width == height.
+        // For texSubImage that will be checked when checking yoffset + height is in range.
+        if (width &gt; maxTextureSizeForLevel) {
+            synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;width or height out of range for cube map&quot;);
+            return false;
+        }
+        break;
+    default:
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid target&quot;);
+        return false;
+    }
+    
+    if (border) {
+        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;border != 0&quot;);
+        return false;
+    }
+    
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncFormatAndType(const char* functionName, GC3Denum internalFormat, GC3Denum format, GC3Denum type, GC3Dint level)
+{
+    switch (format) {
+    case GraphicsContext3D::ALPHA:
+    case GraphicsContext3D::LUMINANCE:
+    case GraphicsContext3D::LUMINANCE_ALPHA:
+    case GraphicsContext3D::RGB:
+    case GraphicsContext3D::RGBA:
+        break;
+    case GraphicsContext3D::DEPTH_STENCIL:
+    case GraphicsContext3D::DEPTH_COMPONENT:
+        if (!m_webglDepthTexture &amp;&amp; isWebGL1()) {
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;depth texture formats not enabled&quot;);
+            return false;
+        }
+        if (level &gt; 0) {
+            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;level must be 0 for depth formats&quot;);
+            return false;
+        }
+        break;
+    case Extensions3D::SRGB_EXT:
+    case Extensions3D::SRGB_ALPHA_EXT:
+        if (!m_extsRGB) {
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;sRGB texture formats not enabled&quot;);
+            return false;
+        }
+        break;
+    default:
+#if ENABLE(WEBGL2)
+        if (!isWebGL1()) {
+            switch (format) {
+            case GraphicsContext3D::RED:
+            case GraphicsContext3D::RED_INTEGER:
+            case GraphicsContext3D::RG:
+            case GraphicsContext3D::RG_INTEGER:
+            case GraphicsContext3D::RGB_INTEGER:
+            case GraphicsContext3D::RGBA_INTEGER:
+                break;
+            default:
+                synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture format&quot;);
+                return false;
+            }
+        } else
+#endif
+        {
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture format&quot;);
+            return false;
+        }
+    }
+
+    switch (type) {
+    case GraphicsContext3D::UNSIGNED_BYTE:
+    case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
+    case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
+    case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
+        break;
+    case GraphicsContext3D::FLOAT:
+        if (!m_oesTextureFloat &amp;&amp; isWebGL1()) {
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture type&quot;);
+            return false;
+        }
+        break;
+    case GraphicsContext3D::HALF_FLOAT:
+    case GraphicsContext3D::HALF_FLOAT_OES:
+        if (!m_oesTextureHalfFloat &amp;&amp; isWebGL1()) {
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture type&quot;);
+            return false;
+        }
+        break;
+    case GraphicsContext3D::UNSIGNED_INT:
+    case GraphicsContext3D::UNSIGNED_INT_24_8:
+    case GraphicsContext3D::UNSIGNED_SHORT:
+        if (!m_webglDepthTexture &amp;&amp; isWebGL1()) {
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture type&quot;);
+            return false;
+        }
+        break;
+    default:
+#if ENABLE(WEBGL2)
+        if (!isWebGL1()) {
+            switch (type) {
+            case GraphicsContext3D::BYTE:
+            case GraphicsContext3D::SHORT:
+            case GraphicsContext3D::INT:
+            case GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV:
+            case GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV:
+            case GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV:
+            case GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV:
+                break;
+            default:
+                synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture type&quot;);
+                return false;
+            }
+        } else
+#endif
+        {
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid texture type&quot;);
+            return false;
+        }
+    }
+    
+    // Verify that the combination of internalformat, format, and type is supported.
+#define INTERNAL_FORMAT_CASE(internalFormatMacro, formatMacro, type0, type1, type2, type3, type4) case GraphicsContext3D::internalFormatMacro: \
+    if (format != GraphicsContext3D::formatMacro) { \
+        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid format for internalformat&quot;); \
+        return false; \
+    } \
+    if (type != type0 &amp;&amp; type != type1 &amp;&amp; type != type2 &amp;&amp; type != type3 &amp;&amp; type != type4) { \
+        if (type != GraphicsContext3D::HALF_FLOAT_OES || (type0 != GraphicsContext3D::HALF_FLOAT &amp;&amp; type1 != GraphicsContext3D::HALF_FLOAT &amp;&amp; type2 != GraphicsContext3D::HALF_FLOAT &amp;&amp; type3 != GraphicsContext3D::HALF_FLOAT)) { \
+            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid type for internalformat&quot;); \
+            return false; \
+        } \
+    } \
+    break;
+    switch (internalFormat) {
+    INTERNAL_FORMAT_CASE(RGB               , RGB            , GraphicsContext3D::UNSIGNED_BYTE                 , GraphicsContext3D::UNSIGNED_SHORT_5_6_5  , GraphicsContext3D::HALF_FLOAT                  , GraphicsContext3D::FLOAT     , 0                       );
+    INTERNAL_FORMAT_CASE(RGBA              , RGBA           , GraphicsContext3D::UNSIGNED_BYTE                 , GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4, GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1      , GraphicsContext3D::HALF_FLOAT, GraphicsContext3D::FLOAT);
+    INTERNAL_FORMAT_CASE(LUMINANCE_ALPHA   , LUMINANCE_ALPHA, GraphicsContext3D::UNSIGNED_BYTE                 , GraphicsContext3D::HALF_FLOAT            , GraphicsContext3D::FLOAT                       , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(LUMINANCE         , LUMINANCE      , GraphicsContext3D::UNSIGNED_BYTE                 , GraphicsContext3D::HALF_FLOAT            , GraphicsContext3D::FLOAT                       , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(ALPHA             , ALPHA          , GraphicsContext3D::UNSIGNED_BYTE                 , GraphicsContext3D::HALF_FLOAT            , GraphicsContext3D::FLOAT                       , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(R8                , RED            , GraphicsContext3D::UNSIGNED_BYTE                 , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(R8_SNORM          , RED            , GraphicsContext3D::BYTE                          , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(R16F              , RED            , GraphicsContext3D::HALF_FLOAT                    , GraphicsContext3D::FLOAT                 , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(R32F              , RED            , GraphicsContext3D::FLOAT                         , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(R8UI              , RED_INTEGER    , GraphicsContext3D::UNSIGNED_BYTE                 , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(R8I               , RED_INTEGER    , GraphicsContext3D::BYTE                          , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(R16UI             , RED_INTEGER    , GraphicsContext3D::UNSIGNED_SHORT                , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(R16I              , RED_INTEGER    , GraphicsContext3D::SHORT                         , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(R32UI             , RED_INTEGER    , GraphicsContext3D::UNSIGNED_INT                  , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(R32I              , RED_INTEGER    , GraphicsContext3D::INT                           , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RG8               , RG             , GraphicsContext3D::UNSIGNED_BYTE                 , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RG8_SNORM         , RG             , GraphicsContext3D::BYTE                          , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RG16F             , RG             , GraphicsContext3D::HALF_FLOAT                    , GraphicsContext3D::FLOAT                 , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RG32F             , RG             , GraphicsContext3D::FLOAT                         , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RG8UI             , RG_INTEGER     , GraphicsContext3D::UNSIGNED_BYTE                 , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RG8I              , RG_INTEGER     , GraphicsContext3D::BYTE                          , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RG16UI            , RG_INTEGER     , GraphicsContext3D::UNSIGNED_SHORT                , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RG16I             , RG_INTEGER     , GraphicsContext3D::SHORT                         , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RG32UI            , RG_INTEGER     , GraphicsContext3D::UNSIGNED_INT                  , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RG32I             , RG_INTEGER     , GraphicsContext3D::INT                           , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGB8              , RGB            , GraphicsContext3D::UNSIGNED_BYTE                 , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(SRGB8             , RGB            , GraphicsContext3D::UNSIGNED_BYTE                 , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGB565            , RGB            , GraphicsContext3D::UNSIGNED_BYTE                 , GraphicsContext3D::UNSIGNED_SHORT_5_6_5  , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGB8_SNORM        , RGB            , GraphicsContext3D::BYTE                          , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(R11F_G11F_B10F    , RGB            , GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV  , GraphicsContext3D::HALF_FLOAT            , GraphicsContext3D::FLOAT                       , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGB9_E5           , RGB            , GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV      , GraphicsContext3D::HALF_FLOAT            , GraphicsContext3D::FLOAT                       , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGB16F            , RGB            , GraphicsContext3D::HALF_FLOAT                    , GraphicsContext3D::FLOAT                 , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGB32F            , RGB            , GraphicsContext3D::FLOAT                         , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGB8UI            , RGB_INTEGER    , GraphicsContext3D::UNSIGNED_BYTE                 , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGB8I             , RGB_INTEGER    , GraphicsContext3D::BYTE                          , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGB16UI           , RGB_INTEGER    , GraphicsContext3D::UNSIGNED_SHORT                , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGB16I            , RGB_INTEGER    , GraphicsContext3D::SHORT                         , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGB32UI           , RGB_INTEGER    , GraphicsContext3D::UNSIGNED_INT                  , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGB32I            , RGB_INTEGER    , GraphicsContext3D::INT                           , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGBA8             , RGBA           , GraphicsContext3D::UNSIGNED_BYTE                 , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(SRGB8_ALPHA8      , RGBA           , GraphicsContext3D::UNSIGNED_BYTE                 , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGBA8_SNORM       , RGBA           , GraphicsContext3D::BYTE                          , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGB5_A1           , RGBA           , GraphicsContext3D::UNSIGNED_BYTE                 , GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1, GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGBA4             , RGBA           , GraphicsContext3D::UNSIGNED_BYTE                 , GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4, 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGB10_A2          , RGBA           , GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV   , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGBA16F           , RGBA           , GraphicsContext3D::HALF_FLOAT                    , GraphicsContext3D::FLOAT                 , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGBA32F           , RGBA           , GraphicsContext3D::FLOAT                         , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGBA8UI           , RGBA_INTEGER   , GraphicsContext3D::UNSIGNED_BYTE                 , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGBA8I            , RGBA_INTEGER   , GraphicsContext3D::BYTE                          , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGB10_A2UI        , RGBA_INTEGER   , GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV   , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGBA16UI          , RGBA_INTEGER   , GraphicsContext3D::UNSIGNED_SHORT                , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGBA16I           , RGBA_INTEGER   , GraphicsContext3D::SHORT                         , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGBA32I           , RGBA_INTEGER   , GraphicsContext3D::INT                           , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(RGBA32UI          , RGBA_INTEGER   , GraphicsContext3D::UNSIGNED_INT                  , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(DEPTH_COMPONENT   , DEPTH_COMPONENT, GraphicsContext3D::UNSIGNED_SHORT                , GraphicsContext3D::UNSIGNED_INT          , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(DEPTH_COMPONENT16 , DEPTH_COMPONENT, GraphicsContext3D::UNSIGNED_SHORT                , GraphicsContext3D::UNSIGNED_INT          , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(DEPTH_COMPONENT24 , DEPTH_COMPONENT, GraphicsContext3D::UNSIGNED_INT                  , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(DEPTH_COMPONENT32F, DEPTH_COMPONENT, GraphicsContext3D::FLOAT                         , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(DEPTH_STENCIL     , DEPTH_STENCIL  , GraphicsContext3D::UNSIGNED_INT_24_8             , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(DEPTH24_STENCIL8  , DEPTH_STENCIL  , GraphicsContext3D::UNSIGNED_INT_24_8             , 0                                        , 0                                              , 0                            , 0                       );
+    INTERNAL_FORMAT_CASE(DEPTH32F_STENCIL8 , DEPTH_STENCIL  , GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV, 0                                        , 0                                              , 0                            , 0                       );
+    case Extensions3D::SRGB_EXT:
+        if (format != internalFormat) {
+            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;format and internalformat must match&quot;);
+            return false;
+        }
+        if (type != GraphicsContext3D::UNSIGNED_BYTE &amp;&amp; type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5 &amp;&amp; type != GraphicsContext3D::FLOAT &amp;&amp; type != GraphicsContext3D::HALF_FLOAT_OES &amp;&amp; type != GraphicsContext3D::HALF_FLOAT) {
+            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid type for internal format&quot;);
+            return false;
+        }
+        break;
+    case Extensions3D::SRGB_ALPHA_EXT:
+        if (format != internalFormat) {
+            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;format and internalformat must match&quot;);
+            return false;
+        }
+        if (type != GraphicsContext3D::UNSIGNED_BYTE &amp;&amp; type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4 &amp;&amp; type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1 &amp;&amp; type != GraphicsContext3D::FLOAT &amp;&amp; type != GraphicsContext3D::HALF_FLOAT_OES &amp;&amp; type != GraphicsContext3D::HALF_FLOAT) {
+            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;invalid type for internal format&quot;);
+            return false;
+        }
+        break;
+    default:
+        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;Unknown internal format&quot;);
+        return false;
+    }
+#undef INTERNAL_FORMAT_CASE
+    
+    return true;
+}
+
+void WebGLRenderingContextBase::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalFormat, GC3Denum format, GC3Denum type, const void* pixels)
+{
+    ASSERT(!isContextLost());
+    ASSERT(validateTexFuncParameters(&quot;texSubImage2D&quot;, TexSubImage, target, level, internalFormat, width, height, 0, format, type));
+    ASSERT(validateSize(&quot;texSubImage2D&quot;, xoffset, yoffset));
+    ASSERT(validateSettableTexInternalFormat(&quot;texSubImage2D&quot;, internalFormat));
+    WebGLTexture* tex = validateTextureBinding(&quot;texSubImage2D&quot;, target, true);
+    if (!tex) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    ASSERT((xoffset + width) &gt;= 0);
+    ASSERT((yoffset + height) &gt;= 0);
+    ASSERT(tex-&gt;getWidth(target, level) &gt;= (xoffset + width));
+    ASSERT(tex-&gt;getHeight(target, level) &gt;= (yoffset + height));
+    ASSERT_UNUSED(internalFormat, tex-&gt;getInternalFormat(target, level) == internalFormat);
+    m_context-&gt;texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void WebGLRenderingContextBase::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
+{
+    if (isContextLostOrPending())
+        return;
+    if (!validateTexFuncParameters(&quot;copyTexImage2D&quot;, CopyTexImage, target, level, internalFormat, width, height, border, internalFormat, GraphicsContext3D::UNSIGNED_BYTE))
+        return;
+    if (!validateSettableTexInternalFormat(&quot;copyTexImage2D&quot;, internalFormat))
+        return;
+    WebGLTexture* tex = validateTextureBinding(&quot;copyTexImage2D&quot;, target, true);
+    if (!tex)
+        return;
+    if (!isTexInternalFormatColorBufferCombinationValid(internalFormat, getBoundFramebufferColorFormat())) {
+        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, &quot;copyTexImage2D&quot;, &quot;framebuffer is incompatible format&quot;);
+        return;
+    }
+    if (!isGLES2NPOTStrict() &amp;&amp; level &amp;&amp; WebGLTexture::isNPOT(width, height)) {
+        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, &quot;copyTexImage2D&quot;, &quot;level &gt; 0 not power of 2&quot;);
+        return;
+    }
+    const char* reason = &quot;framebuffer incomplete&quot;;
+    if (m_framebufferBinding &amp;&amp; !m_framebufferBinding-&gt;onAccess(graphicsContext3D(), !isResourceSafe(), &amp;reason)) {
+        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, &quot;copyTexImage2D&quot;, reason);
+        return;
+    }
+    clearIfComposited();
+    if (isResourceSafe())
+        m_context-&gt;copyTexImage2D(target, level, internalFormat, x, y, width, height, border);
+    else {
+        GC3Dint clippedX, clippedY;
+        GC3Dsizei clippedWidth, clippedHeight;
+        if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &amp;clippedX, &amp;clippedY, &amp;clippedWidth, &amp;clippedHeight)) {
+            m_context-&gt;texImage2DResourceSafe(target, level, internalFormat, width, height, border,
+                internalFormat, GraphicsContext3D::UNSIGNED_BYTE, m_unpackAlignment);
+            if (clippedWidth &gt; 0 &amp;&amp; clippedHeight &gt; 0) {
+                m_context-&gt;copyTexSubImage2D(target, level, clippedX - x, clippedY - y,
+                    clippedX, clippedY, clippedWidth, clippedHeight);
+            }
+        } else
+            m_context-&gt;copyTexImage2D(target, level, internalFormat, x, y, width, height, border);
+    }
+    // FIXME: if the framebuffer is not complete, none of the below should be executed.
+    tex-&gt;setLevelInfo(target, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+}
+
</ins><span class="cx"> ExceptionOr&lt;void&gt; WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Optional&lt;TexImageSource&gt; source)
</span><span class="cx"> {
</span><span class="cx">     if (!source) {
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContextBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (208723 => 208724)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h        2016-11-15 02:20:54 UTC (rev 208723)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h        2016-11-15 02:42:32 UTC (rev 208724)
</span><span class="lines">@@ -150,7 +150,7 @@
</span><span class="cx">     void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, ArrayBufferView&amp; data);
</span><span class="cx">     void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView&amp; data);
</span><span class="cx"> 
</span><del>-    virtual void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) = 0;
</del><ins>+    void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border);
</ins><span class="cx">     void copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;WebGLBuffer&gt; createBuffer();
</span><span class="lines">@@ -246,8 +246,8 @@
</span><span class="cx">     void texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param);
</span><span class="cx">     void texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param);
</span><span class="cx"> 
</span><del>-    virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, RefPtr&lt;ArrayBufferView&gt;&amp;&amp;) = 0;
-    virtual ExceptionOr&lt;void&gt; texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Optional&lt;TexImageSource&gt;&amp;&amp;) = 0;
</del><ins>+    void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, RefPtr&lt;ArrayBufferView&gt;&amp;&amp;);
+    ExceptionOr&lt;void&gt; texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Optional&lt;TexImageSource&gt;&amp;&amp;);
</ins><span class="cx"> 
</span><span class="cx">     void uniform1f(const WebGLUniformLocation*, GC3Dfloat x);
</span><span class="cx">     void uniform1fv(const WebGLUniformLocation*, Float32Array&amp; v);
</span><span class="lines">@@ -594,8 +594,8 @@
</span><span class="cx"> 
</span><span class="cx">     void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels);
</span><span class="cx">     void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha);
</span><del>-    virtual void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels) = 0;
-    virtual void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha) = 0;
</del><ins>+    void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels);
+    void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha);
</ins><span class="cx"> 
</span><span class="cx">     bool checkTextureCompleteness(const char*, bool);
</span><span class="cx"> 
</span><span class="lines">@@ -634,7 +634,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
</span><span class="cx">     // Generates GL error and returns false if parameters are invalid.
</span><del>-    virtual bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) = 0;
</del><ins>+    bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level);
</ins><span class="cx"> 
</span><span class="cx">     // Helper function to check input level for functions {copy}Tex{Sub}Image.
</span><span class="cx">     // Generates GL error and returns false if level is invalid.
</span><span class="lines">@@ -661,12 +661,12 @@
</span><span class="cx"> 
</span><span class="cx">     // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
</span><span class="cx">     // Generates GL error and returns false if parameters are invalid.
</span><del>-    virtual bool validateTexFuncParameters(const char* functionName,
</del><ins>+    bool validateTexFuncParameters(const char* functionName,
</ins><span class="cx">         TexFuncValidationFunctionType,
</span><span class="cx">         GC3Denum target, GC3Dint level,
</span><span class="cx">         GC3Denum internalformat,
</span><span class="cx">         GC3Dsizei width, GC3Dsizei height, GC3Dint border,
</span><del>-        GC3Denum format, GC3Denum type) = 0;
</del><ins>+        GC3Denum format, GC3Denum type);
</ins><span class="cx"> 
</span><span class="cx">     enum NullDisposition {
</span><span class="cx">         NullAllowed,
</span><span class="lines">@@ -676,17 +676,17 @@
</span><span class="cx">     // Helper function to validate that the given ArrayBufferView
</span><span class="cx">     // is of the correct type and contains enough data for the texImage call.
</span><span class="cx">     // Generates GL error and returns false if parameters are invalid.
</span><del>-    virtual bool validateTexFuncData(const char* functionName, GC3Dint level,
</del><ins>+    bool validateTexFuncData(const char* functionName, GC3Dint level,
</ins><span class="cx">         GC3Dsizei width, GC3Dsizei height,
</span><span class="cx">         GC3Denum internalformat, GC3Denum format, GC3Denum type,
</span><span class="cx">         ArrayBufferView* pixels,
</span><del>-        NullDisposition) = 0;
</del><ins>+        NullDisposition);
</ins><span class="cx"> 
</span><span class="cx">     // Helper function to validate a given texture format is settable as in
</span><span class="cx">     // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and
</span><span class="cx">     // copyTexSubImage2D.
</span><span class="cx">     // Generates GL error and returns false if the format is not settable.
</span><del>-    bool validateSettableTexFormat(const char* functionName, GC3Denum format);
</del><ins>+    bool validateSettableTexInternalFormat(const char* functionName, GC3Denum format);
</ins><span class="cx"> 
</span><span class="cx">     // Helper function to validate compressed texture data is correct size
</span><span class="cx">     // for the given format and dimensions.
</span><span class="lines">@@ -804,6 +804,9 @@
</span><span class="cx"> 
</span><span class="cx">     // Check if EXT_draw_buffers extension is supported and if it satisfies the WebGL requirements.
</span><span class="cx">     bool supportsDrawBuffers();
</span><ins>+
+private:
+    bool validateArrayBufferType(const char* functionName, GC3Denum type, Optional&lt;JSC::TypedArrayType&gt;);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsContext3Dcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.cpp (208723 => 208724)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.cpp        2016-11-15 02:20:54 UTC (rev 208723)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.cpp        2016-11-15 02:42:32 UTC (rev 208724)
</span><span class="lines">@@ -167,6 +167,8 @@
</span><span class="cx"> bool GraphicsContext3D::computeFormatAndTypeParameters(GC3Denum format, GC3Denum type, unsigned int* componentsPerPixel, unsigned int* bytesPerComponent)
</span><span class="cx"> {
</span><span class="cx">     switch (format) {
</span><ins>+    case GraphicsContext3D::RED:
+    case GraphicsContext3D::RED_INTEGER:
</ins><span class="cx">     case GraphicsContext3D::ALPHA:
</span><span class="cx">     case GraphicsContext3D::LUMINANCE:
</span><span class="cx">     case GraphicsContext3D::DEPTH_COMPONENT:
</span><span class="lines">@@ -173,14 +175,18 @@
</span><span class="cx">     case GraphicsContext3D::DEPTH_STENCIL:
</span><span class="cx">         *componentsPerPixel = 1;
</span><span class="cx">         break;
</span><ins>+    case GraphicsContext3D::RG:
+    case GraphicsContext3D::RG_INTEGER:
</ins><span class="cx">     case GraphicsContext3D::LUMINANCE_ALPHA:
</span><span class="cx">         *componentsPerPixel = 2;
</span><span class="cx">         break;
</span><span class="cx">     case GraphicsContext3D::RGB:
</span><ins>+    case GraphicsContext3D::RGB_INTEGER:
</ins><span class="cx">     case Extensions3D::SRGB_EXT:
</span><span class="cx">         *componentsPerPixel = 3;
</span><span class="cx">         break;
</span><span class="cx">     case GraphicsContext3D::RGBA:
</span><ins>+    case GraphicsContext3D::RGBA_INTEGER:
</ins><span class="cx">     case Extensions3D::BGRA_EXT: // GL_EXT_texture_format_BGRA8888
</span><span class="cx">     case Extensions3D::SRGB_ALPHA_EXT:
</span><span class="cx">         *componentsPerPixel = 4;
</span><span class="lines">@@ -188,13 +194,20 @@
</span><span class="cx">     default:
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><ins>+
</ins><span class="cx">     switch (type) {
</span><span class="cx">     case GraphicsContext3D::UNSIGNED_BYTE:
</span><span class="cx">         *bytesPerComponent = sizeof(GC3Dubyte);
</span><span class="cx">         break;
</span><ins>+    case GraphicsContext3D::BYTE:
+        *bytesPerComponent = sizeof(GC3Dbyte);
+        break;
</ins><span class="cx">     case GraphicsContext3D::UNSIGNED_SHORT:
</span><span class="cx">         *bytesPerComponent = sizeof(GC3Dushort);
</span><span class="cx">         break;
</span><ins>+    case GraphicsContext3D::SHORT:
+        *bytesPerComponent = sizeof(GC3Dshort);
+        break;
</ins><span class="cx">     case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
</span><span class="cx">     case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
</span><span class="cx">     case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
</span><span class="lines">@@ -202,15 +215,28 @@
</span><span class="cx">         *bytesPerComponent = sizeof(GC3Dushort);
</span><span class="cx">         break;
</span><span class="cx">     case GraphicsContext3D::UNSIGNED_INT_24_8:
</span><ins>+    case GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV:
+    case GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV:
+    case GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV:
+        *componentsPerPixel = 1;
+        *bytesPerComponent = sizeof(GC3Duint);
+        break;
</ins><span class="cx">     case GraphicsContext3D::UNSIGNED_INT:
</span><span class="cx">         *bytesPerComponent = sizeof(GC3Duint);
</span><span class="cx">         break;
</span><ins>+    case GraphicsContext3D::INT:
+        *bytesPerComponent = sizeof(GC3Dint);
+        break;
</ins><span class="cx">     case GraphicsContext3D::FLOAT: // OES_texture_float
</span><span class="cx">         *bytesPerComponent = sizeof(GC3Dfloat);
</span><span class="cx">         break;
</span><ins>+    case GraphicsContext3D::HALF_FLOAT:
</ins><span class="cx">     case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float
</span><span class="cx">         *bytesPerComponent = sizeof(GC3Dhalffloat);
</span><span class="cx">         break;
</span><ins>+    case GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV:
+        *bytesPerComponent = sizeof(GC3Dfloat) + sizeof(GC3Duint);
+        break;
</ins><span class="cx">     default:
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="lines">@@ -217,6 +243,85 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool GraphicsContext3D::possibleFormatAndTypeForInternalFormat(GC3Denum internalFormat, GC3Denum&amp; format, GC3Denum&amp; type)
+{
+#define POSSIBLE_FORMAT_TYPE_CASE(internalFormatMacro, formatMacro, typeMacro) case internalFormatMacro: \
+        format = formatMacro; \
+        type = GraphicsContext3D::typeMacro; \
+        break;
+
+    switch (internalFormat) {
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGB               , GraphicsContext3D::RGB            , UNSIGNED_BYTE                 );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGBA              , GraphicsContext3D::RGBA           , UNSIGNED_BYTE                 );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::LUMINANCE_ALPHA   , GraphicsContext3D::LUMINANCE_ALPHA, UNSIGNED_BYTE                 );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::LUMINANCE         , GraphicsContext3D::LUMINANCE      , UNSIGNED_BYTE                 );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::ALPHA             , GraphicsContext3D::ALPHA          , UNSIGNED_BYTE                 );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::R8                , GraphicsContext3D::RED            , UNSIGNED_BYTE                 );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::R8_SNORM          , GraphicsContext3D::RED            , BYTE                          );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::R16F              , GraphicsContext3D::RED            , HALF_FLOAT                    );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::R32F              , GraphicsContext3D::RED            , FLOAT                         );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::R8UI              , GraphicsContext3D::RED_INTEGER    , UNSIGNED_BYTE                 );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::R8I               , GraphicsContext3D::RED_INTEGER    , BYTE                          );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::R16UI             , GraphicsContext3D::RED_INTEGER    , UNSIGNED_SHORT                );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::R16I              , GraphicsContext3D::RED_INTEGER    , SHORT                         );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::R32UI             , GraphicsContext3D::RED_INTEGER    , UNSIGNED_INT                  );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::R32I              , GraphicsContext3D::RED_INTEGER    , INT                           );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RG8               , GraphicsContext3D::RG             , UNSIGNED_BYTE                 );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RG8_SNORM         , GraphicsContext3D::RG             , BYTE                          );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RG16F             , GraphicsContext3D::RG             , HALF_FLOAT                    );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RG32F             , GraphicsContext3D::RG             , FLOAT                         );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RG8UI             , GraphicsContext3D::RG_INTEGER     , UNSIGNED_BYTE                 );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RG8I              , GraphicsContext3D::RG_INTEGER     , BYTE                          );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RG16UI            , GraphicsContext3D::RG_INTEGER     , UNSIGNED_SHORT                );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RG16I             , GraphicsContext3D::RG_INTEGER     , SHORT                         );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RG32UI            , GraphicsContext3D::RG_INTEGER     , UNSIGNED_INT                  );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RG32I             , GraphicsContext3D::RG_INTEGER     , INT                           );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGB8              , GraphicsContext3D::RGB            , UNSIGNED_BYTE                 );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::SRGB8             , GraphicsContext3D::RGB            , UNSIGNED_BYTE                 );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGB565            , GraphicsContext3D::RGB            , UNSIGNED_SHORT_5_6_5          );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGB8_SNORM        , GraphicsContext3D::RGB            , BYTE                          );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::R11F_G11F_B10F    , GraphicsContext3D::RGB            , UNSIGNED_INT_10F_11F_11F_REV  );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGB9_E5           , GraphicsContext3D::RGB            , UNSIGNED_INT_5_9_9_9_REV      );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGB16F            , GraphicsContext3D::RGB            , HALF_FLOAT                    );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGB32F            , GraphicsContext3D::RGB            , FLOAT                         );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGB8UI            , GraphicsContext3D::RGB_INTEGER    , UNSIGNED_BYTE                 );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGB8I             , GraphicsContext3D::RGB_INTEGER    , BYTE                          );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGB16UI           , GraphicsContext3D::RGB_INTEGER    , UNSIGNED_SHORT                );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGB16I            , GraphicsContext3D::RGB_INTEGER    , SHORT                         );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGB32UI           , GraphicsContext3D::RGB_INTEGER    , UNSIGNED_INT                  );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGB32I            , GraphicsContext3D::RGB_INTEGER    , INT                           );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGBA8             , GraphicsContext3D::RGBA           , UNSIGNED_BYTE                 );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::SRGB8_ALPHA8      , GraphicsContext3D::RGBA           , UNSIGNED_BYTE                 );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGBA8_SNORM       , GraphicsContext3D::RGBA           , BYTE                          );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGB5_A1           , GraphicsContext3D::RGBA           , UNSIGNED_SHORT_5_5_5_1        );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGBA4             , GraphicsContext3D::RGBA           , UNSIGNED_SHORT_4_4_4_4        );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGB10_A2          , GraphicsContext3D::RGBA           , UNSIGNED_INT_2_10_10_10_REV   );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGBA16F           , GraphicsContext3D::RGBA           , HALF_FLOAT                    );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGBA32F           , GraphicsContext3D::RGBA           , FLOAT                         );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGBA8UI           , GraphicsContext3D::RGBA_INTEGER   , UNSIGNED_BYTE                 );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGBA8I            , GraphicsContext3D::RGBA_INTEGER   , BYTE                          );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGB10_A2UI        , GraphicsContext3D::RGBA_INTEGER   , UNSIGNED_INT_2_10_10_10_REV   );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGBA16UI          , GraphicsContext3D::RGBA_INTEGER   , UNSIGNED_SHORT                );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGBA16I           , GraphicsContext3D::RGBA_INTEGER   , SHORT                         );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGBA32I           , GraphicsContext3D::RGBA_INTEGER   , INT                           );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::RGBA32UI          , GraphicsContext3D::RGBA_INTEGER   , UNSIGNED_INT                  );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::DEPTH_COMPONENT16 , GraphicsContext3D::DEPTH_COMPONENT, UNSIGNED_SHORT                );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::DEPTH_COMPONENT   , GraphicsContext3D::DEPTH_COMPONENT, UNSIGNED_SHORT                );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::DEPTH_COMPONENT24 , GraphicsContext3D::DEPTH_COMPONENT, UNSIGNED_INT                  );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::DEPTH_COMPONENT32F, GraphicsContext3D::DEPTH_COMPONENT, FLOAT                         );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::DEPTH_STENCIL     , GraphicsContext3D::DEPTH_STENCIL  , UNSIGNED_INT_24_8             );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::DEPTH24_STENCIL8  , GraphicsContext3D::DEPTH_STENCIL  , UNSIGNED_INT_24_8             );
+    POSSIBLE_FORMAT_TYPE_CASE(GraphicsContext3D::DEPTH32F_STENCIL8 , GraphicsContext3D::DEPTH_STENCIL  , FLOAT_32_UNSIGNED_INT_24_8_REV);
+    POSSIBLE_FORMAT_TYPE_CASE(Extensions3D::SRGB_EXT               , Extensions3D::SRGB_EXT            , UNSIGNED_BYTE                 );
+    POSSIBLE_FORMAT_TYPE_CASE(Extensions3D::SRGB_ALPHA_EXT         , Extensions3D::SRGB_ALPHA_EXT      , UNSIGNED_BYTE                 );
+    default:
+        return false;
+    }
+#undef POSSIBLE_FORMAT_TYPE_CASE
+
+    return true;
+}
+
</ins><span class="cx"> GC3Denum GraphicsContext3D::computeImageSizeInBytes(GC3Denum format, GC3Denum type, GC3Dsizei width, GC3Dsizei height, GC3Dint alignment, unsigned int* imageSizeInBytes, unsigned int* paddingInBytes)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(imageSizeInBytes);
</span><span class="lines">@@ -261,7 +366,7 @@
</span><span class="cx">     m_extractSucceeded = extractImage(premultiplyAlpha, ignoreGammaAndColorProfile);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool GraphicsContext3D::packImageData( Image* image, const void* pixels, GC3Denum format, GC3Denum type, bool flipY, AlphaOp alphaOp, DataFormat sourceFormat, unsigned width, unsigned height, unsigned sourceUnpackAlignment, Vector&lt;uint8_t&gt;&amp; data)
</del><ins>+bool GraphicsContext3D::packImageData(Image* image, const void* pixels, GC3Denum format, GC3Denum type, bool flipY, AlphaOp alphaOp, DataFormat sourceFormat, unsigned width, unsigned height, unsigned sourceUnpackAlignment, Vector&lt;uint8_t&gt;&amp; data)
</ins><span class="cx"> {
</span><span class="cx">     if (!pixels)
</span><span class="cx">         return false;
</span><span class="lines">@@ -361,6 +466,29 @@
</span><span class="cx">     int remainder = sourceUnpackAlignment ? (validSrc % sourceUnpackAlignment) : 0;
</span><span class="cx">     int srcStride = remainder ? (validSrc + sourceUnpackAlignment - remainder) : validSrc;
</span><span class="cx"> 
</span><ins>+    // FIXME: Implement packing pixels to WebGL 2 formats
+    switch (destinationFormat) {
+    case GraphicsContext3D::RED:
+    case GraphicsContext3D::RED_INTEGER:
+    case GraphicsContext3D::RG:
+    case GraphicsContext3D::RG_INTEGER:
+    case GraphicsContext3D::RGB_INTEGER:
+    case GraphicsContext3D::RGBA_INTEGER:
+    case GraphicsContext3D::DEPTH_COMPONENT:
+    case GraphicsContext3D::DEPTH_STENCIL:
+        return false;
+    }
+    switch (destinationType) {
+    case GraphicsContext3D::BYTE:
+    case GraphicsContext3D::SHORT:
+    case GraphicsContext3D::INT:
+    case GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV:
+    case GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV:
+    case GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV:
+    case GraphicsContext3D::UNSIGNED_INT_24_8:
+        return false;
+    }
+
</ins><span class="cx">     DataFormat dstDataFormat = getDataFormat(destinationFormat, destinationType);
</span><span class="cx">     int dstStride = width * TexelBytesForFormat(dstDataFormat);
</span><span class="cx">     if (flipY) {
</span><span class="lines">@@ -424,24 +552,73 @@
</span><span class="cx"> unsigned GraphicsContext3D::getClearBitsByFormat(GC3Denum format)
</span><span class="cx"> {
</span><span class="cx">     switch (format) {
</span><ins>+    case GraphicsContext3D::RGB:
+    case GraphicsContext3D::RGBA:
+    case GraphicsContext3D::LUMINANCE_ALPHA:
+    case GraphicsContext3D::LUMINANCE:
</ins><span class="cx">     case GraphicsContext3D::ALPHA:
</span><del>-    case GraphicsContext3D::LUMINANCE:
-    case GraphicsContext3D::LUMINANCE_ALPHA:
-    case GraphicsContext3D::RGB:
</del><ins>+    case GraphicsContext3D::R8:
+    case GraphicsContext3D::R8_SNORM:
+    case GraphicsContext3D::R16F:
+    case GraphicsContext3D::R32F:
+    case GraphicsContext3D::R8UI:
+    case GraphicsContext3D::R8I:
+    case GraphicsContext3D::R16UI:
+    case GraphicsContext3D::R16I:
+    case GraphicsContext3D::R32UI:
+    case GraphicsContext3D::R32I:
+    case GraphicsContext3D::RG8:
+    case GraphicsContext3D::RG8_SNORM:
+    case GraphicsContext3D::RG16F:
+    case GraphicsContext3D::RG32F:
+    case GraphicsContext3D::RG8UI:
+    case GraphicsContext3D::RG8I:
+    case GraphicsContext3D::RG16UI:
+    case GraphicsContext3D::RG16I:
+    case GraphicsContext3D::RG32UI:
+    case GraphicsContext3D::RG32I:
+    case GraphicsContext3D::RGB8:
+    case GraphicsContext3D::SRGB8:
</ins><span class="cx">     case GraphicsContext3D::RGB565:
</span><del>-    case GraphicsContext3D::RGBA:
</del><ins>+    case GraphicsContext3D::RGB8_SNORM:
+    case GraphicsContext3D::R11F_G11F_B10F:
+    case GraphicsContext3D::RGB9_E5:
+    case GraphicsContext3D::RGB16F:
+    case GraphicsContext3D::RGB32F:
+    case GraphicsContext3D::RGB8UI:
+    case GraphicsContext3D::RGB8I:
+    case GraphicsContext3D::RGB16UI:
+    case GraphicsContext3D::RGB16I:
+    case GraphicsContext3D::RGB32UI:
+    case GraphicsContext3D::RGB32I:
+    case GraphicsContext3D::RGBA8:
+    case GraphicsContext3D::SRGB8_ALPHA8:
+    case GraphicsContext3D::RGBA8_SNORM:
+    case GraphicsContext3D::RGB5_A1:
</ins><span class="cx">     case GraphicsContext3D::RGBA4:
</span><del>-    case GraphicsContext3D::RGB5_A1:
</del><ins>+    case GraphicsContext3D::RGB10_A2:
+    case GraphicsContext3D::RGBA16F:
+    case GraphicsContext3D::RGBA32F:
+    case GraphicsContext3D::RGBA8UI:
+    case GraphicsContext3D::RGBA8I:
+    case GraphicsContext3D::RGB10_A2UI:
+    case GraphicsContext3D::RGBA16UI:
+    case GraphicsContext3D::RGBA16I:
+    case GraphicsContext3D::RGBA32I:
+    case GraphicsContext3D::RGBA32UI:
</ins><span class="cx">     case Extensions3D::SRGB_EXT:
</span><span class="cx">     case Extensions3D::SRGB_ALPHA_EXT:
</span><del>-    case Extensions3D::SRGB8_ALPHA8_EXT:
</del><span class="cx">         return GraphicsContext3D::COLOR_BUFFER_BIT;
</span><span class="cx">     case GraphicsContext3D::DEPTH_COMPONENT16:
</span><ins>+    case GraphicsContext3D::DEPTH_COMPONENT24:
+    case GraphicsContext3D::DEPTH_COMPONENT32F:
</ins><span class="cx">     case GraphicsContext3D::DEPTH_COMPONENT:
</span><span class="cx">         return GraphicsContext3D::DEPTH_BUFFER_BIT;
</span><span class="cx">     case GraphicsContext3D::STENCIL_INDEX8:
</span><span class="cx">         return GraphicsContext3D::STENCIL_BUFFER_BIT;
</span><span class="cx">     case GraphicsContext3D::DEPTH_STENCIL:
</span><ins>+    case GraphicsContext3D::DEPTH24_STENCIL8:
+    case GraphicsContext3D::DEPTH32F_STENCIL8:
</ins><span class="cx">         return GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT;
</span><span class="cx">     default:
</span><span class="cx">         return 0;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsContext3Dh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h (208723 => 208724)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h        2016-11-15 02:20:54 UTC (rev 208723)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h        2016-11-15 02:42:32 UTC (rev 208724)
</span><span class="lines">@@ -811,6 +811,8 @@
</span><span class="cx">                                      unsigned int* imageSizeInBytes,
</span><span class="cx">                                      unsigned int* paddingInBytes);
</span><span class="cx"> 
</span><ins>+    static bool possibleFormatAndTypeForInternalFormat(GC3Denum internalFormat, GC3Denum&amp; format, GC3Denum&amp; type);
+
</ins><span class="cx">     // Extracts the contents of the given ImageData into the passed Vector,
</span><span class="cx">     // packing the pixel data according to the given format and type,
</span><span class="cx">     // and obeying the flipY and premultiplyAlpha flags. Returns true
</span><span class="lines">@@ -884,45 +886,55 @@
</span><span class="cx"> 
</span><span class="cx">     ALWAYS_INLINE static bool hasAlpha(DataFormat format)
</span><span class="cx">     {
</span><del>-        return format == GraphicsContext3D::DataFormatA8
-            || format == GraphicsContext3D::DataFormatA16F
-            || format == GraphicsContext3D::DataFormatA32F
-            || format == GraphicsContext3D::DataFormatRA8
-            || format == GraphicsContext3D::DataFormatAR8
-            || format == GraphicsContext3D::DataFormatRA16F
-            || format == GraphicsContext3D::DataFormatRA32F
-            || format == GraphicsContext3D::DataFormatRGBA8
-            || format == GraphicsContext3D::DataFormatBGRA8
-            || format == GraphicsContext3D::DataFormatARGB8
-            || format == GraphicsContext3D::DataFormatABGR8
-            || format == GraphicsContext3D::DataFormatRGBA16F
-            || format == GraphicsContext3D::DataFormatRGBA32F
-            || format == GraphicsContext3D::DataFormatRGBA4444
-            || format == GraphicsContext3D::DataFormatRGBA5551;
</del><ins>+        switch (format) {
+        case GraphicsContext3D::DataFormatA8:
+        case GraphicsContext3D::DataFormatA16F:
+        case GraphicsContext3D::DataFormatA32F:
+        case GraphicsContext3D::DataFormatRA8:
+        case GraphicsContext3D::DataFormatAR8:
+        case GraphicsContext3D::DataFormatRA16F:
+        case GraphicsContext3D::DataFormatRA32F:
+        case GraphicsContext3D::DataFormatRGBA8:
+        case GraphicsContext3D::DataFormatBGRA8:
+        case GraphicsContext3D::DataFormatARGB8:
+        case GraphicsContext3D::DataFormatABGR8:
+        case GraphicsContext3D::DataFormatRGBA16F:
+        case GraphicsContext3D::DataFormatRGBA32F:
+        case GraphicsContext3D::DataFormatRGBA4444:
+        case GraphicsContext3D::DataFormatRGBA5551:
+            return true;
+        default:
+            return false;
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     ALWAYS_INLINE static bool hasColor(DataFormat format)
</span><span class="cx">     {
</span><del>-        return format == GraphicsContext3D::DataFormatRGBA8
-            || format == GraphicsContext3D::DataFormatRGBA16F
-            || format == GraphicsContext3D::DataFormatRGBA32F
-            || format == GraphicsContext3D::DataFormatRGB8
-            || format == GraphicsContext3D::DataFormatRGB16F
-            || format == GraphicsContext3D::DataFormatRGB32F
-            || format == GraphicsContext3D::DataFormatBGR8
-            || format == GraphicsContext3D::DataFormatBGRA8
-            || format == GraphicsContext3D::DataFormatARGB8
-            || format == GraphicsContext3D::DataFormatABGR8
-            || format == GraphicsContext3D::DataFormatRGBA5551
-            || format == GraphicsContext3D::DataFormatRGBA4444
-            || format == GraphicsContext3D::DataFormatRGB565
-            || format == GraphicsContext3D::DataFormatR8
-            || format == GraphicsContext3D::DataFormatR16F
-            || format == GraphicsContext3D::DataFormatR32F
-            || format == GraphicsContext3D::DataFormatRA8
-            || format == GraphicsContext3D::DataFormatRA16F
-            || format == GraphicsContext3D::DataFormatRA32F
-            || format == GraphicsContext3D::DataFormatAR8;
</del><ins>+        switch (format) {
+        case GraphicsContext3D::DataFormatRGBA8:
+        case GraphicsContext3D::DataFormatRGBA16F:
+        case GraphicsContext3D::DataFormatRGBA32F:
+        case GraphicsContext3D::DataFormatRGB8:
+        case GraphicsContext3D::DataFormatRGB16F:
+        case GraphicsContext3D::DataFormatRGB32F:
+        case GraphicsContext3D::DataFormatBGR8:
+        case GraphicsContext3D::DataFormatBGRA8:
+        case GraphicsContext3D::DataFormatARGB8:
+        case GraphicsContext3D::DataFormatABGR8:
+        case GraphicsContext3D::DataFormatRGBA5551:
+        case GraphicsContext3D::DataFormatRGBA4444:
+        case GraphicsContext3D::DataFormatRGB565:
+        case GraphicsContext3D::DataFormatR8:
+        case GraphicsContext3D::DataFormatR16F:
+        case GraphicsContext3D::DataFormatR32F:
+        case GraphicsContext3D::DataFormatRA8:
+        case GraphicsContext3D::DataFormatRA16F:
+        case GraphicsContext3D::DataFormatRA32F:
+        case GraphicsContext3D::DataFormatAR8:
+            return true;
+        default:
+            return false;
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Check if the format is one of the formats from the ImageData or DOM elements.
</span></span></pre>
</div>
</div>

</body>
</html>