Title: [255315] trunk
Revision
255315
Author
[email protected]
Date
2020-01-28 14:48:05 -0800 (Tue, 28 Jan 2020)

Log Message

Implement [Transferable] property of OffscreenCanvas
https://bugs.webkit.org/show_bug.cgi?id=202574

Patch by Chris Lord <[email protected]> on 2020-01-28
Reviewed by Antti Koivisto.

LayoutTests/imported/w3c:

* web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob-expected.txt:
* web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.w-expected.txt:
* web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap-expected.txt:
* web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.w-expected.txt:
* web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transferrable-expected.txt:
* web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transferrable.w-expected.txt:

Source/WebCore:

Bug 202574 - Implement [Transferable] property of OffscreenCanvas

No new tests. Covered by existing tests.

* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneSerializer::serialize):
(WebCore::CloneSerializer::CloneSerializer):
(WebCore::CloneSerializer::dumpOffscreenCanvas):
(WebCore::CloneSerializer::dumpIfTerminal):
(WebCore::CloneDeserializer::deserialize):
(WebCore::CloneDeserializer::CloneDeserializer):
(WebCore::CloneDeserializer::readOffscreenCanvas):
(WebCore::CloneDeserializer::readTerminal):
(WebCore::SerializedScriptValue::SerializedScriptValue):
(WebCore::SerializedScriptValue::create):
(WebCore::canOffscreenCanvasesDetach):
(WebCore::SerializedScriptValue::deserialize):
* bindings/js/SerializedScriptValue.h:
(WebCore::SerializedScriptValue::SerializedScriptValue):
* html/CanvasBase.h:
(WebCore::CanvasBase::width const):
(WebCore::CanvasBase::height const):
* html/OffscreenCanvas.cpp:
(WebCore::DetachedOffscreenCanvas::DetachedOffscreenCanvas):
(WebCore::DetachedOffscreenCanvas::takeImageBuffer):
(WebCore::OffscreenCanvas::create):
(WebCore::OffscreenCanvas::width const):
(WebCore::OffscreenCanvas::height const):
(WebCore::OffscreenCanvas::setWidth):
(WebCore::OffscreenCanvas::setHeight):
(WebCore::OffscreenCanvas::getContext):
(WebCore::OffscreenCanvas::transferToImageBitmap):
(WebCore::OffscreenCanvas::convertToBlob):
(WebCore::OffscreenCanvas::canDetach const):
(WebCore::OffscreenCanvas::detach):
(WebCore::OffscreenCanvas::takeImageBuffer const):
* html/OffscreenCanvas.h:
(WebCore::DetachedOffscreenCanvas::size const):
(WebCore::DetachedOffscreenCanvas::originClean const):

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (255314 => 255315)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2020-01-28 22:19:03 UTC (rev 255314)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2020-01-28 22:48:05 UTC (rev 255315)
@@ -1,3 +1,17 @@
+2020-01-28  Chris Lord  <[email protected]>
+
+        Implement [Transferable] property of OffscreenCanvas
+        https://bugs.webkit.org/show_bug.cgi?id=202574
+
+        Reviewed by Antti Koivisto.
+
+        * web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob-expected.txt:
+        * web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.w-expected.txt:
+        * web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap-expected.txt:
+        * web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.w-expected.txt:
+        * web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transferrable-expected.txt:
+        * web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transferrable.w-expected.txt:
+
 2020-01-28  Carlos Alberto Lopez Perez  <[email protected]>
 
         [CSS Backgrounds] Import WPT css-backgrounds tests

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob-expected.txt (255314 => 255315)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob-expected.txt	2020-01-28 22:19:03 UTC (rev 255314)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob-expected.txt	2020-01-28 22:48:05 UTC (rev 255315)
@@ -3,7 +3,7 @@
 PASS Test that convertToBlob with png produces correct result 
 PASS Test that convertToBlob with jpge produces correct result 
 PASS Test that convertToBlob with webp produces correct result 
-FAIL Test that call convertToBlob on a detached OffscreenCanvas throws exception The object can not be cloned.
+PASS Test that call convertToBlob on a detached OffscreenCanvas throws exception 
 PASS Test that call convertToBlob on a OffscreenCanvas with size 0 throws exception 
 PASS Test that call convertToBlob on a OffscreenCanvas with tainted origin throws exception 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.w-expected.txt (255314 => 255315)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.w-expected.txt	2020-01-28 22:19:03 UTC (rev 255314)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/convert-to-blob/offscreencanvas.convert.to.blob.w-expected.txt	2020-01-28 22:48:05 UTC (rev 255315)
@@ -1,6 +1,4 @@
 
-Harness Error (FAIL), message = DataCloneError: The object can not be cloned.
-
 PASS Test that convertToBlob with default arguments produces correct result in a worker 
 PASS Test that convertToBlob with default type/1.0 quality produces correct result in a worker 
 PASS Test that convertToBlob with default type/0.2 quality produces correct result in a worker 
@@ -13,7 +11,7 @@
 PASS Test that convertToBlob with webp/default quality produces correct result in a worker 
 PASS Test that convertToBlob with webp/1.0 quality produces correct result in a worker 
 PASS Test that convertToBlob with webp/0.2 quality produces correct result in a worker 
-FAIL Test that call convertToBlob on a detached OffscreenCanvas throws exception in a worker assert_unreached: error Reached unreachable code
+PASS Test that call convertToBlob on a detached OffscreenCanvas throws exception in a worker 
 PASS Test that call convertToBlob on a OffscreenCanvas with size 0 throws exception in a worker 
 PASS Test that call convertToBlob on a OffscreenCanvas with tainted origin throws exception in a worker 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap-expected.txt (255314 => 255315)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap-expected.txt	2020-01-28 22:19:03 UTC (rev 255314)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap-expected.txt	2020-01-28 22:48:05 UTC (rev 255315)
@@ -3,6 +3,6 @@
 FAIL Test that transferToImageBitmap returns an ImageBitmap with correct color assert_equals: Alpha channel of the pixel at (50, 25) expected 255 but got 0
 PASS Test that transferToImageBitmap won't change context's property 
 FAIL Test that transferToImageBitmap preserves transform assert_equals: Green channel of the pixel at (23, 25) expected 255 but got 0
-FAIL Test that call transferToImageBitmap on a detached OffscreenCanvas throws an exception The object can not be cloned.
+PASS Test that call transferToImageBitmap on a detached OffscreenCanvas throws an exception 
 PASS Test that transferToImageBitmap without a context throws an exception 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.w-expected.txt (255314 => 255315)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.w-expected.txt	2020-01-28 22:19:03 UTC (rev 255314)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.w-expected.txt	2020-01-28 22:48:05 UTC (rev 255315)
@@ -5,6 +5,6 @@
 FAIL Test that call transferToImageBitmap twice on a alpha-disabled context returns an ImageBitmap with correct color in a worker assert_array_equals: property 3, expected 255 but got 0
 PASS Test that transferToImageBitmap won't change context's property in a worker 
 FAIL Test that call transferToImageBitmap preserves transform in a worker assert_array_equals: property 1, expected 255 but got 0
-FAIL Test that call transferToImageBitmap on a detached OffscreenCanvas throws an exception in a worker assert_unreached: error Reached unreachable code
+PASS Test that call transferToImageBitmap on a detached OffscreenCanvas throws an exception in a worker 
 PASS Test that call transferToImageBitmap without a context throws an exception in a worker 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transferrable-expected.txt (255314 => 255315)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transferrable-expected.txt	2020-01-28 22:19:03 UTC (rev 255314)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transferrable-expected.txt	2020-01-28 22:48:05 UTC (rev 255315)
@@ -1,9 +1,7 @@
 
-FAIL Test that offscreenCanvas's size is correct after being transferred to a worker. The object can not be cloned.
-FAIL Test that transfer an OffscreenCanvas that has a context throws exception. assert_throws: function "function () {
-            worker.postMessage({offscreenCanvas}, [offscreenCanvas]);
-        }" threw object "DataCloneError: The object can not be cloned." that is not a DOMException InvalidStateError: property "code" is equal to 25, expected 11
-FAIL Test that transfer an OffscreenCanvas twice throws exception. The object can not be cloned.
-FAIL Test that calling getContext('2d') on a detached OffscreenCanvas throws exception. The object can not be cloned.
-FAIL Test that calling getContext('webgl') on a detached OffscreenCanvas throws exception. The object can not be cloned.
+PASS Test that offscreenCanvas's size is correct after being transferred to a worker. 
+PASS Test that transfer an OffscreenCanvas that has a context throws exception. 
+PASS Test that transfer an OffscreenCanvas twice throws exception. 
+PASS Test that calling getContext('2d') on a detached OffscreenCanvas throws exception. 
+PASS Test that calling getContext('webgl') on a detached OffscreenCanvas throws exception. 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transferrable.w-expected.txt (255314 => 255315)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transferrable.w-expected.txt	2020-01-28 22:19:03 UTC (rev 255314)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/offscreen-canvas/the-offscreen-canvas/offscreencanvas.transferrable.w-expected.txt	2020-01-28 22:48:05 UTC (rev 255315)
@@ -1,10 +1,8 @@
 
-Harness Error (FAIL), message = DataCloneError: The object can not be cloned.
+PASS Test that OffscreenCanvas's size is correct after being transferred from a worker. 
+PASS Test that transfer an OffscreenCanvas that has a 2d context throws exception in a worker. 
+PASS Test that transfer an OffscreenCanvas that has a webgl context throws exception in a worker. 
+PASS Test that transfer an OffscreenCanvas twice throws exception in a worker. 
+PASS Test that calling getContext('2d') on a detached OffscreenCanvas throws exception in a worker. 
+PASS Test that calling getContext('webgl') on a detached OffscreenCanvas throws exception in a worker. 
 
-FAIL Test that OffscreenCanvas's size is correct after being transferred from a worker. assert_unreached: error Reached unreachable code
-FAIL Test that transfer an OffscreenCanvas that has a 2d context throws exception in a worker. assert_true: expected true got false
-FAIL Test that transfer an OffscreenCanvas that has a webgl context throws exception in a worker. assert_true: expected true got false
-FAIL Test that transfer an OffscreenCanvas twice throws exception in a worker. assert_unreached: error Reached unreachable code
-FAIL Test that calling getContext('2d') on a detached OffscreenCanvas throws exception in a worker. assert_unreached: error Reached unreachable code
-FAIL Test that calling getContext('webgl') on a detached OffscreenCanvas throws exception in a worker. assert_unreached: error Reached unreachable code
-

Modified: trunk/Source/WebCore/ChangeLog (255314 => 255315)


