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

Side by Side 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: Completely remove CompositingReasonBlending 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
3 * 3 *
4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
5 * 5 *
6 * Other contributors: 6 * Other contributors:
7 * Robert O'Callahan <roc+@cs.cmu.edu> 7 * Robert O'Callahan <roc+@cs.cmu.edu>
8 * David Baron <dbaron@fas.harvard.edu> 8 * David Baron <dbaron@fas.harvard.edu>
9 * Christian Biesinger <cbiesinger@web.de> 9 * Christian Biesinger <cbiesinger@web.de>
10 * Randall Jesup <rjesup@wgate.com> 10 * Randall Jesup <rjesup@wgate.com>
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 , m_hasUnclippedDescendant(false) 131 , m_hasUnclippedDescendant(false)
132 , m_isUnclippedDescendant(false) 132 , m_isUnclippedDescendant(false)
133 , m_needsCompositedScrolling(false) 133 , m_needsCompositedScrolling(false)
134 , m_needsCompositedScrollingHasBeenRecorded(false) 134 , m_needsCompositedScrollingHasBeenRecorded(false)
135 , m_willUseCompositedScrollingHasBeenRecorded(false) 135 , m_willUseCompositedScrollingHasBeenRecorded(false)
136 , m_isScrollableAreaHasBeenRecorded(false) 136 , m_isScrollableAreaHasBeenRecorded(false)
137 , m_canBePromotedToStackingContainer(false) 137 , m_canBePromotedToStackingContainer(false)
138 , m_canBePromotedToStackingContainerDirty(true) 138 , m_canBePromotedToStackingContainerDirty(true)
139 , m_isRootLayer(renderer->isRenderView()) 139 , m_isRootLayer(renderer->isRenderView())
140 , m_usedTransparency(false) 140 , m_usedTransparency(false)
141 , m_isolateLayerFromBlendedContent(false)
141 , m_paintingInsideReflection(false) 142 , m_paintingInsideReflection(false)
142 , m_inOverflowRelayout(false) 143 , m_inOverflowRelayout(false)
143 , m_repaintStatus(NeedsNormalRepaint) 144 , m_repaintStatus(NeedsNormalRepaint)
144 , m_visibleContentStatusDirty(true) 145 , m_visibleContentStatusDirty(true)
145 , m_hasVisibleContent(false) 146 , m_hasVisibleContent(false)
146 , m_visibleDescendantStatusDirty(false) 147 , m_visibleDescendantStatusDirty(false)
147 , m_hasVisibleDescendant(false) 148 , m_hasVisibleDescendant(false)
148 , m_isPaginated(false) 149 , m_isPaginated(false)
149 , m_3DTransformedDescendantStatusDirty(true) 150 , m_3DTransformedDescendantStatusDirty(true)
150 , m_has3DTransformedDescendant(false) 151 , m_has3DTransformedDescendant(false)
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) { 412 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
412 // Don't include repaint rects for composited child layers; they will pa int themselves and have a different origin. 413 // Don't include repaint rects for composited child layers; they will pa int themselves and have a different origin.
413 if (child->isComposited()) 414 if (child->isComposited())
414 continue; 415 continue;
415 416
416 repaintRect.unite(child->repaintRectIncludingNonCompositingDescendants() ); 417 repaintRect.unite(child->repaintRectIncludingNonCompositingDescendants() );
417 } 418 }
418 return repaintRect; 419 return repaintRect;
419 } 420 }
420 421
422 bool RenderLayer::hasNonAcceleratedBlendedChildInCurrentStackingContext() const
423 {
424 if (isComposited())
shawnsingh 2013/09/19 11:05:56 So I've just recently debugged two issues about th
425 return false;
426
427 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
428 bool childIsBlended = child->hasBlendMode();
429
430 if (!childIsBlended && child->isStackingContext())
shawnsingh 2013/09/19 11:05:56 Yeah this is much nicer - but I still think we can
mitica 2013/09/19 11:49:00 Indeed, that looks better, I'll change the method
431 continue;
432
433 if (childIsBlended || child->hasNonAcceleratedBlendedChildInCurrentStack ingContext())
434 return true;
435 }
436
437 return false;
438 }
439
421 void RenderLayer::setAncestorChainHasSelfPaintingLayerDescendant() 440 void RenderLayer::setAncestorChainHasSelfPaintingLayerDescendant()
422 { 441 {
423 for (RenderLayer* layer = this; layer; layer = layer->parent()) { 442 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
424 if (!layer->m_hasSelfPaintingLayerDescendantDirty && layer->hasSelfPaint ingLayerDescendant()) 443 if (!layer->m_hasSelfPaintingLayerDescendantDirty && layer->hasSelfPaint ingLayerDescendant())
425 break; 444 break;
426 445
427 layer->m_hasSelfPaintingLayerDescendantDirty = false; 446 layer->m_hasSelfPaintingLayerDescendantDirty = false;
428 layer->m_hasSelfPaintingLayerDescendant = true; 447 layer->m_hasSelfPaintingLayerDescendant = true;
429 } 448 }
430 } 449 }
(...skipping 1264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1695 return clipRect; 1714 return clipRect;
1696 } 1715 }
1697 1716
1698 LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const Layou tRect& paintDirtyRect, PaintBehavior paintBehavior) 1717 LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const Layou tRect& paintDirtyRect, PaintBehavior paintBehavior)
1699 { 1718 {
1700 return intersection(transparencyClipBox(this, rootLayer, PaintingTransparenc yClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect); 1719 return intersection(transparencyClipBox(this, rootLayer, PaintingTransparenc yClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect);
1701 } 1720 }
1702 1721
1703 void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const Render Layer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior) 1722 void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const Render Layer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
1704 { 1723 {
1705 if (context->paintingDisabled() || (paintsWithTransparency(paintBehavior) && m_usedTransparency)) 1724 if (context->paintingDisabled() || ((paintsWithTransparency(paintBehavior) | | hasBlendMode() || m_isolateLayerFromBlendedContent) && m_usedTransparency))
1706 return; 1725 return;
1707 1726
1708 RenderLayer* ancestor = transparentPaintingAncestor(); 1727 RenderLayer* ancestor = transparentPaintingAncestor();
1709 if (ancestor) 1728 if (ancestor)
1710 ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, pa intBehavior); 1729 ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, pa intBehavior);
1711 1730
1712 if (paintsWithTransparency(paintBehavior)) { 1731 if (paintsWithTransparency(paintBehavior) || hasBlendMode() || m_isolateLaye rFromBlendedContent) {
1713 m_usedTransparency = true; 1732 m_usedTransparency = true;
1714 context->save(); 1733 context->save();
1715 LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, paintBeh avior); 1734 LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, paintBeh avior);
1716 context->clip(clipRect); 1735 context->clip(clipRect);
1736 if (hasBlendMode())
1737 context->setCompositeOperation(context->compositeOperation(), m_blen dMode);
1738
1717 context->beginTransparencyLayer(renderer()->opacity()); 1739 context->beginTransparencyLayer(renderer()->opacity());
1718 #ifdef REVEAL_TRANSPARENCY_LAYERS 1740 #ifdef REVEAL_TRANSPARENCY_LAYERS
1719 context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f)); 1741 context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f));
1720 context->fillRect(clipRect); 1742 context->fillRect(clipRect);
1721 #endif 1743 #endif
1722 } 1744 }
1723 } 1745 }
1724 1746
1725 void* RenderLayer::operator new(size_t sz) 1747 void* RenderLayer::operator new(size_t sz)
1726 { 1748 {
(...skipping 1904 matching lines...) Expand 10 before | Expand all | Expand 10 after
3631 3653
3632 resourceClipper = toRenderSVGResourceClipper(element->renderer() ->toRenderSVGResourceContainer()); 3654 resourceClipper = toRenderSVGResourceClipper(element->renderer() ->toRenderSVGResourceContainer());
3633 if (!resourceClipper->applyClippingToContext(renderer(), rootRel ativeBounds, paintingInfo.paintDirtyRect, context)) { 3655 if (!resourceClipper->applyClippingToContext(renderer(), rootRel ativeBounds, paintingInfo.paintDirtyRect, context)) {
3634 // No need to post-apply the clipper if this failed. 3656 // No need to post-apply the clipper if this failed.
3635 resourceClipper = 0; 3657 resourceClipper = 0;
3636 } 3658 }
3637 } 3659 }
3638 } 3660 }
3639 } 3661 }
3640 3662
3663 // Blending operations must be performed only with the nearest ancestor stac king context.
3664 m_isolateLayerFromBlendedContent = isStackingContext() && hasNonAcceleratedB lendedChildInCurrentStackingContext();
3665 if (m_isolateLayerFromBlendedContent)
3666 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.pa intDirtyRect, paintingInfo.paintBehavior);
3667
3641 LayerPaintingInfo localPaintingInfo(paintingInfo); 3668 LayerPaintingInfo localPaintingInfo(paintingInfo);
3642 FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilte rs()); 3669 FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilte rs());
3643 if (filterPainter.haveFilterEffect() && !context->paintingDisabled()) { 3670 if (filterPainter.haveFilterEffect() && !context->paintingDisabled()) {
3644 RenderLayerFilterInfo* filterInfo = this->filterInfo(); 3671 RenderLayerFilterInfo* filterInfo = this->filterInfo();
3645 ASSERT(filterInfo); 3672 ASSERT(filterInfo);
3646 LayoutRect filterRepaintRect = filterInfo->dirtySourceRect(); 3673 LayoutRect filterRepaintRect = filterInfo->dirtySourceRect();
3647 filterRepaintRect.move(offsetFromRoot.x(), offsetFromRoot.y()); 3674 filterRepaintRect.move(offsetFromRoot.x(), offsetFromRoot.y());
3648 3675
3649 if (!rootRelativeBoundsComputed) { 3676 if (!rootRelativeBoundsComputed) {
3650 rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &o ffsetFromRoot, 0); 3677 rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &o ffsetFromRoot, 0);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
3746 restoreClip(transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect); 3773 restoreClip(transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect);
3747 } 3774 }
3748 3775
3749 // Make sure that we now use the original transparency context. 3776 // Make sure that we now use the original transparency context.
3750 ASSERT(transparencyLayerContext == context); 3777 ASSERT(transparencyLayerContext == context);
3751 3778
3752 if (shouldPaintMask) 3779 if (shouldPaintMask)
3753 paintMaskForFragments(layerFragments, context, localPaintingInfo, painti ngRootForRenderer); 3780 paintMaskForFragments(layerFragments, context, localPaintingInfo, painti ngRootForRenderer);
3754 3781
3755 // End our transparency layer 3782 // End our transparency layer
3756 if (haveTransparency && m_usedTransparency && !m_paintingInsideReflection) { 3783 if ((haveTransparency || hasBlendMode() || m_isolateLayerFromBlendedContent) && m_usedTransparency && !m_paintingInsideReflection) {
3757 context->endLayer(); 3784 context->endLayer();
3758 context->restore(); 3785 context->restore();
3759 m_usedTransparency = false; 3786 m_usedTransparency = false;
3787 m_isolateLayerFromBlendedContent = false;
3760 } 3788 }
3761 3789
3762 if (resourceClipper) 3790 if (resourceClipper)
3763 resourceClipper->postApplyResource(renderer(), context, ApplyToDefaultMo de, 0, 0); 3791 resourceClipper->postApplyResource(renderer(), context, ApplyToDefaultMo de, 0, 0);
3764 3792
3765 if (hasClipPath) 3793 if (hasClipPath)
3766 context->restore(); 3794 context->restore();
3767 } 3795 }
3768 3796
3769 void RenderLayer::paintLayerByApplyingTransform(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutPoint& translationOffset) 3797 void RenderLayer::paintLayerByApplyingTransform(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutPoint& translationOffset)
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
3931 void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragmen ts, GraphicsContext* context, GraphicsContext* transparencyLayerContext, 3959 void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragmen ts, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
3932 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, 3960 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
3933 RenderObject* paintingRootForRenderer) 3961 RenderObject* paintingRootForRenderer)
3934 { 3962 {
3935 for (size_t i = 0; i < layerFragments.size(); ++i) { 3963 for (size_t i = 0; i < layerFragments.size(); ++i) {
3936 const LayerFragment& fragment = layerFragments.at(i); 3964 const LayerFragment& fragment = layerFragments.at(i);
3937 if (!fragment.shouldPaintContent) 3965 if (!fragment.shouldPaintContent)
3938 continue; 3966 continue;
3939 3967
3940 // Begin transparency layers lazily now that we know we have to paint so mething. 3968 // Begin transparency layers lazily now that we know we have to paint so mething.
3941 if (haveTransparency) 3969 if (haveTransparency || hasBlendMode())
3942 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo. rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior); 3970 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo. rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior);
3943 3971
3944 if (localPaintingInfo.clipToDirtyRect) { 3972 if (localPaintingInfo.clipToDirtyRect) {
3945 // Paint our background first, before painting any child layers. 3973 // Paint our background first, before painting any child layers.
3946 // Establish the clip used to paint our background. 3974 // Establish the clip used to paint our background.
3947 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.p aintDirtyRect, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Bac kground painting will handle clipping to self. 3975 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.p aintDirtyRect, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Bac kground painting will handle clipping to self.
3948 } 3976 }
3949 3977
3950 // Paint the background. 3978 // Paint the background.
3951 // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info. 3979 // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
3952 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect .rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, loc alPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer()); 3980 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect .rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, loc alPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
3953 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - r enderBoxLocation() + localPaintingInfo.subPixelAccumulation)); 3981 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - r enderBoxLocation() + localPaintingInfo.subPixelAccumulation));
3954 3982
3955 if (localPaintingInfo.clipToDirtyRect) 3983 if (localPaintingInfo.clipToDirtyRect)
3956 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.back groundRect); 3984 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.back groundRect);
3957 } 3985 }
3958 } 3986 }
3959 3987
3960 void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragmen ts, GraphicsContext* context, GraphicsContext* transparencyLayerContext, 3988 void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragmen ts, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
3961 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, 3989 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
3962 RenderObject* paintingRootForRenderer, bool selectionOnly, bool forceBlackTe xt) 3990 RenderObject* paintingRootForRenderer, bool selectionOnly, bool forceBlackTe xt)
3963 { 3991 {
3964 // Begin transparency if we have something to paint. 3992 // Begin transparency if we have something to paint.
3965 if (haveTransparency) { 3993 if (haveTransparency || hasBlendMode()) {
3966 for (size_t i = 0; i < layerFragments.size(); ++i) { 3994 for (size_t i = 0; i < layerFragments.size(); ++i) {
3967 const LayerFragment& fragment = layerFragments.at(i); 3995 const LayerFragment& fragment = layerFragments.at(i);
3968 if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty( )) { 3996 if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty( )) {
3969 beginTransparencyLayers(transparencyLayerContext, localPaintingI nfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior); 3997 beginTransparencyLayers(transparencyLayerContext, localPaintingI nfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior);
3970 break; 3998 break;
3971 } 3999 }
3972 } 4000 }
3973 } 4001 }
3974 4002
3975 PaintBehavior localPaintBehavior = forceBlackText ? (PaintBehavior)PaintBeha viorForceBlackText : paintBehavior; 4003 PaintBehavior localPaintBehavior = forceBlackText ? (PaintBehavior)PaintBeha viorForceBlackText : paintBehavior;
(...skipping 2471 matching lines...) Expand 10 before | Expand all | Expand 10 after
6447 } 6475 }
6448 } 6476 }
6449 6477
6450 void showLayerTree(const WebCore::RenderObject* renderer) 6478 void showLayerTree(const WebCore::RenderObject* renderer)
6451 { 6479 {
6452 if (!renderer) 6480 if (!renderer)
6453 return; 6481 return;
6454 showLayerTree(renderer->enclosingLayer()); 6482 showLayerTree(renderer->enclosingLayer());
6455 } 6483 }
6456 #endif 6484 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698