Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1030)

Unified Diff: Source/core/rendering/RenderLayer.cpp

Issue 23503046: [CSS Blending] Implement mix-blend-mode in software. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Addressing review comments Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/rendering/RenderLayer.h ('k') | Source/core/rendering/RenderLayerCompositor.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/rendering/RenderLayer.cpp
diff --git a/Source/core/rendering/RenderLayer.cpp b/Source/core/rendering/RenderLayer.cpp
index 2e5e260ea0e15f0a2537a147ad40e33b2640eb5e..c6fb051e6dd4ed79577a733024180120687823fc 100644
--- a/Source/core/rendering/RenderLayer.cpp
+++ b/Source/core/rendering/RenderLayer.cpp
@@ -133,6 +133,7 @@ RenderLayer::RenderLayer(RenderLayerModelObject* renderer)
, m_canBePromotedToStackingContainerDirty(true)
, m_isRootLayer(renderer->isRenderView())
, m_usedTransparency(false)
+ , m_isolateForDescendantBlendMode(false)
, m_paintingInsideReflection(false)
, m_repaintStatus(NeedsNormalRepaint)
, m_visibleContentStatusDirty(true)
@@ -409,6 +410,22 @@ LayoutRect RenderLayer::repaintRectIncludingNonCompositingDescendants() const
return repaintRect;
}
+bool RenderLayer::hasNonAcceleratedBlendedChildInCurrentStackingContext() const
+{
+ if (isComposited() && !backing()->paintsIntoCompositedAncestor())
+ return false;
+
+ for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
+ if (child->hasBlendMode())
+ return true;
+
+ if (!child->isStackingContext() && child->hasNonAcceleratedBlendedChildInCurrentStackingContext())
Julien - ping for review 2013/09/23 18:55:38 Doesn't this means we will walk the whole subtree
mitica 2013/09/23 20:12:20 If, for each time a blend mode would be set on a R
Julien - ping for review 2013/09/23 22:15:09 Yes and this is a fairly common paradigm in Render
+ return true;
+ }
+
+ return false;
+}
+
void RenderLayer::setAncestorChainHasSelfPaintingLayerDescendant()
{
for (RenderLayer* layer = this; layer; layer = layer->parent()) {
@@ -1697,18 +1714,21 @@ LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const Layou
void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
{
- if (context->paintingDisabled() || (paintsWithTransparency(paintBehavior) && m_usedTransparency))
+ if (context->paintingDisabled() || ((paintsWithTransparency(paintBehavior) || hasBlendMode() || m_isolateForDescendantBlendMode) && m_usedTransparency))
return;
RenderLayer* ancestor = transparentPaintingAncestor();
if (ancestor)
ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior);
- if (paintsWithTransparency(paintBehavior)) {
+ if (paintsWithTransparency(paintBehavior) || hasBlendMode() || m_isolateForDescendantBlendMode) {
m_usedTransparency = true;
context->save();
LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, paintBehavior);
context->clip(clipRect);
+ if (hasBlendMode())
+ context->setCompositeOperation(context->compositeOperation(), m_blendMode);
+
context->beginTransparencyLayer(renderer()->opacity());
#ifdef REVEAL_TRANSPARENCY_LAYERS
context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f));
@@ -3272,6 +3292,11 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
}
}
+ // Blending operations must be performed only with the nearest ancestor stacking context.
+ m_isolateForDescendantBlendMode = isStackingContext() && hasNonAcceleratedBlendedChildInCurrentStackingContext();
Julien - ping for review 2013/09/23 18:55:38 Trying to understand the need to have this stored
mitica 2013/09/23 20:12:20 This member is computed using the recursive layer
Julien - ping for review 2013/09/23 22:15:09 That's not what I meant: it is possible for this c
+ if (m_isolateForDescendantBlendMode)
+ beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior);
+
LayerPaintingInfo localPaintingInfo(paintingInfo);
FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilters());
if (filterPainter.haveFilterEffect() && !context->paintingDisabled()) {
@@ -3387,10 +3412,11 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
paintMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer);
// End our transparency layer
- if (haveTransparency && m_usedTransparency && !m_paintingInsideReflection) {
+ if ((haveTransparency || hasBlendMode() || m_isolateForDescendantBlendMode) && m_usedTransparency && !m_paintingInsideReflection) {
context->endLayer();
context->restore();
m_usedTransparency = false;
+ m_isolateForDescendantBlendMode = false;
}
if (resourceClipper)
@@ -3572,7 +3598,7 @@ void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragmen
continue;
// Begin transparency layers lazily now that we know we have to paint something.
- if (haveTransparency)
+ if (haveTransparency || hasBlendMode())
beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior);
if (localPaintingInfo.clipToDirtyRect) {
@@ -3596,7 +3622,7 @@ void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragmen
RenderObject* paintingRootForRenderer, bool selectionOnly, bool forceBlackText)
{
// Begin transparency if we have something to paint.
- if (haveTransparency) {
+ if (haveTransparency || hasBlendMode()) {
for (size_t i = 0; i < layerFragments.size(); ++i) {
const LayerFragment& fragment = layerFragments.at(i);
if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty()) {
« no previous file with comments | « Source/core/rendering/RenderLayer.h ('k') | Source/core/rendering/RenderLayerCompositor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698