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
- trunk/LayoutTests/ChangeLog
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp
- trunk/Source/WebCore/rendering/RenderLayerCompositor.h
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
