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

Side by Side Diff: third_party/WebKit/Source/core/paint/PaintLayer.cpp

Issue 2401343002: Tracking filter mutation via SVGElementProxy (Closed)
Patch Set: Fix fullscreen Created 4 years, 1 month 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 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
3 * reserved. 3 * reserved.
4 * 4 *
5 * Portions are Copyright (C) 1998 Netscape Communications Corporation. 5 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
6 * 6 *
7 * Other contributors: 7 * Other contributors:
8 * Robert O'Callahan <roc+@cs.cmu.edu> 8 * Robert O'Callahan <roc+@cs.cmu.edu>
9 * David Baron <dbaron@fas.harvard.edu> 9 * David Baron <dbaron@fas.harvard.edu>
10 * Christian Biesinger <cbiesinger@web.de> 10 * Christian Biesinger <cbiesinger@web.de>
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 if (!layoutObject->slowFirstChild() && layoutObject->style()) { 181 if (!layoutObject->slowFirstChild() && layoutObject->style()) {
182 m_isVisibleContentDirty = false; 182 m_isVisibleContentDirty = false;
183 m_hasVisibleContent = 183 m_hasVisibleContent =
184 layoutObject->style()->visibility() == EVisibility::Visible; 184 layoutObject->style()->visibility() == EVisibility::Visible;
185 } 185 }
186 186
187 updateScrollableArea(); 187 updateScrollableArea();
188 } 188 }
189 189
190 PaintLayer::~PaintLayer() { 190 PaintLayer::~PaintLayer() {
191 if (m_rareData && m_rareData->filterInfo) 191 if (m_rareData && m_rareData->filterInfo) {
192 layoutObject()->styleRef().filter().removeClient(m_rareData->filterInfo);
192 m_rareData->filterInfo->clearLayer(); 193 m_rareData->filterInfo->clearLayer();
194 }
193 if (layoutObject()->frame() && layoutObject()->frame()->page()) { 195 if (layoutObject()->frame() && layoutObject()->frame()->page()) {
194 if (ScrollingCoordinator* scrollingCoordinator = 196 if (ScrollingCoordinator* scrollingCoordinator =
195 layoutObject()->frame()->page()->scrollingCoordinator()) 197 layoutObject()->frame()->page()->scrollingCoordinator())
196 scrollingCoordinator->willDestroyLayer(this); 198 scrollingCoordinator->willDestroyLayer(this);
197 } 199 }
198 200
199 if (groupedMapping()) { 201 if (groupedMapping()) {
200 DisableCompositingQueryAsserts disabler; 202 DisableCompositingQueryAsserts disabler;
201 setGroupedMapping(0, InvalidateLayerAndRemoveFromMapping); 203 setGroupedMapping(0, InvalidateLayerAndRemoveFromMapping);
202 } 204 }
(...skipping 2441 matching lines...) Expand 10 before | Expand all | Expand 10 after
2644 2646
2645 void PaintLayer::ensureCompositedLayerMapping() { 2647 void PaintLayer::ensureCompositedLayerMapping() {
2646 if (m_rareData && m_rareData->compositedLayerMapping) 2648 if (m_rareData && m_rareData->compositedLayerMapping)
2647 return; 2649 return;
2648 2650
2649 ensureRareData().compositedLayerMapping = 2651 ensureRareData().compositedLayerMapping =
2650 wrapUnique(new CompositedLayerMapping(*this)); 2652 wrapUnique(new CompositedLayerMapping(*this));
2651 m_rareData->compositedLayerMapping->setNeedsGraphicsLayerUpdate( 2653 m_rareData->compositedLayerMapping->setNeedsGraphicsLayerUpdate(
2652 GraphicsLayerUpdateSubtree); 2654 GraphicsLayerUpdateSubtree);
2653 2655
2654 updateOrRemoveFilterEffect(); 2656 if (PaintLayerFilterInfo* filterInfo = this->filterInfo())
2657 filterInfo->invalidateFilterChain();
2655 } 2658 }
2656 2659
2657 void PaintLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) { 2660 void PaintLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) {
2658 if (!layerBeingDestroyed) { 2661 if (!layerBeingDestroyed) {
2659 // We need to make sure our decendants get a geometry update. In principle, 2662 // We need to make sure our decendants get a geometry update. In principle,
2660 // we could call setNeedsGraphicsLayerUpdate on our children, but that would 2663 // we could call setNeedsGraphicsLayerUpdate on our children, but that would
2661 // require walking the z-order lists to find them. Instead, we 2664 // require walking the z-order lists to find them. Instead, we
2662 // over-invalidate by marking our parent as needing a geometry update. 2665 // over-invalidate by marking our parent as needing a geometry update.
2663 if (PaintLayer* compositingParent = 2666 if (PaintLayer* compositingParent =
2664 enclosingLayerWithCompositedLayerMapping(ExcludeSelf)) 2667 enclosingLayerWithCompositedLayerMapping(ExcludeSelf))
2665 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUpdate( 2668 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUpdate(
2666 GraphicsLayerUpdateSubtree); 2669 GraphicsLayerUpdateSubtree);
2667 } 2670 }
2668 2671
2669 if (m_rareData) 2672 if (m_rareData)
2670 m_rareData->compositedLayerMapping.reset(); 2673 m_rareData->compositedLayerMapping.reset();
2671 2674
2672 if (!layerBeingDestroyed) 2675 if (layerBeingDestroyed)
2673 updateOrRemoveFilterEffect(); 2676 return;
2677
2678 if (PaintLayerFilterInfo* filterInfo = this->filterInfo())
2679 filterInfo->invalidateFilterChain();
2674 } 2680 }
2675 2681
2676 void PaintLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping, 2682 void PaintLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping,
2677 SetGroupMappingOptions options) { 2683 SetGroupMappingOptions options) {
2678 CompositedLayerMapping* oldGroupedMapping = this->groupedMapping(); 2684 CompositedLayerMapping* oldGroupedMapping = this->groupedMapping();
2679 if (groupedMapping == oldGroupedMapping) 2685 if (groupedMapping == oldGroupedMapping)
2680 return; 2686 return;
2681 2687
2682 if (options == InvalidateLayerAndRemoveFromMapping && oldGroupedMapping) { 2688 if (options == InvalidateLayerAndRemoveFromMapping && oldGroupedMapping) {
2683 oldGroupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree); 2689 oldGroupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
2858 return false; 2864 return false;
2859 2865
2860 return hasBoxDecorationsOrBackground() || hasOverflowControls(); 2866 return hasBoxDecorationsOrBackground() || hasOverflowControls();
2861 } 2867 }
2862 2868
2863 void PaintLayer::updateFilters(const ComputedStyle* oldStyle, 2869 void PaintLayer::updateFilters(const ComputedStyle* oldStyle,
2864 const ComputedStyle& newStyle) { 2870 const ComputedStyle& newStyle) {
2865 if (!newStyle.hasFilterInducingProperty() && 2871 if (!newStyle.hasFilterInducingProperty() &&
2866 (!oldStyle || !oldStyle->hasFilterInducingProperty())) 2872 (!oldStyle || !oldStyle->hasFilterInducingProperty()))
2867 return; 2873 return;
2868 2874 const bool hadFilterInfo = filterInfo();
2869 updateOrRemoveFilterClients(); 2875 if (newStyle.hasFilterInducingProperty())
2870 updateOrRemoveFilterEffect(); 2876 newStyle.filter().addClient(&ensureFilterInfo());
2877 if (hadFilterInfo && oldStyle)
2878 oldStyle->filter().removeClient(filterInfo());
2879 if (!newStyle.hasFilterInducingProperty()) {
2880 removeFilterInfo();
2881 return;
2882 }
2883 if (PaintLayerFilterInfo* filterInfo = this->filterInfo())
2884 filterInfo->invalidateFilterChain();
2871 } 2885 }
2872 2886
2873 bool PaintLayer::attemptDirectCompositingUpdate(StyleDifference diff, 2887 bool PaintLayer::attemptDirectCompositingUpdate(StyleDifference diff,
2874 const ComputedStyle* oldStyle) { 2888 const ComputedStyle* oldStyle) {
2875 CompositingReasons oldPotentialCompositingReasonsFromStyle = 2889 CompositingReasons oldPotentialCompositingReasonsFromStyle =
2876 potentialCompositingReasonsFromStyle(); 2890 potentialCompositingReasonsFromStyle();
2877 compositor()->updatePotentialCompositingReasonsFromStyle(this); 2891 compositor()->updatePotentialCompositingReasonsFromStyle(this);
2878 2892
2879 // This function implements an optimization for transforms and opacity. 2893 // This function implements an optimization for transforms and opacity.
2880 // A common pattern is for a touchmove handler to update the transform 2894 // A common pattern is for a touchmove handler to update the transform
2881 // and/or an opacity of an element every frame while the user moves their 2895 // and/or an opacity of an element every frame while the user moves their
2882 // finger across the screen. The conditions below recognize when the 2896 // finger across the screen. The conditions below recognize when the
2883 // compositing state is set up to receive a direct transform or opacity 2897 // compositing state is set up to receive a direct transform or opacity
2884 // update. 2898 // update.
2885 2899
2886 if (!diff.hasAtMostPropertySpecificDifferences( 2900 if (!diff.hasAtMostPropertySpecificDifferences(
2887 StyleDifference::TransformChanged | StyleDifference::OpacityChanged)) 2901 StyleDifference::TransformChanged | StyleDifference::OpacityChanged))
2888 return false; 2902 return false;
2889 // The potentialCompositingReasonsFromStyle could have changed without 2903 // The potentialCompositingReasonsFromStyle could have changed without
2890 // a corresponding StyleDifference if an animation started or ended. 2904 // a corresponding StyleDifference if an animation started or ended.
2891 if (potentialCompositingReasonsFromStyle() != 2905 if (potentialCompositingReasonsFromStyle() !=
2892 oldPotentialCompositingReasonsFromStyle) 2906 oldPotentialCompositingReasonsFromStyle)
2893 return false; 2907 return false;
2894 // If we're unwinding a scheduleSVGFilterLayerUpdateHack(), then we can't
2895 // perform a direct compositing update because the filters code is going
2896 // to produce different output this time around. We can remove this code
2897 // once we fix the chicken/egg bugs in the filters code and delete the
2898 // scheduleSVGFilterLayerUpdateHack().
2899 if (layoutObject()->node() &&
2900 layoutObject()->node()->svgFilterNeedsLayerUpdate())
2901 return false;
2902 if (!m_rareData || !m_rareData->compositedLayerMapping) 2908 if (!m_rareData || !m_rareData->compositedLayerMapping)
2903 return false; 2909 return false;
2904 2910
2905 // To cut off almost all the work in the compositing update for 2911 // To cut off almost all the work in the compositing update for
2906 // this case, we treat inline transforms has having assumed overlap 2912 // this case, we treat inline transforms has having assumed overlap
2907 // (similar to how we treat animated transforms). Notice that we read 2913 // (similar to how we treat animated transforms). Notice that we read
2908 // CompositingReasonInlineTransform from the m_compositingReasons, which 2914 // CompositingReasonInlineTransform from the m_compositingReasons, which
2909 // means that the inline transform actually triggered assumed overlap in 2915 // means that the inline transform actually triggered assumed overlap in
2910 // the overlap map. 2916 // the overlap map.
2911 if (diff.transformChanged() && 2917 if (diff.transformChanged() &&
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
3005 return builder.buildFilterOperations(style.backdropFilter()); 3011 return builder.buildFilterOperations(style.backdropFilter());
3006 } 3012 }
3007 3013
3008 PaintLayerFilterInfo& PaintLayer::ensureFilterInfo() { 3014 PaintLayerFilterInfo& PaintLayer::ensureFilterInfo() {
3009 PaintLayerRareData& rareData = ensureRareData(); 3015 PaintLayerRareData& rareData = ensureRareData();
3010 if (!rareData.filterInfo) 3016 if (!rareData.filterInfo)
3011 rareData.filterInfo = new PaintLayerFilterInfo(this); 3017 rareData.filterInfo = new PaintLayerFilterInfo(this);
3012 return *rareData.filterInfo; 3018 return *rareData.filterInfo;
3013 } 3019 }
3014 3020
3021 void PaintLayer::removeFilterInfo() {
3022 if (!m_rareData || !m_rareData->filterInfo)
3023 return;
3024 m_rareData->filterInfo->clearLayer();
3025 m_rareData->filterInfo = nullptr;
3026 }
3027
3015 void PaintLayer::removeAncestorOverflowLayer(const PaintLayer* removedLayer) { 3028 void PaintLayer::removeAncestorOverflowLayer(const PaintLayer* removedLayer) {
3016 // If the current ancestor overflow layer does not match the removed layer 3029 // If the current ancestor overflow layer does not match the removed layer
3017 // the ancestor overflow layer has changed so we can stop searching. 3030 // the ancestor overflow layer has changed so we can stop searching.
3018 if (ancestorOverflowLayer() && ancestorOverflowLayer() != removedLayer) 3031 if (ancestorOverflowLayer() && ancestorOverflowLayer() != removedLayer)
3019 return; 3032 return;
3020 3033
3021 if (ancestorOverflowLayer()) { 3034 if (ancestorOverflowLayer()) {
3022 // TODO(pdr): When slimming paint v2 is enabled, we will need to 3035 // TODO(pdr): When slimming paint v2 is enabled, we will need to
3023 // invalidate the scroll paint property subtree for this so main 3036 // invalidate the scroll paint property subtree for this so main
3024 // thread scroll reasons are recomputed. 3037 // thread scroll reasons are recomputed.
3025 ancestorOverflowLayer() 3038 ancestorOverflowLayer()
3026 ->getScrollableArea() 3039 ->getScrollableArea()
3027 ->invalidateStickyConstraintsFor(this); 3040 ->invalidateStickyConstraintsFor(this);
3028 } 3041 }
3029 updateAncestorOverflowLayer(nullptr); 3042 updateAncestorOverflowLayer(nullptr);
3030 PaintLayer* current = m_first; 3043 PaintLayer* current = m_first;
3031 while (current) { 3044 while (current) {
3032 current->removeAncestorOverflowLayer(removedLayer); 3045 current->removeAncestorOverflowLayer(removedLayer);
3033 current = current->nextSibling(); 3046 current = current->nextSibling();
3034 } 3047 }
3035 } 3048 }
3036 3049
3037 void PaintLayer::updateOrRemoveFilterClients() { 3050 FilterEffect* PaintLayer::lastFilterEffect() const {
3038 const auto& filter = layoutObject()->style()->filter();
3039 if (filter.isEmpty() && m_rareData && m_rareData->filterInfo) {
3040 m_rareData->filterInfo->clearLayer();
3041 m_rareData->filterInfo = nullptr;
3042 } else if (filter.hasReferenceFilter()) {
3043 ensureFilterInfo().updateReferenceFilterClients(filter);
3044 } else if (filterInfo()) {
3045 filterInfo()->clearFilterReferences();
3046 }
3047 }
3048
3049 FilterEffect* PaintLayer::updateFilterEffect() const {
3050 // TODO(chrishtr): ensure (and assert) that compositing is clean here. 3051 // TODO(chrishtr): ensure (and assert) that compositing is clean here.
3051
3052 if (!paintsWithFilters()) 3052 if (!paintsWithFilters())
3053 return nullptr; 3053 return nullptr;
3054
3055 PaintLayerFilterInfo* filterInfo = this->filterInfo(); 3054 PaintLayerFilterInfo* filterInfo = this->filterInfo();
3056
3057 // Should have been added by updateOrRemoveFilterEffect().
3058 DCHECK(filterInfo); 3055 DCHECK(filterInfo);
3059 3056
3060 if (filterInfo->lastEffect()) 3057 if (filterInfo->lastEffect())
3061 return filterInfo->lastEffect(); 3058 return filterInfo->lastEffect();
3062 3059
3063 const ComputedStyle& style = layoutObject()->styleRef(); 3060 const ComputedStyle& style = layoutObject()->styleRef();
3064 FloatRect zoomedReferenceBox; 3061 FloatRect zoomedReferenceBox;
3065 if (style.filter().hasReferenceFilter()) 3062 if (style.filter().hasReferenceFilter())
3066 zoomedReferenceBox = boxForFilter(); 3063 zoomedReferenceBox = boxForFilter();
3067 FilterEffectBuilder builder(enclosingNode(), zoomedReferenceBox, 3064 FilterEffectBuilder builder(enclosingNode(), zoomedReferenceBox,
3068 style.effectiveZoom()); 3065 style.effectiveZoom());
3069 filterInfo->setLastEffect( 3066 filterInfo->setLastEffect(
3070 builder.buildFilterEffect(addReflectionToFilterOperations(style))); 3067 builder.buildFilterEffect(addReflectionToFilterOperations(style)));
3071 return filterInfo->lastEffect(); 3068 return filterInfo->lastEffect();
3072 } 3069 }
3073 3070
3074 FilterEffect* PaintLayer::lastFilterEffect() const {
3075 return updateFilterEffect();
3076 }
3077
3078 FloatRect PaintLayer::mapRectForFilter(const FloatRect& rect) const { 3071 FloatRect PaintLayer::mapRectForFilter(const FloatRect& rect) const {
3079 if (!hasFilterThatMovesPixels()) 3072 if (!hasFilterThatMovesPixels())
3080 return rect; 3073 return rect;
3081 3074
3082 // Ensure the filter-chain is refreshed wrt reference filters. 3075 // Ensure the filter-chain is refreshed wrt reference filters.
3083 updateFilterEffect(); 3076 lastFilterEffect();
pdr. 2016/11/02 06:35:22 I agree with your and Elliott's review comments ab
fs 2016/11/02 15:49:22 After a somewhat related discussion with senorblan
3084 3077
3085 FilterOperations filterOperations = 3078 FilterOperations filterOperations =
3086 addReflectionToFilterOperations(layoutObject()->styleRef()); 3079 addReflectionToFilterOperations(layoutObject()->styleRef());
3087 return filterOperations.mapRect(rect); 3080 return filterOperations.mapRect(rect);
3088 } 3081 }
3089 3082
3090 LayoutRect PaintLayer::mapLayoutRectForFilter(const LayoutRect& rect) const { 3083 LayoutRect PaintLayer::mapLayoutRectForFilter(const LayoutRect& rect) const {
3091 if (!hasFilterThatMovesPixels()) 3084 if (!hasFilterThatMovesPixels())
3092 return rect; 3085 return rect;
3093 return enclosingLayoutRect(mapRectForFilter(FloatRect(rect))); 3086 return enclosingLayoutRect(mapRectForFilter(FloatRect(rect)));
3094 } 3087 }
3095 3088
3096 bool PaintLayer::hasFilterThatMovesPixels() const { 3089 bool PaintLayer::hasFilterThatMovesPixels() const {
3097 if (!hasFilterInducingProperty()) 3090 if (!hasFilterInducingProperty())
3098 return false; 3091 return false;
3099 const ComputedStyle& style = layoutObject()->styleRef(); 3092 const ComputedStyle& style = layoutObject()->styleRef();
3100 if (style.hasFilter() && style.filter().hasFilterThatMovesPixels()) 3093 if (style.hasFilter() && style.filter().hasFilterThatMovesPixels())
3101 return true; 3094 return true;
3102 if (style.hasBoxReflect()) 3095 if (style.hasBoxReflect())
3103 return true; 3096 return true;
3104 return false; 3097 return false;
3105 } 3098 }
3106 3099
3107 void PaintLayer::updateOrRemoveFilterEffect() {
3108 // FilterEffectBuilder is only used to render the filters in software mode,
3109 // so we always need to run updateOrRemoveFilterEffect after the composited
3110 // mode might have changed for this layer.
3111 if (!paintsWithFilters()) {
3112 if (PaintLayerFilterInfo* filterInfo = this->filterInfo())
3113 filterInfo->setLastEffect(nullptr);
3114 return;
3115 }
3116
3117 ensureFilterInfo().setLastEffect(nullptr);
3118 }
3119
3120 void PaintLayer::filterNeedsPaintInvalidation() {
3121 {
3122 DeprecatedScheduleStyleRecalcDuringLayout marker(
3123 layoutObject()->document().lifecycle());
3124 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a style
3125 // recalc, which is a problem because this function can be called right
3126 // before performing layout but after style recalc.
3127 //
3128 // See LayoutView::layout() and the call to
3129 // invalidateSVGRootsWithRelativeLengthDescendents(). This violation is
3130 // worked around in FrameView::updateStyleAndLayoutIfNeededRecursive() by
3131 // doing an extra style recalc and layout in case it's needed.
3132 toElement(layoutObject()->node())->scheduleSVGFilterLayerUpdateHack();
3133 }
3134
3135 layoutObject()->setShouldDoFullPaintInvalidation();
3136 }
3137
3138 void PaintLayer::addLayerHitTestRects(LayerHitTestRects& rects) const { 3100 void PaintLayer::addLayerHitTestRects(LayerHitTestRects& rects) const {
3139 computeSelfHitTestRects(rects); 3101 computeSelfHitTestRects(rects);
3140 for (PaintLayer* child = firstChild(); child; child = child->nextSibling()) 3102 for (PaintLayer* child = firstChild(); child; child = child->nextSibling())
3141 child->addLayerHitTestRects(rects); 3103 child->addLayerHitTestRects(rects);
3142 } 3104 }
3143 3105
3144 void PaintLayer::computeSelfHitTestRects(LayerHitTestRects& rects) const { 3106 void PaintLayer::computeSelfHitTestRects(LayerHitTestRects& rects) const {
3145 if (!size().isEmpty()) { 3107 if (!size().isEmpty()) {
3146 Vector<LayoutRect> rect; 3108 Vector<LayoutRect> rect;
3147 3109
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
3266 } 3228 }
3267 3229
3268 void showLayerTree(const blink::LayoutObject* layoutObject) { 3230 void showLayerTree(const blink::LayoutObject* layoutObject) {
3269 if (!layoutObject) { 3231 if (!layoutObject) {
3270 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n"); 3232 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n");
3271 return; 3233 return;
3272 } 3234 }
3273 showLayerTree(layoutObject->enclosingLayer()); 3235 showLayerTree(layoutObject->enclosingLayer());
3274 } 3236 }
3275 #endif 3237 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698