Title: [241840] trunk
Revision
241840
Author
commit-qu...@webkit.org
Date
2019-02-20 14:28:13 -0800 (Wed, 20 Feb 2019)

Log Message

drawImage() clears the canvas if it's the source of the image and globalCompositeOperation is "copy"
https://bugs.webkit.org/show_bug.cgi?id=194746

Patch by Said Abou-Hallawa <sabouhall...@apple.com> on 2019-02-20
Reviewed by Dean Jackson.

Source/WebCore:

Test: fast/canvas/canvas-drawImage-composite-copy.html

If the source canvas of drawImage() is the same as the destination and
globalCompositeOperation is set to "copy", copy the srcRect from the
canvas to a temporary buffer before calling clearCanvas() then drawImage
from this temporary buffer.

* html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::CanvasRenderingContext2DBase::drawImage):
* platform/graphics/ImageBuffer.cpp:
(WebCore::ImageBuffer::copyRectToBuffer):
* platform/graphics/ImageBuffer.h:

LayoutTests:

* fast/canvas/canvas-drawImage-composite-copy-expected.html: Added.
* fast/canvas/canvas-drawImage-composite-copy.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (241839 => 241840)


--- trunk/LayoutTests/ChangeLog	2019-02-20 22:25:23 UTC (rev 241839)
+++ trunk/LayoutTests/ChangeLog	2019-02-20 22:28:13 UTC (rev 241840)
@@ -1,3 +1,13 @@
+2019-02-20  Said Abou-Hallawa  <sabouhall...@apple.com>
+
+        drawImage() clears the canvas if it's the source of the image and globalCompositeOperation is "copy"
+        https://bugs.webkit.org/show_bug.cgi?id=194746
+
+        Reviewed by Dean Jackson.
+
+        * fast/canvas/canvas-drawImage-composite-copy-expected.html: Added.
+        * fast/canvas/canvas-drawImage-composite-copy.html: Added.
+
 2019-02-20  Shawn Roberts  <srobe...@apple.com>
 
         [ Mac WK2 ] REGRESSION (r231450) Layout Test http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-iframe-with-enforced-and-report-policies.html is a flaky failure

Added: trunk/LayoutTests/fast/canvas/canvas-drawImage-composite-copy-expected.html (0 => 241840)


--- trunk/LayoutTests/fast/canvas/canvas-drawImage-composite-copy-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/canvas/canvas-drawImage-composite-copy-expected.html	2019-02-20 22:28:13 UTC (rev 241840)
@@ -0,0 +1,12 @@
+<body>
+    <canvas id="canvas" width="200" height="200"></canvas>
+    <script>
+        const canvas = document.getElementById("canvas");
+        const ctx = canvas.getContext("2d");
+        const width = canvas.width;
+        const height = canvas.height;
+
+        ctx.fillStyle = "green";
+        ctx.fillRect(0, 0, width / 2, height / 2);
+    </script>
+</body>

Added: trunk/LayoutTests/fast/canvas/canvas-drawImage-composite-copy.html (0 => 241840)


--- trunk/LayoutTests/fast/canvas/canvas-drawImage-composite-copy.html	                        (rev 0)
+++ trunk/LayoutTests/fast/canvas/canvas-drawImage-composite-copy.html	2019-02-20 22:28:13 UTC (rev 241840)
@@ -0,0 +1,21 @@
+<body>
+    <canvas id="canvas" width="200" height="200"></canvas>
+    <script>
+        const canvas = document.getElementById("canvas");
+        const ctx = canvas.getContext("2d");
+        const width = canvas.width;
+        const height = canvas.height;
+
+        ctx.fillStyle = "green";
+        ctx.fillRect(width / 2, height / 2, width / 2, height / 2);
+
+        ctx.globalCompositeOperation = "copy";
+        ctx.imageSmoothingEnabled = false;
+
+        ctx.drawImage(
+            canvas,
+            width / 2, height / 2, width / 2, height / 2,
+            0, 0, width / 2, height / 2
+        );
+    </script>
+</body>

Modified: trunk/Source/WebCore/ChangeLog (241839 => 241840)