--- trunk/Source/WebCore/ChangeLog	2020-01-28 22:19:03 UTC (rev 255314)
+++ trunk/Source/WebCore/ChangeLog	2020-01-28 22:48:05 UTC (rev 255315)
@@ -1,3 +1,50 @@
+2020-01-28  Chris Lord  <[email protected]>
+
+        Implement [Transferable] property of OffscreenCanvas
+        https://bugs.webkit.org/show_bug.cgi?id=202574
+
+        Reviewed by Antti Koivisto.
+
+        Bug 202574 - Implement [Transferable] property of OffscreenCanvas
+
+        No new tests. Covered by existing tests.
+
+        * bindings/js/SerializedScriptValue.cpp:
+        (WebCore::CloneSerializer::serialize):
+        (WebCore::CloneSerializer::CloneSerializer):
+        (WebCore::CloneSerializer::dumpOffscreenCanvas):
+        (WebCore::CloneSerializer::dumpIfTerminal):
+        (WebCore::CloneDeserializer::deserialize):
+        (WebCore::CloneDeserializer::CloneDeserializer):
+        (WebCore::CloneDeserializer::readOffscreenCanvas):
+        (WebCore::CloneDeserializer::readTerminal):
+        (WebCore::SerializedScriptValue::SerializedScriptValue):
+        (WebCore::SerializedScriptValue::create):
+        (WebCore::canOffscreenCanvasesDetach):
+        (WebCore::SerializedScriptValue::deserialize):
+        * bindings/js/SerializedScriptValue.h:
+        (WebCore::SerializedScriptValue::SerializedScriptValue):
+        * html/CanvasBase.h:
+        (WebCore::CanvasBase::width const):
+        (WebCore::CanvasBase::height const):
+        * html/OffscreenCanvas.cpp:
+        (WebCore::DetachedOffscreenCanvas::DetachedOffscreenCanvas):
+        (WebCore::DetachedOffscreenCanvas::takeImageBuffer):
+        (WebCore::OffscreenCanvas::create):
+        (WebCore::OffscreenCanvas::width const):
+        (WebCore::OffscreenCanvas::height const):
+        (WebCore::OffscreenCanvas::setWidth):
+        (WebCore::OffscreenCanvas::setHeight):
+        (WebCore::OffscreenCanvas::getContext):
+        (WebCore::OffscreenCanvas::transferToImageBitmap):
+        (WebCore::OffscreenCanvas::convertToBlob):
+        (WebCore::OffscreenCanvas::canDetach const):
+        (WebCore::OffscreenCanvas::detach):
+        (WebCore::OffscreenCanvas::takeImageBuffer const):
+        * html/OffscreenCanvas.h:
+        (WebCore::DetachedOffscreenCanvas::size const):
+        (WebCore::DetachedOffscreenCanvas::originClean const):
+
 2020-01-28  Andres Gonzalez  <[email protected]>
 
         Properly clear pending changes during AXIsolatedTree removal and applyPendingChanges.

Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (255314 => 255315)


--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp	2020-01-28 22:19:03 UTC (rev 255314)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp	2020-01-28 22:48:05 UTC (rev 255315)
@@ -87,6 +87,11 @@
 #include <wtf/RunLoop.h>
 #include <wtf/Vector.h>
 
+#if ENABLE(OFFSCREEN_CANVAS)
+#include "JSOffscreenCanvas.h"
+#include "OffscreenCanvas.h"
+#endif
+
 #if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN) || CPU(NEEDS_ALIGNED_ACCESS)
 #define ASSUME_LITTLE_ENDIAN 0
 #else
@@ -169,6 +174,9 @@
     RTCCertificateTag = 44,
 #endif
     ImageBitmapTag = 45,
+#if ENABLE(OFFSCREEN_CANVAS)
+    OffscreenCanvasTransferTag = 46,
+#endif
     ErrorTag = 255
 };
 
@@ -352,6 +360,7 @@
  *    | ImageBitmapTransferTag <value:uint32_t>
  *    | RTCCertificateTag
  *    | ImageBitmapTag <originClean:uint8_t> <logicalWidth:int32_t> <logicalHeight:int32_t> <resolutionScale:double> <byteLength:uint32_t>(<imageByteData:uint8_t>)
+ *    | OffscreenCanvasTransferTag <value:uint32_t>
  *
  * Inside certificate, data is serialized in this format as per spec:
  *
