Title: [230274] trunk/Source/WebCore
Revision
230274
Author
commit-qu...@webkit.org
Date
2018-04-04 13:56:50 -0700 (Wed, 04 Apr 2018)

Log Message

Track the paint frequency through a new class named PaintFrequencyTracker
https://bugs.webkit.org/show_bug.cgi?id=184311

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

PaintFrequencyTracker is a class which detects when a layer is painted
frequently. SinglePaintFrequencyTracking is used in conjunction with
PaintFrequencyTracker to recored a single paint timing.

* rendering/PaintFrequencyTracker.h: Added.
(WebCore::PaintFrequencyTracker::begin):
(WebCore::PaintFrequencyTracker::end):
(WebCore::PaintFrequencyTracker::paintingFrequently const):
Simplify the logic for tracking the paint frequency and move it from
RenderLayer.cpp.

(WebCore::SinglePaintFrequencyTracking::SinglePaintFrequencyTracking):
(WebCore::SinglePaintFrequencyTracking::~SinglePaintFrequencyTracking):
A convenient way to bracket the begin() and the end() methods of
PaintFrequencyTracker.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintLayerContents):
(WebCore::RenderLayer::calculateClipRects const):
(WebCore::PaintFrequencyInfo::PaintFrequencyInfo): Deleted.
(WebCore::PaintFrequencyInfo::setPaintedCacheableResource): Deleted.
(WebCore::PaintFrequencyInfo::paintingFrequently const): Deleted.
(WebCore::PaintFrequencyInfo::updatePaintFrequency): Deleted.
(WebCore::PaintFrequencyInfo::paintingCacheableResource): Deleted.
* rendering/RenderLayer.h:
Rename PaintFrequencyInfo to PaintFrequencyTracker and move it a separate
header file.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (230273 => 230274)


--- trunk/Source/WebCore/ChangeLog	2018-04-04 20:29:43 UTC (rev 230273)
+++ trunk/Source/WebCore/ChangeLog	2018-04-04 20:56:50 UTC (rev 230274)
@@ -1,3 +1,38 @@
+2018-04-04  Said Abou-Hallawa  <sabouhall...@apple.com>
+
+        Track the paint frequency through a new class named PaintFrequencyTracker
+        https://bugs.webkit.org/show_bug.cgi?id=184311
+
+        Reviewed by Antti Koivisto.
+
+        PaintFrequencyTracker is a class which detects when a layer is painted 
+        frequently. SinglePaintFrequencyTracking is used in conjunction with
+        PaintFrequencyTracker to recored a single paint timing.
+
+        * rendering/PaintFrequencyTracker.h: Added.
+        (WebCore::PaintFrequencyTracker::begin):
+        (WebCore::PaintFrequencyTracker::end):
+        (WebCore::PaintFrequencyTracker::paintingFrequently const):
+        Simplify the logic for tracking the paint frequency and move it from
+        RenderLayer.cpp.
+
+        (WebCore::SinglePaintFrequencyTracking::SinglePaintFrequencyTracking):
+        (WebCore::SinglePaintFrequencyTracking::~SinglePaintFrequencyTracking):
+        A convenient way to bracket the begin() and the end() methods of
+        PaintFrequencyTracker.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::paintLayerContents):
+        (WebCore::RenderLayer::calculateClipRects const):
+        (WebCore::PaintFrequencyInfo::PaintFrequencyInfo): Deleted.
+        (WebCore::PaintFrequencyInfo::setPaintedCacheableResource): Deleted.
+        (WebCore::PaintFrequencyInfo::paintingFrequently const): Deleted.
+        (WebCore::PaintFrequencyInfo::updatePaintFrequency): Deleted.
+        (WebCore::PaintFrequencyInfo::paintingCacheableResource): Deleted.
+        * rendering/RenderLayer.h:
+        Rename PaintFrequencyInfo to PaintFrequencyTracker and move it a separate
+        header file.
+
 2018-04-04  Jer Noble  <jer.no...@apple.com>
 
         RELEASE_ASSERT in CaptionUserPreferencesMediaAF::CaptionUserPreferencesMediaAF() when MediaToolbox.framework missing

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (230273 => 230274)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-04-04 20:29:43 UTC (rev 230273)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-04-04 20:56:50 UTC (rev 230274)
@@ -1686,6 +1686,7 @@
 		55A336F71D8209F40022C4C7 /* NativeImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 55A336F61D8209F40022C4C7 /* NativeImage.h */; };
 		55A336F91D821E3C0022C4C7 /* ImageBackingStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		55AF14E61EAAC59B0026EEAA /* UTIRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 55AF14E41EAAC59B0026EEAA /* UTIRegistry.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		55EC9599206AA7A0007DD0A9 /* PaintFrequencyTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 55EC95972069C92D007DD0A9 /* PaintFrequencyTracker.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		5704405A1E53936200356601 /* JSAesCbcCfbParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 570440591E53936200356601 /* JSAesCbcCfbParams.h */; };
 		5706A6961DDE5C9500A03B14 /* CryptoAlgorithmRsaOaepParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 5706A6951DDE5C9500A03B14 /* CryptoAlgorithmRsaOaepParams.h */; };
 		5706A6981DDE5E4600A03B14 /* JSRsaOaepParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 5706A6971DDE5E4600A03B14 /* JSRsaOaepParams.h */; };
