Diff
Modified: trunk/LayoutTests/ChangeLog (235610 => 235611)
--- trunk/LayoutTests/ChangeLog 2018-09-04 10:27:27 UTC (rev 235610)
+++ trunk/LayoutTests/ChangeLog 2018-09-04 12:10:34 UTC (rev 235611)
@@ -1,3 +1,13 @@
+2018-09-04 Zan Dobersek <zdober...@igalia.com> and Ms2ger <ms2...@igalia.com>
+
+ Implement support for passing ImageBitmap to texImage2D/texSubImage2D
+ https://bugs.webkit.org/show_bug.cgi?id=187584
+
+ Reviewed by Dean Jackson.
+
+ * fast/canvas/webgl/gl-teximage-imagebitmap-expected.txt: Added.
+ * fast/canvas/webgl/gl-teximage-imagebitmap.html: Added.
+
2018-09-04 Yacine Bandou <yacine.ban...@softathome.com>
[EME] Add layout test for InitData and InitDataType in WebM encrypted event
Added: trunk/LayoutTests/fast/canvas/webgl/gl-teximage-imagebitmap-expected.txt (0 => 235611)
--- trunk/LayoutTests/fast/canvas/webgl/gl-teximage-imagebitmap-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/gl-teximage-imagebitmap-expected.txt 2018-09-04 12:10:34 UTC (rev 235611)
@@ -0,0 +1,15 @@
+PASS getError was expected value: NO_ERROR : Should be no errors from setup.
+PASS getError was expected value: NO_ERROR : Should be no errors from setup
+PASS pixel 0, 149 should be 0, 0, 0, 255 was 0, 0, 0, 255
+PASS pixel 150, 149 should be 0, 0, 255, 255 was 0, 0, 255, 255
+PASS pixel 299, 149 should be 255, 0, 0, 255 was 255, 0, 0, 255
+PASS pixel 0, 75 should be 255, 0, 255, 255 was 255, 0, 255, 255
+PASS pixel 150, 75 should be 255, 0, 0, 255 was 255, 0, 0, 255
+PASS pixel 299, 75 should be 0, 255, 0, 255 was 0, 255, 0, 255
+PASS pixel 0, 0 should be 255, 0, 0, 255 was 255, 0, 0, 255
+PASS pixel 150, 0 should be 255, 255, 0, 255 was 255, 255, 0, 255
+PASS pixel 299, 0 should be 255, 0, 0, 255 was 255, 0, 0, 255
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/canvas/webgl/gl-teximage-imagebitmap.html (0 => 235611)
--- trunk/LayoutTests/fast/canvas/webgl/gl-teximage-imagebitmap.html (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/gl-teximage-imagebitmap.html 2018-09-04 12:10:34 UTC (rev 235611)
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>texImage2D with ImageBitmap.</title>
+<script src=""
+<script src="" </script>
+<script src="" </script>
+</head>
+<body>
+<canvas id="example"></canvas>
+<div id="description"></div>
+<script>
+function loadImage(url) {
+ return new Promise((resolve, reject) => {
+ var img = document.createElement('img');
+ img._onload_ = () => resolve(img);
+ img._onerror_ = e => reject(e);
+ img.src = ""
+ });
+}
+
+function checkPixel(buf, width, x, y, color) {
+ var off = (y * width + x) * 4;
+ var msg = "pixel " + x + ", " + y + " should be " +
+ color[0] + ", " +
+ color[1] + ", " +
+ color[2] + ", " +
+ color[3] + " was " +
+ buf[off + 0] + ", " +
+ buf[off + 1] + ", " +
+ buf[off + 2] + ", " +
+ buf[off + 3];
+
+ for (var ii = 0; ii < 4; ++ii) {
+ if (buf[off + ii] != color[ii]) {
+ testFailed(msg);
+ return;
+ }
+ }
+ testPassed(msg);
+}
+
+function checkPixelRange(buf, width, x, y, color, allowedRange) {
+ var off = (y * width + x) * 4;
+ var msg = "pixel " + x + ", " + y + " should be within " +
+ allowedRange + " units of " +
+ color[0] + ", " +
+ color[1] + ", " +
+ color[2] + ", " +
+ color[3];
+ var subMsg = " was " +
+ buf[off + 0] + ", " +
+ buf[off + 1] + ", " +
+ buf[off + 2] + ", " +
+ buf[off + 3];
+ // When running in WebKit's test harness, we don't want to print the
+ // pixel value when the test passes, because different machines might
+ // have different results and we record the text output.
+ var inDumpRenderTree = window.testRunner;
+ for (var ii = 0; ii < 4; ++ii) {
+ if (Math.abs(buf[off + ii] - color[ii]) > allowedRange) {
+ testFailed(msg + subMsg);
+ return;
+ }
+ }
+ testPassed(msg + (inDumpRenderTree ? "" : subMsg));
+}
+
+async function test() {
+ var wtu = WebGLTestUtils;
+ var canvas = document.getElementById("example");
+ var gl = wtu.create3DContext(canvas);
+ var program = wtu.setupTexturedQuad(gl);
+
+ glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+ var img = await loadImage('resources/3x3.png');
+
+ var loc = gl.getUniformLocation(program, "tex");
+ gl.uniform1i(loc, 0);
+
+ gl.disable(gl.BLEND);
+ gl.disable(gl.DEPTH_TEST);
+
+ var width = canvas.width;
+ var height = canvas.height;
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+
+ var bitmap = await createImageBitmap(img);
+
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ bitmap);
+ glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
+ wtu.drawQuad(gl);
+
+ var buf = new Uint8Array(width * height * 4);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+
+ var left = 0;
+ var middle = Math.floor(width / 2);
+ var right = width - 1;
+ var bottom = 0;
+ var center = Math.floor(height / 2);
+ var top = height - 1;
+ checkPixel(buf, width, left, top, [ 0, 0, 0, 255]);
+ checkPixel(buf, width, middle, top, [ 0, 0, 255, 255]);
+ checkPixel(buf, width, right, top, [255, 0, 0, 255]);
+ checkPixel(buf, width, left, center, [255, 0, 255, 255]);
+ checkPixel(buf, width, middle, center, [255, 0, 0, 255]);
+ checkPixel(buf, width, right, center, [ 0, 255, 0, 255]);
+ checkPixel(buf, width, left, bottom, [255, 0, 0, 255]);
+ checkPixel(buf, width, middle, bottom, [255, 255, 0, 255]);
+ checkPixel(buf, width, right, bottom, [255, 0, 0, 255]);
+}
+
+window.testRunner.waitUntilDone();
+test().then(() => {
+ window.testRunner.notifyDone();
+}, e => {
+ testFailed(String(e));
+});
+</script>
Modified: trunk/Source/WebCore/ChangeLog (235610 => 235611)
--- trunk/Source/WebCore/ChangeLog 2018-09-04 10:27:27 UTC (rev 235610)
+++ trunk/Source/WebCore/ChangeLog 2018-09-04 12:10:34 UTC (rev 235611)
@@ -1,3 +1,21 @@
+2018-09-04 Zan Dobersek <zdober...@igalia.com> and Ms2ger <ms2...@igalia.com>
+
+ Implement support for passing ImageBitmap to texImage2D/texSubImage2D
+ https://bugs.webkit.org/show_bug.cgi?id=187584
+
+ Reviewed by Dean Jackson.
+
+ Test: fast/canvas/webgl/gl-teximage-imagebitmap.html
+
+ * html/canvas/WebGL2RenderingContext.h: Update union type definition.
+ * html/canvas/WebGL2RenderingContext.idl: Update union type definition.
+ * html/canvas/WebGLRenderingContext.idl: Update union type definition.
+ * html/canvas/WebGLRenderingContextBase.cpp:
+ (WebCore::WebGLRenderingContextBase::texSubImage2D): implement.
+ (WebCore::WebGLRenderingContextBase::texImage2D): implement.
+ * html/canvas/WebGLRenderingContextBase.h: Update union type definition; add to TexFuncValidationSourceType.
+ * html/canvas/WebGLRenderingContextBase.idl: Remove unused union type definition.
+
2018-09-04 Yacine Bandou <yacine.bandou_...@softathome.com>
[EME] Add the WebM initData support in ClearKey CDM
Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h (235610 => 235611)
--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h 2018-09-04 10:27:27 UTC (rev 235610)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h 2018-09-04 12:10:34 UTC (rev 235611)
@@ -68,9 +68,9 @@
void texStorage3D(GC3Denum target, GC3Dsizei levels, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth);
#if ENABLE(VIDEO)
- using TexImageSource = WTF::Variant<RefPtr<ImageData>, RefPtr<HTMLImageElement>, RefPtr<HTMLCanvasElement>, RefPtr<HTMLVideoElement>>;
+ using TexImageSource = WTF::Variant<RefPtr<ImageBitmap>, RefPtr<ImageData>, RefPtr<HTMLImageElement>, RefPtr<HTMLCanvasElement>, RefPtr<HTMLVideoElement>>;
#else
- using TexImageSource = WTF::Variant<RefPtr<ImageData>, RefPtr<HTMLImageElement>, RefPtr<HTMLCanvasElement>>;
+ using TexImageSource = WTF::Variant<RefPtr<ImageBitmap>, RefPtr<ImageData>, RefPtr<HTMLImageElement>, RefPtr<HTMLCanvasElement>>;
#endif
using WebGLRenderingContextBase::texImage2D;
Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.idl (235610 => 235611)
--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.idl 2018-09-04 10:27:27 UTC (rev 235610)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.idl 2018-09-04 12:10:34 UTC (rev 235611)
@@ -44,11 +44,10 @@
typedef (Int32Array or sequence<GLint>) Int32List;
typedef (Uint32Array or sequence<GLuint>) Uint32List;
-// FIXME: Should allow ImageBitmap too.
#ifdef ENABLE_VIDEO
-typedef (ImageData or HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) TexImageSource;
+typedef (ImageBitmap or ImageData or HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) TexImageSource;
#else
-typedef (ImageData or HTMLImageElement or HTMLCanvasElement) TexImageSource;
+typedef (ImageBitmap or ImageData or HTMLImageElement or HTMLCanvasElement) TexImageSource;
#endif
[
Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.idl (235610 => 235611)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.idl 2018-09-04 10:27:27 UTC (rev 235610)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.idl 2018-09-04 12:10:34 UTC (rev 235611)
@@ -27,11 +27,10 @@
typedef long GLint;
typedef long GLsizei;
-// FIXME: Should allow ImageBitmap too.
#ifdef ENABLE_VIDEO
-typedef (ImageData or HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) TexImageSource;
+typedef (ImageBitmap or ImageData or HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) TexImageSource;
#else
-typedef (ImageData or HTMLImageElement or HTMLCanvasElement) TexImageSource;
+typedef (ImageBitmap or ImageData or HTMLImageElement or HTMLCanvasElement) TexImageSource;
#endif
[
Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (235610 => 235611)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp 2018-09-04 10:27:27 UTC (rev 235610)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp 2018-09-04 12:10:34 UTC (rev 235611)
@@ -3886,7 +3886,7 @@
if (isContextLostOrPending())
return { };
- auto visitor = WTF::makeVisitor([&](const RefPtr<ImageData>& pixels) -> ExceptionOr<void> {
+ auto visitor = WTF::makeVisitor([&](const RefPtr<ImageBitmap>& bitmap) -> ExceptionOr<void> {
auto texture = validateTextureBinding("texSubImage2D", target, true);
if (!texture)
return { };
@@ -3897,6 +3897,28 @@
return { };
}
+ if (!validateTexFunc("texSubImage2D", TexSubImage, SourceImageBitmap, target, level, internalFormat, bitmap->width(), bitmap->height(), 0, format, type, xoffset, yoffset))
+ return { };
+
+ ImageBuffer* buffer = bitmap->buffer();
+ if (!buffer)
+ return { };
+
+ RefPtr<Image> image = buffer->copyImage(ImageBuffer::fastCopyImageMode());
+ if (image)
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha);
+ return { };
+ }, [&](const RefPtr<ImageData>& pixels) -> ExceptionOr<void> {
+ auto texture = validateTextureBinding("texSubImage2D", target, true);
+ if (!texture)
+ return { };
+
+ GC3Denum internalFormat = texture->getInternalFormat(target, level);
+ if (!internalFormat) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "invalid texture target or level");
+ return { };
+ }
+
if (!validateTexFunc("texSubImage2D", TexSubImage, SourceImageData, target, level, internalFormat, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))
return { };
@@ -4430,7 +4452,38 @@
return { };
}
- auto visitor = WTF::makeVisitor([&](const RefPtr<ImageData>& pixels) -> ExceptionOr<void> {
+ auto visitor = WTF::makeVisitor([&](const RefPtr<ImageBitmap>& bitmap) -> ExceptionOr<void> {
+ if (isContextLostOrPending() || !validateTexFunc("texImage2D", TexImage, SourceImageBitmap, target, level, internalformat, bitmap->width(), bitmap->height(), 0, format, type, 0, 0))
+ return { };
+
+ ImageBuffer* buffer = bitmap->buffer();
+ if (!buffer)
+ return { };
+
+ auto texture = validateTextureBinding("texImage2D", target, true);
+ // If possible, copy from the bitmap directly to the texture
+ // via the GPU, without a read-back to system memory.
+ //
+ // FIXME: restriction of (RGB || RGBA)/UNSIGNED_BYTE should be lifted when
+ // ImageBuffer::copyToPlatformTexture implementations are fully functional.
+ if (texture
+ && (format == GraphicsContext3D::RGB || format == GraphicsContext3D::RGBA)
+ && type == GraphicsContext3D::UNSIGNED_BYTE) {
+ auto textureInternalFormat = texture->getInternalFormat(target, level);
+ if (isRGBFormat(textureInternalFormat) || !texture->isValid(target, level)) {
+ if (buffer->copyToPlatformTexture(*m_context.get(), target, texture->object(), internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+ texture->setLevelInfo(target, level, internalformat, bitmap->width(), bitmap->height(), type);
+ return { };
+ }
+ }
+ }
+
+ // Normal pure SW path.
+ RefPtr<Image> image = buffer->copyImage(ImageBuffer::fastCopyImageMode());
+ if (image)
+ texImage2DImpl(target, level, internalformat, format, type, image.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha);
+ return { };
+ }, [&](const RefPtr<ImageData>& pixels) -> ExceptionOr<void> {
if (isContextLostOrPending() || !validateTexFunc("texImage2D", TexImage, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0))
return { };
Vector<uint8_t> data;
Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (235610 => 235611)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h 2018-09-04 10:27:27 UTC (rev 235610)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h 2018-09-04 12:10:34 UTC (rev 235611)
@@ -232,9 +232,9 @@
void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, RefPtr<ArrayBufferView>&&);
#if ENABLE(VIDEO)
- using TexImageSource = WTF::Variant<RefPtr<ImageData>, RefPtr<HTMLImageElement>, RefPtr<HTMLCanvasElement>, RefPtr<HTMLVideoElement>>;
+ using TexImageSource = WTF::Variant<RefPtr<ImageBitmap>, RefPtr<ImageData>, RefPtr<HTMLImageElement>, RefPtr<HTMLCanvasElement>, RefPtr<HTMLVideoElement>>;
#else
- using TexImageSource = WTF::Variant<RefPtr<ImageData>, RefPtr<HTMLImageElement>, RefPtr<HTMLCanvasElement>>;
+ using TexImageSource = WTF::Variant<RefPtr<ImageBitmap>, RefPtr<ImageData>, RefPtr<HTMLImageElement>, RefPtr<HTMLCanvasElement>>;
#endif
ExceptionOr<void> texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, std::optional<TexImageSource>);
@@ -676,6 +676,7 @@
enum TexFuncValidationSourceType {
SourceArrayBufferView,
+ SourceImageBitmap,
SourceImageData,
SourceHTMLImageElement,
SourceHTMLCanvasElement,
Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.idl (235610 => 235611)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.idl 2018-09-04 10:27:27 UTC (rev 235610)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.idl 2018-09-04 12:10:34 UTC (rev 235611)
@@ -41,13 +41,6 @@
typedef (Float32Array or sequence<GLfloat>) Float32List;
typedef (Int32Array or sequence<GLint>) Int32List;
-// FIXME: Should allow ImageBitmap too.
-#ifdef ENABLE_VIDEO
-typedef (ImageData or HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) TexImageSource;
-#else
-typedef (ImageData or HTMLImageElement or HTMLCanvasElement) TexImageSource;
-#endif
-
typedef (HTMLCanvasElement or OffscreenCanvas) WebGLCanvas;
[