ImageBitmap should be serializable
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Oct 2019 14:53:17 +0000 (14:53 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Oct 2019 14:53:17 +0000 (14:53 +0000)
https://bugs.webkit.org/show_bug.cgi?id=202394

Patch by Chris Lord <clord@igalia.com> on 2019-10-04
Reviewed by Žan Doberšek.

LayoutTests/imported/w3c:

Import from upstream issue #19439

* web-platform-tests/2dcontext/imagebitmap/createImageBitmap-serializable-expected.txt: Added.
* web-platform-tests/2dcontext/imagebitmap/createImageBitmap-serializable.html: Added.
* web-platform-tests/workers/semantics/structured-clone/dedicated-expected.txt:

Source/WebCore:

Test: imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-serializable.html

* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneSerializer::dumpImageBitmap):
(WebCore::CloneDeserializer::readTransferredImageBitmap):
(WebCore::CloneDeserializer::readImageBitmap):
(WebCore::CloneDeserializer::readTerminal):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@250721 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-serializable-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-serializable.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/workers/semantics/structured-clone/dedicated-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/SerializedScriptValue.cpp

index e3e0da3..a9bbb3e 100644 (file)
@@ -1,3 +1,16 @@
+2019-10-04  Chris Lord  <clord@igalia.com>
+
+        ImageBitmap should be serializable
+        https://bugs.webkit.org/show_bug.cgi?id=202394
+
+        Reviewed by Žan Doberšek.
+
+        Import from upstream issue #19439
+
+        * web-platform-tests/2dcontext/imagebitmap/createImageBitmap-serializable-expected.txt: Added.
+        * web-platform-tests/2dcontext/imagebitmap/createImageBitmap-serializable.html: Added.
+        * web-platform-tests/workers/semantics/structured-clone/dedicated-expected.txt:
+
 2019-10-04  Oriol Brufau  <obrufau@igalia.com>
 
         [css-grid] Preserve auto repeat() in getComputedStyle() for non-grids
diff --git a/LayoutTests/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-serializable-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-serializable-expected.txt
new file mode 100644 (file)
index 0000000..718625d
--- /dev/null
@@ -0,0 +1,13 @@
+
+PASS Serialize ImageBitmap created from an HTMLCanvasElement 
+PASS Serialize ImageBitmap created from an HTMLVideoElement 
+PASS Serialize ImageBitmap created from an HTMLVideoElement from a data URL 
+PASS Serialize ImageBitmap created from a bitmap HTMLImageElement 
+PASS Serialize ImageBitmap created from a vector HTMLImageElement 
+FAIL Serialize ImageBitmap created from a bitmap SVGImageElement promise_test: Unhandled rejection with value: object "TypeError: Type error"
+FAIL Serialize ImageBitmap created from a vector SVGImageElement promise_test: Unhandled rejection with value: object "TypeError: Type error"
+FAIL Serialize ImageBitmap created from an OffscreenCanvas promise_test: Unhandled rejection with value: object "TypeError: null is not an object (evaluating 'testCtx.fillStyle = "rgb(255, 0, 0)"')"
+FAIL Serialize ImageBitmap created from an ImageData promise_test: Unhandled rejection with value: object "TypeError: createImageBitmap with ImageData is not implemented"
+PASS Serialize ImageBitmap created from an ImageBitmap 
+PASS Serialize ImageBitmap created from a Blob 
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-serializable.html b/LayoutTests/imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-serializable.html
new file mode 100644 (file)
index 0000000..39a88c6
--- /dev/null
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>createImageBitmap serialize test</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<script src="/common/namespaces.js"></script>
+<script src="common.sub.js"></script>
+<div id=log></div>
+<script>
+let worker, continuations = {};
+setup(function() {
+    worker = new Worker("transfer-worker.js");
+    worker.addEventListener("message", function(event) {
+        let { name, bitmap } = event.data;
+        if (continuations.hasOwnProperty(name)) {
+            continuations[name](bitmap);
+        }
+    });
+});
+
+for (let { name, factory } of imageSourceTypes) {
+    promise_test(function(t) {
+        return factory().then(createImageBitmap).then(function(bitmap) {
+            assert_equals(bitmap.width, 20);
+            assert_equals(bitmap.height, 20);
+
+            worker.postMessage({ name: t.name, bitmap: bitmap });
+
+            assert_equals(bitmap.width, 20);
+            assert_equals(bitmap.height, 20);
+
+            return new Promise(function(resolve) {
+                continuations[t.name] = resolve;
+            });
+        }).then(function(bitmap) {
+            assert_class_string(bitmap, "ImageBitmap");
+            assert_equals(bitmap.width, 20);
+            assert_equals(bitmap.height, 20);
+        });
+    }, `Serialize ImageBitmap created from ${name}`);
+}
+</script>
index 57b71d4..7837149 100644 (file)
@@ -106,12 +106,12 @@ PASS Object with property on prototype
 PASS Object with non-enumerable property 
 PASS Object with non-writable property 
 PASS Object with non-configurable property 
