OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |