Diff
Modified: branches/safari-536.26-branch/LayoutTests/ChangeLog (124131 => 124132)
--- branches/safari-536.26-branch/LayoutTests/ChangeLog 2012-07-31 01:02:13 UTC (rev 124131)
+++ branches/safari-536.26-branch/LayoutTests/ChangeLog 2012-07-31 01:02:59 UTC (rev 124132)
@@ -1,5 +1,21 @@
2012-07-30 Lucas Forschler <[email protected]>
+ Merge 122152
+
+ 2012-07-09 Dean Jackson <[email protected]>
+
+ Tiled drawing means some elements can disappear behind the page
+ https://bugs.webkit.org/show_bug.cgi?id=88906
+
+ Reviewed by Simon Fraser.
+
+ Reftest to make sure elements can't disappear behind the tile cache.
+
+ * compositing/tile-cache-must-flatten-expected.html: Added.
+ * compositing/tile-cache-must-flatten.html: Added.
+
+2012-07-30 Lucas Forschler <[email protected]>
+
Merge 122082
2012-07-05 MORITA Hajime <[email protected]>
Modified: branches/safari-536.26-branch/Source/WebCore/ChangeLog (124131 => 124132)
--- branches/safari-536.26-branch/Source/WebCore/ChangeLog 2012-07-31 01:02:13 UTC (rev 124131)
+++ branches/safari-536.26-branch/Source/WebCore/ChangeLog 2012-07-31 01:02:59 UTC (rev 124132)
@@ -1,5 +1,67 @@
2012-07-30 Lucas Forschler <[email protected]>
+ Merge 122152
+
+ 2012-07-09 Dean Jackson <[email protected]>
+
+ Tiled drawing means some elements can disappear behind the page
+ https://bugs.webkit.org/show_bug.cgi?id=88906
+
+ Reviewed by Simon Fraser.
+
+ The compositing layers in the tile cache could become siblings
+ of the compositing layers for page elements. This meant that in
+ some 3d transforms, the elements could disappear behind the
+ page background (which is rendered into the tile cache) or intersect
+ with the tile cache tiles.
+
+ Fix this by inserting a flattening layer between the tile cache
+ and the page, ensuring that the cache will always be rendered
+ first. I was able to reuse the clipping layer for this, because
+ the tile cache is attached to the RenderView, so there should never
+ be a case where we have both a clipping layer and tiles.
+
+ The unfortunate part of this code is the temporary state variable
+ that wraps the call to GraphicsLayer::create. Because that method
+ calls back into the object, we need to make sure we don't create
+ another tile cache.
+
+ Also added some obvious names to the tile cache layers to
+ help with debugging.
+
+ Test: compositing/tile-cache-must-flatten.html
+
+ * platform/graphics/ca/mac/TileCache.mm:
+ (WebCore::TileCache::TileCache): give the tile host layer a name.
+ (WebCore::TileCache::createTileLayer):
+ * platform/graphics/ca/mac/WebTileCacheLayer.mm:
+ (WebCore): give each tile layer a name.
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore):
+ (WebCore::RenderLayerBacking::shouldUseTileCache): check if we're in the middle
+ of creating the primary graphics layer before answering.
+ (WebCore::RenderLayerBacking::createPrimaryGraphicsLayer): wrap our call to
+ createGraphicsLayer with a message to indicate we are making the layer that should
+ get a tile cache.
+ (WebCore::RenderLayerBacking::destroyGraphicsLayers):
+ (WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration): needs to make
+ sure the flattening layer is in the tree.
+ (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
+ (WebCore::RenderLayerBacking::updateInternalHierarchy):
+ (WebCore::RenderLayerBacking::updateClippingLayers):
+ (WebCore::RenderLayerBacking::backingStoreMemoryEstimate):
+ * rendering/RenderLayerBacking.h: rename m_clippingLayer to m_containmentLayer
+ because it can now either be the clip or the tile cache flattener. Also
+ a new state property used when creating the main graphics layer.
+ (WebCore::RenderLayerBacking::hasClippingLayer):
+ (WebCore::RenderLayerBacking::clippingLayer):
+ (WebCore::RenderLayerBacking::parentForSublayers):
+ (WebCore::RenderLayerBacking::hasTileCacheFlatteningLayer):
+ (WebCore::RenderLayerBacking::tileCacheFlatteningLayer):
+ (RenderLayerBacking):
+
+2012-07-30 Lucas Forschler <[email protected]>
+
Merge 122082
2012-07-05 MORITA Hajime <[email protected]>
Modified: branches/safari-536.26-branch/Source/WebCore/platform/graphics/ca/mac/TileCache.mm (124131 => 124132)
--- branches/safari-536.26-branch/Source/WebCore/platform/graphics/ca/mac/TileCache.mm 2012-07-31 01:02:13 UTC (rev 124131)
+++ branches/safari-536.26-branch/Source/WebCore/platform/graphics/ca/mac/TileCache.mm 2012-07-31 01:02:59 UTC (rev 124132)
@@ -64,6 +64,9 @@
[CATransaction begin];
[CATransaction setDisableActions:YES];
[m_tileCacheLayer addSublayer:m_tileContainerLayer.get()];
+#ifndef NDEBUG
+ [m_tileContainerLayer.get() setName:@"TileCache Container Layer"];
+#endif
[CATransaction commit];
}
@@ -394,6 +397,9 @@
[layer.get() setBorderWidth:m_tileDebugBorderWidth];
[layer.get() setEdgeAntialiasingMask:0];
[layer.get() setOpaque:YES];
+#ifndef NDEBUG
+ [layer.get() setName:@"Tile"];
+#endif
#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
[layer.get() setContentsScale:m_deviceScaleFactor];
Modified: branches/safari-536.26-branch/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm (124131 => 124132)
--- branches/safari-536.26-branch/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm 2012-07-31 01:02:13 UTC (rev 124131)
+++ branches/safari-536.26-branch/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm 2012-07-31 01:02:59 UTC (rev 124132)
@@ -42,7 +42,9 @@
// FIXME: The tile size should be configurable.
_tileCache = TileCache::create(self, IntSize(512, 512));
-
+#ifndef NDEBUG
+ [self setName:@"WebTileCacheLayer"];
+#endif
return self;
}
Modified: branches/safari-536.26-branch/Source/WebCore/rendering/RenderLayerBacking.cpp (124131 => 124132)
--- branches/safari-536.26-branch/Source/WebCore/rendering/RenderLayerBacking.cpp 2012-07-31 01:02:13 UTC (rev 124131)
+++ branches/safari-536.26-branch/Source/WebCore/rendering/RenderLayerBacking.cpp 2012-07-31 01:02:59 UTC (rev 124132)
@@ -87,6 +87,8 @@
return false;
}
+bool RenderLayerBacking::m_creatingPrimaryGraphicsLayer = false;
+
RenderLayerBacking::RenderLayerBacking(RenderLayer* layer)
: m_owningLayer(layer)
, m_artificiallyInflatedBounds(false)
@@ -150,7 +152,7 @@
bool RenderLayerBacking::shouldUseTileCache(const GraphicsLayer*) const
{
- return m_usingTiledCacheLayer;
+ return m_usingTiledCacheLayer && m_creatingPrimaryGraphicsLayer;
}
void RenderLayerBacking::createPrimaryGraphicsLayer()
@@ -159,8 +161,19 @@
#ifndef NDEBUG
layerName = nameForLayer();
#endif
+
+ // The call to createGraphicsLayer ends calling back into here as
+ // a GraphicsLayerClient to ask if it shouldUseTileCache(). We only want
+ // the tile cache on our main layer. This is pretty ugly, but saves us from
+ // exposing the API to all clients.
+
+ m_creatingPrimaryGraphicsLayer = true;
m_graphicsLayer = createGraphicsLayer(layerName);
+ m_creatingPrimaryGraphicsLayer = false;
+ if (m_usingTiledCacheLayer)
+ m_containmentLayer = createGraphicsLayer("TileCache Flattening Layer");
+
if (m_isMainFrameRenderViewLayer) {
m_graphicsLayer->setContentsOpaque(true);
m_graphicsLayer->setAppliesPageScale();
@@ -188,7 +201,7 @@
m_graphicsLayer = nullptr;
m_foregroundLayer = nullptr;
- m_clippingLayer = nullptr;
+ m_containmentLayer = nullptr;
m_maskLayer = nullptr;
}
@@ -335,6 +348,11 @@
if (layerConfigChanged)
updateInternalHierarchy();
+ if (GraphicsLayer* flatteningLayer = tileCacheFlatteningLayer()) {
+ flatteningLayer->removeFromParent();
+ m_graphicsLayer->addChild(flatteningLayer);
+ }
+
if (updateMaskLayer(renderer->hasMask()))
m_graphicsLayer->setMaskLayer(m_maskLayer.get());
@@ -487,11 +505,11 @@
// If we have a layer that clips children, position it.
IntRect clippingBox;
- if (m_clippingLayer) {
+ if (GraphicsLayer* clipLayer = clippingLayer()) {
clippingBox = clipBox(toRenderBox(renderer()));
- m_clippingLayer->setPosition(FloatPoint() + (clippingBox.location() - localCompositingBounds.location()));
- m_clippingLayer->setSize(clippingBox.size());
- m_clippingLayer->setOffsetFromRenderer(clippingBox.location() - IntPoint());
+ clipLayer->setPosition(FloatPoint() + (clippingBox.location() - localCompositingBounds.location()));
+ clipLayer->setSize(clippingBox.size());
+ clipLayer->setOffsetFromRenderer(clippingBox.location() - IntPoint());
}
if (m_maskLayer) {
@@ -518,18 +536,19 @@
m_graphicsLayer->setAnchorPoint(anchor);
RenderStyle* style = renderer()->style();
+ GraphicsLayer* clipLayer = clippingLayer();
if (style->hasPerspective()) {
TransformationMatrix t = owningLayer()->perspectiveTransform();
- if (m_clippingLayer) {
- m_clippingLayer->setChildrenTransform(t);
+ if (clipLayer) {
+ clipLayer->setChildrenTransform(t);
m_graphicsLayer->setChildrenTransform(TransformationMatrix());
}
else
m_graphicsLayer->setChildrenTransform(t);
} else {
- if (m_clippingLayer)
- m_clippingLayer->setChildrenTransform(TransformationMatrix());
+ if (clipLayer)
+ clipLayer->setChildrenTransform(TransformationMatrix());
else
m_graphicsLayer->setChildrenTransform(TransformationMatrix());
}
@@ -541,7 +560,7 @@
FloatPoint foregroundPosition;
FloatSize foregroundSize = newSize;
IntSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
- if (m_clippingLayer) {
+ if (hasClippingLayer()) {
// If we have a clipping layer (which clips descendants), then the foreground layer is a child of it,
// so that it gets correctly sorted with children. In that case, position relative to the clipping layer.
foregroundSize = FloatSize(clippingBox.size());
@@ -579,9 +598,9 @@
m_ancestorClippingLayer->addChild(m_graphicsLayer.get());
}
- if (m_clippingLayer) {
- m_clippingLayer->removeFromParent();
- m_graphicsLayer->addChild(m_clippingLayer.get());
+ if (m_containmentLayer) {
+ m_containmentLayer->removeFromParent();
+ m_graphicsLayer->addChild(m_containmentLayer.get());
// The clip for child layers does not include space for overflow controls, so they exist as
// siblings of the clipping layer if we have one. Normal children of this layer are set as
@@ -629,14 +648,14 @@
}
if (needsDescendantClip) {
- if (!m_clippingLayer) {
- m_clippingLayer = createGraphicsLayer("Child clipping Layer");
- m_clippingLayer->setMasksToBounds(true);
+ if (!m_containmentLayer && !m_usingTiledCacheLayer) {
+ m_containmentLayer = createGraphicsLayer("Child clipping Layer");
+ m_containmentLayer->setMasksToBounds(true);
layersChanged = true;
}
- } else if (m_clippingLayer) {
- m_clippingLayer->removeFromParent();
- m_clippingLayer = nullptr;
+ } else if (hasClippingLayer()) {
+ m_containmentLayer->removeFromParent();
+ m_containmentLayer = nullptr;
layersChanged = true;
}
@@ -1516,7 +1535,7 @@
{
double backingArea;
- // m_ancestorClippingLayer and m_clippingLayer are just used for masking, so have no backing.
+ // m_ancestorClippingLayer and m_containmentLayer are just used for masking or containment, so have no backing.
backingArea = m_graphicsLayer->backingStoreArea();
if (m_foregroundLayer)
backingArea += m_foregroundLayer->backingStoreArea();
Modified: branches/safari-536.26-branch/Source/WebCore/rendering/RenderLayerBacking.h (124131 => 124132)
--- branches/safari-536.26-branch/Source/WebCore/rendering/RenderLayerBacking.h 2012-07-31 01:02:13 UTC (rev 124131)
+++ branches/safari-536.26-branch/Source/WebCore/rendering/RenderLayerBacking.h 2012-07-31 01:02:59 UTC (rev 124132)
@@ -74,8 +74,8 @@
GraphicsLayer* graphicsLayer() const { return m_graphicsLayer.get(); }
// Layer to clip children
- bool hasClippingLayer() const { return m_clippingLayer != 0; }
- GraphicsLayer* clippingLayer() const { return m_clippingLayer.get(); }
+ bool hasClippingLayer() const { return (m_containmentLayer && !m_usingTiledCacheLayer); }
+ GraphicsLayer* clippingLayer() const { return !m_usingTiledCacheLayer ? m_containmentLayer.get() : 0; }
// Layer to get clipped by ancestor
bool hasAncestorClippingLayer() const { return m_ancestorClippingLayer != 0; }
@@ -86,7 +86,7 @@
bool hasMaskLayer() const { return m_maskLayer != 0; }
- GraphicsLayer* parentForSublayers() const { return m_clippingLayer ? m_clippingLayer.get() : m_graphicsLayer.get(); }
+ GraphicsLayer* parentForSublayers() const { return m_containmentLayer ? m_containmentLayer.get() : m_graphicsLayer.get(); }
GraphicsLayer* childForSuperlayers() const { return m_ancestorClippingLayer ? m_ancestorClippingLayer.get() : m_graphicsLayer.get(); }
// RenderLayers with backing normally short-circuit paintLayer() because
@@ -214,6 +214,9 @@
bool shouldClipCompositedBounds() const;
+ bool hasTileCacheFlatteningLayer() const { return (m_containmentLayer && m_usingTiledCacheLayer); }
+ GraphicsLayer* tileCacheFlatteningLayer() const { return m_usingTiledCacheLayer ? m_containmentLayer.get() : 0; }
+
void paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*, const IntRect& paintDirtyRect, PaintBehavior, GraphicsLayerPaintingPhase, RenderObject* paintingRoot);
static CSSPropertyID graphicsLayerToCSSProperty(AnimatedPropertyID);
@@ -224,7 +227,7 @@
OwnPtr<GraphicsLayer> m_ancestorClippingLayer; // only used if we are clipped by an ancestor which is not a stacking context
OwnPtr<GraphicsLayer> m_graphicsLayer;
OwnPtr<GraphicsLayer> m_foregroundLayer; // only used in cases where we need to draw the foreground separately
- OwnPtr<GraphicsLayer> m_clippingLayer; // only used if we have clipping on a stacking context, with compositing children
+ OwnPtr<GraphicsLayer> m_containmentLayer; // Only used if we have clipping on a stacking context with compositing children, or if the layer has a tile cache.
OwnPtr<GraphicsLayer> m_maskLayer; // only used if we have a mask
OwnPtr<GraphicsLayer> m_layerForHorizontalScrollbar;
@@ -239,6 +242,8 @@
#if ENABLE(CSS_FILTERS)
bool m_canCompositeFilters;
#endif
+
+ static bool m_creatingPrimaryGraphicsLayer;
};
} // namespace WebCore