Create a new ImageBuffer type for drawing on a DisplayList
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Feb 2020 20:26:30 +0000 (20:26 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Feb 2020 20:26:30 +0000 (20:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=207109

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2020-02-21
Reviewed by Simon Fraser.

Source/WebCore:

DisplayList::ImageBuffer inherits ConcreteImageBuffer and DrawingContext.
The drawing context will be the context of DrawingContext. The operations
of ConcreteImageBuffer will have to ensure the recorded display-list is
replayed back before getting the pixels of the ImageBufferBackend.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:

* html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::createContext2d):
(WebCore::HTMLCanvasElement::setUsesDisplayListDrawing):
(WebCore::HTMLCanvasElement::setTracksDisplayListReplay):
(WebCore::HTMLCanvasElement::displayListAsText const):
(WebCore::HTMLCanvasElement::replayDisplayListAsText const):
All the DisplayList operations will be routed to the DrawingContext of
the ImageBuffer.

(WebCore::HTMLCanvasElement::createImageBuffer const):
createImageBuffer() can decide the ImageBuffer type based on the settings
and the size of the canvas.

* html/HTMLCanvasElement.h:
* platform/graphics/ConcreteImageBuffer.h:
(WebCore::ConcreteImageBuffer::create):
The type of the ImageBuffer will be passed to this function such that
it can create instances of derived classes.

* platform/graphics/ImageBuffer.cpp:
(WebCore::ImageBuffer::create):
Create ImageBuffers which record the drawing commands to DisplayLists before
committing them to the back-ends.

* platform/graphics/ImageBuffer.h:
(WebCore::ImageBuffer::drawingContext):
(WebCore::ImageBuffer::flushDrawingContext):
Add virtual methods to support DisplayList in ImageBuffer.

* platform/graphics/PlatformImageBuffer.h:
* platform/graphics/RenderingMode.h:
Add DisplayList types to RenderingMode and define platform types for
DisplayList ImageBuffers.

* platform/graphics/displaylists/DisplayListDrawingContext.cpp: Added.
(WebCore::DisplayList::DrawingContext::DrawingContext):
(WebCore::DisplayList::DrawingContext::setTracksDisplayListReplay):
(WebCore::DisplayList::DrawingContext::replayDisplayList):
* platform/graphics/displaylists/DisplayListDrawingContext.h: Added.
(WebCore::DisplayList::DrawingContext::context const):
(WebCore::DisplayList::DrawingContext::displayList):
(WebCore::DisplayList::DrawingContext::displayList const):
(WebCore::DisplayList::DrawingContext::replayedDisplayList const):
DisplayList::DrawingContext holds a recording and an optional replaying
back DisplayLists. It also provides a recording GraphicsContext.

* platform/graphics/displaylists/DisplayListImageBuffer.h: Added.
(WebCore::DisplayList::ImageBuffer::create):
(WebCore::DisplayList::ImageBuffer::ImageBuffer):
(WebCore::DisplayList::ImageBuffer::~ImageBuffer):
Drawing commands will be recorded first because context() is overridden
to return the GraphicsContext of DrawingContext. These drawing commands
will be flushed before getting the pixels of the back-end because
flushDrawingContext() is overridden to replay back the recorded DisplayList
to the GraphicsContext of the back-end.

LayoutTests:

The extra commands are recorded by CanvasBase::setImageBuffer() which
used to issue these GraphicsContext commands directly to the backend.
With this patch, DisplayList::ImageBuffer does not allow access to the
backend context. So all the GraphicsContext commands has to be recorded.

* displaylists/canvas-display-list-expected.txt:

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

15 files changed:
LayoutTests/ChangeLog
LayoutTests/displaylists/canvas-display-list-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/html/HTMLCanvasElement.cpp
Source/WebCore/html/HTMLCanvasElement.h
Source/WebCore/platform/graphics/ConcreteImageBuffer.h
Source/WebCore/platform/graphics/ImageBuffer.cpp
Source/WebCore/platform/graphics/ImageBuffer.h
Source/WebCore/platform/graphics/PlatformImageBuffer.h
Source/WebCore/platform/graphics/RenderingMode.h
Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.h [new file with mode: 0644]
Source/WebCore/platform/graphics/displaylists/DisplayListImageBuffer.h [new file with mode: 0644]

index b23b872..acebc1e 100644 (file)
@@ -1,3 +1,17 @@
+2020-02-21  Said Abou-Hallawa  <sabouhallawa@apple.com>
+
+        Create a new ImageBuffer type for drawing on a DisplayList
+        https://bugs.webkit.org/show_bug.cgi?id=207109
+
+        Reviewed by Simon Fraser.
+
+        The extra commands are recorded by CanvasBase::setImageBuffer() which
+        used to issue these GraphicsContext commands directly to the backend.
+        With this patch, DisplayList::ImageBuffer does not allow access to the
+        backend context. So all the GraphicsContext commands has to be recorded.
+
+        * displaylists/canvas-display-list-expected.txt:
+
 2020-02-21  Jason Lawrence  <lawrence.j@apple.com>
 
         REGRESSION: (r256764?) [ Mac wk1 Release ] legacy-animation-engine/fast/animation/animation-mixed-transform-crash.html is flaky failing.
index 1b57e79..34c87b9 100644 (file)
@@ -1,7 +1,11 @@
  
+(save
+  (restore-index 0))
 (set-state
-  (change-flags 256)
-  (fill-color #C80000))
+  (change-flags 1050912)
+  (stroke-thickness 1.00)
+  (fill-color #C80000)
+  (shadows-ignore-transforms 1))
 (fill-rect
   (extent at (10,10) size 55x50)
   (rect at (10,10) size 55x50))
index c5f2b8e..991bc46 100644 (file)
@@ -1,3 +1,74 @@
+2020-02-21  Said Abou-Hallawa  <sabouhallawa@apple.com>
+
+        Create a new ImageBuffer type for drawing on a DisplayList
+        https://bugs.webkit.org/show_bug.cgi?id=207109
+
+        Reviewed by Simon Fraser.
+
+        DisplayList::ImageBuffer inherits ConcreteImageBuffer and DrawingContext.
+        The drawing context will be the context of DrawingContext. The operations
+        of ConcreteImageBuffer will have to ensure the recorded display-list is
+        replayed back before getting the pixels of the ImageBufferBackend.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+
+        * html/HTMLCanvasElement.cpp:
+        (WebCore::HTMLCanvasElement::createContext2d):
+        (WebCore::HTMLCanvasElement::setUsesDisplayListDrawing):
+        (WebCore::HTMLCanvasElement::setTracksDisplayListReplay):
+        (WebCore::HTMLCanvasElement::displayListAsText const):
+        (WebCore::HTMLCanvasElement::replayDisplayListAsText const):
+        All the DisplayList operations will be routed to the DrawingContext of
+        the ImageBuffer.
+
+        (WebCore::HTMLCanvasElement::createImageBuffer const):
+        createImageBuffer() can decide the ImageBuffer type based on the settings
+        and the size of the canvas.
+
+        * html/HTMLCanvasElement.h:
+        * platform/graphics/ConcreteImageBuffer.h:
+        (WebCore::ConcreteImageBuffer::create):
+        The type of the ImageBuffer will be passed to this function such that
+        it can create instances of derived classes.
+
+        * platform/graphics/ImageBuffer.cpp:
+        (WebCore::ImageBuffer::create):
+        Create ImageBuffers which record the drawing commands to DisplayLists before
+        committing them to the back-ends.
+
+        * platform/graphics/ImageBuffer.h:
+        (WebCore::ImageBuffer::drawingContext):
+        (WebCore::ImageBuffer::flushDrawingContext):
+        Add virtual methods to support DisplayList in ImageBuffer.
+
+        * platform/graphics/PlatformImageBuffer.h:
+        * platform/graphics/RenderingMode.h:
+        Add DisplayList types to RenderingMode and define platform types for
+        DisplayList ImageBuffers.
+
+        * platform/graphics/displaylists/DisplayListDrawingContext.cpp: Added.
+        (WebCore::DisplayList::DrawingContext::DrawingContext):
+        (WebCore::DisplayList::DrawingContext::setTracksDisplayListReplay):
+        (WebCore::DisplayList::DrawingContext::replayDisplayList):
+        * platform/graphics/displaylists/DisplayListDrawingContext.h: Added.
+        (WebCore::DisplayList::DrawingContext::context const):
+        (WebCore::DisplayList::DrawingContext::displayList):
+        (WebCore::DisplayList::DrawingContext::displayList const):
+        (WebCore::DisplayList::DrawingContext::replayedDisplayList const):
+        DisplayList::DrawingContext holds a recording and an optional replaying 
+        back DisplayLists. It also provides a recording GraphicsContext.
+
+        * platform/graphics/displaylists/DisplayListImageBuffer.h: Added.
+        (WebCore::DisplayList::ImageBuffer::create):
+        (WebCore::DisplayList::ImageBuffer::ImageBuffer):
+        (WebCore::DisplayList::ImageBuffer::~ImageBuffer):
+        Drawing commands will be recorded first because context() is overridden
+        to return the GraphicsContext of DrawingContext. These drawing commands
+        will be flushed before getting the pixels of the back-end because 
+        flushDrawingContext() is overridden to replay back the recorded DisplayList
+        to the GraphicsContext of the back-end.
+
 2020-02-21  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         [macOS] Large form controls are rendered at the wrong NSControlSize
index 44bca20..afcaab3 100644 (file)
@@ -1902,6 +1902,7 @@ platform/graphics/WidthIterator.cpp
 platform/graphics/cpu/arm/filters/FELightingNEON.cpp
 
 platform/graphics/displaylists/DisplayList.cpp
+platform/graphics/displaylists/DisplayListDrawingContext.cpp
 platform/graphics/displaylists/DisplayListItems.cpp
 platform/graphics/displaylists/DisplayListRecorder.cpp
 platform/graphics/displaylists/DisplayListReplayer.cpp
index 4cd96a1..7b18a50 100644 (file)
                55BE025D223B29C40032F08A /* SVGAnimatedProperty.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedProperty.cpp; sourceTree = "<group>"; };
                55BE025E223B29C40032F08A /* SVGAnimatedPropertyPairAccessor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedPropertyPairAccessor.h; sourceTree = "<group>"; };
                55BE025F223B29C50032F08A /* SVGAnimationAdditiveFunction.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGAnimationAdditiveFunction.h; sourceTree = "<group>"; };
+               55C0A29523FE2CE000F2CB93 /* DisplayListDrawingContext.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayListDrawingContext.cpp; sourceTree = "<group>"; };
                55D408F71A7C631800C78450 /* SVGImageClients.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGImageClients.h; sourceTree = "<group>"; };
                55DCC51C2240605E00C26E32 /* SVGAnimationDiscreteFunctionImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGAnimationDiscreteFunctionImpl.h; sourceTree = "<group>"; };
                55DCC51D2240615500C26E32 /* SVGAnimationDiscreteFunction.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGAnimationDiscreteFunction.h; sourceTree = "<group>"; };
                72C18A3F230B04B7006847C7 /* ImagePaintingOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImagePaintingOptions.h; sourceTree = "<group>"; };
                72E417611A2E8D2F004C562A /* JSEXTsRGB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSEXTsRGB.cpp; sourceTree = "<group>"; };
                72E417621A2E8D2F004C562A /* JSEXTsRGB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSEXTsRGB.h; sourceTree = "<group>"; };
+               72EA09F723FCCB3D008504A5 /* DisplayListImageBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DisplayListImageBuffer.h; sourceTree = "<group>"; };
+               72EA09F923FCCC6A008504A5 /* DisplayListDrawingContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DisplayListDrawingContext.h; sourceTree = "<group>"; };
                72F1AD9F1A3904C300014E18 /* EXTFragDepth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EXTFragDepth.cpp; sourceTree = "<group>"; };
                72F1ADA01A3904C300014E18 /* EXTFragDepth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXTFragDepth.h; sourceTree = "<group>"; };
                72F1ADA11A3904C300014E18 /* EXTFragDepth.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EXTFragDepth.idl; sourceTree = "<group>"; };
                        children = (
                                0FE5FBCA1C3DD51E0007A2CA /* DisplayList.cpp */,
                                0FE5FBCB1C3DD51E0007A2CA /* DisplayList.h */,
+                               55C0A29523FE2CE000F2CB93 /* DisplayListDrawingContext.cpp */,
+                               72EA09F923FCCC6A008504A5 /* DisplayListDrawingContext.h */,
+                               72EA09F723FCCB3D008504A5 /* DisplayListImageBuffer.h */,
                                0FE5FBCC1C3DD51E0007A2CA /* DisplayListItems.cpp */,
                                0FE5FBCD1C3DD51E0007A2CA /* DisplayListItems.h */,
                                0FE5FBCE1C3DD51E0007A2CA /* DisplayListRecorder.cpp */,
index f5e7650..e6cb75a 100644 (file)
@@ -33,6 +33,7 @@
 #include "CanvasGradient.h"
 #include "CanvasPattern.h"
 #include "CanvasRenderingContext2D.h"
+#include "DisplayListDrawingContext.h"
 #include "Document.h"
 #include "Frame.h"
 #include "FrameLoaderClient.h"
@@ -349,9 +350,6 @@ CanvasRenderingContext2D* HTMLCanvasElement::createContext2d(const String& type)
 
     m_context = CanvasRenderingContext2D::create(*this, document().inQuirksMode());
 
-    downcast<CanvasRenderingContext2D>(*m_context).setUsesDisplayListDrawing(m_usesDisplayListDrawing);
-    downcast<CanvasRenderingContext2D>(*m_context).setTracksDisplayListReplay(m_tracksDisplayListReplay);
-
 #if USE(IOSURFACE_CANVAS_BACKING_STORE) || ENABLE(ACCELERATED_2D_CANVAS)
     // Need to make sure a RenderLayer and compositing layer get created for the Canvas.
     invalidateStyleAndLayerComposition();
@@ -822,38 +820,41 @@ bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const
 
 void HTMLCanvasElement::setUsesDisplayListDrawing(bool usesDisplayListDrawing)
 {
-    if (usesDisplayListDrawing == m_usesDisplayListDrawing)
-        return;
-    
     m_usesDisplayListDrawing = usesDisplayListDrawing;
-
-    if (is<CanvasRenderingContext2D>(m_context.get()))
-        downcast<CanvasRenderingContext2D>(*m_context).setUsesDisplayListDrawing(m_usesDisplayListDrawing);
 }
 
 void HTMLCanvasElement::setTracksDisplayListReplay(bool tracksDisplayListReplay)
 {
-    if (tracksDisplayListReplay == m_tracksDisplayListReplay)
-        return;
-
     m_tracksDisplayListReplay = tracksDisplayListReplay;
 
-    if (is<CanvasRenderingContext2D>(m_context.get()))
-        downcast<CanvasRenderingContext2D>(*m_context).setTracksDisplayListReplay(m_tracksDisplayListReplay);
+    if (!buffer())
+        return;
+
+    auto& buffer = *this->buffer();
+    if (buffer.drawingContext())
+        buffer.drawingContext()->setTracksDisplayListReplay(m_tracksDisplayListReplay);
 }
 
 String HTMLCanvasElement::displayListAsText(DisplayList::AsTextFlags flags) const
 {
-    if (is<CanvasRenderingContext2D>(m_context.get()))
-        return downcast<CanvasRenderingContext2D>(*m_context).displayListAsText(flags);
+    if (!buffer())
+        return String();
+
+    auto& buffer = *this->buffer();
+    if (buffer.drawingContext())
+        return buffer.drawingContext()->displayList().asText(flags);
 
     return String();
 }
 
 String HTMLCanvasElement::replayDisplayListAsText(DisplayList::AsTextFlags flags) const
 {
-    if (is<CanvasRenderingContext2D>(m_context.get()))
-        return downcast<CanvasRenderingContext2D>(*m_context).replayDisplayListAsText(flags);
+    if (!buffer())
+        return String();
+
+    auto& buffer = *this->buffer();
+    if (buffer.drawingContext() && buffer.drawingContext()->replayedDisplayList())
+        return buffer.drawingContext()->replayedDisplayList()->asText(flags);
 
     return String();
 }
@@ -889,11 +890,22 @@ void HTMLCanvasElement::createImageBuffer() const
     if (!width() || !height())
         return;
 
-    RenderingMode renderingMode = shouldAccelerate(size()) ? RenderingMode::Accelerated : RenderingMode::Unaccelerated;
-
     auto hostWindow = (document().view() && document().view()->root()) ? document().view()->root()->hostWindow() : nullptr;
+
+    // FIXME: Add a new setting for DisplayList drawing on canvas.
+    bool usesDisplayListDrawing = m_usesDisplayListDrawing.valueOr(document().settings().displayListDrawingEnabled());
+
+    RenderingMode renderingMode;
+    if (usesDisplayListDrawing)
+        renderingMode = shouldAccelerate(size()) ? RenderingMode::DisplayListAccelerated : RenderingMode::DisplayListUnaccelerated;
+    else
+        renderingMode = shouldAccelerate(size()) ? RenderingMode::Accelerated : RenderingMode::Unaccelerated;
+
     setImageBuffer(ImageBuffer::create(size(), renderingMode, 1, ColorSpace::SRGB, hostWindow));
 
+    if (buffer() && buffer()->drawingContext())
+        buffer()->drawingContext()->setTracksDisplayListReplay(m_tracksDisplayListReplay);
+
 #if USE(IOSURFACE_CANVAS_BACKING_STORE) || ENABLE(ACCELERATED_2D_CANVAS)
     if (m_context && m_context->is2d()) {
         // Recalculate compositing requirements if acceleration state changed.
index b528645..42134a1 100644 (file)
@@ -161,7 +161,7 @@ private:
 
     bool m_ignoreReset { false };
 
-    bool m_usesDisplayListDrawing { false };
+    Optional<bool> m_usesDisplayListDrawing;
     bool m_tracksDisplayListReplay { false };
 
     std::unique_ptr<CanvasRenderingContext> m_context;
index fc68b40..509ddc7 100644 (file)
@@ -33,20 +33,22 @@ namespace WebCore {
 template<typename BackendType>
 class ConcreteImageBuffer : public ImageBuffer {
 public:
-    static std::unique_ptr<ImageBuffer> create(const FloatSize& size, float resolutionScale, ColorSpace colorSpace, const HostWindow* hostWindow)
+    template<typename ImageBufferType = ConcreteImageBuffer, typename... Arguments>
+    static std::unique_ptr<ImageBuffer> create(const FloatSize& size, float resolutionScale, ColorSpace colorSpace, const HostWindow* hostWindow, Arguments&&... arguments)
     {
         auto backend = BackendType::create(size, resolutionScale, colorSpace, hostWindow);
         if (!backend)
             return nullptr;
-        return std::unique_ptr<ConcreteImageBuffer>(new ConcreteImageBuffer(WTFMove(backend)));
+        return std::unique_ptr<ImageBufferType>(new ImageBufferType(WTFMove(backend), std::forward<Arguments>(arguments)...));
     }
 
-    static std::unique_ptr<ImageBuffer> create(const FloatSize& size, const GraphicsContext& context)
+    template<typename ImageBufferType = ConcreteImageBuffer, typename... Arguments>
+    static std::unique_ptr<ImageBuffer> create(const FloatSize& size, const GraphicsContext& context, Arguments&&... arguments)
     {
         auto backend = BackendType::create(size, context);
         if (!backend)
             return nullptr;
-        return std::unique_ptr<ConcreteImageBuffer>(new ConcreteImageBuffer(WTFMove(backend)));
+        return std::unique_ptr<ImageBufferType>(new ImageBufferType(WTFMove(backend), std::forward<Arguments>(arguments)...));
     }
 
 protected:
@@ -67,6 +69,7 @@ protected:
 
     void flushContext() override
     {
+        flushDrawingContext();
         m_backend->flushContext();
     }
 
@@ -80,46 +83,55 @@ protected:
 
     NativeImagePtr copyNativeImage(BackingStoreCopy copyBehavior = CopyBackingStore) const override
     {
+        const_cast<ConcreteImageBuffer&>(*this).flushDrawingContext();
         return m_backend->copyNativeImage(copyBehavior);
     }
 
     RefPtr<Image> copyImage(BackingStoreCopy copyBehavior = CopyBackingStore, PreserveResolution preserveResolution = PreserveResolution::No) const override
     {
+        const_cast<ConcreteImageBuffer&>(*this).flushDrawingContext();
         return m_backend->copyImage(copyBehavior, preserveResolution);
     }
 
     void draw(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) override
     {
+        flushDrawingContext();
         m_backend->draw(destContext, destRect, srcRect, options);
     }
 
     void drawPattern(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& options) override
     {
+        flushDrawingContext();
         m_backend->drawPattern(destContext, destRect, srcRect, patternTransform, phase, spacing, options);
     }
 
     NativeImagePtr sinkIntoNativeImage() override
     {
+        flushDrawingContext();
         return m_backend->sinkIntoNativeImage();
     }
 
     RefPtr<Image> sinkIntoImage(PreserveResolution preserveResolution = PreserveResolution::No) override
     {
+        flushDrawingContext();
         return m_backend->sinkIntoImage(preserveResolution);
     }
 
     void drawConsuming(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) override
     {
+        flushDrawingContext();
         m_backend->drawConsuming(destContext, destRect, srcRect, options);
     }
 
     void convertToLuminanceMask() override
     {
+        flushDrawingContext();
         m_backend->convertToLuminanceMask();
     }
 
     void transformColorSpace(ColorSpace srcColorSpace, ColorSpace destColorSpace) override
     {
+        flushDrawingContext();
         m_backend->transformColorSpace(srcColorSpace, destColorSpace);
     }
 
index 4a3fbea..a8d999e 100644 (file)
@@ -48,6 +48,14 @@ std::unique_ptr<ImageBuffer> ImageBuffer::create(const FloatSize& size, Renderin
         if (!imageBuffer)
             imageBuffer = UnacceleratedImageBuffer::create(size, resolutionScale, colorSpace, hostWindow);
         break;
+            
+    case RenderingMode::DisplayListAccelerated:
+        imageBuffer = DisplayListAcceleratedImageBuffer::create(size, resolutionScale, colorSpace, hostWindow);
+        FALLTHROUGH;
+    case RenderingMode::DisplayListUnaccelerated:
+        if (!imageBuffer)
+            imageBuffer = DisplayListUnacceleratedImageBuffer::create(size, resolutionScale, colorSpace, hostWindow);
+        break;
     }
 
     return imageBuffer;
@@ -65,6 +73,14 @@ std::unique_ptr<ImageBuffer> ImageBuffer::create(const FloatSize& size, const Gr
         if (!imageBuffer)
             imageBuffer = UnacceleratedImageBuffer::create(size, context);
         break;
+            
+    case RenderingMode::DisplayListAccelerated:
+        imageBuffer = DisplayListAcceleratedImageBuffer::create(size, context);
+        FALLTHROUGH;
+    case RenderingMode::DisplayListUnaccelerated:
+        if (!imageBuffer)
+            imageBuffer = DisplayListUnacceleratedImageBuffer::create(size, context);
+        break;
     }
 
     return imageBuffer;
index a0b04af..abfba3e 100644 (file)
 
 namespace WebCore {
 
+namespace DisplayList {
+class DrawingContext;
+}
+
 class ImageBuffer {
 public:
     // Will return a null pointer on allocation failure.
@@ -57,6 +61,9 @@ public:
     virtual GraphicsContext& context() const = 0;
     virtual void flushContext() = 0;
 
+    virtual DisplayList::DrawingContext* drawingContext() { return nullptr; }
+    virtual void flushDrawingContext() { }
+
     virtual AffineTransform baseTransform() const = 0;
     virtual IntSize logicalSize() const = 0;
     virtual IntSize backendSize() const = 0;
index 8f46901..e0174a7 100644 (file)
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "ConcreteImageBuffer.h"
+#include "DisplayListImageBuffer.h"
 
 #if USE(CG)
 #include "ImageBufferCGBitmapBackend.h"
@@ -61,5 +62,7 @@ using AcceleratedImageBufferBackend = UnacceleratedImageBufferBackend;
 
 using UnacceleratedImageBuffer = ConcreteImageBuffer<UnacceleratedImageBufferBackend>;
 using AcceleratedImageBuffer = ConcreteImageBuffer<AcceleratedImageBufferBackend>;
+using DisplayListUnacceleratedImageBuffer = DisplayList::ImageBuffer<UnacceleratedImageBufferBackend>;
+using DisplayListAcceleratedImageBuffer = DisplayList::ImageBuffer<AcceleratedImageBufferBackend>;
 
 } // namespace WebCore
index 69d8ae8..9d83dc8 100644 (file)
@@ -30,6 +30,8 @@ namespace WebCore {
 enum class RenderingMode : uint8_t {
     Accelerated,
     Unaccelerated,
+    DisplayListAccelerated,
+    DisplayListUnaccelerated,
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.cpp b/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.cpp
new file mode 100644 (file)
index 0000000..e1c69b5
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DisplayListDrawingContext.h"
+
+#include "AffineTransform.h"
+#include "DisplayListRecorder.h"
+#include "DisplayListReplayer.h"
+
+namespace WebCore {
+namespace DisplayList {
+
+DrawingContext::DrawingContext(const FloatSize& logicalSize)
+    : m_context([&](GraphicsContext& displayListContext) {
+        return makeUnique<Recorder>(displayListContext, m_displayList, GraphicsContextState(), FloatRect({ }, logicalSize), AffineTransform());
+    })
+{
+}
+
+void DrawingContext::setTracksDisplayListReplay(bool tracksDisplayListReplay)
+{
+    m_tracksDisplayListReplay = tracksDisplayListReplay;
+    m_replayedDisplayList.reset();
+}
+
+void DrawingContext::replayDisplayList(GraphicsContext& destContext)
+{
+    if (!m_displayList.itemCount())
+        return;
+
+    Replayer replayer(destContext, m_displayList);
+    if (m_tracksDisplayListReplay)
+        m_replayedDisplayList = replayer.replay({ }, m_tracksDisplayListReplay);
+    else
+        replayer.replay();
+    m_displayList.clear();
+}
+
+} // DisplayList
+} // WebCore
diff --git a/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.h b/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.h
new file mode 100644 (file)
index 0000000..86ebbc6
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "DisplayList.h"
+#include "GraphicsContext.h"
+
+namespace WebCore {
+namespace DisplayList {
+
+class DrawingContext {
+public:
+    DrawingContext(const FloatSize& logicalSize);
+
+    GraphicsContext& context() const { return const_cast<DrawingContext&>(*this).m_context; }
+    DisplayList& displayList() { return m_displayList; }
+    const DisplayList& displayList() const { return m_displayList; }
+    const DisplayList* replayedDisplayList() const { return m_replayedDisplayList.get(); }
+
+    void setTracksDisplayListReplay(bool);
+    void replayDisplayList(GraphicsContext&);
+
+protected:
+    GraphicsContext m_context;
+    DisplayList m_displayList;
+    std::unique_ptr<DisplayList> m_replayedDisplayList;
+    bool m_tracksDisplayListReplay { false };
+};
+
+} // DisplayList
+} // WebCore
diff --git a/Source/WebCore/platform/graphics/displaylists/DisplayListImageBuffer.h b/Source/WebCore/platform/graphics/displaylists/DisplayListImageBuffer.h
new file mode 100644 (file)
index 0000000..717b2b8
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2020 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ConcreteImageBuffer.h"
+#include "DisplayListDrawingContext.h"
+
+namespace WebCore {
+namespace DisplayList {
+
+template<typename BackendType>
+class ImageBuffer : public ConcreteImageBuffer<BackendType> {
+    using BaseConcreteImageBuffer = ConcreteImageBuffer<BackendType>;
+
+public:
+    static auto create(const FloatSize& size, float resolutionScale, ColorSpace colorSpace, const HostWindow* hostWindow)
+    {
+        return BaseConcreteImageBuffer::template create<ImageBuffer>(size, resolutionScale, colorSpace, hostWindow, size);
+    }
+
+    static auto create(const FloatSize& size, const GraphicsContext& context)
+    {
+        return BaseConcreteImageBuffer::template create<ImageBuffer>(size, context, size);
+    }
+
+    ImageBuffer(std::unique_ptr<BackendType>&& dataBackend, const FloatSize& size)
+        : BaseConcreteImageBuffer(WTFMove(dataBackend))
+        , m_drawingContext(size)
+    {
+    }
+
+    ~ImageBuffer()
+    {
+        flushDrawingContext();
+    }
+
+    GraphicsContext& context() const override
+    {
+        return m_drawingContext.context();
+    }
+
+    DrawingContext* drawingContext() override { return &m_drawingContext; }
+
+    void flushDrawingContext() override
+    {
+        m_drawingContext.replayDisplayList(BaseConcreteImageBuffer::context());
+    }
+
+    DrawingContext m_drawingContext;
+};
+
+} // DisplayList
+} // namespace WebCore