Support invalidation tracking for composited layers
authorvollick@chromium.org <vollick@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 Nov 2012 19:58:52 +0000 (19:58 +0000)
committervollick@chromium.org <vollick@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 Nov 2012 19:58:52 +0000 (19:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=97801

Reviewed by Simon Fraser.

GraphicsLayers now store invalidated rects and can include them in
the layer tree dump.

Source/WebCore:

Test: compositing/repaint/invalidations-on-composited-layers.html

* WebCore.exp.in:
  Exports FrameView::resetTrackedRepaints()
* page/FrameView.cpp:
(WebCore::FrameView::setTracksRepaints):
  Notifies each compositor that we are starting/stopping repaints.
(WebCore::FrameView::resetTrackedRepaints):
  Moved implementation to the cpp file.
* platform/graphics/GraphicsLayer.cpp:
(WebCore::GraphicsLayer::~GraphicsLayer):
  Clears the repaint rects associated with this layer.
(WebCore::GraphicsLayer::resetTrackedRepaints):
  Clears the repaint rects associated with this layer.
  Note that the repaint rects are stored in a statically allocated
  HashMap to avoid using space on the graphics layers.
(WebCore::GraphicsLayer::addRepaintRect):
  Adds a repaint rect to list associated with this layer in the
  hash map mentioned above.
(WebCore::GraphicsLayer::dumpProperties):
  This has been modified to include the repaint rects in the dump
  if they've been requested.
* platform/graphics/GraphicsLayerClient.h:
(WebCore::GraphicsLayerClient::isTrackingRepaints):
  This is how graphics layers check if repaint tracking is happening.
  Returns false by default.
* platform/graphics/blackberry/GraphicsLayerBlackBerry.cpp:
(WebCore::GraphicsLayerBlackBerry::setContentsNeedsDisplay):
(WebCore::GraphicsLayerBlackBerry::setNeedsDisplay):
(WebCore::GraphicsLayerBlackBerry::setNeedsDisplayInRect):
  These now call GraphicsLayer::addRepaintRect as necessary.
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::setNeedsDisplayInRect):
  Now calls GraphicsLayer::addRepaintRect as necessary.
* platform/graphics/chromium/GraphicsLayerChromium.cpp:
(WebCore::GraphicsLayerChromium::setContentsNeedsDisplay):
(WebCore::GraphicsLayerChromium::setNeedsDisplay):
(WebCore::GraphicsLayerChromium::setNeedsDisplayInRect):
  These now call GraphicsLayer::addRepaintRect as necessary.
* platform/graphics/clutter/GraphicsLayerClutter.cpp:
(WebCore::GraphicsLayerClutter::setNeedsDisplay):
(WebCore::GraphicsLayerClutter::setNeedsDisplayInRect):
  These now call GraphicsLayer::addRepaintRect as necessary.
* platform/graphics/texmap/GraphicsLayerTextureMapper.cpp:
(WebCore::GraphicsLayerTextureMapper::setNeedsDisplay):
(WebCore::GraphicsLayerTextureMapper::setContentsNeedsDisplay):
(WebCore::GraphicsLayerTextureMapper::setNeedsDisplayInRect):
  These now call GraphicsLayer::addRepaintRect as necessary.
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::isTrackingRepaints):
  Required since this is a GraphicsLayerClient.
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::layerTreeAsText):
  Now accepts a flag to include the repaint rects in the layer tree
  dump.
(WebCore::resetTrackedRepaintRectsRecursive):
  Clears the repaint rects on all graphics layers.
(WebCore::RenderLayerCompositor::resetTrackedRepaintRects):
  Clears the repaint rects on all graphics layers.
(WebCore::RenderLayerCompositor::isTrackingRepaints):
  Required since this is a GraphicsLayerClient.
* testing/Internals.cpp:
(WebCore::Internals::layerTreeAsText):
* testing/Internals.h:
* testing/Internals.idl:
  The internals changes plumb the new flag for including the repaint
  rects in the layer tree dump.

Source/WebKit/chromium:

(WebKit::WebWidget::isTrackingRepaints):
  Used by the NonCompositedContentHost to determine if we are tracking
  repaint rects.
(WebKit::WebWidget::isTrackingRepaints):
* src/LinkHighlight.cpp:
(WebKit::LinkHighlight::updateGeometry):
  Now calls GraphicsLayer::addRepaintRect when invalidated.
* src/NonCompositedContentHost.cpp:
(WebKit::NonCompositedContentHost::isTrackingRepaints):
  Required as this is a GraphicsLayerClient.
* src/WebViewImpl.cpp:
(WebKit::WebViewImpl::isTrackingRepaints):
  Implementation of WebWidget::isTrackingRepaints.

LayoutTests:

* compositing/repaint/invalidations-on-composited-layers-expected.txt: Added.
* compositing/repaint/invalidations-on-composited-layers.html: Added.
* platform/mac/compositing/repaint/invalidations-on-composited-layers-expected.txt: Added.

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

31 files changed:
LayoutTests/ChangeLog
LayoutTests/compositing/repaint/invalidations-on-composited-layers-expected.txt [new file with mode: 0644]
LayoutTests/compositing/repaint/invalidations-on-composited-layers.html [new file with mode: 0644]
LayoutTests/platform/mac/compositing/repaint/invalidations-on-composited-layers-expected.txt [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/page/Frame.h
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/FrameView.h
Source/WebCore/platform/graphics/GraphicsLayer.cpp
Source/WebCore/platform/graphics/GraphicsLayer.h
Source/WebCore/platform/graphics/GraphicsLayerClient.h
Source/WebCore/platform/graphics/blackberry/GraphicsLayerBlackBerry.cpp
Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp
Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderLayerBacking.h
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebCore/rendering/RenderLayerCompositor.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/public/WebWidget.h
Source/WebKit/chromium/src/LinkHighlight.cpp
Source/WebKit/chromium/src/NonCompositedContentHost.cpp
Source/WebKit/chromium/src/NonCompositedContentHost.h
Source/WebKit/chromium/src/WebViewImpl.cpp
Source/WebKit/chromium/src/WebViewImpl.h

index 8b99d5e..78a584e 100644 (file)
@@ -1,3 +1,17 @@
+2012-11-02  Ian Vollick  <vollick@chromium.org>
+
+        Support invalidation tracking for composited layers
+        https://bugs.webkit.org/show_bug.cgi?id=97801
+
+        Reviewed by Simon Fraser.
+
+        GraphicsLayers now store invalidated rects and can include them in
+        the layer tree dump.
+
+        * compositing/repaint/invalidations-on-composited-layers-expected.txt: Added.
+        * compositing/repaint/invalidations-on-composited-layers.html: Added.
+        * platform/mac/compositing/repaint/invalidations-on-composited-layers-expected.txt: Added.
+
 2012-11-02  Adam Barth  <abarth@webkit.org>
 
         ASSERT in RenderLayer::hitTestContents can fire
diff --git a/LayoutTests/compositing/repaint/invalidations-on-composited-layers-expected.txt b/LayoutTests/compositing/repaint/invalidations-on-composited-layers-expected.txt
new file mode 100644 (file)
index 0000000..035f2a8
--- /dev/null
@@ -0,0 +1,37 @@
+(repaint rects
+  (rect 0 0 800 600)
+  (rect 0 0 800 600)
+  (rect 0 0 800 450)
+  (rect 0 0 800 600)
+  (rect 0 0 800 450)
+  (rect 0 0 800 600)
+)
+(GraphicsLayer
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (children 1
+        (GraphicsLayer
+          (position 8.00 42.00)
+          (bounds 400.00 400.00)
+          (drawsContent 1)
+          (repaint rects
+            (rect 0.00 0.00 400.00 400.00)
+          )
+          (children 1
+            (GraphicsLayer
+              (position 50.00 50.00)
+              (bounds 75.00 75.00)
+              (drawsContent 1)
+              (repaint rects
+                (rect 0.00 0.00 75.00 75.00)
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/repaint/invalidations-on-composited-layers.html b/LayoutTests/compositing/repaint/invalidations-on-composited-layers.html
new file mode 100644 (file)
index 0000000..242fbc7
--- /dev/null
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+
+<!--
+This test checks that repaint testing works with composited layers.
+-->
+
+<html>
+<head>
+  <style type="text/css">
+    #parent {
+        -webkit-transform: translateZ(0px);
+        width: 400px;
+        height: 400px;
+        background: blue;
+    }
+
+    #child {
+        -webkit-transform: translateZ(0px);
+        position: relative;
+        left: 50px;
+        top: 50px;
+        width: 75px;
+        height: 75px;
+        background: green;
+    }
+
+  </style>
+  <script type="text/javascript">
+      window.addEventListener('load', function() {
+          if (!window.testRunner) {
+              alert('This test requires testRunner to run!');
+              return;
+          }
+
+          if (!window.internals) {
+              alert('This test requires window.interals to run!');
+              return;
+          }
+
+          testRunner.dumpAsText(false);
+
+          var parent = document.getElementById('parent');
+          var child = document.getElementById('child');
+
+          window.internals.startTrackingRepaints(document);
+
+          child.style.background = 'blue';
+          parent.style.background = 'green';
+
+          var text = document.getElementById('text');
+          text.innerHTML = 'This text will be replaced with the layer tree';
+
+          // Force a style recalc.
+          var dummy = child.offsetTop;
+
+          var layerTreeText = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_REPAINT_RECTS);
+
+          window.internals.stopTrackingRepaints(document);
+
+          text.innerHTML = layerTreeText;
+      });
+  </script>
+</head>
+<body>
+  <pre id="text"></pre>
+  <div id="parent">
+    <div id="child"></div>
+  </div>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac/compositing/repaint/invalidations-on-composited-layers-expected.txt b/LayoutTests/platform/mac/compositing/repaint/invalidations-on-composited-layers-expected.txt
new file mode 100644 (file)
index 0000000..218f9de
--- /dev/null
@@ -0,0 +1,37 @@
+(repaint rects
+  (rect 0 0 800 600)
+  (rect 0 0 800 600)
+  (rect 0 0 800 449)
+  (rect 0 0 800 600)
+  (rect 0 0 800 449)
+  (rect 0 0 800 600)
+)
+(GraphicsLayer
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (children 1
+        (GraphicsLayer
+          (position 8.00 41.00)
+          (bounds 400.00 400.00)
+          (drawsContent 1)
+          (repaint rects
+            (rect 0.00 0.00 400.00 400.00)
+          )
+          (children 1
+            (GraphicsLayer
+              (position 50.00 50.00)
+              (bounds 75.00 75.00)
+              (drawsContent 1)
+              (repaint rects
+                (rect 0.00 0.00 75.00 75.00)
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
index 40af5b1..397dcd2 100644 (file)
@@ -1,3 +1,81 @@
+2012-11-02  Ian Vollick  <vollick@chromium.org>
+
+        Support invalidation tracking for composited layers
+        https://bugs.webkit.org/show_bug.cgi?id=97801
+
+        Reviewed by Simon Fraser.
+
+        GraphicsLayers now store invalidated rects and can include them in
+        the layer tree dump.
+
+        Test: compositing/repaint/invalidations-on-composited-layers.html
+
+        * WebCore.exp.in:
+          Exports FrameView::resetTrackedRepaints()
+        * page/FrameView.cpp:
+        (WebCore::FrameView::setTracksRepaints):
+          Notifies each compositor that we are starting/stopping repaints.
+        (WebCore::FrameView::resetTrackedRepaints):
+          Moved implementation to the cpp file.
+        * platform/graphics/GraphicsLayer.cpp:
+        (WebCore::GraphicsLayer::~GraphicsLayer):
+          Clears the repaint rects associated with this layer.
+        (WebCore::GraphicsLayer::resetTrackedRepaints):
+          Clears the repaint rects associated with this layer.
+          Note that the repaint rects are stored in a statically allocated
+          HashMap to avoid using space on the graphics layers.
+        (WebCore::GraphicsLayer::addRepaintRect):
+          Adds a repaint rect to list associated with this layer in the
+          hash map mentioned above.
+        (WebCore::GraphicsLayer::dumpProperties):
+          This has been modified to include the repaint rects in the dump
+          if they've been requested.
+        * platform/graphics/GraphicsLayerClient.h:
+        (WebCore::GraphicsLayerClient::isTrackingRepaints):
+          This is how graphics layers check if repaint tracking is happening.
+          Returns false by default.
+        * platform/graphics/blackberry/GraphicsLayerBlackBerry.cpp:
+        (WebCore::GraphicsLayerBlackBerry::setContentsNeedsDisplay):
+        (WebCore::GraphicsLayerBlackBerry::setNeedsDisplay):
+        (WebCore::GraphicsLayerBlackBerry::setNeedsDisplayInRect):
+          These now call GraphicsLayer::addRepaintRect as necessary.
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::setNeedsDisplayInRect):
+          Now calls GraphicsLayer::addRepaintRect as necessary.
+        * platform/graphics/chromium/GraphicsLayerChromium.cpp:
+        (WebCore::GraphicsLayerChromium::setContentsNeedsDisplay):
+        (WebCore::GraphicsLayerChromium::setNeedsDisplay):
+        (WebCore::GraphicsLayerChromium::setNeedsDisplayInRect):
+          These now call GraphicsLayer::addRepaintRect as necessary.
+        * platform/graphics/clutter/GraphicsLayerClutter.cpp:
+        (WebCore::GraphicsLayerClutter::setNeedsDisplay):
+        (WebCore::GraphicsLayerClutter::setNeedsDisplayInRect):
+          These now call GraphicsLayer::addRepaintRect as necessary.
+        * platform/graphics/texmap/GraphicsLayerTextureMapper.cpp:
+        (WebCore::GraphicsLayerTextureMapper::setNeedsDisplay):
+        (WebCore::GraphicsLayerTextureMapper::setContentsNeedsDisplay):
+        (WebCore::GraphicsLayerTextureMapper::setNeedsDisplayInRect):
+          These now call GraphicsLayer::addRepaintRect as necessary.
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::isTrackingRepaints):
+          Required since this is a GraphicsLayerClient.
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::layerTreeAsText):
+          Now accepts a flag to include the repaint rects in the layer tree
+          dump.
+        (WebCore::resetTrackedRepaintRectsRecursive):
+          Clears the repaint rects on all graphics layers.
+        (WebCore::RenderLayerCompositor::resetTrackedRepaintRects):
+          Clears the repaint rects on all graphics layers.
+        (WebCore::RenderLayerCompositor::isTrackingRepaints):
+          Required since this is a GraphicsLayerClient.
+        * testing/Internals.cpp:
+        (WebCore::Internals::layerTreeAsText):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+          The internals changes plumb the new flag for including the repaint
+          rects in the layer tree dump.
+
 2012-11-02  Adam Barth  <abarth@webkit.org>
 
         [V8] Generalize NodeWrapperMap to be able to handle other sorts of keys
index 6428968..8d59b1b 100644 (file)
@@ -272,6 +272,7 @@ __ZN7WebCore14LoaderStrategy21resourceLoadSchedulerEv
 __ZN7WebCore14PluginDocument10pluginNodeEv
 __ZNK7WebCore5Frame25trackedRepaintRectsAsTextEv
 __ZN7WebCore9FrameView17setTracksRepaintsEb
+__ZN7WebCore9FrameView20resetTrackedRepaintsEv
 __ZN7WebCore14PluginDocument12pluginWidgetEv
 __ZN7WebCore14ResourceBuffer12createNSDataEv
 __ZN7WebCore14ResourceBufferD1Ev
index a42798c..9c874ab 100644 (file)
@@ -79,7 +79,8 @@ namespace WebCore {
     enum {
         LayerTreeFlagsIncludeDebugInfo = 1 << 0,
         LayerTreeFlagsIncludeVisibleRects = 1 << 1,
-        LayerTreeFlagsIncludeTileCaches = 1 << 2
+        LayerTreeFlagsIncludeTileCaches = 1 << 2,
+        LayerTreeFlagsIncludeRepaintRects = 1 << 3
     };
     typedef unsigned LayerTreeFlags;
 
index c8f9cb2..123cd26 100644 (file)
@@ -3640,11 +3640,29 @@ void FrameView::setTracksRepaints(bool trackRepaints)
 {
     if (trackRepaints == m_isTrackingRepaints)
         return;
-    
+
+#if USE(ACCELERATED_COMPOSITING)
+    for (Frame* frame = m_frame->tree()->top(); frame; frame = frame->tree()->traverseNext()) {
+        if (RenderView* renderView = frame->contentRenderer())
+            renderView->compositor()->setTracksRepaints(trackRepaints);
+    }
+#endif
+
     resetTrackedRepaints();
     m_isTrackingRepaints = trackRepaints;
 }
 
+void FrameView::resetTrackedRepaints()
+{
+    m_trackedRepaintRects.clear();
+#if USE(ACCELERATED_COMPOSITING)
+    if (RenderView* root = rootRenderer(this)) {
+        RenderLayerCompositor* compositor = root->compositor();
+        compositor->resetTrackedRepaintRects();
+    }
+#endif
+}
+
 String FrameView::trackedRepaintRectsAsText() const
 {
     TextStream ts;
index 2f46ead..545e22b 100644 (file)
@@ -338,7 +338,7 @@ public:
     
     void setTracksRepaints(bool);
     bool isTrackingRepaints() const { return m_isTrackingRepaints; }
-    void resetTrackedRepaints() { m_trackedRepaintRects.clear(); }
+    void resetTrackedRepaints();
     const Vector<IntRect>& trackedRepaintRects() const { return m_trackedRepaintRects; }
     String trackedRepaintRectsAsText() const;
 
index c4cc085..0db2499 100644 (file)
 #include "GraphicsLayer.h"
 
 #include "FloatPoint.h"
+#include "FloatRect.h"
 #include "GraphicsContext.h"
 #include "LayoutTypesInlineMethods.h"
 #include "RotateTransformOperation.h"
 #include "TextStream.h"
+#include <wtf/HashMap.h>
 #include <wtf/text/CString.h>
 #include <wtf/text/StringBuilder.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
+typedef HashMap<const GraphicsLayer*, Vector<FloatRect> > RepaintMap;
+static RepaintMap& repaintRectMap()
+{
+    DEFINE_STATIC_LOCAL(RepaintMap, map, ());
+    return map;
+}
+
 void KeyframeValueList::insert(const AnimationValue* value)
 {
     for (size_t i = 0; i < m_values.size(); ++i) {
@@ -96,6 +105,7 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient* client)
 
 GraphicsLayer::~GraphicsLayer()
 {
+    resetTrackedRepaints();
     ASSERT(!m_parent); // willBeDestroyed should have been called already.
 }
 
@@ -536,6 +546,28 @@ double GraphicsLayer::backingStoreMemoryEstimate() const
     return static_cast<double>(4 * size().width()) * size().height();
 }
 
+void GraphicsLayer::resetTrackedRepaints()
+{
+    repaintRectMap().remove(this);
+}
+
+void GraphicsLayer::addRepaintRect(const FloatRect& repaintRect)
+{
+    if (m_client->isTrackingRepaints()) {
+        FloatRect largestRepaintRect(FloatPoint(), m_size);
+        largestRepaintRect.intersect(repaintRect);
+        RepaintMap::iterator repaintIt = repaintRectMap().find(this);
+        if (repaintIt == repaintRectMap().end()) {
+            Vector<FloatRect> repaintRects;
+            repaintRects.append(largestRepaintRect);
+            repaintRectMap().set(this, repaintRects);
+        } else {
+            Vector<FloatRect>& repaintRects = repaintIt->value;
+            repaintRects.append(largestRepaintRect);
+        }
+    }
+}
+
 void GraphicsLayer::writeIndent(TextStream& ts, int indent)
 {
     for (int i = 0; i != indent; ++i)
@@ -658,7 +690,25 @@ void GraphicsLayer::dumpProperties(TextStream& ts, int indent, LayerTreeAsTextBe
         writeIndent(ts, indent + 1);
         ts << "(replicated layer";
         if (behavior & LayerTreeAsTextDebug)
-            ts << " " << m_replicatedLayer;;
+            ts << " " << m_replicatedLayer;
+        ts << ")\n";
+    }
+
+    if (behavior & LayerTreeAsTextIncludeRepaintRects && repaintRectMap().contains(this) && !repaintRectMap().get(this).isEmpty()) {
+        writeIndent(ts, indent + 1);
+        ts << "(repaint rects\n";
+        for (size_t i = 0; i < repaintRectMap().get(this).size(); ++i) {
+            if (repaintRectMap().get(this)[i].isEmpty())
+                continue;
+            writeIndent(ts, indent + 2);
+            ts << "(rect ";
+            ts << repaintRectMap().get(this)[i].x() << " ";
+            ts << repaintRectMap().get(this)[i].y() << " ";
+            ts << repaintRectMap().get(this)[i].width() << " ";
+            ts << repaintRectMap().get(this)[i].height();
+            ts << ")\n";
+        }
+        writeIndent(ts, indent + 1);
         ts << ")\n";
     }
     
index 50893cd..e937ca5 100644 (file)
@@ -48,13 +48,15 @@ enum LayerTreeAsTextBehaviorFlags {
     LayerTreeAsTextBehaviorNormal = 0,
     LayerTreeAsTextDebug = 1 << 0, // Dump extra debugging info like layer addresses.
     LayerTreeAsTextIncludeVisibleRects = 1 << 1,
-    LayerTreeAsTextIncludeTileCaches = 1 << 2
+    LayerTreeAsTextIncludeTileCaches = 1 << 2,
+    LayerTreeAsTextIncludeRepaintRects = 1 << 3
 };
 typedef unsigned LayerTreeAsTextBehavior;
 
 namespace WebCore {
 
 class FloatPoint3D;
+class FloatRect;
 class GraphicsContext;
 class GraphicsLayerFactory;
 class Image;
@@ -404,6 +406,9 @@ public:
 
     virtual TiledBacking* tiledBacking() const { return 0; }
 
+    void resetTrackedRepaints();
+    void addRepaintRect(const FloatRect&);
+
 #if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
     // This allows several alternative GraphicsLayer implementations in the same port,
     // e.g. if a different GraphicsLayer implementation is needed in WebKit1 vs. WebKit2.
index 3e105ce..06ffb8a 100644 (file)
@@ -85,6 +85,8 @@ public:
     virtual bool showDebugBorders(const GraphicsLayer*) const = 0;
     virtual bool showRepaintCounter(const GraphicsLayer*) const = 0;
 
+    virtual bool isTrackingRepaints() const { return false; }
+
 #ifndef NDEBUG
     // RenderLayerBacking overrides this to verify that it is not
     // currently painting contents. An ASSERT fails, if it is.
index c1a703a..12fc69d 100644 (file)
@@ -379,20 +379,26 @@ void GraphicsLayerBlackBerry::setOpacity(float opacity)
 
 void GraphicsLayerBlackBerry::setContentsNeedsDisplay()
 {
-    if (m_contentsLayer)
+    if (m_contentsLayer) {
         m_contentsLayer->setNeedsDisplay();
+        addRepaintRect(contentsRect());
+    }
 }
 
 void GraphicsLayerBlackBerry::setNeedsDisplay()
 {
-    if (drawsContent())
+    if (drawsContent()) {
         m_layer->setNeedsDisplay();
+        addRepaintRect(FloatRect(FloatPoint(), m_size));
+    }
 }
 
 void GraphicsLayerBlackBerry::setNeedsDisplayInRect(const FloatRect& rect)
 {
-    if (drawsContent())
+    if (drawsContent()) {
         m_layer->setNeedsDisplayInRect(rect);
+        addRepaintRect(rect);
+    }
 }
 
 void GraphicsLayerBlackBerry::setContentsRect(const IntRect& rect)
index 244dff7..a58837c 100644 (file)
@@ -670,6 +670,8 @@ void GraphicsLayerCA::setNeedsDisplayInRect(const FloatRect& r)
         m_dirtyRects[0].unite(rect);
 
     noteLayerPropertyChanged(DirtyRectsChanged);
+
+    addRepaintRect(rect);
 }
 
 void GraphicsLayerCA::setContentsNeedsDisplay()
index dc46dc3..df335d8 100644 (file)
@@ -436,14 +436,17 @@ void GraphicsLayerChromium::setReplicatedByLayer(GraphicsLayer* layer)
 
 void GraphicsLayerChromium::setContentsNeedsDisplay()
 {
-    if (WebLayer* contentsLayer = contentsLayerIfRegistered())
+    if (WebLayer* contentsLayer = contentsLayerIfRegistered()) {
         contentsLayer->invalidate();
+        addRepaintRect(contentsRect());
+    }
 }
 
 void GraphicsLayerChromium::setNeedsDisplay()
 {
     if (drawsContent()) {
         m_layer->layer()->invalidate();
+        addRepaintRect(FloatRect(FloatPoint(), m_size));
         if (m_linkHighlight)
             m_linkHighlight->invalidate();
     }
@@ -453,6 +456,7 @@ void GraphicsLayerChromium::setNeedsDisplayInRect(const FloatRect& rect)
 {
     if (drawsContent()) {
         m_layer->layer()->invalidateRect(rect);
+        addRepaintRect(rect);
         if (m_linkHighlight)
             m_linkHighlight->invalidate();
     }
index 104b798..58bf38d 100644 (file)
@@ -67,11 +67,13 @@ ClutterActor* GraphicsLayerClutter::platformLayer() const
 void GraphicsLayerClutter::setNeedsDisplay()
 {
     notImplemented();
+    addRepaintRect(FloatRect(FloatPoint(), m_size));
 }
 
-void GraphicsLayerClutter::setNeedsDisplayInRect(const FloatRect&)
+void GraphicsLayerClutter::setNeedsDisplayInRect(const FloatRect& rect)
 {
     notImplemented();
+    addRepaintRect(rect);
 }
 
 } // namespace WebCore
index f04cf49..41897c6 100644 (file)
@@ -88,6 +88,7 @@ void GraphicsLayerTextureMapper::setNeedsDisplay()
 {
     m_needsDisplay = true;
     notifyChange(TextureMapperLayer::DisplayChange);
+    addRepaintRect(FloatRect(FloatPoint(), m_size));
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -95,6 +96,7 @@ void GraphicsLayerTextureMapper::setNeedsDisplay()
 void GraphicsLayerTextureMapper::setContentsNeedsDisplay()
 {
     notifyChange(TextureMapperLayer::DisplayChange);
+    addRepaintRect(contentsRect());
 }
 
 /* \reimp (GraphicsLayer.h)
@@ -105,6 +107,7 @@ void GraphicsLayerTextureMapper::setNeedsDisplayInRect(const FloatRect& rect)
         return;
     m_needsDisplayRect.unite(rect);
     notifyChange(TextureMapperLayer::DisplayChange);
+    addRepaintRect(rect);
 }
 
 /* \reimp (GraphicsLayer.h)
index f4766bc..556909e 100644 (file)
@@ -1596,6 +1596,12 @@ bool RenderLayerBacking::showRepaintCounter(const GraphicsLayer*) const
     return compositor() ? compositor()->compositorShowRepaintCounter() : false;
 }
 
+bool RenderLayerBacking::isTrackingRepaints() const
+{
+    GraphicsLayerClient* client = compositor();
+    return client ? client->isTrackingRepaints() : false;
+}
+
 #ifndef NDEBUG
 void RenderLayerBacking::verifyNotPainting()
 {
index 5402fc4..22fb889 100644 (file)
@@ -157,6 +157,8 @@ public:
     virtual bool showDebugBorders(const GraphicsLayer*) const OVERRIDE;
     virtual bool showRepaintCounter(const GraphicsLayer*) const OVERRIDE;
 
+    virtual bool isTrackingRepaints() const OVERRIDE;
+
 #ifndef NDEBUG
     virtual void verifyNotPainting();
 #endif
index 5b19f3e..6aa3851 100644 (file)
@@ -194,6 +194,7 @@ RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
     , m_flushingLayers(false)
     , m_shouldFlushOnReattach(false)
     , m_forceCompositingMode(false)
+    , m_isTrackingRepaints(false)
     , m_rootLayerAttachment(RootLayerUnattached)
 #if !LOG_DISABLED
     , m_rootLayerUpdateCount(0)
@@ -1149,10 +1150,22 @@ String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags)
         layerTreeBehavior |= LayerTreeAsTextIncludeVisibleRects;
     if (flags & LayerTreeFlagsIncludeTileCaches)
         layerTreeBehavior |= LayerTreeAsTextIncludeTileCaches;
+    if (flags & LayerTreeFlagsIncludeRepaintRects)
+        layerTreeBehavior |= LayerTreeAsTextIncludeRepaintRects;
 
     // We skip dumping the scroll and clip layers to keep layerTreeAsText output
     // similar between platforms.
-    return m_rootContentLayer->layerTreeAsText(layerTreeBehavior);
+    String layerTreeText = m_rootContentLayer->layerTreeAsText(layerTreeBehavior);
+
+    // The true root layer is not included in the dump, so if we want to report
+    // its repaint rects, they must be included here.
+    if (flags & LayerTreeFlagsIncludeRepaintRects) {
+        String layerTreeTextWithRootRepaintRects = m_renderView->frameView()->trackedRepaintRectsAsText();
+        layerTreeTextWithRootRepaintRects.append(layerTreeText);
+        return layerTreeTextWithRootRepaintRects;
+    }
+
+    return layerTreeText;
 }
 
 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer)
@@ -2003,6 +2016,34 @@ void RenderLayerCompositor::documentBackgroundColorDidChange()
     graphicsLayer->setBackgroundColor(backgroundColor);
 }
 
+static void resetTrackedRepaintRectsRecursive(GraphicsLayer* graphicsLayer)
+{
+    if (!graphicsLayer)
+        return;
+
+    graphicsLayer->resetTrackedRepaints();
+
+    for (size_t i = 0; i < graphicsLayer->children().size(); ++i)
+        resetTrackedRepaintRectsRecursive(graphicsLayer->children()[i]);
+
+    if (GraphicsLayer* replicaLayer = graphicsLayer->replicaLayer())
+        resetTrackedRepaintRectsRecursive(replicaLayer);
+
+    if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer())
+        resetTrackedRepaintRectsRecursive(maskLayer);
+}
+
+void RenderLayerCompositor::resetTrackedRepaintRects()
+{
+    if (GraphicsLayer* rootLayer = rootGraphicsLayer())
+        resetTrackedRepaintRectsRecursive(rootLayer);
+}
+
+void RenderLayerCompositor::setTracksRepaints(bool tracksRepaints)
+{
+    m_isTrackingRepaints = tracksRepaints;
+}
+
 bool RenderLayerCompositor::showDebugBorders(const GraphicsLayer* layer) const
 {
     if (layer == m_layerForHorizontalScrollbar || layer == m_layerForVerticalScrollbar || layer == m_layerForScrollCorner)
@@ -2019,6 +2060,11 @@ bool RenderLayerCompositor::showRepaintCounter(const GraphicsLayer* layer) const
     return false;
 }
 
+bool RenderLayerCompositor::isTrackingRepaints() const
+{
+    return m_isTrackingRepaints;
+}
+
 float RenderLayerCompositor::deviceScaleFactor() const
 {
     Page* page = this->page();
index 826df99..e58aa3a 100644 (file)
@@ -228,6 +228,9 @@ public:
 
     void documentBackgroundColorDidChange();
 
+    void resetTrackedRepaintRects();
+    void setTracksRepaints(bool);
+
 private:
     class OverlapMap;
 
@@ -238,6 +241,8 @@ private:
 
     virtual bool showDebugBorders(const GraphicsLayer*) const OVERRIDE;
     virtual bool showRepaintCounter(const GraphicsLayer*) const OVERRIDE;
+
+    virtual bool isTrackingRepaints() const OVERRIDE;
     
     // GraphicsLayerUpdaterClient implementation
     virtual void flushLayers(GraphicsLayerUpdater*) OVERRIDE;
@@ -352,6 +357,8 @@ private:
     bool m_shouldFlushOnReattach;
     bool m_forceCompositingMode;
 
+    bool m_isTrackingRepaints; // Used for testing.
+
     RootLayerAttachment m_rootLayerAttachment;
 
     // Enclosing clipping layer for iframe content
index b37b84c..35abbd4 100644 (file)
@@ -1259,6 +1259,8 @@ String Internals::layerTreeAsText(Document* document, unsigned flags, ExceptionC
         layerTreeFlags |= LayerTreeFlagsIncludeVisibleRects;
     if (flags & LAYER_TREE_INCLUDES_TILE_CACHES)
         layerTreeFlags |= LayerTreeFlagsIncludeTileCaches;
+    if (flags & LAYER_TREE_INCLUDES_REPAINT_RECTS)
+        layerTreeFlags |= LayerTreeFlagsIncludeRepaintRects;
 
     return document->frame()->layerTreeAsText(layerTreeFlags);
 }
index 6727d17..1c4c4bb 100644 (file)
@@ -190,7 +190,8 @@ public:
     enum {
         // Values need to be kept in sync with Internals.idl.
         LAYER_TREE_INCLUDES_VISIBLE_RECTS = 1,
-        LAYER_TREE_INCLUDES_TILE_CACHES = 2
+        LAYER_TREE_INCLUDES_TILE_CACHES = 2,
+        LAYER_TREE_INCLUDES_REPAINT_RECTS = 4
         
     };
     String layerTreeAsText(Document*, unsigned flags, ExceptionCode&) const;
index 0486322..5e5268b 100644 (file)
     // Flags for layerTreeAsText.
     const unsigned short LAYER_TREE_INCLUDES_VISIBLE_RECTS = 1;
     const unsigned short LAYER_TREE_INCLUDES_TILE_CACHES = 2;
+    const unsigned short LAYER_TREE_INCLUDES_REPAINT_RECTS = 4;
     DOMString layerTreeAsText(in Document document, in [Optional] unsigned short flags) raises (DOMException);
 
     DOMString scrollingStateTreeAsText(in Document document) raises (DOMException);
index ffecb27..dc44b2c 100644 (file)
@@ -1,3 +1,27 @@
+2012-11-02  Ian Vollick  <vollick@chromium.org>
+
+        Support invalidation tracking for composited layers
+        https://bugs.webkit.org/show_bug.cgi?id=97801
+
+        Reviewed by Simon Fraser.
+
+        GraphicsLayers now store invalidated rects and can include them in
+        the layer tree dump.
+
+        (WebKit::WebWidget::isTrackingRepaints):
+          Used by the NonCompositedContentHost to determine if we are tracking
+          repaint rects.
+        (WebKit::WebWidget::isTrackingRepaints):
+        * src/LinkHighlight.cpp:
+        (WebKit::LinkHighlight::updateGeometry):
+          Now calls GraphicsLayer::addRepaintRect when invalidated.
+        * src/NonCompositedContentHost.cpp:
+        (WebKit::NonCompositedContentHost::isTrackingRepaints):
+          Required as this is a GraphicsLayerClient.
+        * src/WebViewImpl.cpp:
+        (WebKit::WebViewImpl::isTrackingRepaints):
+          Implementation of WebWidget::isTrackingRepaints.
+
 2012-11-02  Stephen White  <senorblanco@chromium.org>
 
         Unreviewed.  Rolled DEPS.
index c846406..f2b3944 100644 (file)
@@ -127,6 +127,9 @@ public:
     // animate or layout in this case.
     virtual void composite(bool finish) = 0;
 
+    // Returns true if we've started tracking repaint rectangles.
+    virtual bool isTrackingRepaints() const { return false; }
+
     // Indicates that the compositing surface associated with this WebWidget is
     // ready to use.
     virtual void setCompositorSurfaceReady() = 0;
index 56ca8ab..9e35181 100644 (file)
@@ -303,6 +303,9 @@ void LinkHighlight::updateGeometry()
         // We only need to invalidate the layer if the highlight size has changed, otherwise
         // we can just re-position the layer without needing to repaint.
         m_contentLayer->layer()->invalidate();
+
+        if (m_currentGraphicsLayer)
+            m_currentGraphicsLayer->addRepaintRect(FloatRect(layer()->position().x, layer()->position().y, layer()->bounds().width, layer()->bounds().height));
     }
 }
 
index 21b9725..23dcdde 100644 (file)
@@ -201,4 +201,9 @@ bool NonCompositedContentHost::showRepaintCounter(const WebCore::GraphicsLayer*)
     return false;
 }
 
+bool NonCompositedContentHost::isTrackingRepaints() const
+{
+    return m_webView->isTrackingRepaints();
+}
+
 } // namespace WebKit
index 08e9c69..2b6ddc1 100644 (file)
@@ -73,6 +73,7 @@ private:
     virtual void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& clipRect);
     virtual bool showDebugBorders(const WebCore::GraphicsLayer*) const;
     virtual bool showRepaintCounter(const WebCore::GraphicsLayer*) const;
+    virtual bool isTrackingRepaints() const;
 
     bool haveScrollLayer();
     WebLayer* scrollLayer();
index 37b9ec1..d5f7cdd 100644 (file)
@@ -1829,6 +1829,14 @@ void WebViewImpl::paint(WebCanvas* canvas, const WebRect& rect, PaintOptions opt
     }
 }
 
+bool WebViewImpl::isTrackingRepaints() const
+{
+    if (!page())
+        return false;
+    FrameView* view = page()->mainFrame()->view();
+    return view->isTrackingRepaints();
+}
+
 void WebViewImpl::themeChanged()
 {
     if (!page())
index 354889f..1c7b214 100644 (file)
@@ -147,6 +147,7 @@ public:
     virtual void layout(); // Also implements WebLayerTreeViewClient::layout()
     virtual void enterForceCompositingMode(bool enable) OVERRIDE;
     virtual void paint(WebCanvas*, const WebRect&, PaintOptions = ReadbackFromCompositorIfAvailable);
+    virtual bool isTrackingRepaints() const OVERRIDE;
     virtual void themeChanged();
     virtual void composite(bool finish);
     virtual void setNeedsRedraw();