Make LOG_WITH_STREAM more efficient
https://bugs.webkit.org/show_bug.cgi?id=197905

Reviewed by Alex Christensen.
Source/WebCore:

No longer need to conditionalize ClipRects logging on the channel being enabled
since LOG_WITH_STREAM fix the performance problem.

Convert some RenderLayerCompositor logging to use LOG_WITH_STREAM.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::calculateClipRects const):
(WebCore::clipRectsLogEnabled): Deleted.
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::computeCompositingRequirements):
(WebCore::RenderLayerCompositor::traverseUnchangedSubtree):

Source/WebCore/PAL:

Make the LOG_WITH_STREAM macro check that the log channel is enabled before
building the stream.

* pal/LogMacros.h:

Source/WTF:

Add a streamable Repeat() class that can be used to output a series of characters.
This is useful for indenting output.

* wtf/text/TextStream.h:
(WTF::TextStream::repeat::repeat):
(WTF::TextStream::operator<<):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@245336 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog
index a421f4d..9b33d2f 100644
--- a/Source/WTF/ChangeLog
+++ b/Source/WTF/ChangeLog
@@ -1,3 +1,17 @@
+2019-05-15  Simon Fraser  <simon.fraser@apple.com>
+
+        Make LOG_WITH_STREAM more efficient
+        https://bugs.webkit.org/show_bug.cgi?id=197905
+
+        Reviewed by Alex Christensen.
+
+        Add a streamable repeat() class that can be used to output a series of characters.
+        This is useful for indenting output.
+
+        * wtf/text/TextStream.h:
+        (WTF::TextStream::repeat::repeat):
+        (WTF::TextStream::operator<<):
+
 2019-05-15  Víctor Manuel Jáquez Leal  <vjaquez@igalia.com>
 
         compilation failure with clang 9
diff --git a/Source/WTF/wtf/text/TextStream.h b/Source/WTF/wtf/text/TextStream.h
index 24a370c..ec7f26c 100644
--- a/Source/WTF/wtf/text/TextStream.h
+++ b/Source/WTF/wtf/text/TextStream.h
@@ -102,6 +102,22 @@
         return (*func)(*this);
     }
 
+    struct Repeat {
+        Repeat(unsigned inWidth, char inCharacter)
+            : width(inWidth), character(inCharacter)
+        { }
+        unsigned width { 0 };
+        char character { ' ' };
+    };
+
+    TextStream& operator<<(const Repeat& repeated)
+    {
+        for (unsigned i = 0; i < repeated.width; ++i)
+            m_text.append(repeated.character);
+
+        return *this;
+    }
+
     class IndentScope {
     public:
         IndentScope(TextStream& ts, int amount = 1)
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index a608751..44db6ae 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -25,6 +25,25 @@
 
 2019-05-15  Simon Fraser  <simon.fraser@apple.com>
 
+        Make LOG_WITH_STREAM more efficient
+        https://bugs.webkit.org/show_bug.cgi?id=197905
+
+        Reviewed by Alex Christensen.
+
+        No longer need to conditionalize ClipRects logging on the channel being enabled
+        since LOG_WITH_STREAM fix the performance problem.
+
+        Convert some RenderLayerCompositor logging to use LOG_WITH_STREAM.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::calculateClipRects const):
+        (WebCore::clipRectsLogEnabled): Deleted.
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
+        (WebCore::RenderLayerCompositor::traverseUnchangedSubtree):
+
+2019-05-15  Simon Fraser  <simon.fraser@apple.com>
+
         Move RenderLayerCompositor's OverlapMap to its own file
         https://bugs.webkit.org/show_bug.cgi?id=197915
 
diff --git a/Source/WebCore/PAL/ChangeLog b/Source/WebCore/PAL/ChangeLog
index 5e75b25..94807af 100644
--- a/Source/WebCore/PAL/ChangeLog
+++ b/Source/WebCore/PAL/ChangeLog
@@ -1,3 +1,15 @@
+2019-05-15  Simon Fraser  <simon.fraser@apple.com>
+
+        Make LOG_WITH_STREAM more efficient
+        https://bugs.webkit.org/show_bug.cgi?id=197905
+
+        Reviewed by Alex Christensen.
+        
+        Make the LOG_WITH_STREAM macro check that the log channel is enabled before
+        building the stream.
+
+        * pal/LogMacros.h:
+
 2019-05-10  Chris Dumez  <cdumez@apple.com>
 
         Add WKWebViewConfiguration._canShowWhileLocked SPI
diff --git a/Source/WebCore/PAL/pal/LogMacros.h b/Source/WebCore/PAL/pal/LogMacros.h
index 418134a..7455836 100644
--- a/Source/WebCore/PAL/pal/LogMacros.h
+++ b/Source/WebCore/PAL/pal/LogMacros.h
@@ -32,9 +32,11 @@
 #else
 
 #define LOG_WITH_STREAM(channel, commands) do { \
