Modified: trunk/Source/WebCore/ChangeLog (139814 => 139815)
--- trunk/Source/WebCore/ChangeLog 2013-01-16 01:48:37 UTC (rev 139814)
+++ trunk/Source/WebCore/ChangeLog 2013-01-16 02:01:39 UTC (rev 139815)
@@ -1,3 +1,53 @@
+2013-01-15 Simon Fraser <[email protected]>
+
+ Add the ability for a RenderLayerBacking to have a layer that renders backgrounds.
+ https://bugs.webkit.org/show_bug.cgi?id=106961
+
+ Reviewed by Dean Jackson.
+
+ In some cases we need a compositing layer to render its background into
+ a separate GraphicsLayer (e.g. for background-attachment: fixed in some scenarios).
+
+ To support this, have RenderLayer optionally create a GraphicsLayer for the background.
+ Currently nothing causes background layers to get created.
+
+ Having a background layer requires that we add an additional containment layer
+ which encloses the background, primary and foreground layers, since the
+ background layer has to be composited behind the primary content. This containment
+ layer gets any transform, including page scale on the RenderView's layer.
+
+ No new tests; there's no way to create a background layer yet. This was tested during
+ development by forcing a background layer.
+
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateDebugIndicators): Show borders on both new layers
+ and repaint counters on the background layer.
+ (WebCore::RenderLayerBacking::destroyGraphicsLayers): Clear the two new layers.
+ (WebCore::RenderLayerBacking::updateTransform): If we have a containment layer, it
+ takes the transform (and clear the transform on the primary layer).
+ (WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration): Make the background
+ layer if we need one (currently never).
+ (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): Position and size
+ the containment layer if we have one. If we do, then the m_graphicsLayer will
+ be at 0,0 in that containment layer. The background layer is also sized similarly
+ to the foreground layer.
+ (WebCore::RenderLayerBacking::updateInternalHierarchy): Adapt to the new hierarchy
+ with containment and background layers if we have them.
+ (WebCore::RenderLayerBacking::updateBackgroundLayer): Here's where we create the background
+ and containment layers.
+ (WebCore::RenderLayerBacking::childForSuperlayers): If we have a containment layer, that's
+ what gets attached to our parent.
+ (WebCore::RenderLayerBacking::getCurrentTransform): The containment layer gets the transform
+ if we have one, so check that here.
+ (WebCore::RenderLayerBacking::backingStoreMemoryEstimate):
+ (WebCore::RenderLayerBacking::reportMemoryUsage):
+ * rendering/RenderLayerBacking.h:
+ (RenderLayerBacking):
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::deviceOrPageScaleFactorChanged): We need to start notifying
+ about page/device scale on the containment layer if there is one (since it takes page scale), so
+ use childForSuperlayers() rather than just getting the primary layer.
+
2013-01-15 Pan Deng <[email protected]>
Remove Key3 and Challenge Response fields from Websocket implementation and Web Inspector.
Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (139814 => 139815)
--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp 2013-01-16 01:48:37 UTC (rev 139814)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp 2013-01-16 02:01:39 UTC (rev 139815)
@@ -233,6 +233,14 @@
m_foregroundLayer->setShowDebugBorder(showBorder);
m_foregroundLayer->setShowRepaintCounter(showRepaintCounter);
}
+
+ if (m_contentsContainmentLayer)
+ m_contentsContainmentLayer->setShowDebugBorder(showBorder);
+
+ if (m_backgroundLayer) {
+ m_backgroundLayer->setShowDebugBorder(showBorder);
+ m_backgroundLayer->setShowRepaintCounter(showRepaintCounter);
+ }
if (m_maskLayer) {
m_maskLayer->setShowDebugBorder(showBorder);
@@ -309,8 +317,10 @@
m_graphicsLayer->removeFromParent();
m_ancestorClippingLayer = nullptr;
+ m_contentsContainmentLayer = nullptr;
m_graphicsLayer = nullptr;
m_foregroundLayer = nullptr;
+ m_backgroundLayer = nullptr;
m_childContainmentLayer = nullptr;
m_maskLayer = nullptr;
@@ -333,7 +343,11 @@
makeMatrixRenderable(t, compositor()->canRender3DTransforms());
}
- m_graphicsLayer->setTransform(t);
+ if (m_contentsContainmentLayer) {
+ m_contentsContainmentLayer->setTransform(t);
+ m_graphicsLayer->setTransform(TransformationMatrix());
+ } else
+ m_graphicsLayer->setTransform(t);
}
#if ENABLE(CSS_FILTERS)
@@ -465,6 +479,11 @@
m_owningLayer->updateZOrderLists();
bool layerConfigChanged = false;
+
+ // FIXME: The background layer is currently unused.
+ if (updateBackgroundLayer(false))
+ layerConfigChanged = true;
+
if (updateForegroundLayer(compositor->needsContentsCompositingLayer(m_owningLayer)))
layerConfigChanged = true;
@@ -576,7 +595,9 @@
m_graphicsLayer->setContentsVisible(m_owningLayer->hasVisibleContent() || hasVisibleNonCompositingDescendantLayers());
RenderStyle* style = renderer()->style();
- m_graphicsLayer->setPreserves3D(style->transformStyle3D() == TransformStyle3DPreserve3D && !renderer()->hasReflection());
+ // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
+ bool preserves3D = style->transformStyle3D() == TransformStyle3DPreserve3D && !renderer()->hasReflection();
+ m_graphicsLayer->setPreserves3D(preserves3D);
m_graphicsLayer->setBackfaceVisibility(style->backfaceVisibility() == BackfaceVisibilityVisible);
RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer();
@@ -630,13 +651,22 @@
graphicsLayerParentLocation = parentClipRect.location();
}
+ FloatSize contentsSize = relativeCompositingBounds.size();
+
+ if (m_contentsContainmentLayer) {
+ m_contentsContainmentLayer->setPreserves3D(preserves3D);
+ m_contentsContainmentLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation));
+ // Use the same size as m_graphicsLayer so transforms behave correctly.
+ m_contentsContainmentLayer->setSize(contentsSize);
+ graphicsLayerParentLocation = relativeCompositingBounds.location();
+ }
+
m_graphicsLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation));
m_graphicsLayer->setOffsetFromRenderer(toIntSize(localCompositingBounds.location()));
FloatSize oldSize = m_graphicsLayer->size();
- FloatSize newSize = relativeCompositingBounds.size();
- if (oldSize != newSize) {
- m_graphicsLayer->setSize(newSize);
+ if (oldSize != contentsSize) {
+ m_graphicsLayer->setSize(contentsSize);
// Usually invalidation will happen via layout etc, but if we've affected the layer
// size by constraining relative to a clipping ancestor or the viewport, we
// have to invalidate to avoid showing stretched content.
@@ -674,7 +704,10 @@
FloatPoint3D anchor(relativeCompositingBounds.width() != 0.0f ? ((layerBounds.x() - relativeCompositingBounds.x()) + transformOrigin.x()) / relativeCompositingBounds.width() : 0.5f,
relativeCompositingBounds.height() != 0.0f ? ((layerBounds.y() - relativeCompositingBounds.y()) + transformOrigin.y()) / relativeCompositingBounds.height() : 0.5f,
transformOrigin.z());
- m_graphicsLayer->setAnchorPoint(anchor);
+ if (m_contentsContainmentLayer)
+ m_contentsContainmentLayer->setAnchorPoint(anchor);
+ else
+ m_graphicsLayer->setAnchorPoint(anchor);
RenderStyle* style = renderer()->style();
GraphicsLayer* clipLayer = clippingLayer();
@@ -695,11 +728,13 @@
}
} else {
m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
+ if (m_contentsContainmentLayer)
+ m_contentsContainmentLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
}
if (m_foregroundLayer) {
FloatPoint foregroundPosition;
- FloatSize foregroundSize = newSize;
+ FloatSize foregroundSize = contentsSize;
IntSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
if (hasClippingLayer()) {
// If we have a clipping layer (which clips descendants), then the foreground layer is a child of it,
@@ -716,6 +751,17 @@
m_foregroundLayer->setOffsetFromRenderer(foregroundOffset);
}
+ if (m_backgroundLayer) {
+ FloatSize backgroundSize = contentsSize;
+ IntSize backgroundOffset = m_graphicsLayer->offsetFromRenderer();
+ m_backgroundLayer->setPosition(FloatPoint());
+ if (backgroundSize != m_backgroundLayer->size()) {
+ m_backgroundLayer->setSize(backgroundSize);
+ m_backgroundLayer->setNeedsDisplay();
+ }
+ m_backgroundLayer->setOffsetFromRenderer(backgroundOffset);
+ }
+
if (m_owningLayer->reflectionLayer() && m_owningLayer->reflectionLayer()->isComposited()) {
RenderLayerBacking* reflectionBacking = m_owningLayer->reflectionLayer()->backing();
reflectionBacking->updateGraphicsLayerGeometry();
@@ -792,12 +838,24 @@
{
// m_foregroundLayer has to be inserted in the correct order with child layers,
// so it's not inserted here.
- if (m_ancestorClippingLayer) {
+ if (m_ancestorClippingLayer)
m_ancestorClippingLayer->removeAllChildren();
- m_graphicsLayer->removeFromParent();
- m_ancestorClippingLayer->addChild(m_graphicsLayer.get());
+
+ if (m_contentsContainmentLayer) {
+ m_contentsContainmentLayer->removeAllChildren();
+ if (m_ancestorClippingLayer)
+ m_ancestorClippingLayer->addChild(m_contentsContainmentLayer.get());
}
+
+ if (m_backgroundLayer)
+ m_contentsContainmentLayer->addChild(m_graphicsLayer.get());
+ m_graphicsLayer->removeFromParent();
+ if (m_contentsContainmentLayer)
+ m_contentsContainmentLayer->addChild(m_graphicsLayer.get());
+ else if (m_ancestorClippingLayer)
+ m_ancestorClippingLayer->addChild(m_graphicsLayer.get());
+
if (m_childContainmentLayer) {
m_childContainmentLayer->removeFromParent();
m_graphicsLayer->addChild(m_childContainmentLayer.get());
@@ -1032,6 +1090,49 @@
return layerChanged;
}
+bool RenderLayerBacking::updateBackgroundLayer(bool needsBackgroundLayer)
+{
+ bool layerChanged = false;
+ if (needsBackgroundLayer) {
+ if (!m_backgroundLayer) {
+ String layerName;
+#ifndef NDEBUG
+ layerName = m_owningLayer->name() + " (background)";
+#endif
+ m_backgroundLayer = createGraphicsLayer(layerName);
+ m_backgroundLayer->setDrawsContent(true);
+ m_backgroundLayer->setAnchorPoint(FloatPoint3D());
+ m_backgroundLayer->setPaintingPhase(GraphicsLayerPaintBackground);
+ layerChanged = true;
+ }
+
+ if (!m_contentsContainmentLayer) {
+ String layerName;
+#ifndef NDEBUG
+ layerName = m_owningLayer->name() + " (contents containment)";
+#endif
+ m_contentsContainmentLayer = createGraphicsLayer(layerName);
+ m_contentsContainmentLayer->setAppliesPageScale(true);
+ m_graphicsLayer->setAppliesPageScale(false);
+ layerChanged = true;
+ }
+ } else {
+ if (m_backgroundLayer) {
+ m_backgroundLayer->removeFromParent();
+ m_backgroundLayer = nullptr;
+ layerChanged = true;
+ }
+ if (m_contentsContainmentLayer) {
+ m_contentsContainmentLayer->removeFromParent();
+ m_contentsContainmentLayer = nullptr;
+ layerChanged = true;
+ m_graphicsLayer->setAppliesPageScale(true);
+ }
+ }
+
+ return layerChanged;
+}
+
bool RenderLayerBacking::updateMaskLayer(bool needsMaskLayer)
{
bool layerChanged = false;
@@ -1548,6 +1649,17 @@
return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
}
+GraphicsLayer* RenderLayerBacking::childForSuperlayers() const
+{
+ if (m_ancestorClippingLayer)
+ return m_ancestorClippingLayer.get();
+
+ if (m_contentsContainmentLayer)
+ return m_contentsContainmentLayer.get();
+
+ return m_graphicsLayer.get();
+}
+
bool RenderLayerBacking::paintsIntoWindow() const
{
if (m_usingTiledCacheLayer)
@@ -1738,7 +1850,8 @@
bool RenderLayerBacking::getCurrentTransform(const GraphicsLayer* graphicsLayer, TransformationMatrix& transform) const
{
- if (graphicsLayer != m_graphicsLayer)
+ GraphicsLayer* transformedLayer = m_contentsContainmentLayer.get() ? m_contentsContainmentLayer.get() : m_graphicsLayer.get();
+ if (graphicsLayer != transformedLayer)
return false;
if (m_owningLayer->hasTransform()) {
@@ -2013,7 +2126,7 @@
{
double backingMemory;
- // m_ancestorClippingLayer and m_childContainmentLayer are just used for masking or containment, so have no backing.
+ // m_ancestorClippingLayer, m_contentsContainmentLayer and m_childContainmentLayer are just used for masking or containment, so have no backing.
backingMemory = m_graphicsLayer->backingStoreMemoryEstimate();
if (m_foregroundLayer)
backingMemory += m_foregroundLayer->backingStoreMemoryEstimate();
@@ -2054,6 +2167,7 @@
MemoryClassInfo info(memoryObjectInfo, this, PlatformMemoryTypes::Rendering);
info.addWeakPointer(m_owningLayer);
info.addMember(m_ancestorClippingLayer);
+ info.addMember(m_contentsContainmentLayer);
info.addMember(m_graphicsLayer);
info.addMember(m_foregroundLayer);
info.addMember(m_childContainmentLayer);
Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.h (139814 => 139815)
--- trunk/Source/WebCore/rendering/RenderLayerBacking.h 2013-01-16 01:48:37 UTC (rev 139814)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.h 2013-01-16 02:01:39 UTC (rev 139815)
@@ -101,7 +101,7 @@
bool hasMaskLayer() const { return m_maskLayer != 0; }
GraphicsLayer* parentForSublayers() const;
- GraphicsLayer* childForSuperlayers() const { return m_ancestorClippingLayer ? m_ancestorClippingLayer.get() : m_graphicsLayer.get(); }
+ GraphicsLayer* childForSuperlayers() const;
// RenderLayers with backing normally short-circuit paintLayer() because
// their content is rendered via callbacks from GraphicsLayer. However, the document
@@ -204,6 +204,7 @@
bool updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip);
bool updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer);
bool updateForegroundLayer(bool needsForegroundLayer);
+ bool updateBackgroundLayer(bool needsBackgroundLayer);
bool updateMaskLayer(bool needsMaskLayer);
bool requiresHorizontalScrollbarLayer() const;
bool requiresVerticalScrollbarLayer() const;
@@ -264,8 +265,10 @@
RenderLayer* m_owningLayer;
OwnPtr<GraphicsLayer> m_ancestorClippingLayer; // Only used if we are clipped by an ancestor which is not a stacking context.
+ OwnPtr<GraphicsLayer> m_contentsContainmentLayer; // Only used if we have a background layer; takes the transform.
OwnPtr<GraphicsLayer> m_graphicsLayer;
OwnPtr<GraphicsLayer> m_foregroundLayer; // Only used in cases where we need to draw the foreground separately.
+ OwnPtr<GraphicsLayer> m_backgroundLayer; // Only used in cases where we need to draw the background separately.
OwnPtr<GraphicsLayer> m_childContainmentLayer; // 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.
Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (139814 => 139815)
--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2013-01-16 01:48:37 UTC (rev 139814)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2013-01-16 02:01:39 UTC (rev 139815)
@@ -2626,7 +2626,7 @@
if (!viewLayer->isComposited())
return;
- if (GraphicsLayer* rootLayer = viewLayer->backing()->graphicsLayer())
+ if (GraphicsLayer* rootLayer = viewLayer->backing()->childForSuperlayers())
rootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
}