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

Side by Side Diff: Source/core/rendering/RenderLayer.cpp

Issue 423823004: Add support for SVG Clip paths in HTML (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Changed LayoutTests and Aligned with review comments Created 6 years, 4 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 1823 matching lines...) Expand 10 before | Expand all | Expand 10 after
1834 if (style->clipPath()->type() == ClipPathOperation::SHAPE) { 1834 if (style->clipPath()->type() == ClipPathOperation::SHAPE) {
1835 clipStateSaver.save(); 1835 clipStateSaver.save();
1836 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style->c lipPath()); 1836 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style->c lipPath());
1837 1837
1838 if (!rootRelativeBoundsComputed) { 1838 if (!rootRelativeBoundsComputed) {
1839 rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndSt ackingChildren(paintingInfo.rootLayer, offsetFromRoot); 1839 rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndSt ackingChildren(paintingInfo.rootLayer, offsetFromRoot);
1840 rootRelativeBoundsComputed = true; 1840 rootRelativeBoundsComputed = true;
1841 } 1841 }
1842 1842
1843 context->clipPath(clipPath->path(rootRelativeBounds), clipPath->wind Rule()); 1843 context->clipPath(clipPath->path(rootRelativeBounds), clipPath->wind Rule());
1844 } else if (style->clipPath()->type() == ClipPathOperation::REFERENCE) { 1844 } else if (m_clipPathInfo && m_clipPathInfo->getClipPathElement() && m_c lipPathInfo->getClipPathElement()->renderer()) {
1845 ReferenceClipPathOperation* referenceClipPathOperation = toReference ClipPathOperation(style->clipPath());
1846 Document& document = renderer()->document();
1847 // FIXME: It doesn't work with forward or external SVG references (h ttps://bugs.webkit.org/show_bug.cgi?id=90405) 1845 // FIXME: It doesn't work with forward or external SVG references (h ttps://bugs.webkit.org/show_bug.cgi?id=90405)
1848 Element* element = document.getElementById(referenceClipPathOperatio n->fragment()); 1846 // FIXME: Saving at this point is not required in the 'mask'-
1849 if (isSVGClipPathElement(element) && element->renderer()) { 1847 // case, or if the clip ends up empty.
1850 // FIXME: Saving at this point is not required in the 'mask'- 1848 clipStateSaver.save();
1851 // case, or if the clip ends up empty. 1849 if (!rootRelativeBoundsComputed) {
1852 clipStateSaver.save(); 1850 rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndSt ackingChildren(paintingInfo.rootLayer, offsetFromRoot);
1853 if (!rootRelativeBoundsComputed) { 1851 rootRelativeBoundsComputed = true;
1854 rootRelativeBounds = physicalBoundingBoxIncludingReflectionA ndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); 1852 }
1855 rootRelativeBoundsComputed = true;
1856 }
1857 1853
1858 resourceClipper = toRenderSVGResourceClipper(toRenderSVGResource Container(element->renderer())); 1854 resourceClipper = toRenderSVGResourceClipper(toRenderSVGResourceCont ainer(m_clipPathInfo->getClipPathElement()->renderer()));
1859 if (!resourceClipper->applyClippingToContext(renderer(), rootRel ativeBounds, 1855 if (!resourceClipper->applyClippingToContext(renderer(), rootRelativ eBounds,
1860 paintingInfo.paintDirtyRect, context, clipperContext)) { 1856 paintingInfo.paintDirtyRect, context, clipperContext)) {
1861 // No need to post-apply the clipper if this failed. 1857 // No need to post-apply the clipper if this failed.
1862 resourceClipper = 0; 1858 resourceClipper = 0;
1863 }
1864 } 1859 }
1865 } 1860 }
1866 } 1861 }
1867 1862
1868 // Blending operations must be performed only with the nearest ancestor stac king context. 1863 // Blending operations must be performed only with the nearest ancestor stac king context.
1869 // Note that there is no need to create a transparency layer if we're painti ng the root. 1864 // Note that there is no need to create a transparency layer if we're painti ng the root.
1870 bool createTransparencyLayerForBlendMode = !renderer()->isDocumentElement() && m_stackingNode->isStackingContext() && m_blendInfo.childLayerHasBlendMode(); 1865 bool createTransparencyLayerForBlendMode = !renderer()->isDocumentElement() && m_stackingNode->isStackingContext() && m_blendInfo.childLayerHasBlendMode();
1871 1866
1872 if (createTransparencyLayerForBlendMode) 1867 if (createTransparencyLayerForBlendMode)
1873 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.pa intDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior); 1868 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.pa intDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
(...skipping 1668 matching lines...) Expand 10 before | Expand all | Expand 10 after
3542 3537
3543 void RenderLayer::updateFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle) 3538 void RenderLayer::updateFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle)
3544 { 3539 {
3545 if (!newStyle->hasFilter() && (!oldStyle || !oldStyle->hasFilter())) 3540 if (!newStyle->hasFilter() && (!oldStyle || !oldStyle->hasFilter()))
3546 return; 3541 return;
3547 3542
3548 updateOrRemoveFilterClients(); 3543 updateOrRemoveFilterClients();
3549 updateOrRemoveFilterEffectRenderer(); 3544 updateOrRemoveFilterEffectRenderer();
3550 } 3545 }
3551 3546
3547 void RenderLayer::updateClipPathInfo(const RenderStyle* oldStyle, const RenderSt yle* newStyle)
3548 {
3549 if (!newStyle->clipPath() && (!oldStyle || !oldStyle->clipPath()))
3550 return;
3551
3552 if (renderer()->hasClipPath() && renderer()->style()->clipPath()->type() == ClipPathOperation::REFERENCE) {
3553 if (!m_clipPathInfo)
3554 m_clipPathInfo = adoptPtr(new RenderLayerClipPathInfo(this));
3555 m_clipPathInfo->updateReferenceClipPathClients(renderer()->style()->clip Path());
3556 } else if (m_clipPathInfo) {
3557 m_clipPathInfo = nullptr;
3558 }
3559 }
3560
3552 bool RenderLayer::attemptDirectCompositingUpdate(StyleDifference diff, const Ren derStyle* oldStyle) 3561 bool RenderLayer::attemptDirectCompositingUpdate(StyleDifference diff, const Ren derStyle* oldStyle)
3553 { 3562 {
3554 CompositingReasons oldPotentialCompositingReasonsFromStyle = m_potentialComp ositingReasonsFromStyle; 3563 CompositingReasons oldPotentialCompositingReasonsFromStyle = m_potentialComp ositingReasonsFromStyle;
3555 compositor()->updatePotentialCompositingReasonsFromStyle(this); 3564 compositor()->updatePotentialCompositingReasonsFromStyle(this);
3556 3565
3557 // This function implements an optimization for transforms and opacity. 3566 // This function implements an optimization for transforms and opacity.
3558 // A common pattern is for a touchmove handler to update the transform 3567 // A common pattern is for a touchmove handler to update the transform
3559 // and/or an opacity of an element every frame while the user moves their 3568 // and/or an opacity of an element every frame while the user moves their
3560 // finger across the screen. The conditions below recognize when the 3569 // finger across the screen. The conditions below recognize when the
3561 // compositing state is set up to receive a direct transform or opacity 3570 // compositing state is set up to receive a direct transform or opacity
3562 // update. 3571 // update.
3563 3572
3564 if (!diff.hasAtMostPropertySpecificDifferences(StyleDifference::TransformCha nged | StyleDifference::OpacityChanged)) 3573 if (!diff.hasAtMostPropertySpecificDifferences(StyleDifference::TransformCha nged | StyleDifference::OpacityChanged))
3565 return false; 3574 return false;
3566 // The potentialCompositingReasonsFromStyle could have changed without 3575 // The potentialCompositingReasonsFromStyle could have changed without
3567 // a corresponding StyleDifference if an animation started or ended. 3576 // a corresponding StyleDifference if an animation started or ended.
3568 if (m_potentialCompositingReasonsFromStyle != oldPotentialCompositingReasons FromStyle) 3577 if (m_potentialCompositingReasonsFromStyle != oldPotentialCompositingReasons FromStyle)
3569 return false; 3578 return false;
3570 // We could add support for reflections if we updated the transform on 3579 // We could add support for reflections if we updated the transform on
3571 // the reflection layers. 3580 // the reflection layers.
3572 if (renderer()->hasReflection()) 3581 if (renderer()->hasReflection())
3573 return false; 3582 return false;
3574 // If we're unwinding a scheduleSVGFilterLayerUpdateHack(), then we can't 3583 // If we're unwinding a scheduleSVGEffectsLayerUpdateHack(), then we can't
3575 // perform a direct compositing update because the filters code is going 3584 // perform a direct compositing update because the filters code is going
3576 // to produce different output this time around. We can remove this code 3585 // to produce different output this time around. We can remove this code
3577 // once we fix the chicken/egg bugs in the filters code and delete the 3586 // once we fix the chicken/egg bugs in the filters code and delete the
3578 // scheduleSVGFilterLayerUpdateHack(). 3587 // scheduleSVGEffectsLayerUpdateHack().
3579 if (renderer()->node() && renderer()->node()->svgFilterNeedsLayerUpdate()) 3588 if (renderer()->node() && renderer()->node()->svgEffectsNeedLayerUpdate())
3580 return false; 3589 return false;
3581 if (!m_compositedLayerMapping) 3590 if (!m_compositedLayerMapping)
3582 return false; 3591 return false;
3583 3592
3584 // To cut off almost all the work in the compositing update for 3593 // To cut off almost all the work in the compositing update for
3585 // this case, we treat inline transforms has having assumed overlap 3594 // this case, we treat inline transforms has having assumed overlap
3586 // (similar to how we treat animated transforms). Notice that we read 3595 // (similar to how we treat animated transforms). Notice that we read
3587 // CompositingReasonInlineTransform from the m_compositingReasons, which 3596 // CompositingReasonInlineTransform from the m_compositingReasons, which
3588 // means that the inline transform actually triggered assumed overlap in 3597 // means that the inline transform actually triggered assumed overlap in
3589 // the overlap map. 3598 // the overlap map.
(...skipping 30 matching lines...) Expand all
3620 3629
3621 // Overlay scrollbars can make this layer self-painting so we need 3630 // Overlay scrollbars can make this layer self-painting so we need
3622 // to recompute the bit once scrollbars have been updated. 3631 // to recompute the bit once scrollbars have been updated.
3623 updateSelfPaintingLayer(); 3632 updateSelfPaintingLayer();
3624 3633
3625 if (!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle)) { 3634 if (!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle)) {
3626 ASSERT(!oldStyle || diff.needsFullLayout()); 3635 ASSERT(!oldStyle || diff.needsFullLayout());
3627 updateReflectionInfo(oldStyle); 3636 updateReflectionInfo(oldStyle);
3628 } 3637 }
3629 3638
3639 updateClipPathInfo(oldStyle, renderer()->style());
3640
3630 if (RuntimeEnabledFeatures::cssCompositingEnabled()) 3641 if (RuntimeEnabledFeatures::cssCompositingEnabled())
3631 m_blendInfo.updateBlendMode(); 3642 m_blendInfo.updateBlendMode();
3632 3643
3633 updateDescendantDependentFlags(); 3644 updateDescendantDependentFlags();
3634 3645
3635 updateTransform(oldStyle, renderer()->style()); 3646 updateTransform(oldStyle, renderer()->style());
3636 updateFilters(oldStyle, renderer()->style()); 3647 updateFilters(oldStyle, renderer()->style());
3637 3648
3638 setNeedsCompositingInputsUpdate(); 3649 setNeedsCompositingInputsUpdate();
3639 } 3650 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3707 // We can optimize away code paths in other places if we know that there are no software filters. 3718 // We can optimize away code paths in other places if we know that there are no software filters.
3708 renderer()->document().view()->setHasSoftwareFilters(true); 3719 renderer()->document().view()->setHasSoftwareFilters(true);
3709 } 3720 }
3710 3721
3711 // If the filter fails to build, remove it from the layer. It will still att empt to 3722 // If the filter fails to build, remove it from the layer. It will still att empt to
3712 // go through regular processing (e.g. compositing), but never apply anythin g. 3723 // go through regular processing (e.g. compositing), but never apply anythin g.
3713 if (!filterInfo->renderer()->build(renderer(), computeFilterOperations(rende rer()->style()))) 3724 if (!filterInfo->renderer()->build(renderer(), computeFilterOperations(rende rer()->style())))
3714 filterInfo->setRenderer(nullptr); 3725 filterInfo->setRenderer(nullptr);
3715 } 3726 }
3716 3727
3717 void RenderLayer::filterNeedsPaintInvalidation() 3728 void RenderLayer::svgEffectsNeedPaintInvalidation()
esprehn 2014/08/06 17:25:10 We should not be adding more callers of this or sc
3718 { 3729 {
3719 { 3730 {
3720 DeprecatedScheduleStyleRecalcDuringLayout marker(renderer()->document(). lifecycle()); 3731 DeprecatedScheduleStyleRecalcDuringLayout marker(renderer()->document(). lifecycle());
3721 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a styl e recalc, which 3732 // It's possible for scheduleSVGEffectsLayerUpdateHack to schedule a sty le recalc, which
3722 // is a problem because this function can be called while performing lay out. 3733 // is a problem because this function can be called while performing lay out.
3723 // Presumably this represents an illegal data flow of layout or composit ing 3734 // Presumably this represents an illegal data flow of layout or composit ing
3724 // information into the style system. 3735 // information into the style system.
3725 toElement(renderer()->node())->scheduleSVGFilterLayerUpdateHack(); 3736 toElement(renderer()->node())->scheduleSVGEffectsLayerUpdateHack();
3726 } 3737 }
3727 3738
3728 if (renderer()->view()) { 3739 if (renderer()->view()) {
3729 if (renderer()->frameView()->isInPerformLayout()) 3740 if (renderer()->frameView()->isInPerformLayout())
3730 renderer()->setShouldDoFullPaintInvalidation(true); 3741 renderer()->setShouldDoFullPaintInvalidation(true);
3731 else 3742 else
3732 renderer()->paintInvalidationForWholeRenderer(); 3743 renderer()->paintInvalidationForWholeRenderer();
3733 } 3744 }
3734 } 3745 }
3735 3746
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3790 } 3801 }
3791 } 3802 }
3792 3803
3793 void showLayerTree(const blink::RenderObject* renderer) 3804 void showLayerTree(const blink::RenderObject* renderer)
3794 { 3805 {
3795 if (!renderer) 3806 if (!renderer)
3796 return; 3807 return;
3797 showLayerTree(renderer->enclosingLayer()); 3808 showLayerTree(renderer->enclosingLayer());
3798 } 3809 }
3799 #endif 3810 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698