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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |