Title: [208910] trunk
Revision
208910
Author
mmaxfi...@apple.com
Date
2016-11-18 17:00:16 -0800 (Fri, 18 Nov 2016)

Log Message

[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.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (208909 => 208910)


--- trunk/LayoutTests/ChangeLog	2016-11-19 00:58:54 UTC (rev 208909)
+++ trunk/LayoutTests/ChangeLog	2016-11-19 01:00:16 UTC (rev 208910)
@@ -1,3 +1,13 @@
+2016-11-18  Myles C. Maxfield  <mmaxfi...@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.
+
 2016-11-17  Alex Christensen  <achristen...@webkit.org>
 
         Support IDN2008 with UTS #46 instead of IDN2003

Added: trunk/LayoutTests/fast/canvas/webgl/webgl2-texStorage-expected.txt (0 => 208910)


--- 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)
@@ -0,0 +1,159 @@
+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
+

Added: trunk/LayoutTests/fast/canvas/webgl/webgl2-texStorage.html (0 => 208910)


--- 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)
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</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=""
+</body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (208909 => 208910)


--- 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)
@@ -1,3 +1,61 @@
+2016-11-18  Myles C. Maxfield  <mmaxfi...@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):
+
 2016-11-18  Alex Christensen  <achristen...@webkit.org>
 
         TextDecoder constructor should not accept replacement encodings

Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp (208909 => 208910)


--- 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)
@@ -312,10 +312,169 @@
 {
 }
 
-void WebGL2RenderingContext::texStorage2D(GC3Denum, GC3Dsizei, GC3Denum, GC3Dsizei, GC3Dsizei)
+bool WebGL2RenderingContext::validateTexStorageFuncParameters(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, const char* functionName)
 {
+    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;
 }
 
+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);
+    }
+}
+
 void WebGL2RenderingContext::texStorage3D(GC3Denum, GC3Dsizei, GC3Denum, GC3Dsizei, GC3Dsizei, GC3Dsizei)
 {
 }

Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h (208909 => 208910)


--- 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)
@@ -64,8 +64,8 @@
     void renderbufferStorageMultisample(GC3Denum target, GC3Dsizei samples, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height);
     
     /* Texture objects */
-    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);
+    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);
     void texImage3D(GC3Denum target, GC3Dint level, GC3Dint internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth, GC3Dint border, GC3Denum format, GC3Denum type, RefPtr<ArrayBufferView>&& pixels);
 
     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);
@@ -191,6 +191,8 @@
     GC3Denum baseInternalFormatFromInternalFormat(GC3Denum internalformat);
     bool isIntegerFormat(GC3Denum internalformat);
     void initializeShaderExtensions();
+
+    bool validateTexStorageFuncParameters(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, const char* functionName);
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp (208909 => 208910)


--- 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)
@@ -772,9 +772,9 @@
         }
         default:
             return false;
+        }
+        elementArrayBuffer->setCachedMaxIndex(type, maxIndex);
     }
-    elementArrayBuffer->setCachedMaxIndex(type, maxIndex);
-    }
     
     if (maxIndex >= 0) {
         // The number of required elements is one more than the maximum

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (208909 => 208910)


--- 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)
@@ -434,6 +434,13 @@
     if (extensions.supports("GL_EXT_debug_marker"))
         extensions.pushGroupMarkerEXT("WebGLRenderingContext");
 
+#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
+
     std::unique_ptr<WebGLRenderingContextBase> renderingContext = nullptr;
 #if ENABLE(WEBGL2)
     if (type == "webgl2")
