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

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: 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 unified diff | Download patch
« no previous file with comments | « Source/core/rendering/RenderLayer.h ('k') | Source/core/rendering/RenderLayerCompositor.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 , m_hasUnclippedDescendant(false) 126 , m_hasUnclippedDescendant(false)
127 , m_isUnclippedDescendant(false) 127 , m_isUnclippedDescendant(false)
128 , m_needsCompositedScrolling(false) 128 , m_needsCompositedScrolling(false)
129 , m_needsCompositedScrollingHasBeenRecorded(false) 129 , m_needsCompositedScrollingHasBeenRecorded(false)
130 , m_willUseCompositedScrollingHasBeenRecorded(false) 130 , m_willUseCompositedScrollingHasBeenRecorded(false)
131 , m_isScrollableAreaHasBeenRecorded(false) 131 , m_isScrollableAreaHasBeenRecorded(false)
132 , m_canBePromotedToStackingContainer(false) 132 , m_canBePromotedToStackingContainer(false)
133 , m_canBePromotedToStackingContainerDirty(true) 133 , m_canBePromotedToStackingContainerDirty(true)
134 , m_isRootLayer(renderer->isRenderView()) 134 , m_isRootLayer(renderer->isRenderView())
135 , m_usedTransparency(false) 135 , m_usedTransparency(false)
136 , m_isolateForDescendantBlendMode(false)
136 , m_paintingInsideReflection(false) 137 , m_paintingInsideReflection(false)
137 , m_repaintStatus(NeedsNormalRepaint) 138 , m_repaintStatus(NeedsNormalRepaint)
138 , m_visibleContentStatusDirty(true) 139 , m_visibleContentStatusDirty(true)
139 , m_hasVisibleContent(false) 140 , m_hasVisibleContent(false)
140 , m_visibleDescendantStatusDirty(false) 141 , m_visibleDescendantStatusDirty(false)
141 , m_hasVisibleDescendant(false) 142 , m_hasVisibleDescendant(false)
142 , m_isPaginated(false) 143 , m_isPaginated(false)
143 , m_3DTransformedDescendantStatusDirty(true) 144 , m_3DTransformedDescendantStatusDirty(true)
144 , m_has3DTransformedDescendant(false) 145 , m_has3DTransformedDescendant(false)
145 , m_containsDirtyOverlayScrollbars(false) 146 , m_containsDirtyOverlayScrollbars(false)
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) { 403 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
403 // Don't include repaint rects for composited child layers; they will pa int themselves and have a different origin. 404 // Don't include repaint rects for composited child layers; they will pa int themselves and have a different origin.
404 if (child->isComposited()) 405 if (child->isComposited())
405 continue; 406 continue;
406 407
407 repaintRect.unite(child->repaintRectIncludingNonCompositingDescendants() ); 408 repaintRect.unite(child->repaintRectIncludingNonCompositingDescendants() );
408 } 409 }
409 return repaintRect; 410 return repaintRect;
410 } 411 }
411 412
413 bool RenderLayer::hasNonAcceleratedBlendedChildInCurrentStackingContext() const
414 {
415 if (isComposited() && !backing()->paintsIntoCompositedAncestor())
416 return false;
417
418 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
419 if (child->hasBlendMode())
420 return true;
421
422 if (!child->isStackingContext() && child->hasNonAcceleratedBlendedChildI nCurrentStackingContext())
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
423 return true;
424 }
425
426 return false;
427 }
428
412 void RenderLayer::setAncestorChainHasSelfPaintingLayerDescendant() 429 void RenderLayer::setAncestorChainHasSelfPaintingLayerDescendant()
413 { 430 {
414 for (RenderLayer* layer = this; layer; layer = layer->parent()) { 431 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
415 if (!layer->m_hasSelfPaintingLayerDescendantDirty && layer->hasSelfPaint ingLayerDescendant()) 432 if (!layer->m_hasSelfPaintingLayerDescendantDirty && layer->hasSelfPaint ingLayerDescendant())
416 break; 433 break;
417 434
418 layer->m_hasSelfPaintingLayerDescendantDirty = false; 435 layer->m_hasSelfPaintingLayerDescendantDirty = false;
419 layer->m_hasSelfPaintingLayerDescendant = true; 436 layer->m_hasSelfPaintingLayerDescendant = true;
420 } 437 }
421 } 438 }
(...skipping 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1690 return clipRect; 1707 return clipRect;
1691 } 1708 }
1692 1709
1693 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)
1694 { 1711 {
1695 return intersection(transparencyClipBox(this, rootLayer, PaintingTransparenc yClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect); 1712 return intersection(transparencyClipBox(this, rootLayer, PaintingTransparenc yClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect);
1696 } 1713 }
1697 1714
1698 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)
1699 { 1716 {
1700 if (context->paintingDisabled() || (paintsWithTransparency(paintBehavior) && m_usedTransparency)) 1717 if (context->paintingDisabled() || ((paintsWithTransparency(paintBehavior) | | hasBlendMode() || m_isolateForDescendantBlendMode) && m_usedTransparency))
1701 return; 1718 return;
1702 1719
1703 RenderLayer* ancestor = transparentPaintingAncestor(); 1720 RenderLayer* ancestor = transparentPaintingAncestor();
1704 if (ancestor) 1721 if (ancestor)
1705 ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, pa intBehavior); 1722 ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, pa intBehavior);
1706 1723
1707 if (paintsWithTransparency(paintBehavior)) { 1724 if (paintsWithTransparency(paintBehavior) || hasBlendMode() || m_isolateForD escendantBlendMode) {
1708 m_usedTransparency = true; 1725 m_usedTransparency = true;
1709 context->save(); 1726 context->save();
1710 LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, paintBeh avior); 1727 LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, paintBeh avior);
1711 context->clip(clipRect); 1728 context->clip(clipRect);
1729 if (hasBlendMode())
1730 context->setCompositeOperation(context->compositeOperation(), m_blen dMode);
1731
1712 context->beginTransparencyLayer(renderer()->opacity()); 1732 context->beginTransparencyLayer(renderer()->opacity());
1713 #ifdef REVEAL_TRANSPARENCY_LAYERS 1733 #ifdef REVEAL_TRANSPARENCY_LAYERS
1714 context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f)); 1734 context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f));
1715 context->fillRect(clipRect); 1735 context->fillRect(clipRect);
1716 #endif 1736 #endif
1717 } 1737 }
1718 } 1738 }
1719 1739
1720 void* RenderLayer::operator new(size_t sz) 1740 void* RenderLayer::operator new(size_t sz)
1721 { 1741 {
(...skipping 1543 matching lines...) Expand 10 before | Expand all | Expand 10 after
3265 3285
3266 resourceClipper = toRenderSVGResourceClipper(element->renderer() ->toRenderSVGResourceContainer()); 3286 resourceClipper = toRenderSVGResourceClipper(element->renderer() ->toRenderSVGResourceContainer());
3267 if (!resourceClipper->applyClippingToContext(renderer(), rootRel ativeBounds, paintingInfo.paintDirtyRect, context)) { 3287 if (!resourceClipper->applyClippingToContext(renderer(), rootRel ativeBounds, paintingInfo.paintDirtyRect, context)) {
3268 // No need to post-apply the clipper if this failed. 3288 // No need to post-apply the clipper if this failed.
3269 resourceClipper = 0; 3289 resourceClipper = 0;
3270 } 3290 }
3271 } 3291 }
3272 } 3292 }
3273 } 3293 }
3274 3294
3295 // Blending operations must be performed only with the nearest ancestor stac king context.
3296 m_isolateForDescendantBlendMode = isStackingContext() && hasNonAcceleratedBl endedChildInCurrentStackingContext();
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
3297 if (m_isolateForDescendantBlendMode)
3298 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.pa intDirtyRect, paintingInfo.paintBehavior);
3299
3275 LayerPaintingInfo localPaintingInfo(paintingInfo); 3300 LayerPaintingInfo localPaintingInfo(paintingInfo);
3276 FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilte rs()); 3301 FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilte rs());
3277 if (filterPainter.haveFilterEffect() && !context->paintingDisabled()) { 3302 if (filterPainter.haveFilterEffect() && !context->paintingDisabled()) {
3278 RenderLayerFilterInfo* filterInfo = this->filterInfo(); 3303 RenderLayerFilterInfo* filterInfo = this->filterInfo();
3279 ASSERT(filterInfo); 3304 ASSERT(filterInfo);
3280 LayoutRect filterRepaintRect = filterInfo->dirtySourceRect(); 3305 LayoutRect filterRepaintRect = filterInfo->dirtySourceRect();
3281 filterRepaintRect.move(offsetFromRoot.x(), offsetFromRoot.y()); 3306 filterRepaintRect.move(offsetFromRoot.x(), offsetFromRoot.y());
3282 3307
3283 if (!rootRelativeBoundsComputed) { 3308 if (!rootRelativeBoundsComputed) {
3284 rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &o ffsetFromRoot, 0); 3309 rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &o ffsetFromRoot, 0);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
3380 restoreClip(transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect); 3405 restoreClip(transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect);
3381 } 3406 }
3382 3407
3383 // Make sure that we now use the original transparency context. 3408 // Make sure that we now use the original transparency context.
3384 ASSERT(transparencyLayerContext == context); 3409 ASSERT(transparencyLayerContext == context);
3385 3410
3386 if (shouldPaintMask) 3411 if (shouldPaintMask)
3387 paintMaskForFragments(layerFragments, context, localPaintingInfo, painti ngRootForRenderer); 3412 paintMaskForFragments(layerFragments, context, localPaintingInfo, painti ngRootForRenderer);
3388 3413
3389 // End our transparency layer 3414 // End our transparency layer
3390 if (haveTransparency && m_usedTransparency && !m_paintingInsideReflection) { 3415 if ((haveTransparency || hasBlendMode() || m_isolateForDescendantBlendMode) && m_usedTransparency && !m_paintingInsideReflection) {
3391 context->endLayer(); 3416 context->endLayer();
3392 context->restore(); 3417 context->restore();
3393 m_usedTransparency = false; 3418 m_usedTransparency = false;
3419 m_isolateForDescendantBlendMode = false;
3394 } 3420 }
3395 3421
3396 if (resourceClipper) 3422 if (resourceClipper)
3397 resourceClipper->postApplyResource(renderer(), context, ApplyToDefaultMo de, 0, 0); 3423 resourceClipper->postApplyResource(renderer(), context, ApplyToDefaultMo de, 0, 0);
3398 3424
3399 if (hasClipPath) 3425 if (hasClipPath)
3400 context->restore(); 3426 context->restore();
3401 } 3427 }
3402 3428
3403 void RenderLayer::paintLayerByApplyingTransform(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutPoint& translationOffset) 3429 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
3565 void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragmen ts, GraphicsContext* context, GraphicsContext* transparencyLayerContext, 3591 void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragmen ts, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
3566 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, 3592 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
3567 RenderObject* paintingRootForRenderer) 3593 RenderObject* paintingRootForRenderer)
3568 { 3594 {
3569 for (size_t i = 0; i < layerFragments.size(); ++i) { 3595 for (size_t i = 0; i < layerFragments.size(); ++i) {
3570 const LayerFragment& fragment = layerFragments.at(i); 3596 const LayerFragment& fragment = layerFragments.at(i);
3571 if (!fragment.shouldPaintContent) 3597 if (!fragment.shouldPaintContent)
3572 continue; 3598 continue;
3573 3599
3574 // Begin transparency layers lazily now that we know we have to paint so mething. 3600 // Begin transparency layers lazily now that we know we have to paint so mething.
3575 if (haveTransparency) 3601 if (haveTransparency || hasBlendMode())
3576 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo. rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior); 3602 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo. rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior);
3577 3603
3578 if (localPaintingInfo.clipToDirtyRect) { 3604 if (localPaintingInfo.clipToDirtyRect) {
3579 // Paint our background first, before painting any child layers. 3605 // Paint our background first, before painting any child layers.
3580 // Establish the clip used to paint our background. 3606 // Establish the clip used to paint our background.
3581 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.p aintDirtyRect, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Bac kground painting will handle clipping to self. 3607 clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.p aintDirtyRect, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Bac kground painting will handle clipping to self.
3582 } 3608 }
3583 3609
3584 // Paint the background. 3610 // Paint the background.
3585 // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info. 3611 // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
3586 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect .rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, loc alPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer()); 3612 PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect .rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, loc alPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
3587 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - r enderBoxLocation() + localPaintingInfo.subPixelAccumulation)); 3613 renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - r enderBoxLocation() + localPaintingInfo.subPixelAccumulation));
3588 3614
3589 if (localPaintingInfo.clipToDirtyRect) 3615 if (localPaintingInfo.clipToDirtyRect)
3590 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.back groundRect); 3616 restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.back groundRect);
3591 } 3617 }
3592 } 3618 }
3593 3619
3594 void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragmen ts, GraphicsContext* context, GraphicsContext* transparencyLayerContext, 3620 void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragmen ts, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
3595 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, 3621 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const L ayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
3596 RenderObject* paintingRootForRenderer, bool selectionOnly, bool forceBlackTe xt) 3622 RenderObject* paintingRootForRenderer, bool selectionOnly, bool forceBlackTe xt)
3597 { 3623 {
3598 // Begin transparency if we have something to paint. 3624 // Begin transparency if we have something to paint.
3599 if (haveTransparency) { 3625 if (haveTransparency || hasBlendMode()) {
3600 for (size_t i = 0; i < layerFragments.size(); ++i) { 3626 for (size_t i = 0; i < layerFragments.size(); ++i) {
3601 const LayerFragment& fragment = layerFragments.at(i); 3627 const LayerFragment& fragment = layerFragments.at(i);
3602 if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty( )) { 3628 if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty( )) {
3603 beginTransparencyLayers(transparencyLayerContext, localPaintingI nfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior); 3629 beginTransparencyLayers(transparencyLayerContext, localPaintingI nfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior);
3604 break; 3630 break;
3605 } 3631 }
3606 } 3632 }
3607 } 3633 }
3608 3634
3609 PaintBehavior localPaintBehavior = forceBlackText ? (PaintBehavior)PaintBeha viorForceBlackText : paintBehavior; 3635 PaintBehavior localPaintBehavior = forceBlackText ? (PaintBehavior)PaintBeha viorForceBlackText : paintBehavior;
(...skipping 2450 matching lines...) Expand 10 before | Expand all | Expand 10 after
6060 } 6086 }
6061 } 6087 }
6062 6088
6063 void showLayerTree(const WebCore::RenderObject* renderer) 6089 void showLayerTree(const WebCore::RenderObject* renderer)
6064 { 6090 {
6065 if (!renderer) 6091 if (!renderer)
6066 return; 6092 return;
6067 showLayerTree(renderer->enclosingLayer()); 6093 showLayerTree(renderer->enclosingLayer());
6068 } 6094 }
6069 #endif 6095 #endif
OLDNEW
« 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