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

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

Issue 2401343002: Tracking filter mutation via SVGElementProxy (Closed)
Patch Set: Rebase 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 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2859 return false; 2865 return false;
2860 2866
2861 return hasBoxDecorationsOrBackground() || hasOverflowControls(); 2867 return hasBoxDecorationsOrBackground() || hasOverflowControls();
2862 } 2868 }
2863 2869
2864 void PaintLayer::updateFilters(const ComputedStyle* oldStyle, 2870 void PaintLayer::updateFilters(const ComputedStyle* oldStyle,
2865 const ComputedStyle& newStyle) { 2871 const ComputedStyle& newStyle) {
2866 if (!newStyle.hasFilterInducingProperty() && 2872 if (!newStyle.hasFilterInducingProperty() &&
2867 (!oldStyle || !oldStyle->hasFilterInducingProperty())) 2873 (!oldStyle || !oldStyle->hasFilterInducingProperty()))
2868 return; 2874 return;
2869 2875 const bool hadFilterInfo = filterInfo();
2870 updateOrRemoveFilterClients(); 2876 if (newStyle.hasFilterInducingProperty())
2871 updateOrRemoveFilterEffect(); 2877 newStyle.filter().addClient(&ensureFilterInfo());
2878 if (hadFilterInfo && oldStyle)
2879 oldStyle->filter().removeClient(filterInfo());
2880 if (!newStyle.hasFilterInducingProperty()) {
2881 removeFilterInfo();
2882 return;
2883 }
2884 if (PaintLayerFilterInfo* filterInfo = this->filterInfo())
2885 filterInfo->invalidateFilterChain();
2872 } 2886 }
2873 2887
2874 bool PaintLayer::attemptDirectCompositingUpdate(StyleDifference diff, 2888 bool PaintLayer::attemptDirectCompositingUpdate(StyleDifference diff,
2875 const ComputedStyle* oldStyle) { 2889 const ComputedStyle* oldStyle) {
2876 CompositingReasons oldPotentialCompositingReasonsFromStyle = 2890 CompositingReasons oldPotentialCompositingReasonsFromStyle =
2877 potentialCompositingReasonsFromStyle(); 2891 potentialCompositingReasonsFromStyle();
2878 compositor()->updatePotentialCompositingReasonsFromStyle(this); 2892 compositor()->updatePotentialCompositingReasonsFromStyle(this);
2879 2893
2880 // This function implements an optimization for transforms and opacity. 2894 // This function implements an optimization for transforms and opacity.
2881 // A common pattern is for a touchmove handler to update the transform 2895 // A common pattern is for a touchmove handler to update the transform
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
3006 return builder.buildFilterOperations(style.backdropFilter()); 3020 return builder.buildFilterOperations(style.backdropFilter());
3007 } 3021 }
3008 3022
3009 PaintLayerFilterInfo& PaintLayer::ensureFilterInfo() { 3023 PaintLayerFilterInfo& PaintLayer::ensureFilterInfo() {
3010 PaintLayerRareData& rareData = ensureRareData(); 3024 PaintLayerRareData& rareData = ensureRareData();
3011 if (!rareData.filterInfo) 3025 if (!rareData.filterInfo)
3012 rareData.filterInfo = new PaintLayerFilterInfo(this); 3026 rareData.filterInfo = new PaintLayerFilterInfo(this);
3013 return *rareData.filterInfo; 3027 return *rareData.filterInfo;
3014 } 3028 }
3015 3029
3030 void PaintLayer::removeFilterInfo() {
3031 if (!m_rareData || !m_rareData->filterInfo)
3032 return;
3033 m_rareData->filterInfo->clearLayer();
3034 m_rareData->filterInfo = nullptr;
3035 }
3036
3016 void PaintLayer::removeAncestorOverflowLayer(const PaintLayer* removedLayer) { 3037 void PaintLayer::removeAncestorOverflowLayer(const PaintLayer* removedLayer) {
3017 // If the current ancestor overflow layer does not match the removed layer 3038 // If the current ancestor overflow layer does not match the removed layer
3018 // the ancestor overflow layer has changed so we can stop searching. 3039 // the ancestor overflow layer has changed so we can stop searching.
3019 if (ancestorOverflowLayer() && ancestorOverflowLayer() != removedLayer) 3040 if (ancestorOverflowLayer() && ancestorOverflowLayer() != removedLayer)
3020 return; 3041 return;
3021 3042
3022 if (ancestorOverflowLayer()) { 3043 if (ancestorOverflowLayer()) {
3023 // TODO(pdr): When slimming paint v2 is enabled, we will need to 3044 // TODO(pdr): When slimming paint v2 is enabled, we will need to
3024 // invalidate the scroll paint property subtree for this so main 3045 // invalidate the scroll paint property subtree for this so main
3025 // thread scroll reasons are recomputed. 3046 // thread scroll reasons are recomputed.
3026 ancestorOverflowLayer() 3047 ancestorOverflowLayer()
3027 ->getScrollableArea() 3048 ->getScrollableArea()
3028 ->invalidateStickyConstraintsFor(this); 3049 ->invalidateStickyConstraintsFor(this);
3029 } 3050 }
3030 updateAncestorOverflowLayer(nullptr); 3051 updateAncestorOverflowLayer(nullptr);
3031 PaintLayer* current = m_first; 3052 PaintLayer* current = m_first;
3032 while (current) { 3053 while (current) {
3033 current->removeAncestorOverflowLayer(removedLayer); 3054 current->removeAncestorOverflowLayer(removedLayer);
3034 current = current->nextSibling(); 3055 current = current->nextSibling();
3035 } 3056 }
3036 } 3057 }
3037 3058
3038 void PaintLayer::updateOrRemoveFilterClients() { 3059 FilterEffect* PaintLayer::lastFilterEffect() const {
3039 const auto& filter = layoutObject()->style()->filter();
3040 if (filter.isEmpty() && m_rareData && m_rareData->filterInfo) {
3041 m_rareData->filterInfo->clearLayer();
3042 m_rareData->filterInfo = nullptr;
3043 } else if (filter.hasReferenceFilter()) {
3044 ensureFilterInfo().updateReferenceFilterClients(filter);
3045 } else if (filterInfo()) {
3046 filterInfo()->clearFilterReferences();
3047 }
3048 }
3049
3050 FilterEffect* PaintLayer::updateFilterEffect() const {
3051 // TODO(chrishtr): ensure (and assert) that compositing is clean here. 3060 // TODO(chrishtr): ensure (and assert) that compositing is clean here.
3052
3053 if (!paintsWithFilters()) 3061 if (!paintsWithFilters())
3054 return nullptr; 3062 return nullptr;
3055
3056 PaintLayerFilterInfo* filterInfo = this->filterInfo(); 3063 PaintLayerFilterInfo* filterInfo = this->filterInfo();
3057 3064 DCHECK(filterInfo);
3058 // Should have been added by updateOrRemoveFilterEffect().
3059 ASSERT(filterInfo);
3060 3065
3061 if (filterInfo->lastEffect()) 3066 if (filterInfo->lastEffect())
3062 return filterInfo->lastEffect(); 3067 return filterInfo->lastEffect();
3063 3068
3064 const ComputedStyle& style = layoutObject()->styleRef(); 3069 const ComputedStyle& style = layoutObject()->styleRef();
3065 FloatRect zoomedReferenceBox; 3070 FloatRect zoomedReferenceBox;
3066 if (style.filter().hasReferenceFilter()) 3071 if (style.filter().hasReferenceFilter())
3067 zoomedReferenceBox = boxForFilter(); 3072 zoomedReferenceBox = boxForFilter();
3068 FilterEffectBuilder builder(enclosingNode(), zoomedReferenceBox, 3073 FilterEffectBuilder builder(enclosingNode(), zoomedReferenceBox,
3069 style.effectiveZoom()); 3074 style.effectiveZoom());
3070 filterInfo->setLastEffect( 3075 filterInfo->setLastEffect(
3071 builder.buildFilterEffect(addReflectionToFilterOperations(style))); 3076 builder.buildFilterEffect(addReflectionToFilterOperations(style)));
3072 return filterInfo->lastEffect(); 3077 return filterInfo->lastEffect();
3073 } 3078 }
3074 3079
3075 FilterEffect* PaintLayer::lastFilterEffect() const {
3076 return updateFilterEffect();
3077 }
3078
3079 FloatRect PaintLayer::mapRectForFilter(const FloatRect& rect) const { 3080 FloatRect PaintLayer::mapRectForFilter(const FloatRect& rect) const {
3080 if (!hasFilterThatMovesPixels()) 3081 if (!hasFilterThatMovesPixels())
3081 return rect; 3082 return rect;
3082 3083
3083 // Ensure the filter-chain is refreshed wrt reference filters. 3084 // Ensure the filter-chain is refreshed wrt reference filters.
3084 updateFilterEffect(); 3085 lastFilterEffect();
3085 3086
3086 FilterOperations filterOperations = 3087 FilterOperations filterOperations =
3087 addReflectionToFilterOperations(layoutObject()->styleRef()); 3088 addReflectionToFilterOperations(layoutObject()->styleRef());
3088 return filterOperations.mapRect(rect); 3089 return filterOperations.mapRect(rect);
3089 } 3090 }
3090 3091
3091 LayoutRect PaintLayer::mapLayoutRectForFilter(const LayoutRect& rect) const { 3092 LayoutRect PaintLayer::mapLayoutRectForFilter(const LayoutRect& rect) const {
3092 if (!hasFilterThatMovesPixels()) 3093 if (!hasFilterThatMovesPixels())
3093 return rect; 3094 return rect;
3094 return enclosingLayoutRect(mapRectForFilter(FloatRect(rect))); 3095 return enclosingLayoutRect(mapRectForFilter(FloatRect(rect)));
3095 } 3096 }
3096 3097
3097 bool PaintLayer::hasFilterThatMovesPixels() const { 3098 bool PaintLayer::hasFilterThatMovesPixels() const {
3098 if (!hasFilterInducingProperty()) 3099 if (!hasFilterInducingProperty())
3099 return false; 3100 return false;
3100 const ComputedStyle& style = layoutObject()->styleRef(); 3101 const ComputedStyle& style = layoutObject()->styleRef();
3101 if (style.hasFilter() && style.filter().hasFilterThatMovesPixels()) 3102 if (style.hasFilter() && style.filter().hasFilterThatMovesPixels())
3102 return true; 3103 return true;
3103 if (style.hasBoxReflect()) 3104 if (style.hasBoxReflect())
3104 return true; 3105 return true;
3105 return false; 3106 return false;
3106 } 3107 }
3107 3108
3108 void PaintLayer::updateOrRemoveFilterEffect() {
3109 // FilterEffectBuilder is only used to render the filters in software mode,
3110 // so we always need to run updateOrRemoveFilterEffect after the composited
3111 // mode might have changed for this layer.
3112 if (!paintsWithFilters()) {
3113 if (PaintLayerFilterInfo* filterInfo = this->filterInfo())
3114 filterInfo->setLastEffect(nullptr);
3115 return;
3116 }
3117
3118 ensureFilterInfo().setLastEffect(nullptr);
3119 }
3120
3121 void PaintLayer::filterNeedsPaintInvalidation() { 3109 void PaintLayer::filterNeedsPaintInvalidation() {
3122 { 3110 {
3123 DeprecatedScheduleStyleRecalcDuringLayout marker( 3111 DeprecatedScheduleStyleRecalcDuringLayout marker(
3124 layoutObject()->document().lifecycle()); 3112 layoutObject()->document().lifecycle());
3125 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a style 3113 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a style
3126 // recalc, which is a problem because this function can be called right 3114 // recalc, which is a problem because this function can be called right
3127 // before performing layout but after style recalc. 3115 // before performing layout but after style recalc.
3128 // 3116 //
3129 // See LayoutView::layout() and the call to 3117 // See LayoutView::layout() and the call to
3130 // invalidateSVGRootsWithRelativeLengthDescendents(). This violation is 3118 // invalidateSVGRootsWithRelativeLengthDescendents(). This violation is
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
3267 } 3255 }
3268 3256
3269 void showLayerTree(const blink::LayoutObject* layoutObject) { 3257 void showLayerTree(const blink::LayoutObject* layoutObject) {
3270 if (!layoutObject) { 3258 if (!layoutObject) {
3271 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n"); 3259 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n");
3272 return; 3260 return;
3273 } 3261 }
3274 showLayerTree(layoutObject->enclosingLayer()); 3262 showLayerTree(layoutObject->enclosingLayer());
3275 } 3263 }
3276 #endif 3264 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698