@@ -1365,7 +1372,7 @@
         std::unique_ptr<unsigned char[]> zero;
         if (width && height) {
             unsigned size;
-            GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &size, 0);
+            GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &size, nullptr);
             if (error != GraphicsContext3D::NO_ERROR) {
                 synthesizeGLError(error, "copyTexSubImage2D", "bad dimensions");
                 return;
@@ -3311,6 +3318,10 @@
         return false;
 
     if (functionType != TexSubImage) {
+        if (functionType == TexImage && texture->immutable()) {
+            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "texStorage() called on this texture previously");
+            return false;
+        }
         if (!validateNPOTTextureLevel(width, height, level, functionName))
             return false;
         // For SourceArrayBufferView, function validateTexFuncData() would handle whether to validate the SettableTexFormat
@@ -3333,7 +3344,7 @@
             synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "dimensions out of range");
             return false;
         }
-        if (texture->getInternalFormat(target, level) != internalFormat || texture->getType(target, level) != type) {
+        if (texture->getInternalFormat(target, level) != internalFormat || (isWebGL1() && texture->getType(target, level) != type)) {
             synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type and format do not match texture");
             return false;
         }
@@ -3629,7 +3640,7 @@
         return false;
     
     unsigned totalBytesRequired;
-    GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
+    GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, nullptr);
     if (error != GraphicsContext3D::NO_ERROR) {
         synthesizeGLError(error, functionName, "invalid texture dimensions");
         return false;
@@ -3963,6 +3974,14 @@
     tex->setLevelInfo(target, level, internalFormat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
 }
 
+static bool isRGBFormat(GC3Denum internalFormat)
+{
+    return internalFormat == GraphicsContext3D::RGB
+        || internalFormat == GraphicsContext3D::RGBA
+        || internalFormat == GraphicsContext3D::RGB8
+        || internalFormat == GraphicsContext3D::RGBA8;
+}
+
 ExceptionOr<void> WebGLRenderingContextBase::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Optional<TexImageSource> source)
 {
     if (!source) {
@@ -4023,12 +4042,14 @@
         // ImageBuffer::copyToPlatformTexture implementations are fully functional.
         if (texture
             && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA)
-            && 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 { };
+            && 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 { };
+                }
             }
         }
 
@@ -4053,11 +4074,13 @@
         if (GraphicsContext3D::TEXTURE_2D == target && texture
             && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA)
             && type == GraphicsContext3D::UNSIGNED_BYTE
-            && (texture->getType(target, level) == GraphicsContext3D::UNSIGNED_BYTE || !texture->isValid(target, level))
             && !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 { };
+            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 { };
+                }
             }
         }
 

Modified: trunk/Source/WebCore/html/canvas/WebGLTexture.cpp (208909 => 208910)


--- 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)
@@ -53,6 +53,7 @@
     , m_isCompressed(false)
     , m_isFloatType(false)
     , m_isHalfFloatType(false)
+    , m_isForWebGL1(ctx.isWebGL1())
 {
     setObject(ctx.graphicsContext3D()->createTexture());
 }
@@ -188,6 +189,7 @@
 
 GC3Denum WebGLTexture::getType(GC3Denum target, GC3Dint level) const
 {
+    ASSERT(m_isForWebGL1);
     const LevelInfo* info = getLevelInfo(target, level);
     if (!info)
         return 0;
@@ -250,10 +252,12 @@
         return false;
     if (m_needToUseBlackTexture)
         return true;
-    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;
-    }
+    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;
     return false;
 }
 
@@ -308,7 +312,7 @@
         const LevelInfo& info = m_info[ii][0];
         if (!info.valid
             || info.width != first.width || info.height != first.height
-            || info.internalFormat != first.internalFormat || info.type != first.type)
+            || info.internalFormat != first.internalFormat || (m_isForWebGL1 && info.type != first.type))
             return false;
     }
     return true;
@@ -334,6 +338,36 @@
     return log + 1;
 }
 
