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

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: 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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 , m_hasSelfPaintingLayerDescendantDirty(false) 128 , m_hasSelfPaintingLayerDescendantDirty(false)
129 , m_hasOutOfFlowPositionedDescendant(false) 129 , m_hasOutOfFlowPositionedDescendant(false)
130 , m_hasOutOfFlowPositionedDescendantDirty(true) 130 , m_hasOutOfFlowPositionedDescendantDirty(true)
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_canBePromotedToStackingContainer(false) 134 , m_canBePromotedToStackingContainer(false)
135 , m_canBePromotedToStackingContainerDirty(true) 135 , m_canBePromotedToStackingContainerDirty(true)
136 , m_isRootLayer(renderer->isRenderView()) 136 , m_isRootLayer(renderer->isRenderView())
137 , m_usedTransparency(false) 137 , m_usedTransparency(false)
138 , m_isolateLayerFromBlendedContent(false)
138 , m_paintingInsideReflection(false) 139 , m_paintingInsideReflection(false)
139 , m_inOverflowRelayout(false) 140 , m_inOverflowRelayout(false)
140 , m_repaintStatus(NeedsNormalRepaint) 141 , m_repaintStatus(NeedsNormalRepaint)
141 , m_visibleContentStatusDirty(true) 142 , m_visibleContentStatusDirty(true)
142 , m_hasVisibleContent(false) 143 , m_hasVisibleContent(false)
143 , m_visibleDescendantStatusDirty(false) 144 , m_visibleDescendantStatusDirty(false)
144 , m_hasVisibleDescendant(false) 145 , m_hasVisibleDescendant(false)
145 , m_isPaginated(false) 146 , m_isPaginated(false)
146 , m_3DTransformedDescendantStatusDirty(true) 147 , m_3DTransformedDescendantStatusDirty(true)
147 , m_has3DTransformedDescendant(false) 148 , m_has3DTransformedDescendant(false)
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) { 409 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
409 // Don't include repaint rects for composited child layers; they will pa int themselves and have a different origin. 410 // Don't include repaint rects for composited child layers; they will pa int themselves and have a different origin.
410 if (child->isComposited()) 411 if (child->isComposited())
411 continue; 412 continue;
412 413
413 repaintRect.unite(child->repaintRectIncludingNonCompositingDescendants() ); 414 repaintRect.unite(child->repaintRectIncludingNonCompositingDescendants() );
414 } 415 }
415 return repaintRect; 416 return repaintRect;
416 } 417 }
417 418
419 bool RenderLayer::hasNonAcceleratedBlendedChildInCurrentStackingContext() const
420 {
421 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
422 if (child->isComposited())
423 continue;
424
425 if (child->hasBlendMode())
426 return true;
427
428 if (child->isStackingContext())
shawnsingh 2013/09/10 21:23:40 The ordering of this logic here is a little bit nu
mitica 2013/09/11 16:04:14 Sounds good, I'll rewrite this method.
429 continue;
430
431 if (child->hasNonAcceleratedBlendedChildInCurrentStackingContext())
432 return true;
433 }
434
435 return false;
436 }
437
418 void RenderLayer::setAncestorChainHasSelfPaintingLayerDescendant() 438 void RenderLayer::setAncestorChainHasSelfPaintingLayerDescendant()
419 { 439 {
420 for (RenderLayer* layer = this; layer; layer = layer->parent()) { 440 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
421 if (!layer->m_hasSelfPaintingLayerDescendantDirty && layer->hasSelfPaint ingLayerDescendant()) 441 if (!layer->m_hasSelfPaintingLayerDescendantDirty && layer->hasSelfPaint ingLayerDescendant())
422 break; 442 break;
423 443
424 layer->m_hasSelfPaintingLayerDescendantDirty = false; 444 layer->m_hasSelfPaintingLayerDescendantDirty = false;
425 layer->m_hasSelfPaintingLayerDescendant = true; 445 layer->m_hasSelfPaintingLayerDescendant = true;
426 } 446 }
427 } 447 }
(...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after
1687 return clipRect; 1707 return clipRect;
1688 } 1708 }
1689 1709
1690 LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const Layou tRect& paintDirtyRect, PaintBehavior paintBehavior) 1710 LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const Layou tRect& paintDirtyRect, PaintBehavior paintBehavior)
1691 { 1711 {
1692 return intersection(transparencyClipBox(this, rootLayer, PaintingTransparenc yClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect); 1712 return intersection(transparencyClipBox(this, rootLayer, PaintingTransparenc yClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect);
1693 } 1713 }
1694 1714
1695 void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const Render Layer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior) 1715 void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const Render Layer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
1696 { 1716 {
1697 if (context->paintingDisabled() || (paintsWithTransparency(paintBehavior) && m_usedTransparency)) 1717 if (context->paintingDisabled() || ((paintsWithTransparency(paintBehavior) | | hasBlendMode()) && m_usedTransparency))
1698 return; 1718 return;
1699 1719
1700 RenderLayer* ancestor = transparentPaintingAncestor(); 1720 RenderLayer* ancestor = transparentPaintingAncestor();
1701 if (ancestor) 1721 if (ancestor)
1702 ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, pa intBehavior); 1722 ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, pa intBehavior);
1703 1723
1704 if (paintsWithTransparency(paintBehavior)) { 1724 if (paintsWithTransparency(paintBehavior) || hasBlendMode()) {
1705 m_usedTransparency = true; 1725 m_usedTransparency = true;
1706 context->save(); 1726 context->save();
1707 LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, paintBeh avior); 1727 LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, paintBeh avior);
1708 context->clip(clipRect); 1728 context->clip(clipRect);
1729 if (hasBlendMode())
1730 context->setCompositeOperation(context->compositeOperation(), m_blen dMode);
1731
1709 context->beginTransparencyLayer(renderer()->opacity()); 1732 context->beginTransparencyLayer(renderer()->opacity());
1710 #ifdef REVEAL_TRANSPARENCY_LAYERS 1733 #ifdef REVEAL_TRANSPARENCY_LAYERS
1711 context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f)); 1734 context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f));
1712 context->fillRect(clipRect); 1735 context->fillRect(clipRect);
1713 #endif 1736 #endif
1714 } 1737 }
1715 } 1738 }
1716 1739
1717 void* RenderLayer::operator new(size_t sz) 1740 void* RenderLayer::operator new(size_t sz)
1718 { 1741 {
(...skipping 1818 matching lines...) Expand 10 before | Expand all | Expand 10 after
3537 // FIXME: This should use a safer cast such as toRenderSVGResour ceContainer(). 3560 // FIXME: This should use a safer cast such as toRenderSVGResour ceContainer().
3538 resourceClipper = static_cast<RenderSVGResourceClipper*>(element ->renderer()); 3561 resourceClipper = static_cast<RenderSVGResourceClipper*>(element ->renderer());
3539 if (!resourceClipper->applyClippingToContext(renderer(), rootRel ativeBounds, paintingInfo.paintDirtyRect, context)) { 3562 if (!resourceClipper->applyClippingToContext(renderer(), rootRel ativeBounds, paintingInfo.paintDirtyRect, context)) {
3540 // No need to post-apply the clipper if this failed. 3563 // No need to post-apply the clipper if this failed.
3541 resourceClipper = 0; 3564 resourceClipper = 0;
3542 } 3565 }
3543 } 3566 }
3544 } 3567 }
3545 } 3568 }
3546 3569
3570 if (isStackingContext() && hasNonAcceleratedBlendedChildInCurrentStackingCon text()) {
3571 // Blending operations must be performed only with the nearest ancestor stacking context.
3572 ASSERT(!m_isolateLayerFromBlendedContent);
3573 context->beginTransparencyLayer(renderer()->opacity());
shawnsingh 2013/09/10 21:23:40 Would it be possible to re-use the existing beginT
mitica 2013/09/11 16:04:14 I've refactored my code to use this logic, good su
3574 m_isolateLayerFromBlendedContent = true;
3575 }
3576
3547 LayerPaintingInfo localPaintingInfo(paintingInfo); 3577 LayerPaintingInfo localPaintingInfo(paintingInfo);
3548 FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilte rs()); 3578 FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilte rs());
3549 if (filterPainter.haveFilterEffect() && !context->paintingDisabled()) { 3579 if (filterPainter.haveFilterEffect() && !context->paintingDisabled()) {
3550 RenderLayerFilterInfo* filterInfo = this->filterInfo(); 3580 RenderLayerFilterInfo* filterInfo = this->filterInfo();
3551 ASSERT(filterInfo); 3581 ASSERT(filterInfo);
3552 LayoutRect filterRepaintRect = filterInfo->dirtySourceRect(); 3582 LayoutRect filterRepaintRect = filterInfo->dirtySourceRect();
3553 filterRepaintRect.move(offsetFromRoot.x(), offsetFromRoot.y()); 3583 filterRepaintRect.move(offsetFromRoot.x(), offsetFromRoot.y());
3554 3584
3555 if (!rootRelativeBoundsComputed) { 3585 if (!rootRelativeBoundsComputed) {
3556 rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &o ffsetFromRoot, 0); 3586 rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &o ffsetFromRoot, 0);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
3652 restoreClip(transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect); 3682 restoreClip(transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect);
3653 } 3683 }
3654 3684
3655 // Make sure that we now use the original transparency context. 3685 // Make sure that we now use the original transparency context.
3656 ASSERT(transparencyLayerContext == context); 3686 ASSERT(transparencyLayerContext == context);
3657 3687
3658 if (shouldPaintMask) 3688 if (shouldPaintMask)
3659 paintMaskForFragments(layerFragments, context, localPaintingInfo, painti ngRootForRenderer); 3689 paintMaskForFragments(layerFragments, context, localPaintingInfo, painti ngRootForRenderer);
3660 3690
3661 // End our transparency layer 3691 // End our transparency layer
3662 if (haveTransparency && m_usedTransparency && !m_paintingInsideReflection) { 3692 if ((haveTransparency || hasBlendMode() ) && m_usedTransparency && !m_painti ngInsideReflection) {
3663 context->endLayer(); 3693 context->endLayer();
3664 context->restore(); 3694 context->restore();
3665 m_usedTransparency = false; 3695 m_usedTransparency = false;
3666 } 3696 }
3667 3697
3698 // End the transparency layer creating for isolating blended elements.
3699 if (m_isolateLayerFromBlendedContent) {
3700 context->endLayer();
3701 m_isolateLayerFromBlendedContent = false;
3702 }
3703
3668 if (resourceClipper) 3704 if (resourceClipper)
3669 resourceClipper->postApplyResource(renderer(), context, ApplyToDefaultMo de, 0, 0); 3705 resourceClipper->postApplyResource(renderer(), context, ApplyToDefaultMo de, 0, 0);
3670 3706
3671 if (hasClipPath) 3707 if (hasClipPath)
3672 context->restore(); 3708 context->restore();
3673 } 3709 }
3674 3710
3675 void RenderLayer::paintLayerByApplyingTransform(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutPoint& translationOffset) 3711 void RenderLayer::paintLayerByApplyingTransform(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutPoint& translationOffset)
3676 { 3712 {
3677 // This involves subtracting out the position of the layer in our current co ordinate space, but preserving 3713 // This involves subtracting out the position of the layer in our current co ordinate space, but preserving
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
3837 void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragmen ts, GraphicsContext* context, GraphicsContext* transparencyLayerContext, 3873 void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragmen ts, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
3838 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, 3874 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
3839 RenderObject* paintingRootForRenderer) 3875 RenderObject* paintingRootForRenderer)
3840 { 3876 {
3841 for (size_t i = 0; i < layerFragments.size(); ++i) { 3877 for (size_t i = 0; i < layerFragments.size(); ++i) {
3842 const LayerFragment& fragment = layerFragments.at(i); 3878 const LayerFragment& fragment = layerFragments.at(i);
3843 if (!fragment.shouldPaintContent) 3879 if (!fragment.shouldPaintContent)
3844 continue; 3880 continue;
3845 3881
3846 // Begin transparency layers lazily now that we know we have to paint so mething. 3882 // Begin transparency layers lazily now that we know we have to paint so mething.
3847 if (haveTransparency) 3883 if (haveTransparency || hasBlendMode())
3848 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo. rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior); 3884 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo. rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior);
3849 3885
3850 if (localPaintingInfo.clipToDirtyRect) { 3886 if (localPaintingInfo.clipToDirtyRect) {
3851 // Paint our background first, before painting any child layers. 3887 // Paint our background first, before painting any child layers.
3852 // Establish the clip used to paint our background. 3888 // Establish the clip used to paint our background.
3853 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.p aintDirtyRect, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Bac kground painting will handle clipping to self. 3889 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.p aintDirtyRect, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Bac kground painting will handle clipping to self.
3854 } 3890 }
3855 3891
3856 // Paint the background. 3892 // Paint the background.
3857 // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info. 3893 // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
3858 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect .rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, loc alPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer()); 3894 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect .rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, loc alPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
3859 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - r enderBoxLocation() + localPaintingInfo.subPixelAccumulation)); 3895 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - r enderBoxLocation() + localPaintingInfo.subPixelAccumulation));
3860 3896
3861 if (localPaintingInfo.clipToDirtyRect) 3897 if (localPaintingInfo.clipToDirtyRect)
3862 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.back groundRect); 3898 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.back groundRect);
3863 } 3899 }
3864 } 3900 }
3865 3901
3866 void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragmen ts, GraphicsContext* context, GraphicsContext* transparencyLayerContext, 3902 void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragmen ts, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
3867 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, 3903 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
3868 RenderObject* paintingRootForRenderer, bool selectionOnly, bool forceBlackTe xt) 3904 RenderObject* paintingRootForRenderer, bool selectionOnly, bool forceBlackTe xt)
3869 { 3905 {
3870 // Begin transparency if we have something to paint. 3906 // Begin transparency if we have something to paint.
3871 if (haveTransparency) { 3907 if (haveTransparency || hasBlendMode()) {
3872 for (size_t i = 0; i < layerFragments.size(); ++i) { 3908 for (size_t i = 0; i < layerFragments.size(); ++i) {
3873 const LayerFragment& fragment = layerFragments.at(i); 3909 const LayerFragment& fragment = layerFragments.at(i);
3874 if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty( )) { 3910 if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty( )) {
3875 beginTransparencyLayers(transparencyLayerContext, localPaintingI nfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior); 3911 beginTransparencyLayers(transparencyLayerContext, localPaintingI nfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior);
3876 break; 3912 break;
3877 } 3913 }
3878 } 3914 }
3879 } 3915 }
3880 3916
3881 PaintBehavior localPaintBehavior = forceBlackText ? (PaintBehavior)PaintBeha viorForceBlackText : paintBehavior; 3917 PaintBehavior localPaintBehavior = forceBlackText ? (PaintBehavior)PaintBeha viorForceBlackText : paintBehavior;
(...skipping 2427 matching lines...) Expand 10 before | Expand all | Expand 10 after
6309 } 6345 }
6310 } 6346 }
6311 6347
6312 void showLayerTree(const WebCore::RenderObject* renderer) 6348 void showLayerTree(const WebCore::RenderObject* renderer)
6313 { 6349 {
6314 if (!renderer) 6350 if (!renderer)
6315 return; 6351 return;
6316 showLayerTree(renderer->enclosingLayer()); 6352 showLayerTree(renderer->enclosingLayer());
6317 } 6353 }
6318 #endif 6354 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698