<!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>[208910] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/208910">208910</a></dd>
<dt>Author</dt> <dd>mmaxfield@apple.com</dd>
<dt>Date</dt> <dd>2016-11-18 17:00:16 -0800 (Fri, 18 Nov 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>[WebGL2] Implement texStorage2D()
https://bugs.webkit.org/show_bug.cgi?id=164493
Reviewed by Dean Jackson.
Source/WebCore:
Create a new validation function which only accepts sized internalFormats.
After running texStorage2D(), we also texSubImage2D() to zero-fill it. This
is to compensate for potentially buggy drivers.
Because glTexStorage2D() was only added to OpenGL in version 4.2, not all
OpenGL 3.2+ contexts can implement this command. However, according to
https://developer.apple.com/opengl/capabilities/ all Apple GPUs have the
GL_ARB_texture_storage which implements this call. In the future, we could
implement texStorage2D() on top of texImage2D() if there are any ports which
want WebGL2 but don't have 4.2 and don't have the extension.
Also, when calling texStorage2D, callers specify an internalFormat but not a
type/format pair. This means that storing the texture's type is only valid
for WebGL 1 contexts. This patch surrounds all calls to reading the texture
type with guards and adds an ASSERT() at the read site to make sure the
right thing is happening.
Test: fast/canvas/webgl/webgl2-texStorage.html
* html/canvas/WebGL2RenderingContext.cpp:
(WebCore::WebGL2RenderingContext::validateTexStorageFuncParameters):
(WebCore::WebGL2RenderingContext::texStorage2D):
* html/canvas/WebGL2RenderingContext.h:
* html/canvas/WebGLRenderingContext.cpp:
(WebCore::WebGLRenderingContext::validateIndexArrayConservative):
* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::create):
(WebCore::WebGLRenderingContextBase::copyTexSubImage2D):
(WebCore::WebGLRenderingContextBase::validateTexFunc):
(WebCore::WebGLRenderingContextBase::validateTexFuncData):
(WebCore::WebGLRenderingContextBase::texImage2D):
* html/canvas/WebGLTexture.cpp:
(WebCore::WebGLTexture::WebGLTexture):
(WebCore::WebGLTexture::getType):
(WebCore::WebGLTexture::needToUseBlackTexture):
(WebCore::WebGLTexture::canGenerateMipmaps):
(WebCore::internalFormatIsFloatType):
(WebCore::internalFormatIsHalfFloatType):
(WebCore::WebGLTexture::update):
* html/canvas/WebGLTexture.h:
* platform/graphics/GraphicsContext3D.cpp:
(WebCore::GraphicsContext3D::texImage2DResourceSafe):
(WebCore::GraphicsContext3D::packImageData):
(WebCore::GraphicsContext3D::extractImageData):
* platform/graphics/GraphicsContext3D.h:
* platform/graphics/opengl/Extensions3DOpenGLCommon.cpp:
(WebCore::Extensions3DOpenGLCommon::initializeAvailableExtensions):
* platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp:
(WebCore::GraphicsContext3D::texStorage2D):
(WebCore::GraphicsContext3D::texStorage3D):
LayoutTests:
* fast/canvas/webgl/webgl2-texStorage-expected.txt: Added.
* fast/canvas/webgl/webgl2-texStorage.html: Added.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGL2RenderingContextcpp">trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGL2RenderingContexth">trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGLRenderingContextcpp">trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGLRenderingContextBasecpp">trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGLTexturecpp">trunk/Source/WebCore/html/canvas/WebGLTexture.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGLTextureh">trunk/Source/WebCore/html/canvas/WebGLTexture.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsContext3Dcpp">trunk/Source/WebCore/platform/graphics/GraphicsContext3D.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsContext3Dh">trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsopenglExtensions3DOpenGLCommoncpp">trunk/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsopenglGraphicsContext3DOpenGLCommoncpp">trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastcanvaswebglwebgl2texStorageexpectedtxt">trunk/LayoutTests/fast/canvas/webgl/webgl2-texStorage-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcanvaswebglwebgl2texStoragehtml">trunk/LayoutTests/fast/canvas/webgl/webgl2-texStorage.html</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (208909 => 208910)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-11-19 00:58:54 UTC (rev 208909)
+++ trunk/LayoutTests/ChangeLog        2016-11-19 01:00:16 UTC (rev 208910)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2016-11-18 Myles C. Maxfield <mmaxfield@apple.com>
+
+ [WebGL2] Implement texStorage2D()
+ https://bugs.webkit.org/show_bug.cgi?id=164493
+
+ Reviewed by Dean Jackson.
+
+ * fast/canvas/webgl/webgl2-texStorage-expected.txt: Added.
+ * fast/canvas/webgl/webgl2-texStorage.html: Added.
+
</ins><span class="cx"> 2016-11-17 Alex Christensen <achristensen@webkit.org>
</span><span class="cx">
</span><span class="cx"> Support IDN2008 with UTS #46 instead of IDN2003
</span></span></pre></div>
<a id="trunkLayoutTestsfastcanvaswebglwebgl2texStorageexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/canvas/webgl/webgl2-texStorage-expected.txt (0 => 208910)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/canvas/webgl/webgl2-texStorage-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/webgl2-texStorage-expected.txt        2016-11-19 01:00:16 UTC (rev 208910)
</span><span class="lines">@@ -0,0 +1,159 @@
</span><ins>+CONSOLE MESSAGE: line 58: WebGL: INVALID_OPERATION: texStorage2D: texStorage2D already called on this texture
+CONSOLE MESSAGE: line 61: WebGL: INVALID_OPERATION: texImage2D: texStorage() called on this texture previously
+Test that texStorage2D() works.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+asdf
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_COMPLETE
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS receiver[i] is 0
+PASS gl.getError() is not gl.NO_ERROR
+PASS gl.getError() is not gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS receiver[i] is 1
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.getError() is gl.NO_ERROR
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcanvaswebglwebgl2texStoragehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/canvas/webgl/webgl2-texStorage.html (0 => 208910)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/canvas/webgl/webgl2-texStorage.html         (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/webgl2-texStorage.html        2016-11-19 01:00:16 UTC (rev 208910)
</span><span class="lines">@@ -0,0 +1,88 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<canvas id="canvas" width="40" height="40"></canvas>
+<script>
+description("Test that texStorage2D() works.");
+
+if (window.internals)
+ internals.setWebGL2Enabled(true);
+
+var canvas = document.getElementById("canvas");
+var width = canvas.width;
+var height = canvas.height;
+var gl = canvas.getContext("webgl2");
+shouldBe("gl.getError()", "gl.NO_ERROR");
+
+var texture = gl.createTexture();
+shouldBe("gl.getError()", "gl.NO_ERROR");
+gl.bindTexture(gl.TEXTURE_2D, texture);
+shouldBe("gl.getError()", "gl.NO_ERROR");
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+shouldBe("gl.getError()", "gl.NO_ERROR");
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+shouldBe("gl.getError()", "gl.NO_ERROR");
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+shouldBe("gl.getError()", "gl.NO_ERROR");
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+shouldBe("gl.getError()", "gl.NO_ERROR");
+
+var width = 4;
+var height = 4;
+debug("asdf");
+gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, width, height);
+shouldBe("gl.getError()", "gl.NO_ERROR");
+
+var framebuffer = gl.createFramebuffer();
+shouldBe("gl.getError()", "gl.NO_ERROR");
+gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
+shouldBe("gl.getError()", "gl.NO_ERROR");
+gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+shouldBe("gl.getError()", "gl.NO_ERROR");
+shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+
+var receiver = new Uint8Array(width * height * 4);
+for (var i = 0; i < width * height * 4; ++i) {
+ receiver[i] = 1;
+}
+
+gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, receiver);
+shouldBe("gl.getError()", "gl.NO_ERROR");
+for (var i = 0; i < width * height * 4; ++i) {
+ shouldBe("receiver[i]", "0");
+}
+
+gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, width, height);
+shouldNotBe("gl.getError()", "gl.NO_ERROR");
+
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, receiver);
+shouldNotBe("gl.getError()", "gl.NO_ERROR");
+
+for (var i = 0; i < width * height * 4; ++i) {
+ receiver[i] = 1;
+}
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, receiver);
+shouldBe("gl.getError()", "gl.NO_ERROR");
+
+for (var i = 0; i < width * height * 4; ++i) {
+ receiver[i] = 0;
+}
+gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, receiver);
+shouldBe("gl.getError()", "gl.NO_ERROR");
+
+for (var i = 0; i < width * height * 4; ++i) {
+ shouldBe("receiver[i]", "1");
+}
+
+gl.deleteFramebuffer(framebuffer);
+shouldBe("gl.getError()", "gl.NO_ERROR");
+
+gl.deleteTexture(texture);
+shouldBe("gl.getError()", "gl.NO_ERROR");
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (208909 => 208910)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-11-19 00:58:54 UTC (rev 208909)
+++ trunk/Source/WebCore/ChangeLog        2016-11-19 01:00:16 UTC (rev 208910)
</span><span class="lines">@@ -1,3 +1,61 @@
</span><ins>+2016-11-18 Myles C. Maxfield <mmaxfield@apple.com>
+
+ [WebGL2] Implement texStorage2D()
+ https://bugs.webkit.org/show_bug.cgi?id=164493
+
+ Reviewed by Dean Jackson.
+
+ Create a new validation function which only accepts sized internalFormats.
+ After running texStorage2D(), we also texSubImage2D() to zero-fill it. This
+ is to compensate for potentially buggy drivers.
+
+ Because glTexStorage2D() was only added to OpenGL in version 4.2, not all
+ OpenGL 3.2+ contexts can implement this command. However, according to
+ https://developer.apple.com/opengl/capabilities/ all Apple GPUs have the
+ GL_ARB_texture_storage which implements this call. In the future, we could
+ implement texStorage2D() on top of texImage2D() if there are any ports which
+ want WebGL2 but don't have 4.2 and don't have the extension.
+
+ Also, when calling texStorage2D, callers specify an internalFormat but not a
+ type/format pair. This means that storing the texture's type is only valid
+ for WebGL 1 contexts. This patch surrounds all calls to reading the texture
+ type with guards and adds an ASSERT() at the read site to make sure the
+ right thing is happening.
+
+ Test: fast/canvas/webgl/webgl2-texStorage.html
+
+ * html/canvas/WebGL2RenderingContext.cpp:
+ (WebCore::WebGL2RenderingContext::validateTexStorageFuncParameters):
+ (WebCore::WebGL2RenderingContext::texStorage2D):
+ * html/canvas/WebGL2RenderingContext.h:
+ * html/canvas/WebGLRenderingContext.cpp:
+ (WebCore::WebGLRenderingContext::validateIndexArrayConservative):
+ * html/canvas/WebGLRenderingContextBase.cpp:
+ (WebCore::WebGLRenderingContextBase::create):
+ (WebCore::WebGLRenderingContextBase::copyTexSubImage2D):
+ (WebCore::WebGLRenderingContextBase::validateTexFunc):
+ (WebCore::WebGLRenderingContextBase::validateTexFuncData):
+ (WebCore::WebGLRenderingContextBase::texImage2D):
+ * html/canvas/WebGLTexture.cpp:
+ (WebCore::WebGLTexture::WebGLTexture):
+ (WebCore::WebGLTexture::getType):
+ (WebCore::WebGLTexture::needToUseBlackTexture):
+ (WebCore::WebGLTexture::canGenerateMipmaps):
+ (WebCore::internalFormatIsFloatType):
+ (WebCore::internalFormatIsHalfFloatType):
+ (WebCore::WebGLTexture::update):
+ * html/canvas/WebGLTexture.h:
+ * platform/graphics/GraphicsContext3D.cpp:
+ (WebCore::GraphicsContext3D::texImage2DResourceSafe):
+ (WebCore::GraphicsContext3D::packImageData):
+ (WebCore::GraphicsContext3D::extractImageData):
+ * platform/graphics/GraphicsContext3D.h:
+ * platform/graphics/opengl/Extensions3DOpenGLCommon.cpp:
+ (WebCore::Extensions3DOpenGLCommon::initializeAvailableExtensions):
+ * platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp:
+ (WebCore::GraphicsContext3D::texStorage2D):
+ (WebCore::GraphicsContext3D::texStorage3D):
+
</ins><span class="cx"> 2016-11-18 Alex Christensen <achristensen@webkit.org>
</span><span class="cx">
</span><span class="cx"> TextDecoder constructor should not accept replacement encodings
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGL2RenderingContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp (208909 => 208910)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp        2016-11-19 00:58:54 UTC (rev 208909)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp        2016-11-19 01:00:16 UTC (rev 208910)
</span><span class="lines">@@ -312,10 +312,169 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void WebGL2RenderingContext::texStorage2D(GC3Denum, GC3Dsizei, GC3Denum, GC3Dsizei, GC3Dsizei)
</del><ins>+bool WebGL2RenderingContext::validateTexStorageFuncParameters(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, const char* functionName)
</ins><span class="cx"> {
</span><ins>+ if (width < 0 || height < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
+ return false;
+ }
+
+ if (width > m_maxTextureSize || height > m_maxTextureSize) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "texture dimensions are larger than the maximum texture size");
+ return false;
+ }
+
+ if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
+ if (width != height) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height for cube map");
+ return false;
+ }
+ } else if (target != GraphicsContext3D::TEXTURE_2D) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
+ return false;
+ }
+
+ if (levels < 0 || levels > m_maxTextureLevel) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "number of levels is out of bounds");
+ return false;
+ }
+
+ switch (internalFormat) {
+ case GraphicsContext3D::R8:
+ case GraphicsContext3D::R8_SNORM:
+ case GraphicsContext3D::R16F:
+ case GraphicsContext3D::R32F:
+ case GraphicsContext3D::R8UI:
+ case GraphicsContext3D::R8I:
+ case GraphicsContext3D::R16UI:
+ case GraphicsContext3D::R16I:
+ case GraphicsContext3D::R32UI:
+ case GraphicsContext3D::R32I:
+ case GraphicsContext3D::RG8:
+ case GraphicsContext3D::RG8_SNORM:
+ case GraphicsContext3D::RG16F:
+ case GraphicsContext3D::RG32F:
+ case GraphicsContext3D::RG8UI:
+ case GraphicsContext3D::RG8I:
+ case GraphicsContext3D::RG16UI:
+ case GraphicsContext3D::RG16I:
+ case GraphicsContext3D::RG32UI:
+ case GraphicsContext3D::RG32I:
+ case GraphicsContext3D::RGB8:
+ case GraphicsContext3D::SRGB8:
+ case GraphicsContext3D::RGB565:
+ case GraphicsContext3D::RGB8_SNORM:
+ case GraphicsContext3D::R11F_G11F_B10F:
+ case GraphicsContext3D::RGB9_E5:
+ case GraphicsContext3D::RGB16F:
+ case GraphicsContext3D::RGB32F:
+ case GraphicsContext3D::RGB8UI:
+ case GraphicsContext3D::RGB8I:
+ case GraphicsContext3D::RGB16UI:
+ case GraphicsContext3D::RGB16I:
+ case GraphicsContext3D::RGB32UI:
+ case GraphicsContext3D::RGB32I:
+ case GraphicsContext3D::RGBA8:
+ case GraphicsContext3D::SRGB8_ALPHA8:
+ case GraphicsContext3D::RGBA8_SNORM:
+ case GraphicsContext3D::RGB5_A1:
+ case GraphicsContext3D::RGBA4:
+ case GraphicsContext3D::RGB10_A2:
+ case GraphicsContext3D::RGBA16F:
+ case GraphicsContext3D::RGBA32F:
+ case GraphicsContext3D::RGBA8UI:
+ case GraphicsContext3D::RGBA8I:
+ case GraphicsContext3D::RGB10_A2UI:
+ case GraphicsContext3D::RGBA16UI:
+ case GraphicsContext3D::RGBA16I:
+ case GraphicsContext3D::RGBA32I:
+ case GraphicsContext3D::RGBA32UI:
+ case GraphicsContext3D::DEPTH_COMPONENT16:
+ case GraphicsContext3D::DEPTH_COMPONENT24:
+ case GraphicsContext3D::DEPTH_COMPONENT32F:
+ case GraphicsContext3D::DEPTH24_STENCIL8:
+ case GraphicsContext3D::DEPTH32F_STENCIL8:
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "Unknown internalFormat");
+ return false;
+ }
+
+ return true;
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+void WebGL2RenderingContext::texStorage2D(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height)
+{
+ if (isContextLostOrPending())
+ return;
+
+ WebGLTexture* texture = validateTextureBinding("texStorage2D", target, false);
+ if (!texture)
+ return;
+
+ if (!validateTexStorageFuncParameters(target, levels, internalFormat, width, height, "texStorage2D"))
+ return;
+
+ if (!validateNPOTTextureLevel(width, height, levels, "texStorage2D"))
+ return;
+
+ if (texture->immutable()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "texStorage2D", "texStorage2D already called on this texture");
+ return;
+ }
+ texture->setImmutable();
+
+ m_context->texStorage2D(target, levels, internalFormat, width, height);
+
+ {
+ GC3Denum format;
+ GC3Denum type;
+ if (!GraphicsContext3D::possibleFormatAndTypeForInternalFormat(internalFormat, format, type)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texStorage2D", "Texture has unknown internal format");
+ return;
+ }
+
+ GC3Dsizei levelWidth = width;
+ GC3Dsizei levelHeight = height;
+
+ unsigned size;
+ GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &size, nullptr);
+ if (error != GraphicsContext3D::NO_ERROR) {
+ synthesizeGLError(error, "texStorage2D", "bad dimensions");
+ return;
+ }
+
+ Vector<char> data(size);
+ memset(data.data(), 0, size);
+
+ for (GC3Dsizei level = 0; level < levels; ++level) {
+ if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
+ m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
+ m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
+ m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
+ m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
+ m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
+ m_context->texSubImage2D(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
+ } else
+ m_context->texSubImage2D(target, level, 0, 0, levelWidth, levelHeight, format, type, data.data());
+ levelWidth = std::max(1, levelWidth / 2);
+ levelHeight = std::max(1, levelHeight / 2);
+ }
+ }
+
+ for (GC3Dsizei level = 0; level < levels; ++level) {
+ if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
+ texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ texture->setLevelInfo(GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ } else
+ texture->setLevelInfo(target, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+ }
+}
+
</ins><span class="cx"> void WebGL2RenderingContext::texStorage3D(GC3Denum, GC3Dsizei, GC3Denum, GC3Dsizei, GC3Dsizei, GC3Dsizei)
</span><span class="cx"> {
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGL2RenderingContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h (208909 => 208910)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h        2016-11-19 00:58:54 UTC (rev 208909)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h        2016-11-19 01:00:16 UTC (rev 208910)
</span><span class="lines">@@ -64,8 +64,8 @@
</span><span class="cx"> void renderbufferStorageMultisample(GC3Denum target, GC3Dsizei samples, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height);
</span><span class="cx">
</span><span class="cx"> /* Texture objects */
</span><del>- void texStorage2D(GC3Denum target, GC3Dsizei levels, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height);
- void texStorage3D(GC3Denum target, GC3Dsizei levels, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth);
</del><ins>+ void texStorage2D(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height);
+ void texStorage3D(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth);
</ins><span class="cx"> void texImage3D(GC3Denum target, GC3Dint level, GC3Dint internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth, GC3Dint border, GC3Denum format, GC3Denum type, RefPtr<ArrayBufferView>&& pixels);
</span><span class="cx">
</span><span class="cx"> void texSubImage3D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint zoffset, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth, GC3Denum format, GC3Denum type, RefPtr<ArrayBufferView>&& pixels);
</span><span class="lines">@@ -191,6 +191,8 @@
</span><span class="cx"> GC3Denum baseInternalFormatFromInternalFormat(GC3Denum internalformat);
</span><span class="cx"> bool isIntegerFormat(GC3Denum internalformat);
</span><span class="cx"> void initializeShaderExtensions();
</span><ins>+
+ bool validateTexStorageFuncParameters(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, const char* functionName);
</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 (208909 => 208910)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp        2016-11-19 00:58:54 UTC (rev 208909)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp        2016-11-19 01:00:16 UTC (rev 208910)
</span><span class="lines">@@ -772,9 +772,9 @@
</span><span class="cx"> }
</span><span class="cx"> default:
</span><span class="cx"> return false;
</span><ins>+ }
+ elementArrayBuffer->setCachedMaxIndex(type, maxIndex);
</ins><span class="cx"> }
</span><del>- elementArrayBuffer->setCachedMaxIndex(type, maxIndex);
- }
</del><span class="cx">
</span><span class="cx"> if (maxIndex >= 0) {
</span><span class="cx"> // The number of required elements is one more than the maximum
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContextBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (208909 => 208910)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp        2016-11-19 00:58:54 UTC (rev 208909)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp        2016-11-19 01:00:16 UTC (rev 208910)
</span><span class="lines">@@ -434,6 +434,13 @@
</span><span class="cx"> if (extensions.supports("GL_EXT_debug_marker"))
</span><span class="cx"> extensions.pushGroupMarkerEXT("WebGLRenderingContext");
</span><span class="cx">
</span><ins>+#if ENABLE(WEBGL2) && PLATFORM(MAC)
+ // glTexStorage() was only added to Core in OpenGL 4.2.
+ // However, according to https://developer.apple.com/opengl/capabilities/ all Apple GPUs support this extension.
+ if (attributes.useGLES3 && !extensions.supports("GL_ARB_texture_storage"))
+ return nullptr;
+#endif
+
</ins><span class="cx"> std::unique_ptr<WebGLRenderingContextBase> renderingContext = nullptr;
</span><span class="cx"> #if ENABLE(WEBGL2)
</span><span class="cx"> if (type == "webgl2")
</span><span class="lines">@@ -1365,7 +1372,7 @@
</span><span class="cx"> std::unique_ptr<unsigned char[]> zero;
</span><span class="cx"> if (width && height) {
</span><span class="cx"> unsigned size;
</span><del>- GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &size, 0);
</del><ins>+ GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &size, nullptr);
</ins><span class="cx"> if (error != GraphicsContext3D::NO_ERROR) {
</span><span class="cx"> synthesizeGLError(error, "copyTexSubImage2D", "bad dimensions");
</span><span class="cx"> return;
</span><span class="lines">@@ -3311,6 +3318,10 @@
</span><span class="cx"> return false;
</span><span class="cx">
</span><span class="cx"> if (functionType != TexSubImage) {
</span><ins>+ if (functionType == TexImage && texture->immutable()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "texStorage() called on this texture previously");
+ return false;
+ }
</ins><span class="cx"> if (!validateNPOTTextureLevel(width, height, level, functionName))
</span><span class="cx"> return false;
</span><span class="cx"> // For SourceArrayBufferView, function validateTexFuncData() would handle whether to validate the SettableTexFormat
</span><span class="lines">@@ -3333,7 +3344,7 @@
</span><span class="cx"> synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "dimensions out of range");
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><del>- if (texture->getInternalFormat(target, level) != internalFormat || texture->getType(target, level) != type) {
</del><ins>+ if (texture->getInternalFormat(target, level) != internalFormat || (isWebGL1() && texture->getType(target, level) != type)) {
</ins><span class="cx"> synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type and format do not match texture");
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="lines">@@ -3629,7 +3640,7 @@
</span><span class="cx"> return false;
</span><span class="cx">
</span><span class="cx"> unsigned totalBytesRequired;
</span><del>- GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
</del><ins>+ GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, nullptr);
</ins><span class="cx"> if (error != GraphicsContext3D::NO_ERROR) {
</span><span class="cx"> synthesizeGLError(error, functionName, "invalid texture dimensions");
</span><span class="cx"> return false;
</span><span class="lines">@@ -3963,6 +3974,14 @@
</span><span class="cx"> tex->setLevelInfo(target, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+static bool isRGBFormat(GC3Denum internalFormat)
+{
+ return internalFormat == GraphicsContext3D::RGB
+ || internalFormat == GraphicsContext3D::RGBA
+ || internalFormat == GraphicsContext3D::RGB8
+ || internalFormat == GraphicsContext3D::RGBA8;
+}
+
</ins><span class="cx"> ExceptionOr<void> WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Optional<TexImageSource> source)
</span><span class="cx"> {
</span><span class="cx"> if (!source) {
</span><span class="lines">@@ -4023,12 +4042,14 @@
</span><span class="cx"> // ImageBuffer::copyToPlatformTexture implementations are fully functional.
</span><span class="cx"> if (texture
</span><span class="cx"> && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA)
</span><del>- && type == GraphicsContext3D::UNSIGNED_BYTE
- && (texture->getType(target, level) == GraphicsContext3D::UNSIGNED_BYTE || !texture->isValid(target, level))) {
- ImageBuffer* buffer = canvas->buffer();
- if (buffer && buffer->copyToPlatformTexture(*m_context.get(), target, texture->object(), internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
- texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
- return { };
</del><ins>+ && type == GraphicsContext3D::UNSIGNED_BYTE) {
+ auto textureInternalFormat = texture->getInternalFormat(target, level);
+ if (isRGBFormat(textureInternalFormat) || !texture->isValid(target, level)) {
+ ImageBuffer* buffer = canvas->buffer();
+ if (buffer && buffer->copyToPlatformTexture(*m_context.get(), target, texture->object(), internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+ texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
+ return { };
+ }
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -4053,11 +4074,13 @@
</span><span class="cx"> if (GraphicsContext3D::TEXTURE_2D == target && texture
</span><span class="cx"> && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA)
</span><span class="cx"> && type == GraphicsContext3D::UNSIGNED_BYTE
</span><del>- && (texture->getType(target, level) == GraphicsContext3D::UNSIGNED_BYTE || !texture->isValid(target, level))
</del><span class="cx"> && !level) {
</span><del>- if (video->copyVideoTextureToPlatformTexture(m_context.get(), texture->object(), target, level, internalformat, format, type, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
- texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), type);
- return { };
</del><ins>+ auto textureInternalFormat = texture->getInternalFormat(target, level);
+ if (isRGBFormat(textureInternalFormat) || !texture->isValid(target, level)) {
+ if (video->copyVideoTextureToPlatformTexture(m_context.get(), texture->object(), target, level, internalformat, format, type, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+ texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), type);
+ return { };
+ }
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLTexturecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLTexture.cpp (208909 => 208910)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLTexture.cpp        2016-11-19 00:58:54 UTC (rev 208909)
+++ trunk/Source/WebCore/html/canvas/WebGLTexture.cpp        2016-11-19 01:00:16 UTC (rev 208910)
</span><span class="lines">@@ -53,6 +53,7 @@
</span><span class="cx"> , m_isCompressed(false)
</span><span class="cx"> , m_isFloatType(false)
</span><span class="cx"> , m_isHalfFloatType(false)
</span><ins>+ , m_isForWebGL1(ctx.isWebGL1())
</ins><span class="cx"> {
</span><span class="cx"> setObject(ctx.graphicsContext3D()->createTexture());
</span><span class="cx"> }
</span><span class="lines">@@ -188,6 +189,7 @@
</span><span class="cx">
</span><span class="cx"> GC3Denum WebGLTexture::getType(GC3Denum target, GC3Dint level) const
</span><span class="cx"> {
</span><ins>+ ASSERT(m_isForWebGL1);
</ins><span class="cx"> const LevelInfo* info = getLevelInfo(target, level);
</span><span class="cx"> if (!info)
</span><span class="cx"> return 0;
</span><span class="lines">@@ -250,10 +252,12 @@
</span><span class="cx"> return false;
</span><span class="cx"> if (m_needToUseBlackTexture)
</span><span class="cx"> return true;
</span><del>- if ((m_isFloatType && !(extensions & TextureExtensionFloatLinearEnabled)) || (m_isHalfFloatType && !(extensions & TextureExtensionHalfFloatLinearEnabled))) {
- if (m_magFilter != GraphicsContext3D::NEAREST || (m_minFilter != GraphicsContext3D::NEAREST && m_minFilter != GraphicsContext3D::NEAREST_MIPMAP_NEAREST))
- return true;
- }
</del><ins>+ if (m_magFilter == GraphicsContext3D::NEAREST && (m_minFilter == GraphicsContext3D::NEAREST || m_minFilter == GraphicsContext3D::NEAREST_MIPMAP_NEAREST))
+ return false;
+ if (m_isForWebGL1 && m_isHalfFloatType && !(extensions & TextureExtensionHalfFloatLinearEnabled))
+ return true;
+ if (m_isFloatType && !(extensions & TextureExtensionFloatLinearEnabled))
+ return true;
</ins><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -308,7 +312,7 @@
</span><span class="cx"> const LevelInfo& info = m_info[ii][0];
</span><span class="cx"> if (!info.valid
</span><span class="cx"> || info.width != first.width || info.height != first.height
</span><del>- || info.internalFormat != first.internalFormat || info.type != first.type)
</del><ins>+ || info.internalFormat != first.internalFormat || (m_isForWebGL1 && info.type != first.type))
</ins><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx"> return true;
</span><span class="lines">@@ -334,6 +338,36 @@
</span><span class="cx"> return log + 1;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+static bool internalFormatIsFloatType(GC3Denum internalFormat)
+{
+ switch (internalFormat) {
+ case GraphicsContext3D::R32F:
+ case GraphicsContext3D::RG32F:
+ case GraphicsContext3D::RGB32F:
+ case GraphicsContext3D::RGBA32F:
+ case GraphicsContext3D::DEPTH_COMPONENT32F:
+ case GraphicsContext3D::DEPTH32F_STENCIL8:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool internalFormatIsHalfFloatType(GC3Denum internalFormat)
+{
+ switch (internalFormat) {
+ case GraphicsContext3D::R16F:
+ case GraphicsContext3D::RG16F:
+ case GraphicsContext3D::R11F_G11F_B10F:
+ case GraphicsContext3D::RGB9_E5:
+ case GraphicsContext3D::RGB16F:
+ case GraphicsContext3D::RGBA16F:
+ return true;
+ default:
+ return false;
+ }
+}
+
</ins><span class="cx"> void WebGLTexture::update()
</span><span class="cx"> {
</span><span class="cx"> m_isNPOT = false;
</span><span class="lines">@@ -353,7 +387,7 @@
</span><span class="cx"> const LevelInfo& info0 = m_info[ii][0];
</span><span class="cx"> if (!info0.valid
</span><span class="cx"> || info0.width != first.width || info0.height != first.height
</span><del>- || info0.internalFormat != first.internalFormat || info0.type != first.type) {
</del><ins>+ || info0.internalFormat != first.internalFormat || (m_isForWebGL1 && info0.type != first.type)) {
</ins><span class="cx"> m_isComplete = false;
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="lines">@@ -365,7 +399,7 @@
</span><span class="cx"> const LevelInfo& info = m_info[ii][level];
</span><span class="cx"> if (!info.valid
</span><span class="cx"> || info.width != width || info.height != height
</span><del>- || info.internalFormat != info0.internalFormat || info.type != info0.type) {
</del><ins>+ || info.internalFormat != info0.internalFormat || (m_isForWebGL1 && info.type != info0.type)) {
</ins><span class="cx"> m_isComplete = false;
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="lines">@@ -375,25 +409,37 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> m_isFloatType = false;
</span><del>- if (m_isComplete)
- m_isFloatType = m_info[0][0].type == GraphicsContext3D::FLOAT;
- else {
- for (size_t ii = 0; ii < m_info.size(); ++ii) {
- if (m_info[ii][0].type == GraphicsContext3D::FLOAT) {
- m_isFloatType = true;
- break;
</del><ins>+ if (m_isForWebGL1) {
+ if (m_isComplete) {
+ if (m_isForWebGL1)
+ m_isFloatType = m_info[0][0].type == GraphicsContext3D::FLOAT;
+ else
+ m_isFloatType = internalFormatIsFloatType(m_info[0][0].internalFormat);
+ } else {
+ for (size_t ii = 0; ii < m_info.size(); ++ii) {
+ if ((m_isForWebGL1 && m_info[ii][0].type == GraphicsContext3D::FLOAT)
+ || (!m_isForWebGL1 && internalFormatIsFloatType(m_info[ii][0].internalFormat))) {
+ m_isFloatType = true;
+ break;
+ }
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> m_isHalfFloatType = false;
</span><del>- if (m_isComplete)
- m_isHalfFloatType = m_info[0][0].type == GraphicsContext3D::HALF_FLOAT_OES;
- else {
- for (size_t ii = 0; ii < m_info.size(); ++ii) {
- if (m_info[ii][0].type == GraphicsContext3D::HALF_FLOAT_OES) {
- m_isHalfFloatType = true;
- break;
</del><ins>+ if (m_isForWebGL1) {
+ if (m_isComplete) {
+ if (m_isForWebGL1)
+ m_isHalfFloatType = internalFormatIsHalfFloatType(m_info[0][0].internalFormat);
+ else
+ m_isHalfFloatType = m_info[0][0].type == GraphicsContext3D::HALF_FLOAT_OES;
+ } else {
+ for (size_t ii = 0; ii < m_info.size(); ++ii) {
+ if ((m_isForWebGL1 && m_info[ii][0].type == GraphicsContext3D::HALF_FLOAT_OES)
+ || (!m_isForWebGL1 && internalFormatIsHalfFloatType(m_info[ii][0].internalFormat))) {
+ m_isHalfFloatType = true;
+ break;
+ }
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLTextureh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLTexture.h (208909 => 208910)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLTexture.h        2016-11-19 00:58:54 UTC (rev 208909)
+++ trunk/Source/WebCore/html/canvas/WebGLTexture.h        2016-11-19 01:00:16 UTC (rev 208910)
</span><span class="lines">@@ -78,6 +78,9 @@
</span><span class="cx">
</span><span class="cx"> static GC3Dint computeLevelCount(GC3Dsizei width, GC3Dsizei height);
</span><span class="cx">
</span><ins>+ bool immutable() const { return m_immutable; }
+ void setImmutable() { m_immutable = true; }
+
</ins><span class="cx"> private:
</span><span class="cx"> WebGLTexture(WebGLRenderingContextBase&);
</span><span class="cx">
</span><span class="lines">@@ -133,6 +136,8 @@
</span><span class="cx"> bool m_isCompressed;
</span><span class="cx"> bool m_isFloatType;
</span><span class="cx"> bool m_isHalfFloatType;
</span><ins>+ bool m_isForWebGL1;
+ bool m_immutable { false };
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsContext3Dcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.cpp (208909 => 208910)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.cpp        2016-11-19 00:58:54 UTC (rev 208909)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.cpp        2016-11-19 01:00:16 UTC (rev 208910)
</span><span class="lines">@@ -149,7 +149,7 @@
</span><span class="cx"> std::unique_ptr<unsigned char[]> zero;
</span><span class="cx"> if (width > 0 && height > 0) {
</span><span class="cx"> unsigned int size;
</span><del>- GC3Denum error = computeImageSizeInBytes(format, type, width, height, unpackAlignment, &size, 0);
</del><ins>+ GC3Denum error = computeImageSizeInBytes(format, type, width, height, unpackAlignment, &size, nullptr);
</ins><span class="cx"> if (error != GraphicsContext3D::NO_ERROR) {
</span><span class="cx"> synthesizeGLError(error);
</span><span class="cx"> return false;
</span><span class="lines">@@ -373,7 +373,7 @@
</span><span class="cx">
</span><span class="cx"> unsigned packedSize;
</span><span class="cx"> // Output data is tightly packed (alignment == 1).
</span><del>- if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR)
</del><ins>+ if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, nullptr) != GraphicsContext3D::NO_ERROR)
</ins><span class="cx"> return false;
</span><span class="cx"> data.resize(packedSize);
</span><span class="cx">
</span><span class="lines">@@ -393,7 +393,7 @@
</span><span class="cx">
</span><span class="cx"> unsigned int packedSize;
</span><span class="cx"> // Output data is tightly packed (alignment == 1).
</span><del>- if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR)
</del><ins>+ if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, nullptr) != GraphicsContext3D::NO_ERROR)
</ins><span class="cx"> return false;
</span><span class="cx"> data.resize(packedSize);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsContext3Dh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h (208909 => 208910)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h        2016-11-19 00:58:54 UTC (rev 208909)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h        2016-11-19 01:00:16 UTC (rev 208910)
</span><span class="lines">@@ -984,6 +984,9 @@
</span><span class="cx"> GC3Dboolean unmapBuffer(GC3Denum target);
</span><span class="cx"> void copyBufferSubData(GC3Denum readTarget, GC3Denum writeTarget, GC3Dintptr readOffset, GC3Dintptr writeOffset, GC3Dsizeiptr);
</span><span class="cx">
</span><ins>+ void texStorage2D(GC3Denum target, GC3Dsizei levels, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height);
+ void texStorage3D(GC3Denum target, GC3Dsizei levels, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth);
+
</ins><span class="cx"> GC3Denum checkFramebufferStatus(GC3Denum target);
</span><span class="cx"> void clear(GC3Dbitfield mask);
</span><span class="cx"> void clearColor(GC3Dclampf red, GC3Dclampf green, GC3Dclampf blue, GC3Dclampf alpha);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsopenglExtensions3DOpenGLCommoncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp (208909 => 208910)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp        2016-11-19 00:58:54 UTC (rev 208909)
+++ trunk/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp        2016-11-19 01:00:16 UTC (rev 208910)
</span><span class="lines">@@ -215,6 +215,15 @@
</span><span class="cx"> ::glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
</span><span class="cx"> for (GLint i = 0; i < numExtensions; ++i)
</span><span class="cx"> m_availableExtensions.add(glGetStringi(GL_EXTENSIONS, i));
</span><ins>+
+ if (!m_availableExtensions.contains(ASCIILiteral("GL_ARB_texture_storage"))) {
+ GLint majorVersion;
+ glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
+ GLint minorVersion;
+ glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
+ if (majorVersion > 4 || (majorVersion == 4 && minorVersion >= 2))
+ m_availableExtensions.add(ASCIILiteral("GL_ARB_texture_storage"));
+ }
</ins><span class="cx"> } else
</span><span class="cx"> #endif
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsopenglGraphicsContext3DOpenGLCommoncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp (208909 => 208910)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp        2016-11-19 00:58:54 UTC (rev 208909)
+++ trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp        2016-11-19 01:00:16 UTC (rev 208910)
</span><span class="lines">@@ -70,6 +70,7 @@
</span><span class="cx"> #define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
</span><span class="cx"> #include <OpenGL/gl.h>
</span><span class="cx"> #include <OpenGL/gl3.h>
</span><ins>+#include <OpenGL/gl3ext.h>
</ins><span class="cx"> #undef GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
</span><span class="cx"> #elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN)
</span><span class="cx"> #include "OpenGLShims.h"
</span><span class="lines">@@ -564,6 +565,18 @@
</span><span class="cx"> makeContextCurrent();
</span><span class="cx"> ::glCopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size);
</span><span class="cx"> }
</span><ins>+
+void GraphicsContext3D::texStorage2D(GC3Denum target, GC3Dsizei levels, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
+{
+ makeContextCurrent();
+ ::glTexStorage2D(target, levels, internalformat, width, height);
+}
+
+void GraphicsContext3D::texStorage3D(GC3Denum target, GC3Dsizei levels, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth)
+{
+ makeContextCurrent();
+ ::glTexStorage3D(target, levels, internalformat, width, height, depth);
+}
</ins><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> GC3Denum GraphicsContext3D::checkFramebufferStatus(GC3Denum target)
</span></span></pre>
</div>
</div>
</body>
</html>