@@ -8260,6 +8261,7 @@
 		55AF14E31EAAC59B0026EEAA /* UTIRegistry.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UTIRegistry.cpp; sourceTree = "<group>"; };
 		55AF14E41EAAC59B0026EEAA /* UTIRegistry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UTIRegistry.h; sourceTree = "<group>"; };
 		55D408F71A7C631800C78450 /* SVGImageClients.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGImageClients.h; sourceTree = "<group>"; };
+		55EC95972069C92D007DD0A9 /* PaintFrequencyTracker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PaintFrequencyTracker.h; sourceTree = "<group>"; };
 		570440571E53851600356601 /* CryptoAlgorithmAES_CFBMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmAES_CFBMac.cpp; sourceTree = "<group>"; };
 		570440591E53936200356601 /* JSAesCbcCfbParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAesCbcCfbParams.h; sourceTree = "<group>"; };
 		5704405B1E53937900356601 /* JSAesCbcCfbParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAesCbcCfbParams.cpp; sourceTree = "<group>"; };
@@ -25516,6 +25518,7 @@
 				CDE7FC43181904B1002BBB77 /* OrderIterator.h */,
 				3774ABA30FA21EB400AD7DE9 /* OverlapTestRequestClient.h */,
 				9377AB9F15DEFEEF0031FD04 /* Pagination.h */,
+				55EC95972069C92D007DD0A9 /* PaintFrequencyTracker.h */,
 				0885067D11DA045B00182B98 /* PaintInfo.h */,
 				0885067E11DA045B00182B98 /* PaintPhase.h */,
 				B2B1F7140D00CAA8004AEA64 /* PointerEventsHitRules.cpp */,
@@ -29217,6 +29220,7 @@
 				371E65CC13661EDC00BEEDB0 /* PageSerializer.h in Headers */,
 				E1284AE110447D4500EAEB52 /* PageTransitionEvent.h in Headers */,
 				9377ABA015DEFEEF0031FD04 /* Pagination.h in Headers */,
+				55EC9599206AA7A0007DD0A9 /* PaintFrequencyTracker.h in Headers */,
 				0885067F11DA045B00182B98 /* PaintInfo.h in Headers */,
 				0885068011DA045B00182B98 /* PaintPhase.h in Headers */,
 				A80E6CFB0A1989CA007FB8C5 /* Pair.h in Headers */,

Added: trunk/Source/WebCore/rendering/PaintFrequencyTracker.h (0 => 230274)