-FAIL ImageBitmap 1x1 transparent black promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL ImageBitmap 1x1 non-transparent non-black promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL Array ImageBitmap object, ImageBitmap 1x1 transparent black promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL Array ImageBitmap object, ImageBitmap 1x1 transparent non-black promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL Object ImageBitmap object, ImageBitmap 1x1 transparent black promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL Object ImageBitmap object, ImageBitmap 1x1 transparent non-black promise_test: Unhandled rejection with value: object "TypeError: Type error"
+PASS ImageBitmap 1x1 transparent black 
+PASS ImageBitmap 1x1 non-transparent non-black 
+PASS Array ImageBitmap object, ImageBitmap 1x1 transparent black 
+PASS Array ImageBitmap object, ImageBitmap 1x1 transparent non-black 
+PASS Object ImageBitmap object, ImageBitmap 1x1 transparent black 
+PASS Object ImageBitmap object, ImageBitmap 1x1 transparent non-black 
 PASS ArrayBuffer 
 PASS MessagePort 
 
index bcb8c9c..b761fb5 100644 (file)
@@ -1,3 +1,18 @@
+2019-10-04  Chris Lord  <clord@igalia.com>
+
+        ImageBitmap should be serializable
+        https://bugs.webkit.org/show_bug.cgi?id=202394
+
+        Reviewed by Žan Doberšek.
+
+        Test: imported/w3c/web-platform-tests/2dcontext/imagebitmap/createImageBitmap-serializable.html
+
+        * bindings/js/SerializedScriptValue.cpp:
+        (WebCore::CloneSerializer::dumpImageBitmap):
+        (WebCore::CloneDeserializer::readTransferredImageBitmap):
+        (WebCore::CloneDeserializer::readImageBitmap):
+        (WebCore::CloneDeserializer::readTerminal):
+
 2019-10-03  Antoine Quint  <graouts@apple.com>
 
         AppleTV named as XSS-payloads trigger when AirPlay is used
index 78ef1fe..3b000b8 100644 (file)
@@ -166,6 +166,7 @@ enum SerializationTag {
 #if ENABLE(WEB_RTC)
     RTCCertificateTag = 44,
 #endif
+    ImageBitmapTag = 45,
     ErrorTag = 255
 };
 
@@ -348,6 +349,7 @@ static const unsigned StringDataIs8BitFlag = 0x80000000;
  *    | DOMQuad
  *    | ImageBitmapTransferTag <value:uint32_t>
  *    | RTCCertificateTag
+ *    | ImageBitmapTag <originClean:uint8_t> <logicalWidth:int32_t> <logicalHeight:int32_t> <resolutionScale:double> <byteLength:uint32_t>(<imageByteData:uint8_t>)
  *
  * Inside certificate, data is serialized in this format as per spec:
  *
