Title: [179771] trunk
Revision
179771
Author
[email protected]
Date
2015-02-06 17:11:07 -0800 (Fri, 06 Feb 2015)

Log Message

Convert the compositing overlap map to use LayoutRects
https://bugs.webkit.org/show_bug.cgi?id=141346
Source/WebCore:

rdar://problem/18206365

Reviewed by Zalan Bujtas.

If two compositing layers were adjoining but not overlapping, but happened to
have non-integral offsets, then using enclosing IntRects in the overlap map
would cause us to think they are overlapping, and create unnecessary backing store.

Fix by converting the overlap map to use LayoutRects.

Test: compositing/layer-creation/subpixel-adjacent-layers-overlap.html

* rendering/RenderLayerCompositor.cpp:
(WebCore::OverlapMapContainer::add):
(WebCore::OverlapMapContainer::overlapsLayers):
(WebCore::RenderLayerCompositor::OverlapMap::add):
(WebCore::RenderLayerCompositor::OverlapMap::overlapsLayers):
(WebCore::RenderLayerCompositor::OverlapMap::RectList::append):
(WebCore::RenderLayerCompositor::OverlapMap::RectList::intersects):
(WebCore::RenderLayerCompositor::logLayerInfo):
(WebCore::RenderLayerCompositor::addToOverlapMap):
(WebCore::RenderLayerCompositor::addToOverlapMapRecursive):
(WebCore::RenderLayerCompositor::computeCompositingRequirements):
* rendering/RenderLayerCompositor.h:

LayoutTests:

Reviewed by Zalan Bujtas.

Test with adjacent layers on non-pixel boundaries.

* compositing/layer-creation/subpixel-adjacent-layers-overlap-expected.txt: Added.
* compositing/layer-creation/subpixel-adjacent-layers-overlap.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (179770 => 179771)


--- trunk/LayoutTests/ChangeLog	2015-02-07 01:08:52 UTC (rev 179770)
+++ trunk/LayoutTests/ChangeLog	2015-02-07 01:11:07 UTC (rev 179771)
@@ -1,3 +1,15 @@
+2015-02-06  Simon Fraser  <[email protected]>
+
+        Convert the compositing overlap map to use LayoutRects
+        https://bugs.webkit.org/show_bug.cgi?id=141346
+
+        Reviewed by Zalan Bujtas.
+        
+        Test with adjacent layers on non-pixel boundaries.
+
+        * compositing/layer-creation/subpixel-adjacent-layers-overlap-expected.txt: Added.
+        * compositing/layer-creation/subpixel-adjacent-layers-overlap.html: Added.
+
 2015-02-06  Bartlomiej Gajda  <[email protected]>
 
         [MSE] Implement Append Error algorithm.

Added: trunk/LayoutTests/compositing/layer-creation/subpixel-adjacent-layers-overlap-expected.txt (0 => 179771)


--- trunk/LayoutTests/compositing/layer-creation/subpixel-adjacent-layers-overlap-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/subpixel-adjacent-layers-overlap-expected.txt	2015-02-07 01:11:07 UTC (rev 179771)
@@ -0,0 +1,20 @@
+Here is some text
+
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 0.00 44.00)
+          (anchor 0.50 0.50)
+          (bounds 200.00 201.00)
+        )
+      )
+    )
+  )
+)
+

Added: trunk/LayoutTests/compositing/layer-creation/subpixel-adjacent-layers-overlap.html (0 => 179771)


--- trunk/LayoutTests/compositing/layer-creation/subpixel-adjacent-layers-overlap.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/subpixel-adjacent-layers-overlap.html	2015-02-07 01:11:07 UTC (rev 179771)
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        body {
+            margin: 0;
+        }
+        .box {
+            height: 200px;
+            width: 200px;
+            background-color: silver;
+            position: relative;
+        }
+        .composited {
+            -webkit-transform: translateZ(0);
+        }
+        
+        p {
+            height: 12.345px; /* Subpixel height */
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        function runTest()
+        {
+            if (window.testRunner)
+              document.getElementById('layers').innerText = window.internals.layerTreeAsText(document);
+        }
+        window.addEventListener('load', runTest, false);
+    </script>
+</head>
+<body>
+<p>Here is some text</p>
+<div class="composited box">
+</div>
+<div class="box">
+</div>
+<pre id="layers"></pre>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (179770 => 179771)


--- trunk/Source/WebCore/ChangeLog	2015-02-07 01:08:52 UTC (rev 179770)
+++ trunk/Source/WebCore/ChangeLog	2015-02-07 01:11:07 UTC (rev 179771)
@@ -1,3 +1,32 @@
+2015-02-06  Simon Fraser  <[email protected]>
+
+        Convert the compositing overlap map to use LayoutRects
+        https://bugs.webkit.org/show_bug.cgi?id=141346
+        rdar://problem/18206365
+
+        Reviewed by Zalan Bujtas.
+        
+        If two compositing layers were adjoining but not overlapping, but happened to
+        have non-integral offsets, then using enclosing IntRects in the overlap map
+        would cause us to think they are overlapping, and create unnecessary backing store.
+        
+        Fix by converting the overlap map to use LayoutRects.
+
+        Test: compositing/layer-creation/subpixel-adjacent-layers-overlap.html
+
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::OverlapMapContainer::add):
+        (WebCore::OverlapMapContainer::overlapsLayers):
+        (WebCore::RenderLayerCompositor::OverlapMap::add):
+        (WebCore::RenderLayerCompositor::OverlapMap::overlapsLayers):
+        (WebCore::RenderLayerCompositor::OverlapMap::RectList::append):
+        (WebCore::RenderLayerCompositor::OverlapMap::RectList::intersects):
+        (WebCore::RenderLayerCompositor::logLayerInfo):
+        (WebCore::RenderLayerCompositor::addToOverlapMap):
+        (WebCore::RenderLayerCompositor::addToOverlapMapRecursive):
+        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
+        * rendering/RenderLayerCompositor.h:
+
 2015-02-06  Andreas Kling  <[email protected]>
 
         Ref-ify various getters that return HTMLCollection.

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (179770 => 179771)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2015-02-07 01:08:52 UTC (rev 179770)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2015-02-07 01:11:07 UTC (rev 179771)
@@ -68,8 +68,6 @@
 
 #if PLATFORM(IOS)
 #include "LegacyTileCache.h"
-#include "MainFrame.h"
-#include "Region.h"
 #include "RenderScrollbar.h"
 #endif
 
@@ -104,13 +102,13 @@
 
 class OverlapMapContainer {
 public:
-    void add(const IntRect& bounds)
+    void add(const LayoutRect& bounds)
     {
         m_layerRects.append(bounds);
         m_boundingBox.unite(bounds);
     }
 
-    bool overlapsLayers(const IntRect& bounds) const
+    bool overlapsLayers(const LayoutRect& bounds) const
     {
         // Checking with the bounding box will quickly reject cases when
         // layers are created for lists of items going in one direction and
@@ -130,8 +128,8 @@
         m_boundingBox.unite(otherContainer.m_boundingBox);
     }
 private:
-    Vector<IntRect> m_layerRects;
-    IntRect m_boundingBox;
+    Vector<LayoutRect> m_layerRects;
+    LayoutRect m_boundingBox;
 };
 
 class RenderLayerCompositor::OverlapMap {
@@ -146,7 +144,7 @@
         pushCompositingContainer();
     }
 
-    void add(const RenderLayer* layer, const IntRect& bounds)
+    void add(const RenderLayer* layer, const LayoutRect& bounds)
     {
         // Layers do not contribute to overlap immediately--instead, they will
         // contribute to overlap as soon as their composited ancestor has been
@@ -161,7 +159,7 @@
         return m_layers.contains(layer);
     }
 
-    bool overlapsLayers(const IntRect& bounds) const
+    bool overlapsLayers(const LayoutRect& bounds) const
     {
         return m_overlapStack.last().overlapsLayers(bounds);
     }
@@ -186,10 +184,10 @@
 
 private:
     struct RectList {
-        Vector<IntRect> rects;
-        IntRect boundingRect;
+        Vector<LayoutRect> rects;
+        LayoutRect boundingRect;
         
-        void append(const IntRect& rect)
+        void append(const LayoutRect& rect)
         {
             rects.append(rect);
             boundingRect.unite(rect);
@@ -201,7 +199,7 @@
             boundingRect.unite(rectList.boundingRect);
         }
         
-        bool intersects(const IntRect& rect) const
+        bool intersects(const LayoutRect& rect) const
         {
             if (!rects.size() || !boundingRect.intersects(rect))
                 return false;
@@ -827,9 +825,12 @@
         m_secondaryBackingStoreBytes += backing->backingStoreMemoryEstimate();
     }
 
+    LayoutRect absoluteBounds = backing->compositedBounds();
+    absoluteBounds.move(layer.offsetFromAncestor(m_renderView.layer()));
+    
     StringBuilder logString;
-    logString.append(String::format("%*p %dx%d %.2fKB", 12 + depth * 2, &layer,
-        backing->compositedBounds().width().round(), backing->compositedBounds().height().round(),
+    logString.append(String::format("%*p (%.6f,%.6f-%.6f,%.6f) %.2fKB", 12 + depth * 2, &layer,
+        absoluteBounds.x().toFloat(), absoluteBounds.y().toFloat(), absoluteBounds.maxX().toFloat(), absoluteBounds.maxY().toFloat(),
         backing->backingStoreMemoryEstimate() / 1024));
     
     logString.append(" (");
@@ -1105,7 +1106,7 @@
     return nullptr;
 }
 
-void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer& layer, IntRect& layerBounds, bool& boundsComputed)
+void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer& layer, LayoutRect& layerBounds, bool& boundsComputed)
 {
     if (layer.isRootLayer())
         return;
@@ -1113,14 +1114,14 @@
     if (!boundsComputed) {
         // FIXME: If this layer's overlap bounds include its children, we don't need to add its
         // children's bounds to the overlap map.
-        layerBounds = enclosingIntRect(overlapMap.geometryMap().absoluteRect(layer.overlapBounds()));
+        layerBounds = enclosingLayoutRect(overlapMap.geometryMap().absoluteRect(layer.overlapBounds()));
         // Empty rects never intersect, but we need them to for the purposes of overlap testing.
         if (layerBounds.isEmpty())
-            layerBounds.setSize(IntSize(1, 1));
+            layerBounds.setSize(LayoutSize(1, 1));
         boundsComputed = true;
     }
 
-    IntRect clipRect = snappedIntRect(layer.backgroundClipRect(RenderLayer::ClipRectsContext(&rootRenderLayer(), AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions.
+    LayoutRect clipRect = layer.backgroundClipRect(RenderLayer::ClipRectsContext(&rootRenderLayer(), AbsoluteClipRects)).rect(); // FIXME: Incorrect for CSS regions.
 
     // On iOS, pageScaleFactor() is not applied by RenderView, so we should not scale here.
     // FIXME: Set Settings::delegatesPageScaling to true for iOS.
@@ -1142,7 +1143,7 @@
     if (ancestorLayer)
         overlapMap.geometryMap().pushMappingsToAncestor(&layer, ancestorLayer);
     
-    IntRect bounds;
+    LayoutRect bounds;
     bool haveComputedBounds = false;
     addToOverlapMap(overlapMap, layer, bounds, haveComputedBounds);
 
@@ -1227,16 +1228,16 @@
 
     RenderLayer::IndirectCompositingReason compositingReason = compositingState.m_subtreeIsCompositing ? RenderLayer::IndirectCompositingReason::Stacking : RenderLayer::IndirectCompositingReason::None;
     bool haveComputedBounds = false;
-    IntRect absBounds;
+    LayoutRect absBounds;
 
     // If we know for sure the layer is going to be composited, don't bother looking it up in the overlap map
     if (!willBeComposited && !overlapMap.isEmpty() && compositingState.m_testingOverlap) {
         // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
-        absBounds = enclosingIntRect(overlapMap.geometryMap().absoluteRect(layer.overlapBounds()));
+        absBounds = enclosingLayoutRect(overlapMap.geometryMap().absoluteRect(layer.overlapBounds()));
 
         // Empty rects never intersect, but we need them to for the purposes of overlap testing.
         if (absBounds.isEmpty())
-            absBounds.setSize(IntSize(1, 1));
+            absBounds.setSize(LayoutSize(1, 1));
         haveComputedBounds = true;
         compositingReason = overlapMap.overlapsLayers(absBounds) ? RenderLayer::IndirectCompositingReason::Overlap : RenderLayer::IndirectCompositingReason::None;
     }

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.h (179770 => 179771)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2015-02-07 01:08:52 UTC (rev 179770)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2015-02-07 01:11:07 UTC (rev 179771)
@@ -333,7 +333,7 @@
     // Repaint this and its child layers.
     void recursiveRepaintLayer(RenderLayer&);
 
-    void addToOverlapMap(OverlapMap&, RenderLayer&, IntRect& layerBounds, bool& boundsComputed);
+    void addToOverlapMap(OverlapMap&, RenderLayer&, LayoutRect& layerBounds, bool& boundsComputed);
     void addToOverlapMapRecursive(OverlapMap&, RenderLayer&, RenderLayer* ancestorLayer = nullptr);
 
     void updateCompositingLayersTimerFired();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to