| Index: Source/core/rendering/RenderLayer.cpp | 
| diff --git a/Source/core/rendering/RenderLayer.cpp b/Source/core/rendering/RenderLayer.cpp | 
| index 3db81e33e92bb8b428490476965e92164f5d84e0..1feec46b424d2956b68ab716aee7ee2903ef5b06 100644 | 
| --- a/Source/core/rendering/RenderLayer.cpp | 
| +++ b/Source/core/rendering/RenderLayer.cpp | 
| @@ -121,6 +121,8 @@ RenderLayer::RenderLayer(RenderLayerModelObject* renderer) | 
| , m_canBePromotedToStackingContainerDirty(true) | 
| , m_isRootLayer(renderer->isRenderView()) | 
| , m_usedTransparency(false) | 
| +    , m_childLayerHasBlendMode(false) | 
| +    , m_childLayerHasBlendModeStatusDirty(false) | 
| , m_paintingInsideReflection(false) | 
| , m_visibleContentStatusDirty(true) | 
| , m_hasVisibleContent(false) | 
| @@ -725,9 +727,15 @@ void RenderLayer::updateBlendMode() | 
| if (!RuntimeEnabledFeatures::cssCompositingEnabled()) | 
| return; | 
|  | 
| +    bool hadBlendMode = m_blendMode != BlendModeNormal; | 
| BlendMode newBlendMode = renderer()->style()->blendMode(); | 
| if (newBlendMode != m_blendMode) { | 
| m_blendMode = newBlendMode; | 
| + | 
| +        // Only update the flag if a blend mode is set or unset. | 
| +        if (!hadBlendMode || !hasBlendMode()) | 
| +            dirtyAncestorChainBlendedDescendantStatus(); | 
| + | 
| if (compositedLayerMapping()) | 
| compositedLayerMapping()->setBlendMode(newBlendMode); | 
| } | 
| @@ -960,6 +968,33 @@ void RenderLayer::setAncestorChainHasVisibleDescendant() | 
| } | 
| } | 
|  | 
| +void RenderLayer::dirtyAncestorChainBlendedDescendantStatus() | 
| +{ | 
| +    for (RenderLayer* layer = this; layer; layer = layer->parent()) { | 
| +        if (layer->m_childLayerHasBlendModeStatusDirty) | 
| +            break; | 
| + | 
| +        layer->m_childLayerHasBlendModeStatusDirty = true; | 
| + | 
| +        if (layer->isStackingContext()) | 
| +            break; | 
| +    } | 
| +} | 
| + | 
| +void RenderLayer::setAncestorChainBlendedDescendant() | 
| +{ | 
| +    for (RenderLayer* layer = this; layer; layer = layer->parent()) { | 
| +        if (!layer->m_childLayerHasBlendModeStatusDirty && layer->childLayerHasBlendMode()) | 
| +            break; | 
| + | 
| +        layer->m_childLayerHasBlendMode = true; | 
| +        layer->m_childLayerHasBlendModeStatusDirty = false; | 
| + | 
| +        if (layer->isStackingContext()) | 
| +            break; | 
| +    } | 
| +} | 
| + | 
| void RenderLayer::updateHasUnclippedDescendant() | 
| { | 
| TRACE_EVENT0("blink_rendering", "RenderLayer::updateHasUnclippedDescendant"); | 
| @@ -1019,6 +1054,20 @@ void RenderLayer::updateDescendantDependentFlags() | 
| m_hasOutOfFlowPositionedDescendantDirty = false; | 
| } | 
|  | 
| +    if (m_childLayerHasBlendModeStatusDirty) { | 
| +        for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) { | 
| +            if (!child->isStackingContext()) | 
| +                child->updateDescendantDependentFlags(); | 
| + | 
| +            bool childLayerHasBlendMode = child->hasBlendMode() || (child->m_childLayerHasBlendMode && !child->isStackingContext()); | 
| +            m_childLayerHasBlendMode |= childLayerHasBlendMode; | 
| + | 
| +            if (m_childLayerHasBlendMode) | 
| +                break; | 
| +        } | 
| +        m_childLayerHasBlendModeStatusDirty = false; | 
| +    } | 
| + | 
| if (m_visibleContentStatusDirty) { | 
| if (renderer()->style()->visibility() == VISIBLE) | 
| m_hasVisibleContent = true; | 
| @@ -1547,18 +1596,22 @@ 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)) | 
| +    bool createTransparencyLayerForBlendMode = isStackingContext() && m_childLayerHasBlendMode; | 
| +    if (context->paintingDisabled() || ((paintsWithTransparency(paintBehavior) || hasBlendMode() || createTransparencyLayerForBlendMode) && m_usedTransparency)) | 
| return; | 
|  | 
| RenderLayer* ancestor = transparentPaintingAncestor(); | 
| if (ancestor) | 
| ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior); | 
|  | 
| -    if (paintsWithTransparency(paintBehavior)) { | 
| +    if (paintsWithTransparency(paintBehavior) || hasBlendMode() || createTransparencyLayerForBlendMode) { | 
| 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)); | 
| @@ -1613,6 +1666,9 @@ void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild) | 
| if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant()) | 
| setAncestorChainHasSelfPaintingLayerDescendant(); | 
|  | 
| +    if (child->hasBlendMode() || child->childLayerHasBlendMode()) | 
| +        setAncestorChainBlendedDescendant(); | 
| + | 
| if (subtreeContainsOutOfFlowPositionedLayer(child)) { | 
| // Now that the out of flow positioned descendant is in the tree, we | 
| // need to tell the compositor to reevaluate the compositing | 
| @@ -1671,6 +1727,9 @@ RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild) | 
| if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant) | 
| dirtyAncestorChainVisibleDescendantStatus(); | 
|  | 
| +    if (oldChild->hasBlendMode() || oldChild->childLayerHasBlendMode()) | 
| +        dirtyAncestorChainBlendedDescendantStatus(); | 
| + | 
| if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescendant()) | 
| dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); | 
|  | 
| @@ -2689,6 +2748,12 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti | 
| } | 
| } | 
|  | 
| +    // Blending operations must be performed only with the nearest ancestor stacking context. | 
| +    bool createTransparencyLayerForBlendMode = isStackingContext() && m_childLayerHasBlendMode; | 
| + | 
| +    if (createTransparencyLayerForBlendMode) | 
| +        beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior); | 
| + | 
| LayerPaintingInfo localPaintingInfo(paintingInfo); | 
| FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilters()); | 
| if (filterPainter.haveFilterEffect() && !context->paintingDisabled()) { | 
| @@ -2810,7 +2875,7 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti | 
| } | 
|  | 
| // End our transparency layer | 
| -    if (haveTransparency && m_usedTransparency && !m_paintingInsideReflection) { | 
| +    if ((haveTransparency || hasBlendMode() || createTransparencyLayerForBlendMode) && m_usedTransparency && !m_paintingInsideReflection) { | 
| context->endLayer(); | 
| context->restore(); | 
| m_usedTransparency = false; | 
| @@ -2995,7 +3060,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) { | 
| @@ -3019,7 +3084,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()) { | 
| @@ -5074,12 +5139,12 @@ void RenderLayer::styleChanged(StyleDifference, const RenderStyle* oldStyle) | 
| updateReflectionStyle(); | 
| } | 
|  | 
| -    updateDescendantDependentFlags(); | 
| -    updateTransform(); | 
| - | 
| if (RuntimeEnabledFeatures::cssCompositingEnabled()) | 
| updateBlendMode(); | 
|  | 
| +    updateDescendantDependentFlags(); | 
| +    updateTransform(); | 
| + | 
| bool didPaintWithFilters = false; | 
|  | 
| if (paintsWithFilters()) | 
|  |