-        WTF::TextStream stream(WTF::TextStream::LineMode::SingleLine); \
-        commands; \
-        WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), "%s", stream.release().utf8().data()); \
+        if (JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel).state == WTFLogChannelState::On) { \
+            WTF::TextStream stream(WTF::TextStream::LineMode::SingleLine); \
+            commands; \
+            WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), "%s", stream.release().utf8().data()); \
+        } \
     } while (0)
 
 #endif // !LOG_DISABLED
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index 1f7c686..e5034c5 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -280,10 +280,6 @@
     return ts;
 }
 
-static bool clipRectsLogEnabled()
-{
-    return LogClipRects.state == WTFLogChannelState::On;
-}
 #endif
 
 RenderLayer::RenderLayer(RenderLayerModelObject& rendererLayerModelObject)
@@ -5629,10 +5625,7 @@
         }
     }
 
-#if !LOG_DISABLED
-    if (clipRectsLogEnabled())
-        LOG_WITH_STREAM(ClipRects, stream << "RenderLayer " << this << " calculateClipRects " << clipRects);
-#endif
+    LOG_WITH_STREAM(ClipRects, stream << "RenderLayer " << this << " calculateClipRects " << clipRects);
 }
 
 Ref<ClipRects> RenderLayer::parentClipRects(const ClipRectsContext& clipRectsContext) const
@@ -5678,10 +5671,7 @@
     if (parentRects->fixed() && &clipRectsContext.rootLayer->renderer() == &view && !backgroundClipRect.isInfinite())
         backgroundClipRect.moveBy(view.frameView().scrollPositionForFixedPosition());
 
-#if !LOG_DISABLED
-    if (clipRectsLogEnabled())
-        LOG_WITH_STREAM(ClipRects, stream << "RenderLayer " << this << " backgroundClipRect with context " << clipRectsContext << " returning " << backgroundClipRect);
-#endif
+    LOG_WITH_STREAM(ClipRects, stream << "RenderLayer " << this << " backgroundClipRect with context " << clipRectsContext << " returning " << backgroundClipRect);
     return backgroundClipRect;
 }
 
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index 1f65c85..b633bf9 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -138,7 +138,7 @@
 #if ENABLE(CSS_COMPOSITING)
         childState.hasNotIsolatedCompositedBlendingDescendants = false; // FIXME: should this only be reset for stacking contexts?
 #endif
-#if ENABLE(TREE_DEBUGGING)
+#if !LOG_DISABLED
         childState.depth = depth + 1;
 #endif
         return childState;
@@ -167,8 +167,8 @@
 #if ENABLE(CSS_COMPOSITING)
     bool hasNotIsolatedCompositedBlendingDescendants { false };
 #endif
-#if ENABLE(TREE_DEBUGGING)
-    int depth { 0 };
+#if !LOG_DISABLED
+    unsigned depth { 0 };
 #endif
 };
 
@@ -830,9 +830,7 @@
         return;
     }
 
-#if ENABLE(TREE_DEBUGGING)
-    LOG(Compositing, "%*p %s computeCompositingRequirements (backing provider candidate %p)", 12 + compositingState.depth * 2, &layer, layer.isNormalFlowOnly() ? "n" : "s", backingSharingState.backingProviderCandidate());
-#endif
+    LOG_WITH_STREAM(Compositing, stream << TextStream::Repeat(compositingState.depth * 2, ' ') << &layer << (layer.isNormalFlowOnly() ? " n" : " s") << " computeCompositingRequirements (backing provider candidate " << backingSharingState.backingProviderCandidate() << ")");
 
     // FIXME: maybe we can avoid updating all remaining layers in paint order.
     compositingState.fullPaintOrderTraversalRequired |= layer.needsCompositingRequirementsTraversal();
@@ -1060,13 +1058,10 @@
         layer.setNeedsCompositingLayerConnection();
     }
 
-#if ENABLE(TREE_DEBUGGING)
-    LOG(Compositing, "%*p computeCompositingRequirements - willBeComposited %d (backing provider candidate %p)", 12 + compositingState.depth * 2, &layer, willBeComposited, backingSharingState.backingProviderCandidate());
-#endif
-
     layer.clearCompositingRequirementsTraversalState();
-    
     overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer);
+
+    LOG_WITH_STREAM(Compositing, stream << TextStream::Repeat(compositingState.depth * 2, ' ') << &layer << " computeCompositingRequirements - willBeComposited " << willBeComposited << " (backing provider candidate " << backingSharingState.backingProviderCandidate() << ")");
 }
 
 // We have to traverse unchanged layers to fill in the overlap map.
@@ -1076,9 +1071,7 @@
     ASSERT(!layer.hasDescendantNeedingCompositingRequirementsTraversal());
     ASSERT(!layer.needsCompositingRequirementsTraversal());
 
-#if ENABLE(TREE_DEBUGGING)
-    LOG(Compositing, "%*p traverseUnchangedSubtree", 12 + compositingState.depth * 2, &layer);
-#endif
+    LOG_WITH_STREAM(Compositing, stream << TextStream::Repeat(compositingState.depth * 2, ' ') << &layer << (layer.isNormalFlowOnly() ? " n" : " s") << " traverseUnchangedSubtree");
 
     layer.updateDescendantDependentFlags();
     layer.updateLayerListsIfNeeded();