Title: [279722] trunk
Revision
279722
Author
[email protected]
Date
2021-07-08 08:52:51 -0700 (Thu, 08 Jul 2021)

Log Message

[GPU Process] Canvas image rendering can render arbitrary DOM content in the GPU process, which is against policy (for now)
https://bugs.webkit.org/show_bug.cgi?id=227519
<rdar://problem/76678163>

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

* web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-flipY-expected.txt:

Source/WebCore:

Rendering arbitrary DOM content in the GPU process isn't supported yet, but canvas rendering is. However,
canvas has a drawImage() function which can accept an HTMLImageElement as its source, and an HTMLImageElement
can have an SVG document as its source, which would end up triggering our DOM codepath in canvas and thus
in the GPU process.

This patch disables this for now, by rendering the SVG into an ImageBuffer and then drawing the ImageBuffer
in the GPU process. When we eventually implement arbitrary DOM rendering in the GPU process, this patch will
need to be reverted.

Test: fast/images/svg-mask-in-canvas.html

* svg/graphics/SVGImage.cpp:
(WebCore::SVGImage::nativeImage):
(WebCore::SVGImage::draw):
(WebCore::SVGImage::drawAsNativeImage):
* svg/graphics/SVGImage.h:

LayoutTests:

* fast/images/resources/mask.svg: Added.
* fast/images/svg-mask-in-canvas-expected.html: Added.
* fast/images/svg-mask-in-canvas.html: Added.
* platform/mac-wk1/imported/w3c/web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-flipY-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-flipY-expected.txt.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (279721 => 279722)


--- trunk/LayoutTests/ChangeLog	2021-07-08 14:47:34 UTC (rev 279721)
+++ trunk/LayoutTests/ChangeLog	2021-07-08 15:52:51 UTC (rev 279722)
@@ -1,3 +1,16 @@
+2021-07-08  Myles C. Maxfield  <[email protected]>
+
+        [GPU Process] Canvas image rendering can render arbitrary DOM content in the GPU process, which is against policy (for now)
+        https://bugs.webkit.org/show_bug.cgi?id=227519
+        <rdar://problem/76678163>
+
+        Reviewed by Darin Adler.
+
+        * fast/images/resources/mask.svg: Added.
+        * fast/images/svg-mask-in-canvas-expected.html: Added.
+        * fast/images/svg-mask-in-canvas.html: Added.
+        * platform/mac-wk1/imported/w3c/web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-flipY-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-flipY-expected.txt.
+
 2021-07-08  Antti Koivisto  <[email protected]>
 
         Shadow host stops rendering after removing a slot, updating style, then its assigned node

Added: trunk/LayoutTests/fast/images/resources/mask.svg (0 => 279722)


--- trunk/LayoutTests/fast/images/resources/mask.svg	                        (rev 0)
+++ trunk/LayoutTests/fast/images/resources/mask.svg	2021-07-08 15:52:51 UTC (rev 279722)
@@ -0,0 +1,9 @@
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300px" height="300px" viewBox="0 0 300 300" version="1.1">
+    <defs>
+        <mask id="mask" maskUnits="userSpaceOnUse" x="0" y="0" width="300" height="300">
+            <rect x="50" y="50" width="200" height="200" fill="white"/>
+        </mask>
+    </defs>
+    <rect x="100" y="0" width="100" height="300" fill="black" mask="url(#mask)"/>
+</svg>

Added: trunk/LayoutTests/fast/images/svg-mask-in-canvas-expected.html (0 => 279722)


--- trunk/LayoutTests/fast/images/svg-mask-in-canvas-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/images/svg-mask-in-canvas-expected.html	2021-07-08 15:52:51 UTC (rev 279722)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<p>This test passes if you see a black rectangle with a green border below.</p>
+<div style="position: relative;">
+    <div style="position: absolute; left: 100px; top: 50px; width: 100px; height: 200px; background: black;"></div>
+    <div style="position: absolute; top: 47px; left: 97px; width: 6px; height: 206px; background: green;"></div>
+    <div style="position: absolute; top: 47px; left: 197px; width: 6px; height: 206px; background: green;"></div>
+    <div style="position: absolute; top: 47px; left: 97px; width: 106px; height: 6px; background: green;"></div>
+    <div style="position: absolute; top: 247px; left: 97px; width: 106px; height: 6px; background: green;"></div>
+</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/images/svg-mask-in-canvas.html (0 => 279722)


--- trunk/LayoutTests/fast/images/svg-mask-in-canvas.html	                        (rev 0)
+++ trunk/LayoutTests/fast/images/svg-mask-in-canvas.html	2021-07-08 15:52:51 UTC (rev 279722)
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<p>This test passes if you see a black rectangle with a green border below.</p>
+<div style="position: relative;">
+    <canvas id="canvas" width="300" height="300"></canvas>
+    <div style="position: absolute; top: 47px; left: 97px; width: 6px; height: 206px; background: green;"></div>
+    <div style="position: absolute; top: 47px; left: 197px; width: 6px; height: 206px; background: green;"></div>
+    <div style="position: absolute; top: 47px; left: 97px; width: 106px; height: 6px; background: green;"></div>
+    <div style="position: absolute; top: 247px; left: 97px; width: 106px; height: 6px; background: green;"></div>
+</div>
+<script>
+if (window.testRunner)
+    testRunner.waitUntilDone();
+let canvas = document.getElementById("canvas");
+let context = canvas.getContext("2d");
+let image = document.createElement("img");
+image.addEventListener("load", function() {
+    context.drawImage(image, 0, 0, 300, 300);
+    if (window.testRunner)
+        testRunner.notifyDone();
+});
+image.src = ""
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (279721 => 279722)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2021-07-08 14:47:34 UTC (rev 279721)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2021-07-08 15:52:51 UTC (rev 279722)
@@ -1,3 +1,13 @@
+2021-07-08  Myles C. Maxfield  <[email protected]>
+
+        [GPU Process] Canvas image rendering can render arbitrary DOM content in the GPU process, which is against policy (for now)
+        https://bugs.webkit.org/show_bug.cgi?id=227519
+        <rdar://problem/76678163>
+
+        Reviewed by Darin Adler.
+
+        * web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-flipY-expected.txt:
+
 2021-07-07  Chris Dumez  <[email protected]>
 
         Our structured cloning implementation does not encode all of RegExp's flags

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-flipY-expected.txt (279721 => 279722)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-flipY-expected.txt	2021-07-08 14:47:34 UTC (rev 279721)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-flipY-expected.txt	2021-07-08 15:52:51 UTC (rev 279722)
@@ -8,7 +8,7 @@
 PASS createImageBitmap from a bitmap HTMLImageElement imageOrientation: "none", and drawImage on the created ImageBitmap
 PASS createImageBitmap from a bitmap HTMLImageElement imageOrientation: "flipY", and drawImage on the created ImageBitmap
 PASS createImageBitmap from a vector HTMLImageElement imageOrientation: "none", and drawImage on the created ImageBitmap
-FAIL createImageBitmap from a vector HTMLImageElement imageOrientation: "flipY", and drawImage on the created ImageBitmap assert_approx_equals: Red channel of the pixel at (5, 15) expected 255 +/- 10 but got 0
+PASS createImageBitmap from a vector HTMLImageElement imageOrientation: "flipY", and drawImage on the created ImageBitmap
 FAIL createImageBitmap from a bitmap SVGImageElement imageOrientation: "none", and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: Type error"
 FAIL createImageBitmap from a bitmap SVGImageElement imageOrientation: "flipY", and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: Type error"
 FAIL createImageBitmap from a vector SVGImageElement imageOrientation: "none", and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: Type error"

Copied: trunk/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-flipY-expected.txt (from rev 279721, trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-flipY-expected.txt) (0 => 279722)


--- trunk/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-flipY-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-flipY-expected.txt	2021-07-08 15:52:51 UTC (rev 279722)
@@ -0,0 +1,24 @@
+
+PASS createImageBitmap from an HTMLCanvasElement imageOrientation: "none", and drawImage on the created ImageBitmap
+PASS createImageBitmap from an HTMLCanvasElement imageOrientation: "flipY", and drawImage on the created ImageBitmap
+PASS createImageBitmap from an HTMLVideoElement imageOrientation: "none", and drawImage on the created ImageBitmap
+PASS createImageBitmap from an HTMLVideoElement imageOrientation: "flipY", and drawImage on the created ImageBitmap
+PASS createImageBitmap from an HTMLVideoElement from a data URL imageOrientation: "none", and drawImage on the created ImageBitmap
+PASS createImageBitmap from an HTMLVideoElement from a data URL imageOrientation: "flipY", and drawImage on the created ImageBitmap
+PASS createImageBitmap from a bitmap HTMLImageElement imageOrientation: "none", and drawImage on the created ImageBitmap
+PASS createImageBitmap from a bitmap HTMLImageElement imageOrientation: "flipY", and drawImage on the created ImageBitmap
+PASS createImageBitmap from a vector HTMLImageElement imageOrientation: "none", and drawImage on the created ImageBitmap
+FAIL createImageBitmap from a vector HTMLImageElement imageOrientation: "flipY", and drawImage on the created ImageBitmap assert_approx_equals: Red channel of the pixel at (5, 15) expected 255 +/- 10 but got 0
+FAIL createImageBitmap from a bitmap SVGImageElement imageOrientation: "none", and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: Type error"
+FAIL createImageBitmap from a bitmap SVGImageElement imageOrientation: "flipY", and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: Type error"
+FAIL createImageBitmap from a vector SVGImageElement imageOrientation: "none", and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: Type error"
+FAIL createImageBitmap from a vector SVGImageElement imageOrientation: "flipY", and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "TypeError: Type error"
+FAIL createImageBitmap from an OffscreenCanvas imageOrientation: "none", and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "ReferenceError: Can't find variable: OffscreenCanvas"
+FAIL createImageBitmap from an OffscreenCanvas imageOrientation: "flipY", and drawImage on the created ImageBitmap promise_test: Unhandled rejection with value: object "ReferenceError: Can't find variable: OffscreenCanvas"
+PASS createImageBitmap from an ImageData imageOrientation: "none", and drawImage on the created ImageBitmap
+PASS createImageBitmap from an ImageData imageOrientation: "flipY", and drawImage on the created ImageBitmap
+PASS createImageBitmap from an ImageBitmap imageOrientation: "none", and drawImage on the created ImageBitmap
+PASS createImageBitmap from an ImageBitmap imageOrientation: "flipY", and drawImage on the created ImageBitmap
+PASS createImageBitmap from a Blob imageOrientation: "none", and drawImage on the created ImageBitmap
+PASS createImageBitmap from a Blob imageOrientation: "flipY", and drawImage on the created ImageBitmap
+

Modified: trunk/Source/WebCore/ChangeLog (279721 => 279722)


--- trunk/Source/WebCore/ChangeLog	2021-07-08 14:47:34 UTC (rev 279721)
+++ trunk/Source/WebCore/ChangeLog	2021-07-08 15:52:51 UTC (rev 279722)
@@ -1,3 +1,28 @@
+2021-07-08  Myles C. Maxfield  <[email protected]>
+
+        [GPU Process] Canvas image rendering can render arbitrary DOM content in the GPU process, which is against policy (for now)
+        https://bugs.webkit.org/show_bug.cgi?id=227519
+        <rdar://problem/76678163>
+
+        Reviewed by Darin Adler.
+
+        Rendering arbitrary DOM content in the GPU process isn't supported yet, but canvas rendering is. However,
+        canvas has a drawImage() function which can accept an HTMLImageElement as its source, and an HTMLImageElement
+        can have an SVG document as its source, which would end up triggering our DOM codepath in canvas and thus
+        in the GPU process.
+
+        This patch disables this for now, by rendering the SVG into an ImageBuffer and then drawing the ImageBuffer
+        in the GPU process. When we eventually implement arbitrary DOM rendering in the GPU process, this patch will
+        need to be reverted.
+
+        Test: fast/images/svg-mask-in-canvas.html
+
+        * svg/graphics/SVGImage.cpp:
+        (WebCore::SVGImage::nativeImage):
+        (WebCore::SVGImage::draw):
+        (WebCore::SVGImage::drawAsNativeImage):
+        * svg/graphics/SVGImage.h:
+
 2021-07-08  Antti Koivisto  <[email protected]>
 
         Shadow host stops rendering after removing a slot, updating style, then its assigned node

Modified: trunk/Source/WebCore/svg/graphics/SVGImage.cpp (279721 => 279722)