--- trunk/Source/WebCore/rendering/PaintFrequencyTracker.h	                        (rev 0)
+++ trunk/Source/WebCore/rendering/PaintFrequencyTracker.h	2018-04-04 20:56:50 UTC (rev 230274)
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2018 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
+
+namespace WebCore {
+
+// This class is used to detect when we are painting frequently so that - even in a painting model
+// without display lists - we can build and cache portions of display lists and reuse them only when
+// animating. Once we transition fully to display lists, we can probably just pull from the previous
+// paint's display list if it is still around and get rid of this code.
+class PaintFrequencyTracker {
+    WTF_MAKE_FAST_ALLOCATED;
+
+public:
+    PaintFrequencyTracker() = default;
+
+    void begin()
+    {
+        static unsigned paintFrequencyPaintCountThreshold = 30;
+        static Seconds paintFrequencyTimePerFrameThreshold = 32_ms;
+        static Seconds paintFrequencySecondsIdleThreshold = 5_s;
+
+        // Start by assuming the paint frequency is low
+        m_paintFrequency = PaintFrequency::Low;
+
+        MonotonicTime now = MonotonicTime::now();
+        if (!m_firstPaintTime) {
+            // Handle the first time this method is called.
+            m_firstPaintTime = now;
+        } else if (now - m_lastPaintTime > paintFrequencySecondsIdleThreshold) {
+            // It has been 5 seconds since last time we draw this renderer. Reset the state
+            // of this object as if, we've just started tracking the paint frequency.
+            m_firstPaintTime = now;
+            m_totalPaints = 0;
+        } else if (m_totalPaints >= paintFrequencyPaintCountThreshold && ((m_lastPaintTime - m_firstPaintTime) / m_totalPaints) <= paintFrequencyTimePerFrameThreshold) {
+            // Change the paint frequency to be high only if:
+            //  - This renderer has been painted at least 30 times.
+            //  - The frame rate to paint this renderer has been at least 31.25 FPS.
+            m_paintFrequency = PaintFrequency::High;
+        }
+    }
+
+    void end()
+    {
+        m_lastPaintTime = MonotonicTime::now();
+        ASSERT(m_firstPaintTime);
+        ASSERT(m_firstPaintTime <= m_lastPaintTime);
+        ++m_totalPaints;
+    }
+
+    bool paintingFrequently() const { return m_paintFrequency == PaintFrequency::High; }
+
+private:
+    MonotonicTime m_firstPaintTime;
+    MonotonicTime m_lastPaintTime;
+    unsigned m_totalPaints { 0 };
+
+    enum class PaintFrequency { Low, High };
+    PaintFrequency m_paintFrequency { PaintFrequency::Low };
+};
+
+class SinglePaintFrequencyTracking {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    SinglePaintFrequencyTracking(PaintFrequencyTracker& paintFrequencyTracker, bool track = true)
+        : m_paintFrequencyTracker(paintFrequencyTracker)
+        , m_track(track)
+    {
+        if (m_track)
+            m_paintFrequencyTracker.begin();
+    }
+
+    ~SinglePaintFrequencyTracking()
+    {
+        if (m_track)
+            m_paintFrequencyTracker.end();
+    }
+
+private:
+    PaintFrequencyTracker& m_paintFrequencyTracker;
+    bool m_track;
+};
+
+}

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (230273 => 230274)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2018-04-04 20:29:43 UTC (rev 230273)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2018-04-04 20:56:50 UTC (rev 230274)
@@ -134,65 +134,10 @@
 
 #define MIN_INTERSECT_FOR_REVEAL 32
 
-const Seconds paintFrequencyTimePerFrameThreshold = 32_ms;
-const Seconds paintFrequencySecondsIdleThreshold = 5_s;
-
 namespace WebCore {
 
 using namespace HTMLNames;
 
-// This class is used to detect when we are painting frequently so that - even in a painting model
-// without display lists - we can build and cache portions of display lists and reuse them only when
-// animating. Once we transition fully to display lists, we can probably just pull from the previous
-// paint's display list if it is still around and get rid of this code.
-class PaintFrequencyInfo {
-    WTF_MAKE_FAST_ALLOCATED;
-    
-public:
-    PaintFrequencyInfo(MonotonicTime now)
-        : m_firstPaintTime(now)
-        , m_lastPaintTime(now)
-    { }
-
-    enum PaintFrequency { Idle, Low, High };
-    PaintFrequency updatePaintFrequency();
-    
-    void paintingCacheableResource(MonotonicTime);
-    void setPaintedCacheableResource(bool painted) { m_paintedCacheableResource = painted; }
-
-    bool paintingFrequently() const { return m_paintingFrequently; }
-
-private:
-    MonotonicTime m_firstPaintTime;
-    MonotonicTime m_lastPaintTime;
-    unsigned m_totalPaints { 1 };
-    bool m_paintedCacheableResource { false };
-    bool m_paintingFrequently { false };
-};
-
-PaintFrequencyInfo::PaintFrequency PaintFrequencyInfo::updatePaintFrequency()
-{
-    MonotonicTime now = MonotonicTime::now(); // FIXME: Should have a single time for the paint of the whole frame.
-    if ((now - m_lastPaintTime) > paintFrequencySecondsIdleThreshold)
-        return Idle;
-    if (m_totalPaints && ((now - m_firstPaintTime) / m_totalPaints) <= paintFrequencyTimePerFrameThreshold) {
-        m_paintingFrequently = true;
-        return High;
-    }
-    m_paintingFrequently = false;
-    return Low;
-}
-
-void PaintFrequencyInfo::paintingCacheableResource(MonotonicTime now)
-{
-    if (m_paintedCacheableResource)
-        return;
-    
-    m_paintedCacheableResource = true;
-    m_lastPaintTime = now;
-    m_totalPaints++;
-}
-
 class ClipRects : public RefCounted<ClipRects> {
     WTF_MAKE_FAST_ALLOCATED;
 public:
@@ -4351,10 +4296,9 @@
 
     bool selectionAndBackgroundsOnly = paintingInfo.paintBehavior & PaintBehaviorSelectionAndBackgroundsOnly;
     bool selectionOnly = paintingInfo.paintBehavior & PaintBehaviorSelectionOnly;
-    
-    if (shouldPaintContent && m_paintFrequencyInfo && m_paintFrequencyInfo->updatePaintFrequency() == PaintFrequencyInfo::PaintFrequency::Idle)
-        clearPaintFrequencyInfo();
 
+    SinglePaintFrequencyTracking singlePaintFrequencyTracking(m_paintFrequencyTracker, shouldPaintContent);
+
     LayerFragments layerFragments;
     RenderObject* subtreePaintRootForRenderer = nullptr;
 
@@ -6876,28 +6820,6 @@
     return newStyle;
 }
 
-bool RenderLayer::paintingFrequently() const
-{
-    return m_paintFrequencyInfo && m_paintFrequencyInfo->paintingFrequently();
-}
-
-void RenderLayer::simulateFrequentPaint()
-{
-    auto now = MonotonicTime::now();
-    if (!m_paintFrequencyInfo)
-        m_paintFrequencyInfo = std::make_unique<PaintFrequencyInfo>(now);
-    else {
-        m_paintFrequencyInfo->paintingCacheableResource(now);
-        m_paintFrequencyInfo->setPaintedCacheableResource(false);
-        m_paintFrequencyInfo->updatePaintFrequency();
-    }
-}
-
-void RenderLayer::clearPaintFrequencyInfo()
-{
-    m_paintFrequencyInfo = nullptr;
-}
-
 void RenderLayer::updateOrRemoveFilterClients()
 {
     if (!hasFilter()) {

Modified: trunk/Source/WebCore/rendering/RenderLayer.h (230273 => 230274)


--- trunk/Source/WebCore/rendering/RenderLayer.h	2018-04-04 20:29:43 UTC (rev 230273)
+++ trunk/Source/WebCore/rendering/RenderLayer.h	2018-04-04 20:56:50 UTC (rev 230274)
@@ -46,6 +46,7 @@
 #include "ClipRect.h"
 #include "GraphicsLayer.h"
 #include "LayerFragment.h"
+#include "PaintFrequencyTracker.h"
 #include "PaintInfo.h"
 #include "RenderBox.h"
 #include "RenderPtr.h"
@@ -66,7 +67,6 @@
 class HitTestRequest;
 class HitTestResult;
 class HitTestingTransformState;
-class PaintFrequencyInfo;
 class RenderFragmentedFlow;
 class RenderGeometryMap;
 class RenderLayerBacking;
@@ -713,9 +713,8 @@
 
     bool shouldPlaceBlockDirectionScrollbarOnLeft() const final { return renderer().shouldPlaceBlockDirectionScrollbarOnLeft(); }
 
-    WEBCORE_EXPORT void simulateFrequentPaint();
-    WEBCORE_EXPORT bool paintingFrequently() const;
-    void clearPaintFrequencyInfo();
+    void simulateFrequentPaint() { SinglePaintFrequencyTracking { m_paintFrequencyTracker }; }
+    bool paintingFrequently() const { return m_paintFrequencyTracker.paintingFrequently(); }
 
 private:
     enum CollectLayersBehavior { StopAtStackingContexts, StopAtStackingContainers };
@@ -1170,7 +1169,7 @@
 
     std::unique_ptr<RenderLayerBacking> m_backing;
     
-    std::unique_ptr<PaintFrequencyInfo> m_paintFrequencyInfo;
+    PaintFrequencyTracker m_paintFrequencyTracker;
 };
 
 inline void RenderLayer::clearZOrderLists()
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to