https://bugs.webkit.org/show_bug.cgi?id=132420
Reviewed by Sam Weinig.
Source/WebCore:
Previously, -webkit-backface-visibility:hidden unconditionally created
compositing layers with backing store. This results in high memory use
on pages with this style applied to many elements (a cargo-cult "optimization").
Fix by only having -webkit-backface-visibility:hidden create compositing layers
if some ancestor has a 3D transform. That's the only scenario in which the
element can be flipped around to reveal the back side, so the only time we need
to do compositing for this property. In future, we could be smarter, and only
consider 3D transforms in the current preserve-3d context.
Tests: compositing/backing/backface-visibility-in-3dtransformed.html
compositing/backing/backface-visibility-in-transformed.html
compositing/backing/backface-visibility.html
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::RenderLayer):
(WebCore::RenderLayer::updateLayerPositions):
(WebCore::RenderLayer::hitTestLayer):
* rendering/RenderLayer.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::requiresCompositingLayer):
(WebCore::RenderLayerCompositor::requiresOwnBackingStore):
(WebCore::RenderLayerCompositor::requiresCompositingForBackfaceVisibility):
* rendering/RenderLayerCompositor.h:
LayoutTests:
Dump layers for elements with backface-visibility: hidden with various types
of ancestors.
* compositing/backing/backface-visibility-expected.txt: Added.
* compositing/backing/backface-visibility-in-3dtransformed-expected.txt: Added.
* compositing/backing/backface-visibility-in-3dtransformed.html: Added.
* compositing/backing/backface-visibility-in-transformed-expected.txt: Added.
* compositing/backing/backface-visibility-in-transformed.html: Added.
* compositing/backing/backface-visibility.html: Added.
* inspector-protocol/layers/layers-anonymous.html: Don't use backface-visibility
for force a layer.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@168119
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2014-05-01 Simon Fraser <simon.fraser@apple.com>
+
+ Don't always make backing store for -webkit-backface-visibility:hidden
+ https://bugs.webkit.org/show_bug.cgi?id=132420
+
+ Reviewed by Sam Weinig.
+
+ Dump layers for elements with backface-visibility: hidden with various types
+ of ancestors.
+
+ * compositing/backing/backface-visibility-expected.txt: Added.
+ * compositing/backing/backface-visibility-in-3dtransformed-expected.txt: Added.
+ * compositing/backing/backface-visibility-in-3dtransformed.html: Added.
+ * compositing/backing/backface-visibility-in-transformed-expected.txt: Added.
+ * compositing/backing/backface-visibility-in-transformed.html: Added.
+ * compositing/backing/backface-visibility.html: Added.
+ * inspector-protocol/layers/layers-anonymous.html: Don't use backface-visibility
+ for force a layer.
+
2014-05-01 Brent Fulgham <bfulgham@apple.com>
Fix handling of attributes prior to compiling shader
--- /dev/null
+Should be no layers here.
+
+
--- /dev/null
+Should be several layers here.
+
+(GraphicsLayer
+ (bounds 800.00 600.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 800.00 600.00)
+ (contentsOpaque 1)
+ (children 1
+ (GraphicsLayer
+ (position 8.00 50.00)
+ (bounds 122.00 122.00)
+ (drawsContent 1)
+ (transform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 0.00] [0.00 0.00 10.00 1.00])
+ (children 1
+ (GraphicsLayer
+ (position 11.00 11.00)
+ (bounds 100.00 100.00)
+ (contentsOpaque 1)
+ (backfaceVisibility hidden)
+ )
+ )
+ )
+ )
+ )
+ )
+)
+
--- /dev/null
+<!DOCTYPE html>
+
+<html>
+<head>
+ <style>
+ .container {
+ height: 100px;
+ width: 100px;
+ padding: 10px;
+ border: 1px solid gray;
+ }
+ .box {
+ width: 100px;
+ height: 100px;
+ background-color: silver;
+ }
+
+ .transformed {
+ -webkit-transform: translateZ(10px);
+ }
+ .backface-hidden {
+ -webkit-backface-visibility: hidden;
+ }
+ </style>
+ <script>
+ if (window.testRunner)
+ testRunner.dumpAsText();
+
+ function dumpLayers()
+ {
+ var layersResult = document.getElementById('layers');
+ if (window.testRunner)
+ layersResult.innerText = window.internals.layerTreeAsText(document);
+
+ }
+ window.addEventListener('load', dumpLayers, false)
+ </script>
+</head>
+<body>
+ <p>Should be several layers here.</p>
+ <div class="transformed container">
+ <div class="backface-hidden box"></div>
+ </div>
+<pre id="layers"></pre>
+</body>
+</html>
--- /dev/null
+Should be no layers here.
+
+
--- /dev/null
+<!DOCTYPE html>
+
+<html>
+<head>
+ <style>
+ .container {
+ height: 100px;
+ width: 100px;
+ padding: 10px;
+ border: 1px solid gray;
+ }
+ .box {
+ width: 100px;
+ height: 100px;
+ background-color: silver;
+ }
+
+ .transformed {
+ -webkit-transform: translate(10px, 10px);
+ }
+ .backface-hidden {
+ -webkit-backface-visibility: hidden;
+ }
+ </style>
+ <script>
+ if (window.testRunner)
+ testRunner.dumpAsText();
+
+ function dumpLayers()
+ {
+ var layersResult = document.getElementById('layers');
+ if (window.testRunner)
+ layersResult.innerText = window.internals.layerTreeAsText(document);
+
+ }
+ window.addEventListener('load', dumpLayers, false)
+ </script>
+</head>
+<body>
+ <p>Should be no layers here.</p>
+ <div class="transformed container">
+ <div class="backface-hidden box"></div>
+ </div>
+<pre id="layers"></pre>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+
+<html>
+<head>
+ <style>
+ .box {
+ width: 100px;
+ height: 100px;
+ background-color: silver;
+ }
+
+ .backface-hidden {
+ -webkit-backface-visibility: hidden;
+ }
+ </style>
+ <script>
+ if (window.testRunner)
+ testRunner.dumpAsText();
+
+ function dumpLayers()
+ {
+ var layersResult = document.getElementById('layers');
+ if (window.testRunner)
+ layersResult.innerText = window.internals.layerTreeAsText(document);
+
+ }
+ window.addEventListener('load', dumpLayers, false)
+ </script>
+</head>
+<body>
+ <p>Should be no layers here.</p>
+ <div class="backface-hidden box"></div>
+<pre id="layers"></pre>
+</body>
+</html>
#first-letter::first-letter {
float: left;
- -webkit-backface-visibility: hidden;
+ -webkit-transform: translateZ(0);
}
</style>
+2014-05-01 Simon Fraser <simon.fraser@apple.com>
+
+ Don't always make backing store for -webkit-backface-visibility:hidden
+ https://bugs.webkit.org/show_bug.cgi?id=132420
+
+ Reviewed by Sam Weinig.
+
+ Previously, -webkit-backface-visibility:hidden unconditionally created
+ compositing layers with backing store. This results in high memory use
+ on pages with this style applied to many elements (a cargo-cult "optimization").
+
+ Fix by only having -webkit-backface-visibility:hidden create compositing layers
+ if some ancestor has a 3D transform. That's the only scenario in which the
+ element can be flipped around to reveal the back side, so the only time we need
+ to do compositing for this property. In future, we could be smarter, and only
+ consider 3D transforms in the current preserve-3d context.
+
+ Tests: compositing/backing/backface-visibility-in-3dtransformed.html
+ compositing/backing/backface-visibility-in-transformed.html
+ compositing/backing/backface-visibility.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::RenderLayer):
+ (WebCore::RenderLayer::updateLayerPositions):
+ (WebCore::RenderLayer::hitTestLayer):
+ * rendering/RenderLayer.h:
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::requiresCompositingLayer):
+ (WebCore::RenderLayerCompositor::requiresOwnBackingStore):
+ (WebCore::RenderLayerCompositor::requiresCompositingForBackfaceVisibility):
+ * rendering/RenderLayerCompositor.h:
+
2014-05-01 Alex Christensen <achristensen@webkit.org>
Finish updating ANGLE.
, m_3DTransformedDescendantStatusDirty(true)
, m_has3DTransformedDescendant(false)
, m_hasCompositingDescendant(false)
+ , m_hasTransformedAncestor(false)
+ , m_has3DTransformedAncestor(false)
, m_indirectCompositingReason(NoIndirectCompositingReason)
, m_viewportConstrainedNotCompositedReason(NoNotCompositedReason)
#if PLATFORM(IOS)
clearRepaintRects();
m_repaintStatus = NeedsNormalRepaint;
+ m_hasTransformedAncestor = flags & SeenTransformedLayer;
+ m_has3DTransformedAncestor = flags & Seen3DTransformedLayer;
// Go ahead and update the reflection's position and size.
if (m_reflection)
if (renderer().hasColumns())
flags |= UpdatePagination;
+ if (transform()) {
+ flags |= SeenTransformedLayer;
+ if (!transform()->isAffine())
+ flags |= Seen3DTransformedLayer;
+ }
+
for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
child->updateLayerPositions(geometryMap, flags);
// We computed the correct state in the caller (above code), so just reference it.
ASSERT(transformState);
localTransformState = const_cast<HitTestingTransformState*>(transformState);
- } else if (transformState || m_has3DTransformedDescendant || preserves3D()) {
+ } else if (transformState || has3DTransformedDescendant() || preserves3D()) {
// We need transform state for the first time, or to offset the container state, so create it here.
localTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState);
}
NeedsFullRepaintInBacking = 1 << 1,
IsCompositingUpdateRoot = 1 << 2,
UpdateCompositingLayers = 1 << 3,
- UpdatePagination = 1 << 4
+ UpdatePagination = 1 << 4,
+ SeenTransformedLayer = 1 << 5,
+ Seen3DTransformedLayer = 1 << 6
};
typedef unsigned UpdateLayerPositionsFlags;
static const UpdateLayerPositionsFlags defaultFlags = CheckForRepaint | IsCompositingUpdateRoot | UpdateCompositingLayers;
void updateDescendantDependentFlags(HashSet<const RenderObject*>* outOfFlowDescendantContainingBlocks = 0);
bool checkIfDescendantClippingContextNeedsUpdate(bool isClipping);
- // This flag is computed by RenderLayerCompositor, which knows more about 3d hierarchies than we do.
- void setHas3DTransformedDescendant(bool b) { m_has3DTransformedDescendant = b; }
bool has3DTransformedDescendant() const { return m_has3DTransformedDescendant; }
-
+
+ bool hasTransformedAncestor() const { return m_hasTransformedAncestor; }
+ bool has3DTransformedAncestor() const { return m_has3DTransformedAncestor; }
+
void dirty3DTransformedDescendantStatus();
// Both updates the status, and returns true if descendants of this have 3d.
bool update3DTransformedDescendantStatus();
bool m_has3DTransformedDescendant : 1; // Set on a stacking context layer that has 3D descendants anywhere
// in a preserves3D hierarchy. Hint to do 3D-aware hit testing.
bool m_hasCompositingDescendant : 1; // In the z-order tree.
+
+ bool m_hasTransformedAncestor : 1;
+ bool m_has3DTransformedAncestor : 1;
+
unsigned m_indirectCompositingReason : 3;
unsigned m_viewportConstrainedNotCompositedReason : 2;
|| requiresCompositingForCanvas(*renderer)
|| requiresCompositingForPlugin(*renderer)
|| requiresCompositingForFrame(*renderer)
- || (canRender3DTransforms() && renderer->style().backfaceVisibility() == BackfaceVisibilityHidden)
+ || requiresCompositingForBackfaceVisibility(*renderer)
|| clipsCompositingDescendants(*renderer->layer())
|| requiresCompositingForAnimation(*renderer)
|| requiresCompositingForFilters(*renderer)
|| requiresCompositingForCanvas(renderer)
|| requiresCompositingForPlugin(renderer)
|| requiresCompositingForFrame(renderer)
- || (canRender3DTransforms() && renderer.style().backfaceVisibility() == BackfaceVisibilityHidden)
+ || requiresCompositingForBackfaceVisibility(renderer)
|| requiresCompositingForAnimation(renderer)
|| requiresCompositingForFilters(renderer)
|| requiresCompositingForPosition(renderer, layer)
return renderer.hasTransform() && renderer.style().transform().has3DOperation();
}
+bool RenderLayerCompositor::requiresCompositingForBackfaceVisibility(RenderLayerModelObject& renderer) const
+{
+ if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
+ return false;
+
+ return renderer.style().backfaceVisibility() == BackfaceVisibilityHidden && renderer.layer()->has3DTransformedAncestor();
+}
+
bool RenderLayerCompositor::requiresCompositingForVideo(RenderLayerModelObject& renderer) const
{
if (!(m_compositingTriggers & ChromeClient::VideoTrigger))
// Whether a running transition or animation enforces the need for a compositing layer.
bool requiresCompositingForAnimation(RenderLayerModelObject&) const;
bool requiresCompositingForTransform(RenderLayerModelObject&) const;
+ bool requiresCompositingForBackfaceVisibility(RenderLayerModelObject&) const;
bool requiresCompositingForVideo(RenderLayerModelObject&) const;
bool requiresCompositingForCanvas(RenderLayerModelObject&) const;
bool requiresCompositingForPlugin(RenderLayerModelObject&) const;
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
- BlueprintIdentifier = "1AD7451818D0D26C006F3A1E"
- BuildableName = "WebKit.framework"
- BlueprintName = "WebKit"
+ BlueprintIdentifier = "9398100A0824BF01008DF038"
+ BuildableName = "WebKitLegacy.framework"
+ BlueprintName = "WebKitLegacy"
ReferencedContainer = "container:Source/WebKit/WebKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
- BlueprintIdentifier = "1AD7451818D0D26C006F3A1E"
- BuildableName = "WebKit.framework"
- BlueprintName = "WebKit"
+ BlueprintIdentifier = "9398100A0824BF01008DF038"
+ BuildableName = "WebKitLegacy.framework"
+ BlueprintName = "WebKitLegacy"
ReferencedContainer = "container:Source/WebKit/WebKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>