--- trunk/Source/WebCore/svg/graphics/SVGImage.cpp	2021-07-08 14:47:34 UTC (rev 279721)
+++ trunk/Source/WebCore/svg/graphics/SVGImage.cpp	2021-07-08 15:52:51 UTC (rev 279722)
@@ -214,18 +214,25 @@
 
 RefPtr<NativeImage> SVGImage::nativeImage(const GraphicsContext*)
 {
+    return nativeImage(size(), FloatRect(FloatPoint(), size()));
+}
+
+RefPtr<NativeImage> SVGImage::nativeImage(const FloatSize& imageSize, const FloatRect& sourceRect)
+{
     if (!m_page)
         return nullptr;
 
-    auto imageBuffer = ImageBuffer::create(size(), RenderingMode::Unaccelerated, 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8);
+    auto imageBuffer = ImageBuffer::create(imageSize, RenderingMode::Unaccelerated, 1, DestinationColorSpace::SRGB(), PixelFormat::BGRA8);
     if (!imageBuffer)
         return nullptr;
 
     ImageObserver* observer = imageObserver();
-
     setImageObserver(nullptr);
     setContainerSize(size());
 
+    auto scaleFactor = imageSize / sourceRect.size();
+    imageBuffer->context().scale(scaleFactor);
+    imageBuffer->context().translate(-sourceRect.location());
     imageBuffer->context().drawImage(*this, FloatPoint(0, 0));
 
     setImageObserver(observer);
@@ -273,6 +280,12 @@
     if (!m_page)
         return ImageDrawResult::DidNothing;
 
+    if (!context.hasPlatformContext()) {
+        // Display list drawing can't handle arbitrary DOM content.
+        // FIXME https://bugs.webkit.org/show_bug.cgi?id=227748: Remove this when it can.
+        return drawAsNativeImage(context, dstRect, srcRect, options);
+    }
+
     auto view = makeRefPtr(frameView());
     ASSERT(view);
 
@@ -322,6 +335,29 @@
     return ImageDrawResult::DidDraw;
 }
 
+
+ImageDrawResult SVGImage::drawAsNativeImage(GraphicsContext& context, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& options)
+{
+    ASSERT(!context.hasPlatformContext());
+
+    auto rectInNativeImage = FloatRect { { }, destination.size() };
+    auto nativeImage = this->nativeImage(rectInNativeImage.size(), source);
+    if (!nativeImage)
+        return ImageDrawResult::DidNothing;
+
+    auto localImagePaintingOptions = options;
+    ImageOrientation::Orientation orientation = options.orientation();
+    if (orientation == ImageOrientation::Orientation::FromImage)
+        localImagePaintingOptions = ImagePaintingOptions(options, ImageOrientation::Orientation::None);
+
+    context.drawNativeImage(*nativeImage, rectInNativeImage.size(), destination, rectInNativeImage, localImagePaintingOptions);
+
+    if (imageObserver())
+        imageObserver()->didDraw(*this);
+
+    return ImageDrawResult::DidDraw;
+}
+
 RenderBox* SVGImage::embeddedContentBox() const
 {
     auto rootElement = this->rootElement();

Modified: trunk/Source/WebCore/svg/graphics/SVGImage.h (279721 => 279722)


--- trunk/Source/WebCore/svg/graphics/SVGImage.h	2021-07-08 14:47:34 UTC (rev 279721)
+++ trunk/Source/WebCore/svg/graphics/SVGImage.h	2021-07-08 15:52:51 UTC (rev 279722)
@@ -88,11 +88,13 @@
 
     RefPtr<NativeImage> nativeImageForCurrentFrame(const GraphicsContext* = nullptr) final;
     RefPtr<NativeImage> nativeImage(const GraphicsContext* = nullptr) final;
+    RefPtr<NativeImage> nativeImage(const FloatSize& imageSize, const FloatRect& sourceRect);
 
     void startAnimationTimerFired();
 
     explicit SVGImage(ImageObserver&);
-    ImageDrawResult draw(GraphicsContext&, const FloatRect& fromRect, const FloatRect& toRect, const ImagePaintingOptions& = { }) final;
+    ImageDrawResult draw(GraphicsContext&, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& = { }) final;
+    ImageDrawResult drawAsNativeImage(GraphicsContext&, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& = { });
     ImageDrawResult drawForContainer(GraphicsContext&, const FloatSize containerSize, float containerZoom, const URL& initialFragmentURL, const FloatRect& dstRect, const FloatRect& srcRect, const ImagePaintingOptions& = { });
     void drawPatternForContainer(GraphicsContext&, const FloatSize& containerSize, float containerZoom, const URL& initialFragmentURL, const FloatRect& srcRect, const AffineTransform&, const FloatPoint& phase, const FloatSize& spacing, const FloatRect&, const ImagePaintingOptions& = { });
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to