@@ -909,8 +911,35 @@ private:
             return;
         }
 
-        // Copying ImageBitmaps is not yet supported.
-        code = SerializationReturnCode::ValidationError;
+        auto& imageBitmap = jsCast<JSImageBitmap*>(obj)->wrapped();
+        auto* buffer = imageBitmap.buffer();
+
+        if (!buffer) {
+            code = SerializationReturnCode::ValidationError;
+            return;
+        }
+
+        const IntSize& logicalSize = buffer->logicalSize();
+        auto imageData = buffer->getPremultipliedImageData(IntRect(0, 0, logicalSize.width(), logicalSize.height()));
+        if (!imageData) {
+            code = SerializationReturnCode::ValidationError;
+            return;
+        }
+
+        RefPtr<ArrayBuffer> arrayBuffer = imageData->possiblySharedBuffer();
+        if (!arrayBuffer) {
+            code = SerializationReturnCode::ValidationError;
+            return;
+        }
+
+        write(ImageBitmapTag);
+        write(static_cast<uint8_t>(imageBitmap.originClean()));
+        write(static_cast<int32_t>(logicalSize.width()));
+        write(static_cast<int32_t>(logicalSize.height()));
+        write(static_cast<double>(buffer->resolutionScale()));
+
+        write(static_cast<uint32_t>(arrayBuffer->byteLength()));
+        write(static_cast<const uint8_t*>(arrayBuffer->data()), arrayBuffer->byteLength());
     }
 
     bool dumpIfTerminal(JSValue value, SerializationReturnCode& code)
@@ -2672,7 +2701,7 @@ private:
         return toJSNewlyCreated(m_exec, jsCast<JSDOMGlobalObject*>(m_globalObject), DOMQuad::create(p1.value(), p2.value(), p3.value(), p4.value()));
     }
 
-    JSValue readImageBitmap()
+    JSValue readTransferredImageBitmap()
     {
         uint32_t index;
         bool indexSuccessfullyRead = read(index);
@@ -2735,6 +2764,37 @@ private:
     }
 #endif
 
+    JSValue readImageBitmap()
+    {
+        uint8_t originClean;
+        int32_t logicalWidth;
+        int32_t logicalHeight;
+        double resolutionScale;
+        RefPtr<ArrayBuffer> arrayBuffer;
+
+        if (!read(originClean) || !read(logicalWidth) || !read(logicalHeight) || !read(resolutionScale) || !readArrayBuffer(arrayBuffer)) {
+            fail();
+            return JSValue();
+        }
+
+        auto imageData = Uint8ClampedArray::tryCreate(WTFMove(arrayBuffer), 0, arrayBuffer->byteLength());
+        if (!imageData) {
+            fail();
+            return JSValue();
+        }
+
+        auto buffer = ImageBuffer::create(FloatSize(logicalWidth, logicalHeight), Unaccelerated, resolutionScale);
+        if (!buffer) {
+            fail();
+            return JSValue();
+        }
+
+        buffer->putByteArray(*imageData, AlphaPremultiplication::Premultiplied, IntSize(logicalWidth, logicalHeight), IntRect(0, 0, logicalWidth, logicalHeight), IntPoint());
+
+        auto bitmap = ImageBitmap::create({ WTFMove(buffer), static_cast<bool>(originClean) });
+        return getJSValue(bitmap);
+    }
+
     JSValue readTerminal()
     {
         SerializationTag tag = readTag();
@@ -3024,12 +3084,14 @@ private:
         case DOMQuadTag:
             return readDOMQuad();
         case ImageBitmapTransferTag:
-            return readImageBitmap();
+            return readTransferredImageBitmap();
 #if ENABLE(WEB_RTC)
         case RTCCertificateTag:
             return readRTCCertificate();
 
 #endif
+        case ImageBitmapTag:
+            return readImageBitmap();
         default:
             m_ptr--; // Push the tag back
             return JSValue();