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

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

Issue 2401343002: Tracking filter mutation via SVGElementProxy (Closed)
Patch Set: referenceChanged -> proxiedElementChanged Created 4 years, 2 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 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 2444 matching lines...) Expand 10 before | Expand all | Expand 10 after
2647 2649
2648 void PaintLayer::ensureCompositedLayerMapping() { 2650 void PaintLayer::ensureCompositedLayerMapping() {
2649 if (m_rareData && m_rareData->compositedLayerMapping) 2651 if (m_rareData && m_rareData->compositedLayerMapping)
2650 return; 2652 return;
2651 2653
2652 ensureRareData().compositedLayerMapping = 2654 ensureRareData().compositedLayerMapping =
2653 wrapUnique(new CompositedLayerMapping(*this)); 2655 wrapUnique(new CompositedLayerMapping(*this));
2654 m_rareData->compositedLayerMapping->setNeedsGraphicsLayerUpdate( 2656 m_rareData->compositedLayerMapping->setNeedsGraphicsLayerUpdate(
2655 GraphicsLayerUpdateSubtree); 2657 GraphicsLayerUpdateSubtree);
2656 2658
2657 updateOrRemoveFilterEffect(); 2659 if (PaintLayerFilterInfo* filterInfo = this->filterInfo())
2660 filterInfo->invalidateFilterChain();
2658 } 2661 }
2659 2662
2660 void PaintLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) { 2663 void PaintLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) {
2661 if (!layerBeingDestroyed) { 2664 if (!layerBeingDestroyed) {
2662 // We need to make sure our decendants get a geometry update. In principle, 2665 // We need to make sure our decendants get a geometry update. In principle,
2663 // we could call setNeedsGraphicsLayerUpdate on our children, but that would 2666 // we could call setNeedsGraphicsLayerUpdate on our children, but that would
2664 // require walking the z-order lists to find them. Instead, we 2667 // require walking the z-order lists to find them. Instead, we
2665 // over-invalidate by marking our parent as needing a geometry update. 2668 // over-invalidate by marking our parent as needing a geometry update.
2666 if (PaintLayer* compositingParent = 2669 if (PaintLayer* compositingParent =
2667 enclosingLayerWithCompositedLayerMapping(ExcludeSelf)) 2670 enclosingLayerWithCompositedLayerMapping(ExcludeSelf))
2668 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUpdate( 2671 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUpdate(
2669 GraphicsLayerUpdateSubtree); 2672 GraphicsLayerUpdateSubtree);
2670 } 2673 }
2671 2674
2672 if (m_rareData) 2675 if (m_rareData)
2673 m_rareData->compositedLayerMapping.reset(); 2676 m_rareData->compositedLayerMapping.reset();
2674 2677
2675 if (!layerBeingDestroyed) 2678 if (layerBeingDestroyed)
2676 updateOrRemoveFilterEffect(); 2679 return;
2680
2681 if (PaintLayerFilterInfo* filterInfo = this->filterInfo())
2682 filterInfo->invalidateFilterChain();
2677 } 2683 }
2678 2684
2679 void PaintLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping, 2685 void PaintLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping,
2680 SetGroupMappingOptions options) { 2686 SetGroupMappingOptions options) {
2681 CompositedLayerMapping* oldGroupedMapping = this->groupedMapping(); 2687 CompositedLayerMapping* oldGroupedMapping = this->groupedMapping();
2682 if (groupedMapping == oldGroupedMapping) 2688 if (groupedMapping == oldGroupedMapping)
2683 return; 2689 return;
2684 2690
2685 if (options == InvalidateLayerAndRemoveFromMapping && oldGroupedMapping) { 2691 if (options == InvalidateLayerAndRemoveFromMapping && oldGroupedMapping) {
2686 oldGroupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree); 2692 oldGroupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
2861 return false; 2867 return false;
2862 2868
2863 return hasBoxDecorationsOrBackground() || hasOverflowControls(); 2869 return hasBoxDecorationsOrBackground() || hasOverflowControls();
2864 } 2870 }
2865 2871
2866 void PaintLayer::updateFilters(const ComputedStyle* oldStyle, 2872 void PaintLayer::updateFilters(const ComputedStyle* oldStyle,
2867 const ComputedStyle& newStyle) { 2873 const ComputedStyle& newStyle) {
2868 if (!newStyle.hasFilterInducingProperty() && 2874 if (!newStyle.hasFilterInducingProperty() &&
2869 (!oldStyle || !oldStyle->hasFilterInducingProperty())) 2875 (!oldStyle || !oldStyle->hasFilterInducingProperty()))
2870 return; 2876 return;
2871 2877 const bool hadFilterInfo = filterInfo();
2872 updateOrRemoveFilterClients(); 2878 if (newStyle.hasFilterInducingProperty())
2873 updateOrRemoveFilterEffect(); 2879 newStyle.filter().addClient(&ensureFilterInfo());
2880 if (hadFilterInfo && oldStyle)
2881 oldStyle->filter().removeClient(filterInfo());
2882 if (!newStyle.hasFilterInducingProperty()) {
2883 removeFilterInfo();
2884 return;
2885 }
2886 if (PaintLayerFilterInfo* filterInfo = this->filterInfo())
2887 filterInfo->invalidateFilterChain();
2874 } 2888 }
2875 2889
2876 bool PaintLayer::attemptDirectCompositingUpdate(StyleDifference diff, 2890 bool PaintLayer::attemptDirectCompositingUpdate(StyleDifference diff,
2877 const ComputedStyle* oldStyle) { 2891 const ComputedStyle* oldStyle) {
2878 CompositingReasons oldPotentialCompositingReasonsFromStyle = 2892 CompositingReasons oldPotentialCompositingReasonsFromStyle =
2879 potentialCompositingReasonsFromStyle(); 2893 potentialCompositingReasonsFromStyle();
2880 compositor()->updatePotentialCompositingReasonsFromStyle(this); 2894 compositor()->updatePotentialCompositingReasonsFromStyle(this);
2881 2895
2882 // This function implements an optimization for transforms and opacity. 2896 // This function implements an optimization for transforms and opacity.
2883 // A common pattern is for a touchmove handler to update the transform 2897 // A common pattern is for a touchmove handler to update the transform
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
3008 return builder.buildFilterOperations(style.backdropFilter()); 3022 return builder.buildFilterOperations(style.backdropFilter());
3009 } 3023 }
3010 3024
3011 PaintLayerFilterInfo& PaintLayer::ensureFilterInfo() { 3025 PaintLayerFilterInfo& PaintLayer::ensureFilterInfo() {
3012 PaintLayerRareData& rareData = ensureRareData(); 3026 PaintLayerRareData& rareData = ensureRareData();
3013 if (!rareData.filterInfo) 3027 if (!rareData.filterInfo)
3014 rareData.filterInfo = new PaintLayerFilterInfo(this); 3028 rareData.filterInfo = new PaintLayerFilterInfo(this);
3015 return *rareData.filterInfo; 3029 return *rareData.filterInfo;
3016 } 3030 }
3017 3031
3032 void PaintLayer::removeFilterInfo() {
3033 if (!m_rareData || !m_rareData->filterInfo)
3034 return;
3035 m_rareData->filterInfo->clearLayer();
3036 m_rareData->filterInfo = nullptr;
3037 }
3038
3018 void PaintLayer::removeAncestorOverflowLayer(const PaintLayer* removedLayer) { 3039 void PaintLayer::removeAncestorOverflowLayer(const PaintLayer* removedLayer) {
3019 // If the current ancestor overflow layer does not match the removed layer 3040 // If the current ancestor overflow layer does not match the removed layer
3020 // the ancestor overflow layer has changed so we can stop searching. 3041 // the ancestor overflow layer has changed so we can stop searching.
3021 if (ancestorOverflowLayer() && ancestorOverflowLayer() != removedLayer) 3042 if (ancestorOverflowLayer() && ancestorOverflowLayer() != removedLayer)
3022 return; 3043 return;
3023 3044
3024 if (ancestorOverflowLayer()) { 3045 if (ancestorOverflowLayer()) {
3025 // TODO(pdr): When slimming paint v2 is enabled, we will need to 3046 // TODO(pdr): When slimming paint v2 is enabled, we will need to
3026 // invalidate the scroll paint property subtree for this so main 3047 // invalidate the scroll paint property subtree for this so main
3027 // thread scroll reasons are recomputed. 3048 // thread scroll reasons are recomputed.
3028 ancestorOverflowLayer() 3049 ancestorOverflowLayer()
3029 ->getScrollableArea() 3050 ->getScrollableArea()
3030 ->invalidateStickyConstraintsFor(this); 3051 ->invalidateStickyConstraintsFor(this);
3031 } 3052 }
3032 updateAncestorOverflowLayer(nullptr); 3053 updateAncestorOverflowLayer(nullptr);
3033 PaintLayer* current = m_first; 3054 PaintLayer* current = m_first;
3034 while (current) { 3055 while (current) {
3035 current->removeAncestorOverflowLayer(removedLayer); 3056 current->removeAncestorOverflowLayer(removedLayer);
3036 current = current->nextSibling(); 3057 current = current->nextSibling();
3037 } 3058 }
3038 } 3059 }
3039 3060
3040 void PaintLayer::updateOrRemoveFilterClients() { 3061 FilterEffect* PaintLayer::lastFilterEffect() const {
3041 const auto& filter = layoutObject()->style()->filter();
3042 if (filter.isEmpty() && m_rareData && m_rareData->filterInfo) {
3043 m_rareData->filterInfo->clearLayer();
3044 m_rareData->filterInfo = nullptr;
3045 } else if (filter.hasReferenceFilter()) {
3046 ensureFilterInfo().updateReferenceFilterClients(filter);
3047 } else if (filterInfo()) {
3048 filterInfo()->clearFilterReferences();
3049 }
3050 }
3051
3052 FilterEffect* PaintLayer::updateFilterEffect() const {
3053 // TODO(chrishtr): ensure (and assert) that compositing is clean here. 3062 // TODO(chrishtr): ensure (and assert) that compositing is clean here.
3054
3055 if (!paintsWithFilters()) 3063 if (!paintsWithFilters())
3056 return nullptr; 3064 return nullptr;
3057
3058 PaintLayerFilterInfo* filterInfo = this->filterInfo(); 3065 PaintLayerFilterInfo* filterInfo = this->filterInfo();
3059
3060 // Should have been added by updateOrRemoveFilterEffect().
3061 DCHECK(filterInfo); 3066 DCHECK(filterInfo);
3062 3067
3063 if (filterInfo->lastEffect()) 3068 if (filterInfo->lastEffect())
3064 return filterInfo->lastEffect(); 3069 return filterInfo->lastEffect();
3065 3070
3066 const ComputedStyle& style = layoutObject()->styleRef(); 3071 const ComputedStyle& style = layoutObject()->styleRef();
3067 FloatRect zoomedReferenceBox; 3072 FloatRect zoomedReferenceBox;
3068 if (style.filter().hasReferenceFilter()) 3073 if (style.filter().hasReferenceFilter())
3069 zoomedReferenceBox = boxForFilter(); 3074 zoomedReferenceBox = boxForFilter();
3070 FilterEffectBuilder builder(enclosingNode(), zoomedReferenceBox, 3075 FilterEffectBuilder builder(enclosingNode(), zoomedReferenceBox,
3071 style.effectiveZoom()); 3076 style.effectiveZoom());
3072 filterInfo->setLastEffect( 3077 filterInfo->setLastEffect(
3073 builder.buildFilterEffect(addReflectionToFilterOperations(style))); 3078 builder.buildFilterEffect(addReflectionToFilterOperations(style)));
3074 return filterInfo->lastEffect(); 3079 return filterInfo->lastEffect();
3075 } 3080 }
3076 3081
3077 FilterEffect* PaintLayer::lastFilterEffect() const {
3078 return updateFilterEffect();
3079 }
3080
3081 FloatRect PaintLayer::mapRectForFilter(const FloatRect& rect) const { 3082 FloatRect PaintLayer::mapRectForFilter(const FloatRect& rect) const {
3082 if (!hasFilterThatMovesPixels()) 3083 if (!hasFilterThatMovesPixels())
3083 return rect; 3084 return rect;
3084 3085
3085 // Ensure the filter-chain is refreshed wrt reference filters. 3086 // Ensure the filter-chain is refreshed wrt reference filters.
3086 updateFilterEffect(); 3087 lastFilterEffect();
esprehn 2016/10/25 01:18:42 This is strange that it has side effects. Can we r
fs 2016/10/25 15:00:53 Sure. That would mean that every time this is call
3087 3088
3088 FilterOperations filterOperations = 3089 FilterOperations filterOperations =
3089 addReflectionToFilterOperations(layoutObject()->styleRef()); 3090 addReflectionToFilterOperations(layoutObject()->styleRef());
3090 return filterOperations.mapRect(rect); 3091 return filterOperations.mapRect(rect);
3091 } 3092 }
3092 3093
3093 LayoutRect PaintLayer::mapLayoutRectForFilter(const LayoutRect& rect) const { 3094 LayoutRect PaintLayer::mapLayoutRectForFilter(const LayoutRect& rect) const {
3094 if (!hasFilterThatMovesPixels()) 3095 if (!hasFilterThatMovesPixels())
3095 return rect; 3096 return rect;
3096 return enclosingLayoutRect(mapRectForFilter(FloatRect(rect))); 3097 return enclosingLayoutRect(mapRectForFilter(FloatRect(rect)));
3097 } 3098 }
3098 3099
3099 bool PaintLayer::hasFilterThatMovesPixels() const { 3100 bool PaintLayer::hasFilterThatMovesPixels() const {
3100 if (!hasFilterInducingProperty()) 3101 if (!hasFilterInducingProperty())
3101 return false; 3102 return false;
3102 const ComputedStyle& style = layoutObject()->styleRef(); 3103 const ComputedStyle& style = layoutObject()->styleRef();
3103 if (style.hasFilter() && style.filter().hasFilterThatMovesPixels()) 3104 if (style.hasFilter() && style.filter().hasFilterThatMovesPixels())
3104 return true; 3105 return true;
3105 if (style.hasBoxReflect()) 3106 if (style.hasBoxReflect())
3106 return true; 3107 return true;
3107 return false; 3108 return false;
3108 } 3109 }
3109 3110
3110 void PaintLayer::updateOrRemoveFilterEffect() {
3111 // FilterEffectBuilder is only used to render the filters in software mode,
3112 // so we always need to run updateOrRemoveFilterEffect after the composited
3113 // mode might have changed for this layer.
3114 if (!paintsWithFilters()) {
3115 if (PaintLayerFilterInfo* filterInfo = this->filterInfo())
3116 filterInfo->setLastEffect(nullptr);
3117 return;
3118 }
3119
3120 ensureFilterInfo().setLastEffect(nullptr);
3121 }
3122
3123 void PaintLayer::filterNeedsPaintInvalidation() { 3111 void PaintLayer::filterNeedsPaintInvalidation() {
3124 { 3112 {
3125 DeprecatedScheduleStyleRecalcDuringLayout marker( 3113 DeprecatedScheduleStyleRecalcDuringLayout marker(
3126 layoutObject()->document().lifecycle()); 3114 layoutObject()->document().lifecycle());
3127 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a style 3115 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a style
3128 // recalc, which is a problem because this function can be called right 3116 // recalc, which is a problem because this function can be called right
3129 // before performing layout but after style recalc. 3117 // before performing layout but after style recalc.
3130 // 3118 //
3131 // See LayoutView::layout() and the call to 3119 // See LayoutView::layout() and the call to
3132 // invalidateSVGRootsWithRelativeLengthDescendents(). This violation is 3120 // invalidateSVGRootsWithRelativeLengthDescendents(). This violation is
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
3269 } 3257 }
3270 3258
3271 void showLayerTree(const blink::LayoutObject* layoutObject) { 3259 void showLayerTree(const blink::LayoutObject* layoutObject) {
3272 if (!layoutObject) { 3260 if (!layoutObject) {
3273 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n"); 3261 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n");
3274 return; 3262 return;
3275 } 3263 }
3276 showLayerTree(layoutObject->enclosingLayer()); 3264 showLayerTree(layoutObject->enclosingLayer());
3277 } 3265 }
3278 #endif 3266 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698