Commit 0a70eebb authored by rosca@adobe.com's avatar rosca@adobe.com

hasDescendantWithBlendMode should not be propagated outside

the current stacking context.

If a stacking context element has descendants with blend mode, it should
create a new transparency layer, so that blending descendants will blend
only with the content within this stacking context (stacking context
will isolate blending).

With this CL, hasDescendantWithBlendMode will be set only if
the descendant is right inside the current stacking context, without
looking into nested stacking context elements. It also renames
hasDescendantWithBlendMode to hasNonIsolatedDescendantWithBlendMode,
which is more self-explanatory.

This change is necessary after https://codereview.chromium.org/466193002
(Disentangle blend mode from updateDescendantDependentFlags).

The "isolating" state used to be tested with DRT, but this property has
been removed with https://codereview.chromium.org/466943002/
(Remove isolatesBlending from render tree dumps).

We cannot test this change using layout tests. The effect is that
RenderLayer doesn't create any aditional and unnecessary skia
transparency layers.

Review URL: https://codereview.chromium.org/478333002

git-svn-id: svn://svn.chromium.org/blink/trunk@183806 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent dcf5a7f4
<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 100px;
height: 100px;
position: relative;
z-index: 1;
top: 10px;
background-color: red;
border: 1px black solid;
}
.blending {
mix-blend-mode: difference;
}
#container {
position: absolute;
left: 0px;
z-index: 0;
}
</style>
<script src="../resources/runner.js"></script>
<script src="resources/framerate.js"></script>
<script>
window.onload = function () {
PerfTestRunner.prepareToMeasureValuesAsync({done: onCompletedRun, unit: 'fps'});
// The leaf element has blending
var lastElement = document.createElement("div");
lastElement.setAttribute("class", "blending box");
for (var i = 0; i < 100; i++) {
var el = document.createElement("div");
el.setAttribute("class", "box");
el.appendChild(lastElement);
lastElement = el;
}
var container = document.getElementById("container");
container.appendChild(lastElement);
startTrackingFrameRate({run: softwareAnimationStep});
}
function onCompletedRun() {
stopTrackingFrameRate();
}
function softwareAnimationStep() {
var leftVal = parseInt(container.style.left) || 0;
container.style.left = (leftVal + 1) + "px";
}
</script>
</head>
<body>
<pre id="log"> </pre>
<div id="container"> </div>
</body>
</html>
(function(){
var framesPerTimerReading = 10;
var frameCount = 0;
var startTime;
var trackingFrameRate = false;
var currentTest;
function trackFrameRate(currTime)
{
if (++frameCount == framesPerTimerReading) {
frameCount = 0;
PerfTestRunner.measureValueAsync(1000 * framesPerTimerReading / (currTime - startTime));
startTime = currTime;
}
if (currentTest && currentTest.run)
currentTest.run();
if (trackingFrameRate)
requestAnimationFrame(trackFrameRate);
}
window.startTrackingFrameRate = function(test) {
if (trackingFrameRate)
return;
trackingFrameRate = true;
currentTest = test;
startTime = performance.now();
trackFrameRate();
};
window.stopTrackingFrameRate = function() {
trackingFrameRate = false;
currentTest = undefined;
};
})();
......@@ -115,7 +115,7 @@ void LayerPainter::paintLayer(GraphicsContext* context, const LayerPaintingInfo&
void LayerPainter::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
{
bool createTransparencyLayerForBlendMode = m_renderLayer.stackingNode()->isStackingContext() && m_renderLayer.hasDescendantWithBlendMode();
bool createTransparencyLayerForBlendMode = m_renderLayer.stackingNode()->isStackingContext() && m_renderLayer.hasNonIsolatedDescendantWithBlendMode();
if ((m_renderLayer.paintsWithTransparency(paintBehavior) || m_renderLayer.paintsWithBlendMode() || createTransparencyLayerForBlendMode) && m_renderLayer.usedTransparency())
return;
......@@ -247,7 +247,7 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint
// Blending operations must be performed only with the nearest ancestor stacking context.
// Note that there is no need to create a transparency layer if we're painting the root.
bool createTransparencyLayerForBlendMode = !m_renderLayer.renderer()->isDocumentElement() && m_renderLayer.stackingNode()->isStackingContext() && m_renderLayer.hasDescendantWithBlendMode();
bool createTransparencyLayerForBlendMode = !m_renderLayer.renderer()->isDocumentElement() && m_renderLayer.stackingNode()->isStackingContext() && m_renderLayer.hasNonIsolatedDescendantWithBlendMode();
if (createTransparencyLayerForBlendMode)
beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
......
......@@ -445,11 +445,11 @@ public:
public:
DescendantDependentCompositingInputs()
: hasDescendantWithClipPath(false)
, hasDescendantWithBlendMode(false)
, hasNonIsolatedDescendantWithBlendMode(false)
{ }
unsigned hasDescendantWithClipPath : 1;
unsigned hasDescendantWithBlendMode : 1;
unsigned hasNonIsolatedDescendantWithBlendMode : 1;
};
void setNeedsCompositingInputsUpdate();
......@@ -480,7 +480,7 @@ public:
bool isUnclippedDescendant() const { return ancestorDependentCompositingInputs().isUnclippedDescendant; }
bool hasAncestorWithClipPath() const { return ancestorDependentCompositingInputs().hasAncestorWithClipPath; }
bool hasDescendantWithClipPath() const { return descendantDependentCompositingInputs().hasDescendantWithClipPath; }
bool hasDescendantWithBlendMode() const { return descendantDependentCompositingInputs().hasDescendantWithBlendMode; }
bool hasNonIsolatedDescendantWithBlendMode() const { return descendantDependentCompositingInputs().hasNonIsolatedDescendantWithBlendMode; }
bool lostGroupedMapping() const { ASSERT(isAllowedToQueryCompositingState()); return m_lostGroupedMapping; }
void setLostGroupedMapping(bool b) { m_lostGroupedMapping = b; }
......
......@@ -174,7 +174,7 @@ void CompositingInputsUpdater::updateRecursive(RenderLayer* layer, UpdateType up
updateRecursive(child, updateType, info);
descendantProperties.hasDescendantWithClipPath |= child->hasDescendantWithClipPath() || child->renderer()->hasClipPath();
descendantProperties.hasDescendantWithBlendMode |= child->hasDescendantWithBlendMode() || child->renderer()->hasBlendMode();
descendantProperties.hasNonIsolatedDescendantWithBlendMode |= (!child->stackingNode()->isStackingContext() && child->hasNonIsolatedDescendantWithBlendMode()) || child->renderer()->hasBlendMode();
}
layer->updateDescendantDependentCompositingInputs(descendantProperties);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment