<!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>[179842] trunk/Source/WebCore</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/179842">179842</a></dd>
<dt>Author</dt> <dd>roger_fong@apple.com</dd>
<dt>Date</dt> <dd>2015-02-09 12:50:15 -0800 (Mon, 09 Feb 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>WebGL 2: Texture call format, internal format, and type validation.
https://bugs.webkit.org/show_bug.cgi?id=141318.
&lt;rdar://problem/19733828&gt;

Reviewed by Brent Fulgham.

Tests will be covered by WebGL2 conformance tests.

* html/canvas/WebGL2RenderingContext.cpp:
(WebCore::WebGL2RenderingContext::getFramebufferAttachmentParameter): Add missing ExceptionCode argument.
(WebCore::WebGL2RenderingContext::copyTexImage2D): Validate texture formats based on GLES3 spec.
(WebCore::WebGL2RenderingContext::texSubImage2DBase): Validate using internal format from texture target.
(WebCore::WebGL2RenderingContext::texSubImage2DImpl): Validate using internal format from texture target.
(WebCore::WebGL2RenderingContext::texSubImage2D): Validate using internal format from texture target.
(WebCore::WebGL2RenderingContext::validateTexFuncParameters): Do extra validation for copyTexImage2D.
(WebCore::WebGL2RenderingContext::validateTexFuncFormatAndType): Validate internal format, format and type combination.
(WebCore::WebGL2RenderingContext::validateTexFuncData): Validate new data types.
This method now accepts an internal format argument.
(WebCore::WebGL2RenderingContext::baseInternalFormatFromInternalFormat):
Helper method to convert internal format to base internal format.
* html/canvas/WebGL2RenderingContext.h:

* html/canvas/WebGLRenderingContext.cpp:
(WebCore::WebGLRenderingContext::copyTexImage2D): Moved from WebGLRenderingContextBase.
(WebCore::WebGLRenderingContext::texSubImage2DBase): Ditto.
(WebCore::WebGLRenderingContext::texSubImage2DImpl): Ditto.
(WebCore::WebGLRenderingContext::texSubImage2D): Ditto.
(WebCore::WebGLRenderingContext::validateTexFuncParameters): Ditto.
(WebCore::WebGLRenderingContext::validateTexFuncFormatAndType): Ditto.
(WebCore::WebGLRenderingContext::validateTexFuncData): Ditto.
* html/canvas/WebGLRenderingContext.h:

* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::texImage2DBase):
(WebCore::WebGLRenderingContextBase::validateTexFunc):
(WebCore::WebGLRenderingContextBase::texImage2D):
(WebCore::WebGLRenderingContextBase::copyTexImage2D): Deleted.
(WebCore::WebGLRenderingContextBase::texSubImage2DBase): Deleted.
(WebCore::WebGLRenderingContextBase::texSubImage2DImpl): Deleted.
(WebCore::WebGLRenderingContextBase::texSubImage2D): Deleted.
(WebCore::WebGLRenderingContextBase::validateTexFuncFormatAndType): Deleted.
(WebCore::WebGLRenderingContextBase::validateTexFuncParameters): Deleted.
(WebCore::WebGLRenderingContextBase::validateTexFuncData): Deleted.
* html/canvas/WebGLRenderingContextBase.h: Modify validation type enums to differentiate between CopyImage, TexImage and TexSubImage calls.
(WebCore::ScopedDrawingBufferBinder::ScopedDrawingBufferBinder):  Moved from WebGLRenderingContextBase.
(WebCore::ScopedDrawingBufferBinder::~ScopedDrawingBufferBinder): Ditto.
(WebCore::clip1D): Ditto.
(WebCore::clip2D): Ditto.
* platform/graphics/GraphicsContext3D.h: Rename a typo'ed enum.</pre>

<h3>Modified Paths</h3>
<ul>
<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="#trunkSourceWebCoreplatformgraphicsGraphicsContext3Dh">trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (179841 => 179842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-02-09 20:27:51 UTC (rev 179841)
+++ trunk/Source/WebCore/ChangeLog        2015-02-09 20:50:15 UTC (rev 179842)
</span><span class="lines">@@ -1,3 +1,55 @@
</span><ins>+2015-02-07  Roger Fong  &lt;roger_fong@apple.com&gt;
+
+        WebGL 2: Texture call format, internal format, and type validation.
+        https://bugs.webkit.org/show_bug.cgi?id=141318.
+        &lt;rdar://problem/19733828&gt;
+
+        Reviewed by Brent Fulgham.
+
+        Tests will be covered by WebGL2 conformance tests.
+
+        * html/canvas/WebGL2RenderingContext.cpp:
+        (WebCore::WebGL2RenderingContext::getFramebufferAttachmentParameter): Add missing ExceptionCode argument.
+        (WebCore::WebGL2RenderingContext::copyTexImage2D): Validate texture formats based on GLES3 spec.
+        (WebCore::WebGL2RenderingContext::texSubImage2DBase): Validate using internal format from texture target.
+        (WebCore::WebGL2RenderingContext::texSubImage2DImpl): Validate using internal format from texture target.
+        (WebCore::WebGL2RenderingContext::texSubImage2D): Validate using internal format from texture target.
+        (WebCore::WebGL2RenderingContext::validateTexFuncParameters): Do extra validation for copyTexImage2D.
+        (WebCore::WebGL2RenderingContext::validateTexFuncFormatAndType): Validate internal format, format and type combination.
+        (WebCore::WebGL2RenderingContext::validateTexFuncData): Validate new data types.
+        This method now accepts an internal format argument.
+        (WebCore::WebGL2RenderingContext::baseInternalFormatFromInternalFormat):
+        Helper method to convert internal format to base internal format.
+        * html/canvas/WebGL2RenderingContext.h:
+
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore::WebGLRenderingContext::copyTexImage2D): Moved from WebGLRenderingContextBase.
+        (WebCore::WebGLRenderingContext::texSubImage2DBase): Ditto.
+        (WebCore::WebGLRenderingContext::texSubImage2DImpl): Ditto.
+        (WebCore::WebGLRenderingContext::texSubImage2D): Ditto.
+        (WebCore::WebGLRenderingContext::validateTexFuncParameters): Ditto.
+        (WebCore::WebGLRenderingContext::validateTexFuncFormatAndType): Ditto.
+        (WebCore::WebGLRenderingContext::validateTexFuncData): Ditto.
+        * html/canvas/WebGLRenderingContext.h:
+
+        * html/canvas/WebGLRenderingContextBase.cpp:
+        (WebCore::WebGLRenderingContextBase::texImage2DBase):
+        (WebCore::WebGLRenderingContextBase::validateTexFunc):
+        (WebCore::WebGLRenderingContextBase::texImage2D):
+        (WebCore::WebGLRenderingContextBase::copyTexImage2D): Deleted.
+        (WebCore::WebGLRenderingContextBase::texSubImage2DBase): Deleted.
+        (WebCore::WebGLRenderingContextBase::texSubImage2DImpl): Deleted.
+        (WebCore::WebGLRenderingContextBase::texSubImage2D): Deleted.
+        (WebCore::WebGLRenderingContextBase::validateTexFuncFormatAndType): Deleted.
+        (WebCore::WebGLRenderingContextBase::validateTexFuncParameters): Deleted.
+        (WebCore::WebGLRenderingContextBase::validateTexFuncData): Deleted.
+        * html/canvas/WebGLRenderingContextBase.h: Modify validation type enums to differentiate between CopyImage, TexImage and TexSubImage calls.
+        (WebCore::ScopedDrawingBufferBinder::ScopedDrawingBufferBinder):  Moved from WebGLRenderingContextBase.
+        (WebCore::ScopedDrawingBufferBinder::~ScopedDrawingBufferBinder): Ditto.
+        (WebCore::clip1D): Ditto.
+        (WebCore::clip2D): Ditto.
+        * platform/graphics/GraphicsContext3D.h: Rename a typo'ed enum.
+
</ins><span class="cx"> 2015-02-09  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r179494.
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGL2RenderingContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp (179841 => 179842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp        2015-02-09 20:27:51 UTC (rev 179841)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp        2015-02-09 20:50:15 UTC (rev 179842)
</span><span class="lines">@@ -28,16 +28,23 @@
</span><span class="cx"> #if ENABLE(WEBGL)
</span><span class="cx"> #include &quot;WebGL2RenderingContext.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;CachedImage.h&quot;
</ins><span class="cx"> #include &quot;EXTTextureFilterAnisotropic.h&quot;
</span><span class="cx"> #include &quot;Extensions3D.h&quot;
</span><ins>+#include &quot;HTMLCanvasElement.h&quot;
+#include &quot;HTMLImageElement.h&quot;
+#include &quot;HTMLVideoElement.h&quot;
+#include &quot;ImageData.h&quot;
</ins><span class="cx"> #include &quot;OESTextureFloat.h&quot;
</span><span class="cx"> #include &quot;OESTextureFloatLinear.h&quot;
</span><span class="cx"> #include &quot;OESTextureHalfFloat.h&quot;
</span><span class="cx"> #include &quot;OESTextureHalfFloatLinear.h&quot;
</span><ins>+#include &quot;RenderBox.h&quot;
</ins><span class="cx"> #include &quot;WebGLActiveInfo.h&quot;
</span><span class="cx"> #include &quot;WebGLCompressedTextureATC.h&quot;
</span><span class="cx"> #include &quot;WebGLCompressedTexturePVRTC.h&quot;
</span><span class="cx"> #include &quot;WebGLCompressedTextureS3TC.h&quot;
</span><ins>+#include &quot;WebGLContextAttributes.h&quot;
</ins><span class="cx"> #include &quot;WebGLDebugRendererInfo.h&quot;
</span><span class="cx"> #include &quot;WebGLDebugShaders.h&quot;
</span><span class="cx"> #include &quot;WebGLDepthTexture.h&quot;
</span><span class="lines">@@ -82,11 +89,12 @@
</span><span class="cx">     UNUSED_PARAM(returnedData);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-WebGLGetInfo WebGL2RenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname)
</del><ins>+WebGLGetInfo WebGL2RenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&amp; ec)
</ins><span class="cx"> {
</span><span class="cx">     UNUSED_PARAM(target);
</span><span class="cx">     UNUSED_PARAM(attachment);
</span><span class="cx">     UNUSED_PARAM(pname);
</span><ins>+    UNUSED_PARAM(ec);
</ins><span class="cx">     return WebGLGetInfo();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -900,6 +908,812 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+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()) {
+        ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+        m_context-&gt;copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+    } else {
+        ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+        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, ExceptionCode&amp; ec)
+{
+    ec = 0;
+    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, ExceptionCode&amp; ec)
+{
+    ec = 0;
+    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, ec);
+    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, ArrayBufferView* pixels, ExceptionCode&amp; ec)
+{
+    if (isContextLostOrPending() || !validateTexFuncData(&quot;texSubImage2D&quot;, level, width, height, GraphicsContext3D::NONE, format, type, pixels, 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, ec);
+    if (changeUnpackAlignment)
+        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode&amp; ec)
+{
+    ec = 0;
+    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, 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(), ec);
+    if (m_unpackAlignment != 1)
+        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode&amp; ec)
+{
+    ec = 0;
+    if (isContextLostOrPending() || !validateHTMLImageElement(&quot;texSubImage2D&quot;, image, ec))
+        return;
+    
+    RefPtr&lt;Image&gt; imageForRender = image-&gt;cachedImage()-&gt;imageForRenderer(image-&gt;renderer());
+    if (imageForRender-&gt;isSVGImage())
+        imageForRender = drawImageIntoBuffer(imageForRender.get(), 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, ec);
+}
+
+void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+    GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode&amp; ec)
+{
+    ec = 0;
+    if (isContextLostOrPending() || !validateHTMLCanvasElement(&quot;texSubImage2D&quot;, canvas, ec)
+        || !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, imageData.get(), ec);
+    else
+        texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas-&gt;copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+
+#if ENABLE(VIDEO)
+void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode&amp; ec)
+{
+    ec = 0;
+    if (isContextLostOrPending() || !validateHTMLVideoElement(&quot;texSubImage2D&quot;, video, ec)
+        || !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, ImageBuffer::fastCopyImageMode(), ec);
+    if (!image)
+        return;
+    texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+#endif
+
+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;
+        }
+
+        ExceptionCode ec;
+        bool isSRGB = (getFramebufferAttachmentParameter(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, ec).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::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) {
+            error = 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;
+}
+
+GC3Denum WebGL2RenderingContext::baseInternalFormatFromInternalFormat(GC3Denum internalformat)
+{
+    // Handles sized, unsized, and compressed internal formats.
+    switch (internalformat) {
+    case GraphicsContext3D::R8:
+    case GraphicsContext3D::R8_SNORM:
+    case GraphicsContext3D::R16F:
+    case GraphicsContext3D::R32F:
+    case GraphicsContext3D::R8I:
+    case GraphicsContext3D::R8UI:
+    case GraphicsContext3D::R16I:
+    case GraphicsContext3D::R16UI:
+    case GraphicsContext3D::R32I:
+    case GraphicsContext3D::R32UI:
+    case GraphicsContext3D::COMPRESSED_R11_EAC:
+    case GraphicsContext3D::COMPRESSED_SIGNED_R11_EAC:
+        return GraphicsContext3D::RED;
+    case GraphicsContext3D::RG8:
+    case GraphicsContext3D::RG8_SNORM:
+    case GraphicsContext3D::RG16F:
+    case GraphicsContext3D::RG32F:
+    case GraphicsContext3D::RG8I:
+    case GraphicsContext3D::RG8UI:
+    case GraphicsContext3D::RG16I:
+    case GraphicsContext3D::RG16UI:
+    case GraphicsContext3D::RG32I:
+    case GraphicsContext3D::RG32UI:
+    case GraphicsContext3D::COMPRESSED_RG11_EAC:
+    case GraphicsContext3D::COMPRESSED_SIGNED_RG11_EAC:
+        return GraphicsContext3D::RG;
+    case GraphicsContext3D::RGB8:
+    case GraphicsContext3D::RGB8_SNORM:
+    case GraphicsContext3D::RGB565:
+    case GraphicsContext3D::SRGB8:
+    case GraphicsContext3D::RGB16F:
+    case GraphicsContext3D::RGB32F:
+    case GraphicsContext3D::RGB8I:
+    case GraphicsContext3D::RGB8UI:
+    case GraphicsContext3D::RGB16I:
+    case GraphicsContext3D::RGB16UI:
+    case GraphicsContext3D::RGB32I:
+    case GraphicsContext3D::RGB32UI:
+    case GraphicsContext3D::RGB:
+    case GraphicsContext3D::COMPRESSED_RGB8_ETC2:
+    case GraphicsContext3D::COMPRESSED_SRGB8_ETC2:
+        return GraphicsContext3D::RGB;
+    case GraphicsContext3D::RGBA4:
+    case GraphicsContext3D::RGB5_A1:
+    case GraphicsContext3D::RGBA8:
+    case GraphicsContext3D::RGBA8_SNORM:
+    case GraphicsContext3D::RGB10_A2:
+    case GraphicsContext3D::RGB10_A2UI:
+    case GraphicsContext3D::SRGB8_ALPHA8:
+    case GraphicsContext3D::RGBA16F:
+    case GraphicsContext3D::RGBA32F:
+    case GraphicsContext3D::RGBA8I:
+    case GraphicsContext3D::RGBA8UI:
+    case GraphicsContext3D::RGBA16I:
+    case GraphicsContext3D::RGBA16UI:
+    case GraphicsContext3D::RGBA32I:
+    case GraphicsContext3D::RGBA32UI:
+    case GraphicsContext3D::RGBA:
+    case GraphicsContext3D::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+    case GraphicsContext3D::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+    case GraphicsContext3D::COMPRESSED_RGBA8_ETC2_EAC:
+    case GraphicsContext3D::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+        return GraphicsContext3D::RGBA;
+    case GraphicsContext3D::DEPTH_COMPONENT16:
+    case GraphicsContext3D::DEPTH_COMPONENT24:
+    case GraphicsContext3D::DEPTH_COMPONENT32F:
+        return GraphicsContext3D::DEPTH_COMPONENT;
+    case GraphicsContext3D::DEPTH24_STENCIL8:
+    case GraphicsContext3D::DEPTH32F_STENCIL8:
+        return GraphicsContext3D::DEPTH_STENCIL;
+    case GraphicsContext3D::LUMINANCE:
+    case GraphicsContext3D::LUMINANCE_ALPHA:
+    case GraphicsContext3D::ALPHA:
+        return internalformat;
+    default:
+        ASSERT_NOT_REACHED();
+        return GraphicsContext3D::NONE;
+    }
+}
+
</ins><span class="cx"> WebGLGetInfo WebGL2RenderingContext::getParameter(GC3Denum pname, ExceptionCode&amp; ec)
</span><span class="cx"> {
</span><span class="cx">     UNUSED_PARAM(ec);
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGL2RenderingContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h (179841 => 179842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h        2015-02-09 20:27:51 UTC (rev 179841)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h        2015-02-09 20:50:15 UTC (rev 179842)
</span><span class="lines">@@ -48,7 +48,7 @@
</span><span class="cx">     void getBufferSubData(GC3Denum target, GC3Dint64 offset, ArrayBuffer* returnedData);
</span><span class="cx">     
</span><span class="cx">     /* Framebuffer objects */
</span><del>-    WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname);
</del><ins>+    WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&amp;);
</ins><span class="cx">     void blitFramebuffer(GC3Dint srcX0, GC3Dint srcY0, GC3Dint srcX1, GC3Dint srcY1, GC3Dint dstX0, GC3Dint dstY0, GC3Dint dstX1, GC3Dint dstY1, GC3Dbitfield mask, GC3Denum filter);
</span><span class="cx">     void framebufferTextureLayer(GC3Denum target, GC3Denum attachment, GC3Duint texture, GC3Dint level, GC3Dint layer);
</span><span class="cx">     WebGLGetInfo getInternalformatParameter(GC3Denum target, GC3Denum internalformat, GC3Denum pname);
</span><span class="lines">@@ -169,7 +169,41 @@
</span><span class="cx">     virtual Vector&lt;String&gt; getSupportedExtensions() override;
</span><span class="cx"> 
</span><span class="cx">     virtual WebGLGetInfo getParameter(GC3Denum pname, ExceptionCode&amp;) override;
</span><del>-    bool validateCapability(const char* functionName, GC3Denum cap) override;
</del><ins>+    
+    virtual void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) override;
+    virtual void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&amp;) override;
+    virtual void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&amp;) override;
+    virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+        GC3Dsizei width, GC3Dsizei height,
+        GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&amp;) override;
+    virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+        GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&amp;) override;
+    virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+        GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&amp;) override;
+    virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+        GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&amp;) override;
+#if ENABLE(VIDEO)
+    virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+        GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&amp;) override;
+#endif
+
+protected:
+    virtual bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) override;
+    virtual bool validateTexFuncParameters(const char* functionName,
+        TexFuncValidationFunctionType,
+        GC3Denum target, GC3Dint level,
+        GC3Denum internalformat,
+        GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+        GC3Denum format, GC3Denum type) override;
+    virtual bool validateTexFuncData(const char* functionName, GC3Dint level,
+        GC3Dsizei width, GC3Dsizei height,
+        GC3Denum internalformat, GC3Denum format, GC3Denum type,
+        ArrayBufferView* pixels,
+        NullDisposition) override;
+    virtual bool validateCapability(const char* functionName, GC3Denum cap) override;
+    
+private:
+    GC3Denum baseInternalFormatFromInternalFormat(GC3Denum internalformat);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp (179841 => 179842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp        2015-02-09 20:27:51 UTC (rev 179841)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp        2015-02-09 20:50:15 UTC (rev 179842)
</span><span class="lines">@@ -29,12 +29,17 @@
</span><span class="cx"> #include &quot;WebGLRenderingContext.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ANGLEInstancedArrays.h&quot;
</span><ins>+#include &quot;CachedImage.h&quot;
</ins><span class="cx"> #include &quot;EXTBlendMinMax.h&quot;
</span><span class="cx"> #include &quot;EXTFragDepth.h&quot;
</span><span class="cx"> #include &quot;EXTShaderTextureLOD.h&quot;
</span><span class="cx"> #include &quot;EXTTextureFilterAnisotropic.h&quot;
</span><span class="cx"> #include &quot;EXTsRGB.h&quot;
</span><span class="cx"> #include &quot;Extensions3D.h&quot;
</span><ins>+#include &quot;HTMLCanvasElement.h&quot;
+#include &quot;HTMLImageElement.h&quot;
+#include &quot;HTMLVideoElement.h&quot;
+#include &quot;ImageData.h&quot;
</ins><span class="cx"> #include &quot;OESElementIndexUint.h&quot;
</span><span class="cx"> #include &quot;OESStandardDerivatives.h&quot;
</span><span class="cx"> #include &quot;OESTextureFloat.h&quot;
</span><span class="lines">@@ -42,6 +47,7 @@
</span><span class="cx"> #include &quot;OESTextureHalfFloat.h&quot;
</span><span class="cx"> #include &quot;OESTextureHalfFloatLinear.h&quot;
</span><span class="cx"> #include &quot;OESVertexArrayObject.h&quot;
</span><ins>+#include &quot;RenderBox.h&quot;
</ins><span class="cx"> #include &quot;WebGLCompressedTextureATC.h&quot;
</span><span class="cx"> #include &quot;WebGLCompressedTexturePVRTC.h&quot;
</span><span class="cx"> #include &quot;WebGLCompressedTextureS3TC.h&quot;
</span><span class="lines">@@ -281,6 +287,454 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+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()) {
+        ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+        m_context-&gt;copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+    } else {
+        ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+        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, ExceptionCode&amp; ec)
+{
+    UNUSED_PARAM(internalformat);
+    // FIXME: For now we ignore any errors returned
+    ec = 0;
+    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, ExceptionCode&amp; ec)
+{
+    ec = 0;
+    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, ec);
+    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, ArrayBufferView* pixels, ExceptionCode&amp; ec)
+{
+    if (isContextLostOrPending() || !validateTexFuncData(&quot;texSubImage2D&quot;, level, width, height, format, format, type, pixels, 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, ec);
+    if (changeUnpackAlignment)
+        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode&amp; ec)
+{
+    ec = 0;
+    if (isContextLostOrPending() || !pixels || !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, 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(), ec);
+    if (m_unpackAlignment != 1)
+        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode&amp; ec)
+{
+    ec = 0;
+    if (isContextLostOrPending() || !validateHTMLImageElement(&quot;texSubImage2D&quot;, image, ec))
+        return;
+    
+    RefPtr&lt;Image&gt; imageForRender = image-&gt;cachedImage()-&gt;imageForRenderer(image-&gt;renderer());
+    if (imageForRender-&gt;isSVGImage())
+        imageForRender = drawImageIntoBuffer(imageForRender.get(), 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, ec);
+}
+
+void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode&amp; ec)
+{
+    ec = 0;
+    if (isContextLostOrPending() || !validateHTMLCanvasElement(&quot;texSubImage2D&quot;, canvas, ec)
+        || !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, imageData.get(), ec);
+    else
+        texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas-&gt;copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+
+#if ENABLE(VIDEO)
+void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode&amp; ec)
+{
+    ec = 0;
+    if (isContextLostOrPending() || !validateHTMLVideoElement(&quot;texSubImage2D&quot;, video, ec)
+        || !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, ImageBuffer::fastCopyImageMode(), ec);
+    if (!image)
+        return;
+    texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+#endif
+
+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) {
+            error = 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;
+}
+
</ins><span class="cx"> WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode&amp; ec)
</span><span class="cx"> {
</span><span class="cx">     UNUSED_PARAM(ec);
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h (179841 => 179842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h        2015-02-09 20:27:51 UTC (rev 179841)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h        2015-02-09 20:50:15 UTC (rev 179842)
</span><span class="lines">@@ -39,7 +39,38 @@
</span><span class="cx">     virtual WebGLExtension* getExtension(const String&amp;) override;
</span><span class="cx">     virtual WebGLGetInfo getParameter(GC3Denum pname, ExceptionCode&amp;) override;
</span><span class="cx">     virtual Vector&lt;String&gt; getSupportedExtensions() override;
</span><del>-    bool validateCapability(const char* functionName, GC3Denum cap) override;
</del><ins>+
+    virtual void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) override;
+    virtual void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&amp;) override;
+    virtual void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&amp;) override;
+    virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+        GC3Dsizei width, GC3Dsizei height,
+        GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&amp;) override;
+    virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+        GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&amp;) override;
+    virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+        GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&amp;) override;
+    virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+        GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&amp;) override;
+#if ENABLE(VIDEO)
+    virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+        GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&amp;) override;
+#endif
+
+protected:
+    virtual bool validateTexFuncParameters(const char* functionName,
+        TexFuncValidationFunctionType,
+        GC3Denum target, GC3Dint level,
+        GC3Denum internalformat,
+        GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+        GC3Denum format, GC3Denum type) override;
+    virtual bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) override;
+    virtual bool validateTexFuncData(const char* functionName, GC3Dint level,
+        GC3Dsizei width, GC3Dsizei height,
+        GC3Denum internalformat, GC3Denum format, GC3Denum type,
+        ArrayBufferView* pixels,
+        NullDisposition) override;
+    virtual bool validateCapability(const char* functionName, GC3Denum cap) override;
</ins><span class="cx"> };
</span><span class="cx">     
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContextBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (179841 => 179842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp        2015-02-09 20:27:51 UTC (rev 179841)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp        2015-02-09 20:50:15 UTC (rev 179842)
</span><span class="lines">@@ -99,60 +99,12 @@
</span><span class="cx"> const int maxGLErrorsAllowedToConsole = 256;
</span><span class="cx"> 
</span><span class="cx"> namespace {
</span><del>-
-    class ScopedDrawingBufferBinder {
-    public:
-        ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* framebufferBinding)
-            : m_drawingBuffer(drawingBuffer)
-            , m_framebufferBinding(framebufferBinding)
-        {
-            // Commit DrawingBuffer if needed (e.g., for multisampling)
-            if (!m_framebufferBinding &amp;&amp; m_drawingBuffer)
-                m_drawingBuffer-&gt;commit();
-        }
-
-        ~ScopedDrawingBufferBinder()
-        {
-            // Restore DrawingBuffer if needed
-            if (!m_framebufferBinding &amp;&amp; m_drawingBuffer)
-                m_drawingBuffer-&gt;bind();
-        }
-
-    private:
-        DrawingBuffer* m_drawingBuffer;
-        WebGLFramebuffer* m_framebufferBinding;
-    };
-
</del><ins>+    
</ins><span class="cx">     Platform3DObject objectOrZero(WebGLObject* object)
</span><span class="cx">     {
</span><span class="cx">         return object ? object-&gt;object() : 0;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void clip1D(GC3Dint start, GC3Dsizei range, GC3Dsizei sourceRange, GC3Dint* clippedStart, GC3Dsizei* clippedRange)
-    {
-        ASSERT(clippedStart &amp;&amp; clippedRange);
-        if (start &lt; 0) {
-            range += start;
-            start = 0;
-        }
-        GC3Dint end = start + range;
-        if (end &gt; sourceRange)
-            range -= end - sourceRange;
-        *clippedStart = start;
-        *clippedRange = range;
-    }
-
-    // Returns false if no clipping is necessary, i.e., x, y, width, height stay the same.
-    bool clip2D(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height,
-                GC3Dsizei sourceWidth, GC3Dsizei sourceHeight,
-                GC3Dint* clippedX, GC3Dint* clippedY, GC3Dsizei* clippedWidth, GC3Dsizei*clippedHeight)
-    {
-        ASSERT(clippedX &amp;&amp; clippedY &amp;&amp; clippedWidth &amp;&amp; clippedHeight);
-        clip1D(x, width, sourceWidth, clippedX, clippedWidth);
-        clip1D(y, height, sourceHeight, clippedY, clippedHeight);
-        return (*clippedX != x || *clippedY != y || *clippedWidth != width || *clippedHeight != height);
-    }
-
</del><span class="cx">     GC3Dint clamp(GC3Dint value, GC3Dint min, GC3Dint max)
</span><span class="cx">     {
</span><span class="cx">         if (value &lt; min)
</span><span class="lines">@@ -1442,52 +1394,6 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-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;, NotTexSubImage2D, 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()) {
-        ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
-        m_context-&gt;copyTexImage2D(target, level, internalformat, x, y, width, height, border);
-    } else {
-        ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
-        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);
-}
-
</del><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="cx"> {
</span><span class="cx">     if (isContextLostOrPending())
</span><span class="lines">@@ -3547,7 +3453,7 @@
</span><span class="cx">     // FIXME: For now we ignore any errors returned.
</span><span class="cx">     ec = 0;
</span><span class="cx">     WebGLTexture* tex = validateTextureBinding(&quot;texImage2D&quot;, target, true);
</span><del>-    ASSERT(validateTexFuncParameters(&quot;texImage2D&quot;, NotTexSubImage2D, 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(!level || !WebGLTexture::isNPOT(width, height));
</span><span class="cx">     if (!pixels) {
</span><span class="lines">@@ -3616,7 +3522,7 @@
</span><span class="cx">     if (!texture)
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    if (functionType == NotTexSubImage2D) {
</del><ins>+    if (functionType != TexSubImage) {
</ins><span class="cx">         if (level &amp;&amp; WebGLTexture::isNPOT(width, height)) {
</span><span class="cx">             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;level &gt; 0 not power of 2&quot;);
</span><span class="cx">             return false;
</span><span class="lines">@@ -3654,8 +3560,8 @@
</span><span class="cx">                                        GC3Dsizei width, GC3Dsizei height, GC3Dint border,
</span><span class="cx">                                        GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode&amp; ec)
</span><span class="cx"> {
</span><del>-    if (isContextLostOrPending() || !validateTexFuncData(&quot;texImage2D&quot;, level, width, height, format, type, pixels, NullAllowed)
-        || !validateTexFunc(&quot;texImage2D&quot;, NotTexSubImage2D, 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, 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">@@ -3682,7 +3588,7 @@
</span><span class="cx">                                        GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode&amp; ec)
</span><span class="cx"> {
</span><span class="cx">     ec = 0;
</span><del>-    if (isContextLostOrPending() || !pixels || !validateTexFunc(&quot;texImage2D&quot;, NotTexSubImage2D, SourceImageData, target, level, internalformat, pixels-&gt;width(), pixels-&gt;height(), 0, format, type, 0, 0))
</del><ins>+    if (isContextLostOrPending() || !pixels || !validateTexFunc(&quot;texImage2D&quot;, TexImage, SourceImageData, target, level, internalformat, pixels-&gt;width(), pixels-&gt;height(), 0, format, type, 0, 0))
</ins><span class="cx">         return;
</span><span class="cx">     Vector&lt;uint8_t&gt; data;
</span><span class="cx">     bool needConversion = true;
</span><span class="lines">@@ -3730,7 +3636,7 @@
</span><span class="cx">     if (imageForRender-&gt;isSVGImage())
</span><span class="cx">         imageForRender = drawImageIntoBuffer(imageForRender.get(), image-&gt;width(), image-&gt;height(), 1);
</span><span class="cx"> 
</span><del>-    if (!imageForRender || !validateTexFunc(&quot;texImage2D&quot;, NotTexSubImage2D, SourceHTMLImageElement, target, level, internalformat, imageForRender-&gt;width(), imageForRender-&gt;height(), 0, format, type, 0, 0))
</del><ins>+    if (!imageForRender || !validateTexFunc(&quot;texImage2D&quot;, TexImage, SourceHTMLImageElement, target, level, internalformat, imageForRender-&gt;width(), imageForRender-&gt;height(), 0, format, type, 0, 0))
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
</span><span class="lines">@@ -3740,7 +3646,7 @@
</span><span class="cx">                                        GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode&amp; ec)
</span><span class="cx"> {
</span><span class="cx">     ec = 0;
</span><del>-    if (isContextLostOrPending() || !validateHTMLCanvasElement(&quot;texImage2D&quot;, canvas, ec) || !validateTexFunc(&quot;texImage2D&quot;, NotTexSubImage2D, SourceHTMLCanvasElement, target, level, internalformat, canvas-&gt;width(), canvas-&gt;height(), 0, format, type, 0, 0))
</del><ins>+    if (isContextLostOrPending() || !validateHTMLCanvasElement(&quot;texImage2D&quot;, canvas, ec) || !validateTexFunc(&quot;texImage2D&quot;, TexImage, SourceHTMLCanvasElement, target, level, internalformat, canvas-&gt;width(), canvas-&gt;height(), 0, format, type, 0, 0))
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     WebGLTexture* texture = validateTextureBinding(&quot;texImage2D&quot;, target, true);
</span><span class="lines">@@ -3785,7 +3691,7 @@
</span><span class="cx"> {
</span><span class="cx">     ec = 0;
</span><span class="cx">     if (isContextLostOrPending() || !validateHTMLVideoElement(&quot;texImage2D&quot;, video, ec)
</span><del>-        || !validateTexFunc(&quot;texImage2D&quot;, NotTexSubImage2D, SourceHTMLVideoElement, target, level, internalformat, video-&gt;videoWidth(), video-&gt;videoHeight(), 0, format, type, 0, 0))
</del><ins>+        || !validateTexFunc(&quot;texImage2D&quot;, TexImage, SourceHTMLVideoElement, target, level, internalformat, video-&gt;videoWidth(), video-&gt;videoHeight(), 0, format, type, 0, 0))
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
</span><span class="lines">@@ -3860,159 +3766,6 @@
</span><span class="cx">     texParameter(target, pname, 0, param, false);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebGLRenderingContextBase::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&amp; ec)
-{
-    // FIXME: For now we ignore any errors returned
-    ec = 0;
-    ASSERT(!isContextLost());
-    ASSERT(validateTexFuncParameters(&quot;texSubImage2D&quot;, TexSubImage2D, 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 WebGLRenderingContextBase::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionCode&amp; ec)
-{
-    ec = 0;
-    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, type,  needConversion ? data.data() : imagePixelData, ec);
-    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, ArrayBufferView* pixels, ExceptionCode&amp; ec)
-{
-    if (isContextLostOrPending() || !validateTexFuncData(&quot;texSubImage2D&quot;, level, width, height, format, type, pixels, NullNotAllowed)
-        || !validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage2D, 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, type, data, ec);
-    if (changeUnpackAlignment)
-        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
-                                          GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode&amp; ec)
-{
-    ec = 0;
-    if (isContextLostOrPending() || !pixels || !validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage2D, 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, 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, type, needConversion ? data.data() : pixels-&gt;data()-&gt;data(), ec);
-    if (m_unpackAlignment != 1)
-        m_context-&gt;pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
-                                          GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode&amp; ec)
-{
-    ec = 0;
-    if (isContextLostOrPending() || !validateHTMLImageElement(&quot;texSubImage2D&quot;, image, ec))
-        return;
-
-    RefPtr&lt;Image&gt; imageForRender = image-&gt;cachedImage()-&gt;imageForRenderer(image-&gt;renderer());
-    if (imageForRender-&gt;isSVGImage())
-        imageForRender = drawImageIntoBuffer(imageForRender.get(), image-&gt;width(), image-&gt;height(), 1);
-
-    if (!imageForRender || !validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage2D, 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, ec);
-}
-
-void WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
-                                          GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode&amp; ec)
-{
-    ec = 0;
-    if (isContextLostOrPending() || !validateHTMLCanvasElement(&quot;texSubImage2D&quot;, canvas, ec)
-        || !validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage2D, 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, imageData.get(), ec);
-    else
-        texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas-&gt;copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-
-#if ENABLE(VIDEO)
-void WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
-                                          GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode&amp; ec)
-{
-    ec = 0;
-    if (isContextLostOrPending() || !validateHTMLVideoElement(&quot;texSubImage2D&quot;, video, ec)
-        || !validateTexFunc(&quot;texSubImage2D&quot;, TexSubImage2D, SourceHTMLVideoElement, target, level, format, video-&gt;videoWidth(), video-&gt;videoHeight(), 0, format, type, xoffset, yoffset))
-        return;
-
-    RefPtr&lt;Image&gt; image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode(), ec);
-    if (!image)
-        return;
-    texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-#endif
-
</del><span class="cx"> void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GC3Dfloat x, ExceptionCode&amp; ec)
</span><span class="cx"> {
</span><span class="cx">     UNUSED_PARAM(ec);
</span><span class="lines">@@ -4863,128 +4616,6 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool WebGLRenderingContextBase::validateTexFuncFormatAndType(const char* functionName, 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)
-            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;
-}
-
</del><span class="cx"> bool WebGLRenderingContextBase::validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level)
</span><span class="cx"> {
</span><span class="cx">     if (level &lt; 0) {
</span><span class="lines">@@ -5015,138 +4646,6 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-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, 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 != TexSubImage2D &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 WebGLRenderingContextBase::validateTexFuncData(const char* functionName, GC3Dint level,
-                                                GC3Dsizei width, GC3Dsizei height,
-                                                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, 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 int 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) {
-          error = 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"> bool WebGLRenderingContextBase::validateCompressedTexFormat(GC3Denum format)
</span><span class="cx"> {
</span><span class="cx">     return m_compressedTextureFormats.contains(format);
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContextBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (179841 => 179842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h        2015-02-09 20:27:51 UTC (rev 179841)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h        2015-02-09 20:50:15 UTC (rev 179842)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;ImageBuffer.h&quot;
</span><span class="cx"> #include &quot;Timer.h&quot;
</span><span class="cx"> #include &quot;WebGLGetInfo.h&quot;
</span><ins>+#include &quot;WebGLObject.h&quot;
</ins><span class="cx"> #include &lt;memory&gt;
</span><span class="cx"> #include &lt;runtime/Float32Array.h&gt;
</span><span class="cx"> #include &lt;runtime/Int32Array.h&gt;
</span><span class="lines">@@ -85,6 +86,54 @@
</span><span class="cx"> 
</span><span class="cx"> typedef int ExceptionCode;
</span><span class="cx"> 
</span><ins>+class ScopedDrawingBufferBinder {
+public:
+    ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* framebufferBinding)
+        : m_drawingBuffer(drawingBuffer)
+        , m_framebufferBinding(framebufferBinding)
+    {
+        // Commit DrawingBuffer if needed (e.g., for multisampling)
+        if (!m_framebufferBinding &amp;&amp; m_drawingBuffer)
+            m_drawingBuffer-&gt;commit();
+    }
+    
+    ~ScopedDrawingBufferBinder()
+    {
+        // Restore DrawingBuffer if needed
+        if (!m_framebufferBinding &amp;&amp; m_drawingBuffer)
+            m_drawingBuffer-&gt;bind();
+    }
+    
+private:
+    DrawingBuffer* m_drawingBuffer;
+    WebGLFramebuffer* m_framebufferBinding;
+};
+
+inline void clip1D(GC3Dint start, GC3Dsizei range, GC3Dsizei sourceRange, GC3Dint* clippedStart, GC3Dsizei* clippedRange)
+{
+    ASSERT(clippedStart &amp;&amp; clippedRange);
+    if (start &lt; 0) {
+        range += start;
+        start = 0;
+    }
+    GC3Dint end = start + range;
+    if (end &gt; sourceRange)
+        range -= end - sourceRange;
+    *clippedStart = start;
+    *clippedRange = range;
+}
+
+// Returns false if no clipping is necessary, i.e., x, y, width, height stay the same.
+inline bool clip2D(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height,
+    GC3Dsizei sourceWidth, GC3Dsizei sourceHeight,
+    GC3Dint* clippedX, GC3Dint* clippedY, GC3Dsizei* clippedWidth, GC3Dsizei*clippedHeight)
+{
+    ASSERT(clippedX &amp;&amp; clippedY &amp;&amp; clippedWidth &amp;&amp; clippedHeight);
+    clip1D(x, width, sourceWidth, clippedX, clippedWidth);
+    clip1D(y, height, sourceHeight, clippedY, clippedHeight);
+    return (*clippedX != x || *clippedY != y || *clippedWidth != width || *clippedHeight != height);
+}
+
</ins><span class="cx"> class WebGLRenderingContextBase : public CanvasRenderingContext, public ActiveDOMObject {
</span><span class="cx"> public:
</span><span class="cx">     static std::unique_ptr&lt;WebGLRenderingContextBase&gt; create(HTMLCanvasElement*, WebGLContextAttributes*, const String&amp;);
</span><span class="lines">@@ -132,7 +181,7 @@
</span><span class="cx">     void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
</span><span class="cx">                                  GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data);
</span><span class="cx"> 
</span><del>-    void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border);
</del><ins>+    virtual void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) = 0;
</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">     PassRefPtr&lt;WebGLBuffer&gt; createBuffer();
</span><span class="lines">@@ -237,18 +286,18 @@
</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>-    void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
-                       GC3Dsizei width, GC3Dsizei height,
-                       GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&amp;);
-    void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
-                       GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&amp;);
-    void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
-                       GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&amp;);
-    void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
-                       GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&amp;);
</del><ins>+    virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+        GC3Dsizei width, GC3Dsizei height,
+        GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&amp;) = 0;
+    virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+        GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&amp;) = 0;
+    virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+        GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&amp;) = 0;
+    virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+        GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&amp;) = 0;
</ins><span class="cx"> #if ENABLE(VIDEO)
</span><del>-    void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
-                       GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&amp;);
</del><ins>+    virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+        GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&amp;) = 0;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     void uniform1f(const WebGLUniformLocation* location, GC3Dfloat x, ExceptionCode&amp;);
</span><span class="lines">@@ -584,8 +633,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, ExceptionCode&amp;);
</span><span class="cx">     void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&amp;);
</span><del>-    void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&amp;);
-    void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&amp;);
</del><ins>+    virtual void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&amp;) = 0;
+    virtual void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&amp;) = 0;
</ins><span class="cx"> 
</span><span class="cx">     void checkTextureCompleteness(const char*, bool);
</span><span class="cx"> 
</span><span class="lines">@@ -624,15 +673,16 @@
</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>-    bool validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type, GC3Dint level);
</del><ins>+    virtual bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) = 0;
</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="cx">     bool validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level);
</span><span class="cx"> 
</span><span class="cx">     enum TexFuncValidationFunctionType {
</span><del>-        NotTexSubImage2D,
-        TexSubImage2D,
</del><ins>+        TexImage,
+        TexSubImage,
+        CopyTexImage
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     enum TexFuncValidationSourceType {
</span><span class="lines">@@ -650,12 +700,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>-    bool validateTexFuncParameters(const char* functionName,
-                                   TexFuncValidationFunctionType,
-                                   GC3Denum target, GC3Dint level,
-                                   GC3Denum internalformat,
-                                   GC3Dsizei width, GC3Dsizei height, GC3Dint border,
-                                   GC3Denum format, GC3Denum type);
</del><ins>+    virtual bool validateTexFuncParameters(const char* functionName,
+        TexFuncValidationFunctionType,
+        GC3Denum target, GC3Dint level,
+        GC3Denum internalformat,
+        GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+        GC3Denum format, GC3Denum type) = 0;
</ins><span class="cx"> 
</span><span class="cx">     enum NullDisposition {
</span><span class="cx">         NullAllowed,
</span><span class="lines">@@ -665,11 +715,11 @@
</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>-    bool validateTexFuncData(const char* functionName, GC3Dint level,
-                             GC3Dsizei width, GC3Dsizei height,
-                             GC3Denum format, GC3Denum type,
-                             ArrayBufferView* pixels,
-                             NullDisposition);
</del><ins>+    virtual bool validateTexFuncData(const char* functionName, GC3Dint level,
+        GC3Dsizei width, GC3Dsizei height,
+        GC3Denum internalformat, GC3Denum format, GC3Denum type,
+        ArrayBufferView* pixels,
+        NullDisposition) = 0;
</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></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsContext3Dh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h (179841 => 179842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h        2015-02-09 20:27:51 UTC (rev 179841)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h        2015-02-09 20:50:15 UTC (rev 179842)
</span><span class="lines">@@ -508,7 +508,7 @@
</span><span class="cx">         COMPARE_REF_TO_TEXTURE = 0x884E,
</span><span class="cx">         RGBA32F = 0x8814,
</span><span class="cx">         RGB32F = 0x8815,
</span><del>-        RGBA16 = 0x881A,
</del><ins>+        RGBA16F = 0x881A,
</ins><span class="cx">         RGB16F = 0x881B,
</span><span class="cx">         VERTEX_ATTRIB_ARRAY_INTEGER = 0x88FD,
</span><span class="cx">         MAX_ARRAY_TEXTURE_LAYERS = 0x88FF,
</span></span></pre>
</div>
</div>

</body>
</html>