When recording the drawing, the DisplayList should be initialized with the GraphicsCo...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 6 Apr 2018 19:19:41 +0000 (19:19 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 6 Apr 2018 19:19:41 +0000 (19:19 +0000)
https://bugs.webkit.org/show_bug.cgi?id=184336

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2018-04-06
Reviewed by Antti Koivisto.

The state of the drawing context has to be transfered to the recording
DisplayList before recording. Many recording GraphicsContext functions
will behave wrongly if it gets the default state.

* html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::DisplayListDrawingContext::DisplayListDrawingContext):
(WebCore::CanvasRenderingContext2DBase::drawingContext const):
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::recursiveCommitChanges):
* platform/graphics/displaylists/DisplayListRecorder.cpp:
(WebCore::DisplayList::Recorder::Recorder):
* platform/graphics/displaylists/DisplayListRecorder.h:
(WebCore::DisplayList::Recorder::ContextState::ContextState):
(WebCore::DisplayList::Recorder::ContextState::cloneForSave const):
* platform/graphics/displaylists/DisplayListReplayer.cpp:
(WebCore::DisplayList::Replayer::replay):
* platform/graphics/displaylists/DisplayListReplayer.h:
(WebCore::DisplayList::Replayer::replay): If we do not have a clipping
rectangle and we want to record all the drawing, we need a default value
for the clipping rectangle and we want no clipping to happen.

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

Source/WebCore/ChangeLog
Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp
Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp
Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h
Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp
Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.h

index c5bf8c1..3241b58 100644 (file)
@@ -1,3 +1,31 @@
+2018-04-06  Said Abou-Hallawa  <sabouhallawa@apple.com>
+
+        When recording the drawing, the DisplayList should be initialized with the GraphicsContextState of the underlying GraphicsContext
+        https://bugs.webkit.org/show_bug.cgi?id=184336
+
+        Reviewed by Antti Koivisto.
+
+        The state of the drawing context has to be transfered to the recording 
+        DisplayList before recording. Many recording GraphicsContext functions 
+        will behave wrongly if it gets the default state.
+
+        * html/canvas/CanvasRenderingContext2DBase.cpp:
+        (WebCore::DisplayListDrawingContext::DisplayListDrawingContext):
+        (WebCore::CanvasRenderingContext2DBase::drawingContext const):
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::recursiveCommitChanges):
+        * platform/graphics/displaylists/DisplayListRecorder.cpp:
+        (WebCore::DisplayList::Recorder::Recorder):
+        * platform/graphics/displaylists/DisplayListRecorder.h:
+        (WebCore::DisplayList::Recorder::ContextState::ContextState):
+        (WebCore::DisplayList::Recorder::ContextState::cloneForSave const):
+        * platform/graphics/displaylists/DisplayListReplayer.cpp:
+        (WebCore::DisplayList::Replayer::replay):
+        * platform/graphics/displaylists/DisplayListReplayer.h:
+        (WebCore::DisplayList::Replayer::replay): If we do not have a clipping
+        rectangle and we want to record all the drawing, we need a default value
+        for the clipping rectangle and we want no clipping to happen.
+
 2018-04-06  Daniel Bates  <dabates@apple.com>
 
         Emit a more informative message when a script is blocked due to "X-Content-Type: nosniff"
index ab307bc..768c0fc 100644 (file)
@@ -87,9 +87,9 @@ public:
     GraphicsContext context;
     DisplayList::DisplayList displayList;
     
-    DisplayListDrawingContext(const FloatRect& clip)
-        : context([&](GraphicsContext& context) {
-            return std::make_unique<DisplayList::Recorder>(context, displayList, clip, AffineTransform());
+    DisplayListDrawingContext(GraphicsContext& context, const FloatRect& clip)
+        : context([&](GraphicsContext& displayListContext) {
+            return std::make_unique<DisplayList::Recorder>(displayListContext, displayList, context.state(), clip, AffineTransform());
         })
     {
     }
@@ -2086,7 +2086,7 @@ GraphicsContext* CanvasRenderingContext2DBase::drawingContext() const
     auto& canvas = downcast<HTMLCanvasElement>(canvasBase());
     if (UNLIKELY(m_usesDisplayListDrawing)) {
         if (!m_recordingContext)
-            m_recordingContext = std::make_unique<DisplayListDrawingContext>(FloatRect(FloatPoint::zero(), canvas.size()));
+            m_recordingContext = std::make_unique<DisplayListDrawingContext>(*canvas.drawingContext(), FloatRect(FloatPoint::zero(), canvas.size()));
         return &m_recordingContext->context;
     }
 
index b28bf58..aab5495 100644 (file)
@@ -1585,7 +1585,7 @@ void GraphicsLayerCA::recursiveCommitChanges(const CommitState& commitState, con
         FloatRect initialClip(boundsOrigin(), size());
 
         GraphicsContext context([&](GraphicsContext& context) {
-            return std::make_unique<DisplayList::Recorder>(context, *m_displayList, initialClip, AffineTransform());
+            return std::make_unique<DisplayList::Recorder>(context, *m_displayList, GraphicsContextState(), initialClip, AffineTransform());
         });
         paintGraphicsLayerContents(context, FloatRect(FloatPoint(), size()));
     }
index 3054423..85d0416 100644 (file)
 namespace WebCore {
 namespace DisplayList {
 
-Recorder::Recorder(GraphicsContext& context, DisplayList& displayList, const FloatRect& initialClip, const AffineTransform& baseCTM)
+Recorder::Recorder(GraphicsContext& context, DisplayList& displayList, const GraphicsContextState& state, const FloatRect& initialClip, const AffineTransform& baseCTM)
     : GraphicsContextImpl(context, initialClip, baseCTM)
     , m_displayList(displayList)
 {
     LOG_WITH_STREAM(DisplayLists, stream << "\nRecording with clip " << initialClip);
-    m_stateStack.append(ContextState(baseCTM, initialClip));
+    m_stateStack.append(ContextState(state, baseCTM, initialClip));
 }
 
 Recorder::~Recorder()
index 58dd07e..057bbf1 100644 (file)
@@ -50,7 +50,7 @@ class DrawingItem;
 class Recorder : public GraphicsContextImpl {
     WTF_MAKE_NONCOPYABLE(Recorder);
 public:
-    Recorder(GraphicsContext&, DisplayList&, const FloatRect& initialClip, const AffineTransform&);
+    Recorder(GraphicsContext&, DisplayList&, const GraphicsContextState&, const FloatRect& initialClip, const AffineTransform&);
     virtual ~Recorder();
 
     size_t itemCount() const { return m_displayList.itemCount(); }
@@ -145,17 +145,17 @@ private:
         bool wasUsedForDrawing { false };
         size_t saveItemIndex { 0 };
         
-        ContextState(const AffineTransform& transform, const FloatRect& clip)
+        ContextState(const GraphicsContextState& state, const AffineTransform& transform, const FloatRect& clip)
             : ctm(transform)
             , clipBounds(clip)
+            , lastDrawingState(state)
         {
         }
         
         ContextState cloneForSave(size_t saveIndex) const
         {
-            ContextState state(ctm, clipBounds);
+            ContextState state(lastDrawingState, ctm, clipBounds);
             state.stateChange = stateChange;
-            state.lastDrawingState = lastDrawingState;
             state.saveItemIndex = saveIndex;
             return state;
         }
index 9ae3094..8feaa2f 100644 (file)
@@ -55,7 +55,7 @@ std::unique_ptr<DisplayList> Replayer::replay(const FloatRect& initialClip, bool
     for (size_t i = 0; i < numItems; ++i) {
         auto& item = m_displayList.list()[i].get();
 
-        if (is<DrawingItem>(item)) {
+        if (!initialClip.isZero() && is<DrawingItem>(item)) {
             const DrawingItem& drawingItem = downcast<DrawingItem>(item);
             if (drawingItem.extentKnown() && !drawingItem.extent().intersects(initialClip)) {
                 LOG_WITH_STREAM(DisplayLists, stream << "skipping " << i << " " << item);
index fb383e2..4f968e8 100644 (file)
@@ -42,7 +42,7 @@ public:
     Replayer(GraphicsContext&, const DisplayList&);
     ~Replayer();
 
-    std::unique_ptr<DisplayList> replay(const FloatRect& initialClip, bool trackReplayList = false);
+    std::unique_ptr<DisplayList> replay(const FloatRect& initialClip = { }, bool trackReplayList = false);
     
 private:
     const DisplayList& m_displayList;