+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;
+    }
+}
+
 void WebGLTexture::update()
 {
     m_isNPOT = false;
@@ -353,7 +387,7 @@
             const LevelInfo& info0 = m_info[ii][0];
             if (!info0.valid
                 || info0.width != first.width || info0.height != first.height
-                || info0.internalFormat != first.internalFormat || info0.type != first.type) {
+                || info0.internalFormat != first.internalFormat || (m_isForWebGL1 && info0.type != first.type)) {
                 m_isComplete = false;
                 break;
             }
@@ -365,7 +399,7 @@
                 const LevelInfo& info = m_info[ii][level];
                 if (!info.valid
                     || info.width != width || info.height != height
-                    || info.internalFormat != info0.internalFormat || info.type != info0.type) {
+                    || info.internalFormat != info0.internalFormat || (m_isForWebGL1 && info.type != info0.type)) {
                     m_isComplete = false;
                     break;
                 }
@@ -375,25 +409,37 @@
     }
 
     m_isFloatType = false;
-    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;
+    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;
+                }
             }
         }
     }
 
     m_isHalfFloatType = false;
-    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;
+    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;
+                }
             }
         }
     }

Modified: trunk/Source/WebCore/html/canvas/WebGLTexture.h (208909 => 208910)


--- 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)
@@ -78,6 +78,9 @@
 
     static GC3Dint computeLevelCount(GC3Dsizei width, GC3Dsizei height);
 
+    bool immutable() const { return m_immutable; }
+    void setImmutable() { m_immutable = true; }
+
 private:
     WebGLTexture(WebGLRenderingContextBase&);
 
@@ -133,6 +136,8 @@
     bool m_isCompressed;
     bool m_isFloatType;
     bool m_isHalfFloatType;
+    bool m_isForWebGL1;
+    bool m_immutable { false };
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.cpp (208909 => 208910)


--- 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)
@@ -149,7 +149,7 @@
     std::unique_ptr<unsigned char[]> zero;
     if (width > 0 && height > 0) {
         unsigned int size;
-        GC3Denum error = computeImageSizeInBytes(format, type, width, height, unpackAlignment, &size, 0);
+        GC3Denum error = computeImageSizeInBytes(format, type, width, height, unpackAlignment, &size, nullptr);
         if (error != GraphicsContext3D::NO_ERROR) {
             synthesizeGLError(error);
             return false;
@@ -373,7 +373,7 @@
 
     unsigned packedSize;
     // Output data is tightly packed (alignment == 1).
-    if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR)
+    if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, nullptr) != GraphicsContext3D::NO_ERROR)
         return false;
     data.resize(packedSize);
 
@@ -393,7 +393,7 @@
 
     unsigned int packedSize;
     // Output data is tightly packed (alignment == 1).
-    if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR)
+    if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, nullptr) != GraphicsContext3D::NO_ERROR)
         return false;
     data.resize(packedSize);
 

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h (208909 => 208910)


--- 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)
@@ -984,6 +984,9 @@
     GC3Dboolean unmapBuffer(GC3Denum target);
     void copyBufferSubData(GC3Denum readTarget, GC3Denum writeTarget, GC3Dintptr readOffset, GC3Dintptr writeOffset, GC3Dsizeiptr);
 
+    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);
+
     GC3Denum checkFramebufferStatus(GC3Denum target);
     void clear(GC3Dbitfield mask);
     void clearColor(GC3Dclampf red, GC3Dclampf green, GC3Dclampf blue, GC3Dclampf alpha);

Modified: trunk/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp (208909 => 208910)


--- 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)
@@ -215,6 +215,15 @@
         ::glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
         for (GLint i = 0; i < numExtensions; ++i)
             m_availableExtensions.add(glGetStringi(GL_EXTENSIONS, i));
+
+        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"));
+        }
     } else
 #endif
     {

Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp (208909 => 208910)


--- 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)
@@ -70,6 +70,7 @@
 #define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
 #include <OpenGL/gl.h>
 #include <OpenGL/gl3.h>
+#include <OpenGL/gl3ext.h>
 #undef GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
 #elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WIN)
 #include "OpenGLShims.h"
@@ -564,6 +565,18 @@
     makeContextCurrent();
     ::glCopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size);
 }
+
+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);
+}
 #endif
 
 GC3Denum GraphicsContext3D::checkFramebufferStatus(GC3Denum target)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to