@@ -549,6 +558,9 @@
 class CloneSerializer : CloneBase {
 public:
     static SerializationReturnCode serialize(JSGlobalObject* lexicalGlobalObject, JSValue value, Vector<RefPtr<MessagePort>>& messagePorts, Vector<RefPtr<JSC::ArrayBuffer>>& arrayBuffers, const Vector<RefPtr<ImageBitmap>>& imageBitmaps,
+#if ENABLE(OFFSCREEN_CANVAS)
+            const Vector<RefPtr<OffscreenCanvas>>& offscreenCanvases,
+#endif
 #if ENABLE(WEBASSEMBLY)
             WasmModuleArray& wasmModules,
 #endif
@@ -555,6 +567,9 @@
         Vector<String>& blobURLs, Vector<uint8_t>& out, SerializationContext context, ArrayBufferContentsArray& sharedBuffers)
     {
         CloneSerializer serializer(lexicalGlobalObject, messagePorts, arrayBuffers, imageBitmaps,
+#if ENABLE(OFFSCREEN_CANVAS)
+            offscreenCanvases,
+#endif
 #if ENABLE(WEBASSEMBLY)
             wasmModules,
 #endif
@@ -582,6 +597,9 @@
     typedef HashMap<JSObject*, uint32_t> ObjectPool;
 
     CloneSerializer(JSGlobalObject* lexicalGlobalObject, Vector<RefPtr<MessagePort>>& messagePorts, Vector<RefPtr<JSC::ArrayBuffer>>& arrayBuffers, const Vector<RefPtr<ImageBitmap>>& imageBitmaps,
+#if ENABLE(OFFSCREEN_CANVAS)
+            const Vector<RefPtr<OffscreenCanvas>>& offscreenCanvases,
+#endif
 #if ENABLE(WEBASSEMBLY)
             WasmModuleArray& wasmModules,
 #endif
@@ -600,6 +618,9 @@
         fillTransferMap(messagePorts, m_transferredMessagePorts);
         fillTransferMap(arrayBuffers, m_transferredArrayBuffers);
         fillTransferMap(imageBitmaps, m_transferredImageBitmaps);
+#if ENABLE(OFFSCREEN_CANVAS)
+        fillTransferMap(offscreenCanvases, m_transferredOffscreenCanvases);
+#endif
     }
 
     template <class T>
@@ -944,6 +965,20 @@
         write(static_cast<const uint8_t*>(arrayBuffer->data()), arrayBuffer->byteLength());
     }
 
+#if ENABLE(OFFSCREEN_CANVAS)
+    void dumpOffscreenCanvas(JSObject* obj, SerializationReturnCode& code)
+    {
+        auto index = m_transferredOffscreenCanvases.find(obj);
+        if (index != m_transferredOffscreenCanvases.end()) {
+            write(OffscreenCanvasTransferTag);
+            write(index->value);
+            return;
+        }
+
+        code = SerializationReturnCode::DataCloneError;
+    }
+#endif
+
     bool dumpIfTerminal(JSValue value, SerializationReturnCode& code)
     {
         if (!value.isCell()) {
@@ -1095,6 +1130,9 @@
 #endif
                 ArrayBufferContentsArray dummySharedBuffers;
                 CloneSerializer rawKeySerializer(m_lexicalGlobalObject, dummyMessagePorts, dummyArrayBuffers, { },
+#if ENABLE(OFFSCREEN_CANVAS)
+                    { },
+#endif
 #if ENABLE(WEBASSEMBLY)
                     dummyModules,
 #endif
@@ -1154,6 +1192,12 @@
                 dumpImageBitmap(obj, code);
                 return true;
             }
+#if ENABLE(OFFSCREEN_CANVAS)
+            if (obj->inherits(vm, JSOffscreenCanvas::info())) {
+                dumpOffscreenCanvas(obj, code);
+                return true;
+            }
+#endif
             return false;
         }
         // Any other types are expected to serialize as null.
@@ -1501,6 +1545,9 @@
     ObjectPool m_transferredMessagePorts;
     ObjectPool m_transferredArrayBuffers;
     ObjectPool m_transferredImageBitmaps;
+#if ENABLE(OFFSCREEN_CANVAS)
+    ObjectPool m_transferredOffscreenCanvases;
+#endif
     typedef HashMap<RefPtr<UniquedStringImpl>, uint32_t, IdentifierRepHash> StringConstantPool;
     StringConstantPool m_constantPool;
     Identifier m_emptyIdentifier;
@@ -1780,7 +1827,11 @@
         return str;
     }
 
-    static DeserializationResult deserialize(JSGlobalObject* lexicalGlobalObject, JSGlobalObject* globalObject, const Vector<RefPtr<MessagePort>>& messagePorts, Vector<std::pair<std::unique_ptr<ImageBuffer>, bool>>&& imageBuffers, ArrayBufferContentsArray* arrayBufferContentsArray, const Vector<uint8_t>& buffer, const Vector<String>& blobURLs, const Vector<String> blobFilePaths, ArrayBufferContentsArray* sharedBuffers
+    static DeserializationResult deserialize(JSGlobalObject* lexicalGlobalObject, JSGlobalObject* globalObject, const Vector<RefPtr<MessagePort>>& messagePorts, Vector<std::pair<std::unique_ptr<ImageBuffer>, bool>>&& imageBuffers
+#if ENABLE(OFFSCREEN_CANVAS)
+        , Vector<std::unique_ptr<DetachedOffscreenCanvas>>&& detachedOffscreenCanvases
+#endif
+        , ArrayBufferContentsArray* arrayBufferContentsArray, const Vector<uint8_t>& buffer, const Vector<String>& blobURLs, const Vector<String> blobFilePaths, ArrayBufferContentsArray* sharedBuffers
 #if ENABLE(WEBASSEMBLY)
         , WasmModuleArray* wasmModules
 #endif
@@ -1789,6 +1840,9 @@
         if (!buffer.size())
             return std::make_pair(jsNull(), SerializationReturnCode::UnspecifiedError);
         CloneDeserializer deserializer(lexicalGlobalObject, globalObject, messagePorts, arrayBufferContentsArray, buffer, blobURLs, blobFilePaths, sharedBuffers, WTFMove(imageBuffers)
+#if ENABLE(OFFSCREEN_CANVAS)
+            , WTFMove(detachedOffscreenCanvases)
+#endif
 #if ENABLE(WEBASSEMBLY)
             , wasmModules
 #endif
@@ -1838,11 +1892,14 @@
         size_t m_index;
     };
 
-    CloneDeserializer(JSGlobalObject* lexicalGlobalObject, JSGlobalObject* globalObject, const Vector<RefPtr<MessagePort>>& messagePorts, ArrayBufferContentsArray* arrayBufferContents, Vector<std::pair<std::unique_ptr<ImageBuffer>, bool>>&& imageBuffers,
+    CloneDeserializer(JSGlobalObject* lexicalGlobalObject, JSGlobalObject* globalObject, const Vector<RefPtr<MessagePort>>& messagePorts, ArrayBufferContentsArray* arrayBufferContents, Vector<std::pair<std::unique_ptr<ImageBuffer>, bool>>&& imageBuffers, const Vector<uint8_t>& buffer
+#if ENABLE(OFFSCREEN_CANVAS)
+        , Vector<std::unique_ptr<DetachedOffscreenCanvas>>&& detachedOffscreenCanvases = { }
+#endif
 #if ENABLE(WEBASSEMBLY)
-        WasmModuleArray* wasmModules,
+        , WasmModuleArray* wasmModules = nullptr
 #endif
-        const Vector<uint8_t>& buffer)
+        )
         : CloneBase(lexicalGlobalObject)
         , m_globalObject(globalObject)
         , m_isDOMGlobalObject(globalObject->inherits<JSDOMGlobalObject>(globalObject->vm()))
@@ -1854,6 +1911,10 @@
         , m_arrayBuffers(arrayBufferContents ? arrayBufferContents->size() : 0)
         , m_imageBuffers(WTFMove(imageBuffers))
         , m_imageBitmaps(m_imageBuffers.size())
+#if ENABLE(OFFSCREEN_CANVAS)
+        , m_detachedOffscreenCanvases(WTFMove(detachedOffscreenCanvases))
+        , m_offscreenCanvases(m_detachedOffscreenCanvases.size())
+#endif
 #if ENABLE(WEBASSEMBLY)
         , m_wasmModules(wasmModules)
 #endif
@@ -1863,6 +1924,9 @@
     }
 
     CloneDeserializer(JSGlobalObject* lexicalGlobalObject, JSGlobalObject* globalObject, const Vector<RefPtr<MessagePort>>& messagePorts, ArrayBufferContentsArray* arrayBufferContents, const Vector<uint8_t>& buffer, const Vector<String>& blobURLs, const Vector<String> blobFilePaths, ArrayBufferContentsArray* sharedBuffers, Vector<std::pair<std::unique_ptr<ImageBuffer>, bool>>&& imageBuffers
+#if ENABLE(OFFSCREEN_CANVAS)
+        , Vector<std::unique_ptr<DetachedOffscreenCanvas>>&& detachedOffscreenCanvases
+#endif
 #if ENABLE(WEBASSEMBLY)
         , WasmModuleArray* wasmModules
 #endif
@@ -1881,6 +1945,10 @@
         , m_sharedBuffers(sharedBuffers)
         , m_imageBuffers(WTFMove(imageBuffers))
         , m_imageBitmaps(m_imageBuffers.size())
+#if ENABLE(OFFSCREEN_CANVAS)
+        , m_detachedOffscreenCanvases(WTFMove(detachedOffscreenCanvases))
+        , m_offscreenCanvases(m_detachedOffscreenCanvases.size())
+#endif
 #if ENABLE(WEBASSEMBLY)
         , m_wasmModules(wasmModules)
 #endif
@@ -2719,6 +2787,24 @@
         return getJSValue(bitmap);
     }
 
+#if ENABLE(OFFSCREEN_CANVAS)
+    JSValue readOffscreenCanvas()
+    {
+        uint32_t index;
+        bool indexSuccessfullyRead = read(index);
+        if (!indexSuccessfullyRead || index >= m_detachedOffscreenCanvases.size()) {
+            fail();
+            return JSValue();
+        }
+
+        if (!m_offscreenCanvases[index])
+            m_offscreenCanvases[index] = OffscreenCanvas::create(*scriptExecutionContextFromExecState(m_lexicalGlobalObject), WTFMove(m_detachedOffscreenCanvases.at(index)));
+
+        auto offscreenCanvas = m_offscreenCanvases[index].get();
+        return getJSValue(offscreenCanvas);
+    }
+#endif
+
 #if ENABLE(WEB_RTC)
     JSValue readRTCCertificate()
     {
@@ -3058,11 +3144,7 @@
             }
             JSValue cryptoKey;
             Vector<RefPtr<MessagePort>> dummyMessagePorts;
-            CloneDeserializer rawKeyDeserializer(m_lexicalGlobalObject, m_globalObject, dummyMessagePorts, nullptr, { },
-#if ENABLE(WEBASSEMBLY)
-                nullptr,
-#endif
-                serializedKey);
+            CloneDeserializer rawKeyDeserializer(m_lexicalGlobalObject, m_globalObject, dummyMessagePorts, nullptr, { }, serializedKey);
             if (!rawKeyDeserializer.readCryptoKey(cryptoKey)) {
                 fail();
                 return JSValue();
@@ -3094,6 +3176,10 @@
 #endif
         case ImageBitmapTag:
             return readImageBitmap();
+#if ENABLE(OFFSCREEN_CANVAS)
+        case OffscreenCanvasTransferTag:
+            return readOffscreenCanvas();
+#endif
         default:
             m_ptr--; // Push the tag back
             return JSValue();
@@ -3123,6 +3209,10 @@
     ArrayBufferContentsArray* m_sharedBuffers;
     Vector<std::pair<std::unique_ptr<ImageBuffer>, bool>> m_imageBuffers;
     Vector<RefPtr<ImageBitmap>> m_imageBitmaps;
+#if ENABLE(OFFSCREEN_CANVAS)
+    Vector<std::unique_ptr<DetachedOffscreenCanvas>> m_detachedOffscreenCanvases;
+    Vector<RefPtr<OffscreenCanvas>> m_offscreenCanvases;
+#endif
 #if ENABLE(WEBASSEMBLY)
     WasmModuleArray* m_wasmModules;
 #endif
@@ -3340,6 +3430,9 @@
 }
 
 SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>&& buffer, const Vector<String>& blobURLs, std::unique_ptr<ArrayBufferContentsArray> arrayBufferContentsArray, std::unique_ptr<ArrayBufferContentsArray> sharedBufferContentsArray, Vector<std::pair<std::unique_ptr<ImageBuffer>, bool>>&& imageBuffers
+#if ENABLE(OFFSCREEN_CANVAS)
+        , Vector<std::unique_ptr<DetachedOffscreenCanvas>>&& detachedOffscreenCanvases
+#endif
 #if ENABLE(WEBASSEMBLY)
         , std::unique_ptr<WasmModuleArray> wasmModulesArray
 #endif
@@ -3348,6 +3441,9 @@
     , m_arrayBufferContentsArray(WTFMove(arrayBufferContentsArray))
     , m_sharedBufferContentsArray(WTFMove(sharedBufferContentsArray))
     , m_imageBuffers(WTFMove(imageBuffers))
+#if ENABLE(OFFSCREEN_CANVAS)
+    , m_detachedOffscreenCanvases(WTFMove(detachedOffscreenCanvases))
+#endif
 #if ENABLE(WEBASSEMBLY)
     , m_wasmModulesArray(WTFMove(wasmModulesArray))
 #endif
@@ -3435,6 +3531,9 @@
     Vector<String> blobURLs;
     Vector<RefPtr<MessagePort>> dummyMessagePorts;
     Vector<RefPtr<ImageBitmap>> dummyImageBitmaps;
+#if ENABLE(OFFSCREEN_CANVAS)
+    Vector<RefPtr<OffscreenCanvas>> dummyOffscreenCanvases;
+#endif
     Vector<RefPtr<JSC::ArrayBuffer>> dummyArrayBuffers;
 #if ENABLE(WEBASSEMBLY)
     WasmModuleArray dummyModules;
@@ -3441,6 +3540,9 @@
 #endif
     ArrayBufferContentsArray dummySharedBuffers;
     auto code = CloneSerializer::serialize(&lexicalGlobalObject, value, dummyMessagePorts, dummyArrayBuffers, dummyImageBitmaps,
+#if ENABLE(OFFSCREEN_CANVAS)
+        dummyOffscreenCanvases,
+#endif
 #if ENABLE(WEBASSEMBLY)
         dummyModules,
 #endif
@@ -3456,11 +3558,7 @@
     if (code != SerializationReturnCode::SuccessfullyCompleted)
         return nullptr;
 
-    return adoptRef(*new SerializedScriptValue(WTFMove(buffer), blobURLs, nullptr, nullptr, { }
-#if ENABLE(WEBASSEMBLY)
-        , nullptr
-#endif
-            ));
+    return adoptRef(*new SerializedScriptValue(WTFMove(buffer), blobURLs, nullptr, nullptr, { }));
 }
 
 static bool containsDuplicates(const Vector<RefPtr<ImageBitmap>>& imageBitmaps)
@@ -3473,11 +3571,29 @@
     return false;
 }
 
+#if ENABLE(OFFSCREEN_CANVAS)
+static bool canOffscreenCanvasesDetach(const Vector<RefPtr<OffscreenCanvas>>& offscreenCanvases)
+{
+    HashSet<OffscreenCanvas*> visited;
+    for (auto& offscreenCanvas : offscreenCanvases) {
+        if (!offscreenCanvas->canDetach())
+            return false;
+        // Check the return value of add, we should not encounter duplicates.
+        if (!visited.add(offscreenCanvas.get()))
+            return false;
+    }
+    return true;
+}
+#endif
+
 ExceptionOr<Ref<SerializedScriptValue>> SerializedScriptValue::create(JSGlobalObject& lexicalGlobalObject, JSValue value, Vector<JSC::Strong<JSC::JSObject>>&& transferList, Vector<RefPtr<MessagePort>>& messagePorts, SerializationContext context)
 {
     VM& vm = lexicalGlobalObject.vm();
     Vector<RefPtr<JSC::ArrayBuffer>> arrayBuffers;
     Vector<RefPtr<ImageBitmap>> imageBitmaps;
+#if ENABLE(OFFSCREEN_CANVAS)
+    Vector<RefPtr<OffscreenCanvas>> offscreenCanvases;
+#endif
     for (auto& transferable : transferList) {
         if (auto arrayBuffer = toPossiblySharedArrayBuffer(vm, transferable.get())) {
             if (arrayBuffer->isNeutered())
@@ -3504,11 +3620,22 @@
             continue;
         }
 
+#if ENABLE(OFFSCREEN_CANVAS)
+        if (auto offscreenCanvas = JSOffscreenCanvas::toWrapped(vm, transferable.get())) {
+            offscreenCanvases.append(WTFMove(offscreenCanvas));
+            continue;
+        }
+#endif
+
         return Exception { DataCloneError };
     }
 
     if (containsDuplicates(imageBitmaps))
         return Exception { DataCloneError };
+#if ENABLE(OFFSCREEN_CANVAS)
+    if (!canOffscreenCanvasesDetach(offscreenCanvases))
+        return Exception { InvalidStateError };
+#endif
 
     Vector<uint8_t> buffer;
     Vector<String> blobURLs;
@@ -3517,6 +3644,9 @@
 #endif
     std::unique_ptr<ArrayBufferContentsArray> sharedBuffers = makeUnique<ArrayBufferContentsArray>();
     auto code = CloneSerializer::serialize(&lexicalGlobalObject, value, messagePorts, arrayBuffers, imageBitmaps,
+#if ENABLE(OFFSCREEN_CANVAS)
+        offscreenCanvases,
+#endif
 #if ENABLE(WEBASSEMBLY)
         wasmModules, 
 #endif
@@ -3531,7 +3661,16 @@
 
     auto imageBuffers = ImageBitmap::detachBitmaps(WTFMove(imageBitmaps));
 
+#if ENABLE(OFFSCREEN_CANVAS)
+    Vector<std::unique_ptr<DetachedOffscreenCanvas>> detachedCanvases;
+    for (auto offscreenCanvas : offscreenCanvases)
+        detachedCanvases.append(offscreenCanvas->detach());
+#endif
+
     return adoptRef(*new SerializedScriptValue(WTFMove(buffer), blobURLs, arrayBufferContentsArray.releaseReturnValue(), context == SerializationContext::WorkerPostMessage ? WTFMove(sharedBuffers) : nullptr, WTFMove(imageBuffers)
+#if ENABLE(OFFSCREEN_CANVAS)
+                , WTFMove(detachedCanvases)
+#endif
 #if ENABLE(WEBASSEMBLY)
                 , makeUnique<WasmModuleArray>(wasmModules)
 #endif
@@ -3584,7 +3723,11 @@
 
 JSValue SerializedScriptValue::deserialize(JSGlobalObject& lexicalGlobalObject, JSGlobalObject* globalObject, const Vector<RefPtr<MessagePort>>& messagePorts, const Vector<String>& blobURLs, const Vector<String>& blobFilePaths, SerializationErrorMode throwExceptions)
 {
-    DeserializationResult result = CloneDeserializer::deserialize(&lexicalGlobalObject, globalObject, messagePorts, WTFMove(m_imageBuffers), m_arrayBufferContentsArray.get(), m_data, blobURLs, blobFilePaths, m_sharedBufferContentsArray.get()
+    DeserializationResult result = CloneDeserializer::deserialize(&lexicalGlobalObject, globalObject, messagePorts, WTFMove(m_imageBuffers)
+#if ENABLE(OFFSCREEN_CANVAS)
+        , WTFMove(m_detachedOffscreenCanvases)
+#endif
+        , m_arrayBufferContentsArray.get(), m_data, blobURLs, blobFilePaths, m_sharedBufferContentsArray.get()
 #if ENABLE(WEBASSEMBLY)
         , m_wasmModulesArray.get()
 #endif

Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.h (255314 => 255315)


--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.h	2020-01-28 22:19:03 UTC (rev 255314)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.h	2020-01-28 22:48:05 UTC (rev 255315)
@@ -47,6 +47,9 @@
 
 namespace WebCore {
 
+#if ENABLE(OFFSCREEN_CANVAS)
+class DetachedOffscreenCanvas;
+#endif
 class IDBValue;
 class ImageBitmap;
 class MessagePort;
@@ -113,8 +116,11 @@
     WEBCORE_EXPORT SerializedScriptValue(Vector<unsigned char>&&);
     WEBCORE_EXPORT SerializedScriptValue(Vector<unsigned char>&&, std::unique_ptr<ArrayBufferContentsArray>);
     SerializedScriptValue(Vector<unsigned char>&&, const Vector<String>& blobURLs, std::unique_ptr<ArrayBufferContentsArray>, std::unique_ptr<ArrayBufferContentsArray> sharedBuffers, Vector<std::pair<std::unique_ptr<ImageBuffer>, bool>>&& imageBuffers
+#if ENABLE(OFFSCREEN_CANVAS)
+        , Vector<std::unique_ptr<DetachedOffscreenCanvas>>&& = { }
+#endif
 #if ENABLE(WEBASSEMBLY)
-        , std::unique_ptr<WasmModuleArray>
+        , std::unique_ptr<WasmModuleArray> = nullptr
 #endif
         );
 
@@ -122,6 +128,9 @@
     std::unique_ptr<ArrayBufferContentsArray> m_arrayBufferContentsArray;
     std::unique_ptr<ArrayBufferContentsArray> m_sharedBufferContentsArray;
     Vector<std::pair<std::unique_ptr<ImageBuffer>, bool>> m_imageBuffers;
+#if ENABLE(OFFSCREEN_CANVAS)
+    Vector<std::unique_ptr<DetachedOffscreenCanvas>> m_detachedOffscreenCanvases;
+#endif
 #if ENABLE(WEBASSEMBLY)
     std::unique_ptr<WasmModuleArray> m_wasmModulesArray;
 #endif

Modified: trunk/Source/WebCore/html/CanvasBase.h (255314 => 255315)


--- trunk/Source/WebCore/html/CanvasBase.h	2020-01-28 22:19:03 UTC (rev 255314)
+++ trunk/Source/WebCore/html/CanvasBase.h	2020-01-28 22:48:05 UTC (rev 255315)
@@ -65,8 +65,8 @@
     virtual bool isOffscreenCanvas() const { return false; }
     virtual bool isCustomPaintCanvas() const { return false; }
 
-    unsigned width() const { return m_size.width(); }
-    unsigned height() const { return m_size.height(); }
+    virtual unsigned width() const { return m_size.width(); }
+    virtual unsigned height() const { return m_size.height(); }
     const IntSize& size() const { return m_size; }
 
     ImageBuffer* buffer() const;

Modified: trunk/Source/WebCore/html/OffscreenCanvas.cpp (255314 => 255315)


--- trunk/Source/WebCore/html/OffscreenCanvas.cpp	2020-01-28 22:19:03 UTC (rev 255314)
+++ trunk/Source/WebCore/html/OffscreenCanvas.cpp	2020-01-28 22:48:05 UTC (rev 255315)
@@ -43,11 +43,33 @@
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(OffscreenCanvas);
 
+DetachedOffscreenCanvas::DetachedOffscreenCanvas(std::unique_ptr<ImageBuffer>&& buffer, const IntSize& size, bool originClean)
+    : m_buffer(WTFMove(buffer))
+    , m_size(size)
+    , m_originClean(originClean)
+{
+}
+
+std::unique_ptr<ImageBuffer> DetachedOffscreenCanvas::takeImageBuffer()
+{
+    return WTFMove(m_buffer);
+}
+
 Ref<OffscreenCanvas> OffscreenCanvas::create(ScriptExecutionContext& context, unsigned width, unsigned height)
 {
     return adoptRef(*new OffscreenCanvas(context, width, height));
 }
 
+Ref<OffscreenCanvas> OffscreenCanvas::create(ScriptExecutionContext& context, std::unique_ptr<DetachedOffscreenCanvas>&& detachedCanvas)
+{
+    Ref<OffscreenCanvas> clone = adoptRef(*new OffscreenCanvas(context, detachedCanvas->size().width(), detachedCanvas->size().height()));
+    clone->setImageBuffer(detachedCanvas->takeImageBuffer());
+    if (!detachedCanvas->originClean())
+        clone->setOriginTainted();
+
+    return clone;
+}
+
 OffscreenCanvas::OffscreenCanvas(ScriptExecutionContext& context, unsigned width, unsigned height)
     : CanvasBase(IntSize(width, height))
     , ContextDestructionObserver(&context)
@@ -62,13 +84,31 @@
     setImageBuffer(nullptr);
 }
 
+unsigned OffscreenCanvas::width() const
+{
+    if (m_detached)
+        return 0;
+    return CanvasBase::width();
+}
+
+unsigned OffscreenCanvas::height() const
+{
+    if (m_detached)
+        return 0;
+    return CanvasBase::height();
+}
+
 void OffscreenCanvas::setWidth(unsigned newWidth)
 {
+    if (m_detached)
+        return;
     setSize(IntSize(newWidth, height()));
 }
 
 void OffscreenCanvas::setHeight(unsigned newHeight)
 {
+    if (m_detached)
+        return;
     setSize(IntSize(width(), newHeight));
 }
 
@@ -80,6 +120,9 @@
 
 ExceptionOr<OffscreenRenderingContext> OffscreenCanvas::getContext(JSC::JSGlobalObject& state, RenderingContextType contextType, Vector<JSC::Strong<JSC::Unknown>>&& arguments)
 {
+    if (m_detached)
+        return Exception { InvalidStateError };
+
     if (contextType == RenderingContextType::_2d) {
         if (m_context) {
             if (!is<OffscreenCanvasRenderingContext2D>(*m_context))
@@ -118,7 +161,7 @@
 
 ExceptionOr<RefPtr<ImageBitmap>> OffscreenCanvas::transferToImageBitmap()
 {
-    if (!m_context)
+    if (m_detached || !m_context)
         return Exception { InvalidStateError };
 
     if (is<OffscreenCanvasRenderingContext2D>(*m_context)) {
@@ -192,7 +235,7 @@
         promise->reject(IndexSizeError);
         return;
     }
-    if (!buffer()) {
+    if (m_detached || !buffer()) {
         promise->reject(InvalidStateError);
         return;
     }
@@ -226,6 +269,21 @@
     return &downcast<Document>(context).securityOrigin();
 }
 
+bool OffscreenCanvas::canDetach() const
+{
+    return !m_detached && !m_context;
+}
+
+std::unique_ptr<DetachedOffscreenCanvas> OffscreenCanvas::detach()
+{
+    if (!canDetach())
+        return nullptr;
+
+    m_detached = true;
+
+    return makeUnique<DetachedOffscreenCanvas>(takeImageBuffer(), size(), originClean());
+}
+
 CSSValuePool& OffscreenCanvas::cssValuePool()
 {
     auto* context = canvasBaseScriptExecutionContext();
@@ -248,7 +306,8 @@
 
 std::unique_ptr<ImageBuffer> OffscreenCanvas::takeImageBuffer() const
 {
-    m_hasCreatedImageBuffer = true;
+    if (!m_detached)
+        m_hasCreatedImageBuffer = true;
 
     // This function is primarily for use with transferToImageBitmap, which
     // requires that the canvas bitmap refer to a new, blank bitmap of the same
@@ -257,7 +316,7 @@
     if (size().isEmpty())
         return nullptr;
 
-    return setImageBuffer(ImageBuffer::create(size(), RenderingMode::Unaccelerated));
+    return setImageBuffer(m_detached ? nullptr : ImageBuffer::create(size(), RenderingMode::Unaccelerated));
 }
 
 void OffscreenCanvas::reset()

Modified: trunk/Source/WebCore/html/OffscreenCanvas.h (255314 => 255315)


--- trunk/Source/WebCore/html/OffscreenCanvas.h	2020-01-28 22:19:03 UTC (rev 255314)
+++ trunk/Source/WebCore/html/OffscreenCanvas.h	2020-01-28 22:48:05 UTC (rev 255315)
@@ -54,6 +54,22 @@
 using OffscreenRenderingContext = Variant<RefPtr<OffscreenCanvasRenderingContext2D>>;
 #endif
 
+class DetachedOffscreenCanvas {
+    WTF_MAKE_NONCOPYABLE(DetachedOffscreenCanvas);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    DetachedOffscreenCanvas(std::unique_ptr<ImageBuffer>&&, const IntSize&, bool originClean);
+
+    std::unique_ptr<ImageBuffer> takeImageBuffer();
+    const IntSize& size() const { return m_size; }
+    bool originClean() const { return m_originClean; }
+
+private:
+    std::unique_ptr<ImageBuffer> m_buffer;
+    IntSize m_size;
+    bool m_originClean;
+};
+
 class OffscreenCanvas final : public RefCounted<OffscreenCanvas>, public CanvasBase, public EventTargetWithInlineData, private ContextDestructionObserver {
     WTF_MAKE_ISO_ALLOCATED(OffscreenCanvas);
 public:
@@ -69,8 +85,11 @@
     };
 
     static Ref<OffscreenCanvas> create(ScriptExecutionContext&, unsigned width, unsigned height);
+    static Ref<OffscreenCanvas> create(ScriptExecutionContext&, std::unique_ptr<DetachedOffscreenCanvas>&&);
     virtual ~OffscreenCanvas();
 
+    unsigned width() const final;
+    unsigned height() const final;
     void setWidth(unsigned);
     void setHeight(unsigned);
 
@@ -88,6 +107,10 @@
     bool hasCreatedImageBuffer() const final { return m_hasCreatedImageBuffer; }
 
     SecurityOrigin* securityOrigin() const final;
+
+    bool canDetach() const;
+    std::unique_ptr<DetachedOffscreenCanvas> detach();
+
     CSSValuePool& cssValuePool();
 
     using RefCounted::ref;
@@ -119,6 +142,8 @@
 
     // m_hasCreatedImageBuffer means we tried to malloc the buffer. We didn't necessarily get it.
     mutable bool m_hasCreatedImageBuffer { false };
+
+    bool m_detached { false };
 };
 
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to