--- trunk/Source/WebCore/ChangeLog	2019-02-20 22:25:23 UTC (rev 241839)
+++ trunk/Source/WebCore/ChangeLog	2019-02-20 22:28:13 UTC (rev 241840)
@@ -1,3 +1,23 @@
+2019-02-20  Said Abou-Hallawa  <sabouhall...@apple.com>
+
+        drawImage() clears the canvas if it's the source of the image and globalCompositeOperation is "copy"
+        https://bugs.webkit.org/show_bug.cgi?id=194746
+
+        Reviewed by Dean Jackson.
+
+        Test: fast/canvas/canvas-drawImage-composite-copy.html
+
+        If the source canvas of drawImage() is the same as the destination and
+        globalCompositeOperation is set to "copy", copy the srcRect from the 
+        canvas to a temporary buffer before calling clearCanvas() then drawImage
+        from this temporary buffer.
+
+        * html/canvas/CanvasRenderingContext2DBase.cpp:
+        (WebCore::CanvasRenderingContext2DBase::drawImage):
+        * platform/graphics/ImageBuffer.cpp:
+        (WebCore::ImageBuffer::copyRectToBuffer):
+        * platform/graphics/ImageBuffer.h:
+
 2019-02-20  Simon Fraser  <simon.fra...@apple.com>
 
         REGRESSION (r241788>): ASSERTION FAILED: !m_normalFlowListDirty in TestWebKitAPI.WebKit.ResizeReversePaginatedWebView test

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp (241839 => 241840)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp	2019-02-20 22:25:23 UTC (rev 241839)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp	2019-02-20 22:28:13 UTC (rev 241840)
@@ -1643,8 +1643,15 @@
         fullCanvasCompositedDrawImage(*buffer, dstRect, srcRect, state().globalComposite);
         didDrawEntireCanvas();
     } else if (state().globalComposite == CompositeCopy) {
-        clearCanvas();
-        c->drawImageBuffer(*buffer, dstRect, srcRect, ImagePaintingOptions(state().globalComposite, state().globalBlend));
+        if (&sourceCanvas == &canvasBase()) {
+            if (auto copy = buffer->copyRectToBuffer(srcRect, ColorSpaceSRGB, *c)) {
+                clearCanvas();
+                c->drawImageBuffer(*copy, dstRect, { { }, srcRect.size() }, ImagePaintingOptions(state().globalComposite, state().globalBlend));
+            }
+        } else {
+            clearCanvas();
+            c->drawImageBuffer(*buffer, dstRect, srcRect, ImagePaintingOptions(state().globalComposite, state().globalBlend));
+        }
         didDrawEntireCanvas();
     } else {
         c->drawImageBuffer(*buffer, dstRect, srcRect, ImagePaintingOptions(state().globalComposite, state().globalBlend));

Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp (241839 => 241840)


--- trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp	2019-02-20 22:25:23 UTC (rev 241839)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp	2019-02-20 22:28:13 UTC (rev 241840)
@@ -194,6 +194,21 @@
 }
 #endif
 
+std::unique_ptr<ImageBuffer> ImageBuffer::copyRectToBuffer(const FloatRect& rect, ColorSpace colorSpace, const GraphicsContext& context)
+{
+    if (rect.isEmpty())
+        return nullptr;
+
+    IntSize scaledSize = ImageBuffer::compatibleBufferSize(rect.size(), context);
+
+    auto buffer = ImageBuffer::createCompatibleBuffer(scaledSize, 1, colorSpace, context);
+    if (!buffer)
+        return nullptr;
+
+    buffer->context().drawImageBuffer(*this, -rect.location());
+    return buffer;
+}
+
 std::unique_ptr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize& size, ColorSpace colorSpace, const GraphicsContext& context)
 {
     if (size.isEmpty())

Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.h (241839 => 241840)


--- trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2019-02-20 22:25:23 UTC (rev 241839)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2019-02-20 22:28:13 UTC (rev 241840)
@@ -71,6 +71,9 @@
     WEBCORE_EXPORT static std::unique_ptr<ImageBuffer> create(const FloatSize&, RenderingMode, const GraphicsContext*, float resolutionScale = 1, ColorSpace = ColorSpaceSRGB, const HostWindow* = nullptr);
 #endif
 
+    // Create an image buffer compatible with the context and copy rect from this buffer into this new one.
+    std::unique_ptr<ImageBuffer> copyRectToBuffer(const FloatRect&, ColorSpace, const GraphicsContext&);
+
     // Create an image buffer compatible with the context, with suitable resolution for drawing into the buffer and then into this context.
     static std::unique_ptr<ImageBuffer> createCompatibleBuffer(const FloatSize&, const GraphicsContext&);
     static std::unique_ptr<ImageBuffer> createCompatibleBuffer(const FloatSize&, ColorSpace, const GraphicsContext&);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to