Commit 83e19482 authored by commit-queue@webkit.org's avatar commit-queue@webkit.org
Browse files

[CSS Regions] The layers from the flow thread should be collected under the regions' layers.

https://bugs.webkit.org/show_bug.cgi?id=120457

Patch by Mihai Maerean <mmaerean@adobe.com> on 2013-10-21
Reviewed by David Hyatt.

Source/WebCore:

This patch is based on the work of Alexandru Chiculita at https://bugs.webkit.org/attachment.cgi?id=203872&action=review

The composited layers inside the named flow threads are collected as part of the regions (as children of the
GraphicsLayer of the layer that corresponds to the region (which is attached to the parent renderer of
RenderNameFlowFragment)).
When a region displays a layer that needs accelerated compositing we activate the accelerated compositing for
that region too (inside RenderLayerCompositor::computeRegionCompositingRequirements).

This patch has landed before (as http://trac.webkit.org/changeset/156451), but was reverted because
fast/multicol/mixed-positioning-stacking-order.html failed. The fix is inside RenderLayerCompositor::canBeComposited
that only enables compositing for layers inside flow threads that collect the graphics layers under the regions.

Another change from changeset #156451 is that now the region renderers are created as anonymous renderers under
the element that has the flow-from property. When a composited layer is needed for the region, it sits in it's
parent renderer, not in the region renderer (RenderNamedFlowFragment).

Tests: compositing/regions/crash-transform-inside-region.html
       compositing/regions/floated-region-with-transformed-child.html
       compositing/regions/move-layer-from-one-region-to-another.html
       compositing/regions/propagate-region-box-shadow-border-padding-for-video.html
       compositing/regions/propagate-region-box-shadow-border-padding.html
       compositing/regions/region-as-layer-in-another-flowthread.html
       compositing/regions/transform-transparent-positioned-video-inside-region.html
       compositing/regions/transformed-layer-inside-transformed-layer.html
       compositing/regions/z-index-update.html
       compositing/regions/z-index.html

* rendering/FlowThreadController.cpp:
(WebCore::FlowThreadController::updateRenderFlowThreadLayersIfNeeded):
* rendering/RenderElement.cpp:
(WebCore::RenderElement::propagateStyleToAnonymousChildren): Not for RenderFlowThreads, as they are updated
through the RenderView::styleDidChange function.
* rendering/RenderFlowThread.cpp:
(WebCore::RenderFlowThread::layout): When the layout of the flow thread is over (including the 2 phase layout),
we update all the mappings between the layers inside the flow thread and the regions where those layers will be
painted.
(WebCore::RenderFlowThread::hasCompositingRegionDescendant): Whether any of the regions has a compositing descendant.
(WebCore::RenderFlowThread::getLayerListForRegion):
(WebCore::RenderFlowThread::regionForCompositedLayer):
(WebCore::RenderFlowThread::cachedRegionForCompositedLayer):
(WebCore::RenderFlowThread::collectsGraphicsLayersUnderRegions):
(WebCore::RenderFlowThread::updateLayerToRegionMappings): Triggers an update of the layers if a layer has moved
from a region to another since the last update.
(WebCore::RenderFlowThread::updateAllLayerToRegionMappings):
* rendering/RenderFlowThread.h:
* rendering/RenderGeometryMap.cpp:
(WebCore::RenderGeometryMap::pushRenderFlowThread):
* rendering/RenderGeometryMap.h:
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintList):
(WebCore::RenderLayer::enclosingFlowThreadAncestor):
(WebCore::RenderLayer::isFlowThreadCollectingGraphicsLayersUnderRegions):
(WebCore::RenderLayer::hitTestList):
(WebCore::RenderLayer::calculateLayerBounds): When we calculate the bounds of the RenderView, we ignore those
flow threads that collect the graphics layers under the regions.
(WebCore::RenderLayer::dirtyZOrderLists):
(WebCore::RenderLayer::dirtyNormalFlowList):
* rendering/RenderLayer.h:
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::shouldClipCompositedBounds): Not if it's a flow thread that collects the graphics
layers under the regions
(WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): Now adjusts the ancestorCompositingBounds for the FlowThread.
(WebCore::RenderLayerBacking::adjustAncestorCompositingBoundsForFlowThread): Make sure that the region propagates
its borders, paddings, outlines or box-shadows to layers inside it.
(WebCore::RenderLayerBacking::isSimpleContainerCompositingLayer):
* rendering/RenderLayerBacking.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::computeCompositingRequirements): Now calls computeRegionCompositingRequirements.
(WebCore::RenderLayerCompositor::computeRegionCompositingRequirements):
(WebCore::RenderLayerCompositor::rebuildCompositingLayerTree): Do not iterate the RenderFlowThread directly if
we are going to collect the composited layers as part of regions.
(WebCore::RenderLayerCompositor::rebuildRegionCompositingLayerTree):
(WebCore::RenderLayerCompositor::canBeComposited): CSS Regions flow threads do not need to be composited as we
use composited RenderRegions to render the background of the RenderFlowThread.
(WebCore::RenderLayerCompositor::requiresCompositingForIndirectReason): If it's a container of a css region.
* rendering/RenderLayerCompositor.h:
* rendering/RenderMultiColumnSet.cpp:
(WebCore::RenderMultiColumnSet::adjustRegionBoundsFromFlowThreadPortionRect):
* rendering/RenderMultiColumnSet.h:
* rendering/RenderNamedFlowFragment.h:
(WebCore::RenderNamedFlowFragment::layerOwner): When the content inside the region requires the region to have a
layer, the layer will be created on the region's parent renderer instead. This method returns that renderer
holding the layer. The return value may be null.
* rendering/RenderNamedFlowThread.cpp:
(WebCore::RenderNamedFlowThread::RenderNamedFlowThread):
(WebCore::RenderNamedFlowThread::nextRendererForNode):
(WebCore::RenderNamedFlowThread::previousRendererForNode):
(WebCore::RenderNamedFlowThread::addFlowChild):
(WebCore::RenderNamedFlowThread::removeFlowChild):
(WebCore::RenderNamedFlowThread::collectsGraphicsLayersUnderRegions):
* rendering/RenderNamedFlowThread.h: m_flowThreadChildList is now allocated through an OwnPtr to keep the render
arena under the size limit.
* rendering/RenderRegion.cpp:
(WebCore::RenderRegion::adjustRegionBoundsFromFlowThreadPortionRect):
* rendering/RenderRegion.h:
(WebCore::toRenderRegion):
* rendering/RenderTreeAsText.cpp:
(WebCore::writeLayers):
* WebCore.exp.in: WebCore::RenderLayer::isFlowThreadCollectingGraphicsLayersUnderRegions

LayoutTests:

* compositing/regions/crash-transform-inside-region-expected.html: Added.
* compositing/regions/crash-transform-inside-region.html: Added.
* compositing/regions/floated-region-with-transformed-child-expected.html: Added.
* compositing/regions/floated-region-with-transformed-child.html: Added.
* compositing/regions/move-layer-from-one-region-to-another-expected.html: Added.
* compositing/regions/move-layer-from-one-region-to-another.html: Added.
* compositing/regions/propagate-region-box-shadow-border-padding-expected.html: Added.
* compositing/regions/propagate-region-box-shadow-border-padding-for-video-expected.html: Added.
* compositing/regions/propagate-region-box-shadow-border-padding-for-video.html: Added.
* compositing/regions/propagate-region-box-shadow-border-padding.html: Added.
* compositing/regions/region-as-layer-in-another-flowthread-expected.html: Added.
* compositing/regions/region-as-layer-in-another-flowthread.html: Added.
* compositing/regions/transform-transparent-positioned-video-inside-region-expected.html: Added.
* compositing/regions/transform-transparent-positioned-video-inside-region.html: Added.
* compositing/regions/transformed-layer-inside-transformed-layer-expected.html: Added.
* compositing/regions/transformed-layer-inside-transformed-layer.html: Added.
* compositing/regions/webkit-flow-renderer-layer-compositing-expected.html:
* compositing/regions/webkit-flow-renderer-layer-compositing.html:
* compositing/regions/z-index-expected.html: Added.
* compositing/regions/z-index-update-expected.html: Added.
* compositing/regions/z-index-update.html: Added.
* compositing/regions/z-index.html: Added.
* fast/multicol/mixed-positioning-stacking-order-expected.html:
* fast/multicol/mixed-positioning-stacking-order.html:
* fast/repaint/region-painting-composited-element-expected.html:
* fast/repaint/region-painting-composited-element.html:
* platform/mac-wk2/TestExpectations:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@157725 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 72d3832f
2013-10-21 Mihai Maerean <mmaerean@adobe.com>
[CSS Regions] The layers from the flow thread should be collected under the regions' layers.
https://bugs.webkit.org/show_bug.cgi?id=120457
Reviewed by David Hyatt.
* compositing/regions/crash-transform-inside-region-expected.html: Added.
* compositing/regions/crash-transform-inside-region.html: Added.
* compositing/regions/floated-region-with-transformed-child-expected.html: Added.
* compositing/regions/floated-region-with-transformed-child.html: Added.
* compositing/regions/move-layer-from-one-region-to-another-expected.html: Added.
* compositing/regions/move-layer-from-one-region-to-another.html: Added.
* compositing/regions/propagate-region-box-shadow-border-padding-expected.html: Added.
* compositing/regions/propagate-region-box-shadow-border-padding-for-video-expected.html: Added.
* compositing/regions/propagate-region-box-shadow-border-padding-for-video.html: Added.
* compositing/regions/propagate-region-box-shadow-border-padding.html: Added.
* compositing/regions/region-as-layer-in-another-flowthread-expected.html: Added.
* compositing/regions/region-as-layer-in-another-flowthread.html: Added.
* compositing/regions/transform-transparent-positioned-video-inside-region-expected.html: Added.
* compositing/regions/transform-transparent-positioned-video-inside-region.html: Added.
* compositing/regions/transformed-layer-inside-transformed-layer-expected.html: Added.
* compositing/regions/transformed-layer-inside-transformed-layer.html: Added.
* compositing/regions/webkit-flow-renderer-layer-compositing-expected.html:
* compositing/regions/webkit-flow-renderer-layer-compositing.html:
* compositing/regions/z-index-expected.html: Added.
* compositing/regions/z-index-update-expected.html: Added.
* compositing/regions/z-index-update.html: Added.
* compositing/regions/z-index.html: Added.
* fast/multicol/mixed-positioning-stacking-order-expected.html:
* fast/multicol/mixed-positioning-stacking-order.html:
* fast/repaint/region-painting-composited-element-expected.html:
* fast/repaint/region-painting-composited-element.html:
* platform/mac-wk2/TestExpectations:
2013-10-21 Oliver Hunt <oliver@apple.com>
Support expression property names in object literals
......
<!doctype html>
<html>
<head>
<title>Bug 120457: [CSS Regions] The layers from the flow thread should be collected under the regions' layers.</title>
<style>
html {
-webkit-font-smoothing: none;
}
.transformed {
-webkit-transform:rotateX(15deg) rotateZ(15deg);
}
.content {
}
.region {
-webkit-transform:rotateZ(0deg); /*so the div is composited, just like the region*/
}
</style>
<script>
window.addEventListener( "load", function () {
var div = document.querySelector("#transformed");
for(var i = 0; i < 10; ++i ) {
div.className = "transformed content";
document.body.offsetTop;
div.className = "content";
document.body.offsetTop;
}
}, false);
</script>
</head>
<body>
<div id="transformed" class="transformed content">transformed content</div>
<div id="transformed" class="transformed content">transformed content</div>
<div class="content">not transformed content</div>
<div class="region"></div>
<div>Test PASSES if it doesn't crash or assert</div>
</body>
</html>
\ No newline at end of file
<!doctype html>
<html>
<head>
<title>Bug 120457: [CSS Regions] The layers from the flow thread should be collected under the regions' layers.</title>
<style>
html {
-webkit-font-smoothing: none;
}
.transformed {
-webkit-transform:rotateX(15deg) rotateZ(15deg);
}
.content {
-webkit-flow-into:theFlow;
}
.region {
-webkit-flow-from:theFlow;
}
</style>
<script>
window.addEventListener( "load", function () {
var div = document.querySelector("#transformed");
for(var i = 0; i < 10; ++i ) {
div.className = "transformed content";
document.body.offsetTop;
div.className = "content";
document.body.offsetTop;
}
}, false);
</script>
</head>
<body>
<div id="transformed" class="transformed content">transformed content</div>
<div id="transformed" class="transformed content">transformed content</div>
<div class="content">not transformed content</div>
<div class="region"></div>
<div>Test PASSES if it doesn't crash or assert</div>
</body>
</html>
\ No newline at end of file
<html>
<head>
<title>Bug #</title>
<style>
html {
-webkit-font-smoothing: none;
}
.content {
}
.transformed {
-webkit-transform:rotateX(15deg) rotateZ(15deg);
}
.region {
display: inline-block;
float: right;
width: 210px;
height: 110px;
background-color: #eee;
-webkit-transform:rotateZ(0deg); /*so the div is composited, just like the region*/
}
.text {
width: 600px;
}
* {
border:solid 1px #888;
padding: 2px;
margin: 3px;
}
</style>
<script src="../resources/media-testing.js"></script>
<script src="../../media/media-file.js"></script>
<script type="text/javascript" charset="utf-8">
function testDone() {
if (window.testRunner)
testRunner.notifyDone();
}
window.onload = function() {
var video = document.getElementsByTagName('video')[0];
setupVideo(video, '../../media/content/counting', null, testDone);
};
</script>
</head>
<body>
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia, cupiditate, porro, dignissimos fuga impedit corrupti suscipit tempora earum odit asperiores quia nam soluta repellat perspiciatis iste et voluptatem molestiae magni a voluptas maxime officiis iusto dolor ut dicta.
<div class="region">
<div class="content">Long text inside the region</div>
<video class="content transformed" height="100" width="96" id="video" controls></video>
<div class="content transformed">Long text inside the region</div>
</div>
Et, ad sit praesentium recusandae omnis reiciendis ipsa eveniet accusantium vero reprehenderit enim minus perferendis sapiente maxime fugiat iure soluta minima suscipit.</div>
<div class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia, cupiditate, porro, dignissimos fuga impedit corrupti suscipit tempora earum odit asperiores quia nam soluta repellat perspiciatis iste et voluptatem molestiae magni a voluptas maxime officiis iusto dolor ut dicta. Et, ad sit praesentium recusandae omnis reiciendis ipsa eveniet accusantium vero reprehenderit enim minus perferendis sapiente maxime fugiat iure soluta minima suscipit.</div>
</body>
</html>
\ No newline at end of file
<html>
<head>
<title>Bug #</title>
<style>
html {
-webkit-font-smoothing: none;
}
.content {
-webkit-flow-into: theFlow;
}
.transformed {
-webkit-transform:rotateX(15deg) rotateZ(15deg);
}
.region {
-webkit-flow-from: theFlow;
display: inline-block;
float: right;
width: 210px;
height: 110px;
background-color: #eee;
}
.text {
width: 600px;
}
* {
border:solid 1px #888;
padding: 2px;
margin: 3px;
}
</style>
<script src="../resources/media-testing.js"></script>
<script src="../../media/media-file.js"></script>
<script type="text/javascript" charset="utf-8">
function testDone() {
if (window.testRunner)
testRunner.notifyDone();
}
window.onload = function() {
var video = document.getElementsByTagName('video')[0];
setupVideo(video, '../../media/content/counting', null, testDone);
};
</script>
</head>
<body>
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia, cupiditate, porro, dignissimos fuga impedit corrupti suscipit tempora earum odit asperiores quia nam soluta repellat perspiciatis iste et voluptatem molestiae magni a voluptas maxime officiis iusto dolor ut dicta.
<div class="region"></div>
Et, ad sit praesentium recusandae omnis reiciendis ipsa eveniet accusantium vero reprehenderit enim minus perferendis sapiente maxime fugiat iure soluta minima suscipit.
</div>
<div class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia, cupiditate, porro, dignissimos fuga impedit corrupti suscipit tempora earum odit asperiores quia nam soluta repellat perspiciatis iste et voluptatem molestiae magni a voluptas maxime officiis iusto dolor ut dicta. Et, ad sit praesentium recusandae omnis reiciendis ipsa eveniet accusantium vero reprehenderit enim minus perferendis sapiente maxime fugiat iure soluta minima suscipit.</div>
<div class="content">Long text inside the region</div>
<video class="content transformed" height="100" width="96" id="video" controls></video>
<div class="content transformed">Long text inside the region</div>
</body>
</html>
\ No newline at end of file
<html>
<head>
<title>Bug 120457: [CSS Regions] The layers from the flow thread should be collected under the regions' layers.</title>
<style>
html {
-webkit-font-smoothing: none;
}
.content {
width: 150px;
height: 100px;
background-color: Yellow;
}
body .region:nth-child(2) .content {
margin-top: 0px; /*margins are collapsed when fragmented*/
}
.movesTheLayerToNextRegion {
height: 225px;
}
#causesTheRegionToBeComposited {
-webkit-transform:translateZ(1px); /*so the div is composited*/
width: 100px;
height: 40px;
background-color: Lime;
}
.region {
-webkit-transform:translateZ(1px); /*so the div is composited, just like the region*/
height: 230px;
border:solid 1px #888;
}
</style>
</head>
<body>
some text 1.
<div class="region">
<div id="willBeAddedToTheFlow" class="content movesTheLayerToNextRegion">goes in the 1st region.</div>
</div>
some text.
<div class="region">
<div class="content">
some text 2.
<div id="causesTheRegionToBeComposited">
some text 3.
</div>
some text 4.
<div>some text.</div>
<div>some text.</div>
<div>some text.</div>
<div>some text.</div>
</div>
</div>
some text 5.
<p>If we have layers that moved from one region to another, we trigger a composited layers rebuild to make sure that the regions will collect the right layers.</p>
</body>
</html>
\ No newline at end of file
<html>
<head>
<title>Bug 120457: [CSS Regions] The layers from the flow thread should be collected under the regions' layers.</title>
<style>
html {
-webkit-font-smoothing: none;
}
.content {
-webkit-flow-into: flow;
width: 150px;
height: 100px;
background-color: Yellow;
}
#causesTheRegionToBeComposited {
-webkit-transform: translateZ(1px);
width: 100px;
height: 40px;
background-color: Lime;
}
.movesTheLayerToNextRegion {
height: 225px;
}
.region {
-webkit-flow-from: flow;
height: 230px;
border:solid 1px #888;
}
</style>
</head>
<body>
some text 1.
<div class="content">goes in the 1st region.</div>
<div class="content">
some text 2.
<div id="causesTheRegionToBeComposited">
some text 3.
</div>
some text 4.
<div>some text.</div>
<div>some text.</div>
<div>some text.</div>
<div>some text.</div>
</div>
<div class="region" id="r1"></div>
some text.
<div class="region" id="r2"></div>
some text 5.
<p>If we have layers that moved from one region to another, we trigger a composited layers rebuild to make sure that the regions will collect the right layers.</p>
<script>
document.body.offsetTop; // do the layout.
document.querySelector("body .content:first-child").className = "content movesTheLayerToNextRegion";
</script>
</body>
</html>
\ No newline at end of file
<html>
<head>
<title>Bug 120457: [CSS Regions] The layers from the flow thread should be collected under the regions' layers.</title>
<style>
html {
-webkit-font-smoothing: none;
}
#content {
width: 150px;
height: 100px;
background-color: Yellow;
padding: 2px 3px 4px 5px;
margin: 3px 4px 5px 6px;
}
#causesTheRegionToBeComposited {
-webkit-transform: translateZ(-30px) translateX(-35px);
width: 100px;
height: 40px;
background-color: Lime;
padding: 4px 5px 6px 7px;
margin: 5px 6px 7px 8px;
}
#region {
box-shadow: 2px 2px 15px Black;
border: double 3px Green;
border-width: 3px 4px 5px 6px;
outline: double 5px Blue;
padding: 6px 7px 8px 9px;
margin: 7px 8px 9px 10px;
}
</style>
</head>
<body>
some text 1.
<div id="region">
<div id="content">
some text 2.
<div id="causesTheRegionToBeComposited">
some text 3.
</div>
some text 4.
</div>
</div>
some text 5.
<p>Make sure that the region propagates its borders, paddings, outlines or box-shadows to layers inside it.</p>
</body>
</html>
\ No newline at end of file
<html>
<head>
<title>Bug 120457: [CSS Regions] The layers from the flow thread should be collected under the regions' layers.</title>
<style>
html {
-webkit-font-smoothing: none;
background-color: #f8f8f8;
}
#content {
width: 150px;
background-color: Yellow;
padding: 2px 3px 4px 5px;
margin: 3px 4px 5px 6px;
}
#region {
width: 90%;
border: double 3px Green;
border-width: 3px 4px 5px 6px;
outline: double 5px Blue;
padding: 6px 7px 8px 9px;
margin: 7px 8px 9px 10px;
}
</style>
<script src="../resources/media-testing.js"></script>
<script src="../../media/media-file.js"></script>
<script type="text/javascript" charset="utf-8">
function testDone() {
if (window.testRunner)
testRunner.notifyDone();
}
window.onload = function() {
var video = document.getElementsByTagName('video')[0];
setupVideo(video, '../../media/content/counting', null, testDone);
};
</script>
</head>
<body>
some text 1.
<div id="region">
<div id="content">
some text 2.
<video height="270" width="480" id="video" controls></video>
some text 4.
</div>
</div>
some text 5.
<p>Make sure that the region propagates its borders, paddings, outlines or box-shadows to video layers inside it.</p>
</body>
</html>
\ No newline at end of file
<html>
<head>
<title>Bug 120457: [CSS Regions] The layers from the flow thread should be collected under the regions' layers.</title>
<style>
html {
-webkit-font-smoothing: none;
background-color: #f8f8f8;
}
#content {
-webkit-flow-into: flow;
width: 150px;
background-color: Yellow;
padding: 2px 3px 4px 5px;
margin: 3px 4px 5px 6px;
}
#region {
-webkit-flow-from: flow;
width: 90%;
border: double 3px Green;
border-width: 3px 4px 5px 6px;
outline: double 5px Blue;
padding: 6px 7px 8px 9px;
margin: 7px 8px 9px 10px;
}
</style>
<script src="../resources/media-testing.js"></script>
<script src="../../media/media-file.js"></script>
<script type="text/javascript" charset="utf-8">
function testDone() {
if (window.testRunner)
testRunner.notifyDone();
}
window.onload = function() {
var video = document.getElementsByTagName('video')[0];
setupVideo(video, '../../media/content/counting', null, testDone);
};
</script>
</head>
<body>
some text 1.
<div id="content">
some text 2.
<video height="270" width="480" id="video" controls></video>
some text 4.
</div>
<div id="region"></div>
some text 5.
<p>Make sure that the region propagates its borders, paddings, outlines or box-shadows to video layers inside it.</p>
</body>
</html>
\ No newline at end of file
<html>
<head>
<title>Bug 120457: [CSS Regions] The layers from the flow thread should be collected under the regions' layers.</title>
<style>
html {
-webkit-font-smoothing: none;
}
#content {
-webkit-flow-into: flow;
width: 150px;
height: 100px;
background-color: Yellow;
padding: 2px 3px 4px 5px;
margin: 3px 4px 5px 6px;
}
#causesTheRegionToBeComposited {
-webkit-transform: translateZ(-30px) translateX(-35px);
width: 100px;
height: 40px;
background-color: Lime;
padding: 4px 5px 6px 7px;
margin: 5px 6px 7px 8px;
}
#region {
-webkit-flow-from: flow;
box-shadow: 2px 2px 15px Black;
border: double 3px Green;
border-width: 3px 4px 5px 6px;
outline: double 5px Blue;
padding: 6px 7px 8px 9px;
margin: 7px 8px 9px 10px;
}
</style>
</head>
<body>
some text 1.
<div id="content">
some text 2.
<div id="causesTheRegionToBeComposited">