OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |