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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 * version of this file under any of the LGPL, the MPL or the GPL. | 42 * version of this file under any of the LGPL, the MPL or the GPL. |
43 */ | 43 */ |
44 | 44 |
45 #include "core/paint/PaintLayer.h" | 45 #include "core/paint/PaintLayer.h" |
46 | 46 |
47 #include "core/CSSPropertyNames.h" | 47 #include "core/CSSPropertyNames.h" |
48 #include "core/HTMLNames.h" | 48 #include "core/HTMLNames.h" |
49 #include "core/css/PseudoStyleRequest.h" | 49 #include "core/css/PseudoStyleRequest.h" |
50 #include "core/dom/Document.h" | 50 #include "core/dom/Document.h" |
51 #include "core/dom/shadow/ShadowRoot.h" | 51 #include "core/dom/shadow/ShadowRoot.h" |
52 #include "core/frame/DeprecatedScheduleStyleRecalcDuringLayout.h" | |
53 #include "core/frame/FrameView.h" | 52 #include "core/frame/FrameView.h" |
54 #include "core/frame/LocalFrame.h" | 53 #include "core/frame/LocalFrame.h" |
55 #include "core/frame/Settings.h" | 54 #include "core/frame/Settings.h" |
56 #include "core/html/HTMLFrameElement.h" | |
57 #include "core/layout/FragmentainerIterator.h" | 55 #include "core/layout/FragmentainerIterator.h" |
58 #include "core/layout/HitTestRequest.h" | 56 #include "core/layout/HitTestRequest.h" |
59 #include "core/layout/HitTestResult.h" | 57 #include "core/layout/HitTestResult.h" |
60 #include "core/layout/HitTestingTransformState.h" | 58 #include "core/layout/HitTestingTransformState.h" |
61 #include "core/layout/LayoutFlowThread.h" | 59 #include "core/layout/LayoutFlowThread.h" |
62 #include "core/layout/LayoutInline.h" | 60 #include "core/layout/LayoutInline.h" |
63 #include "core/layout/LayoutPart.h" | 61 #include "core/layout/LayoutPart.h" |
64 #include "core/layout/LayoutTreeAsText.h" | 62 #include "core/layout/LayoutTreeAsText.h" |
65 #include "core/layout/LayoutView.h" | 63 #include "core/layout/LayoutView.h" |
66 #include "core/layout/api/LayoutPartItem.h" | 64 #include "core/layout/api/LayoutPartItem.h" |
67 #include "core/layout/api/LayoutViewItem.h" | 65 #include "core/layout/api/LayoutViewItem.h" |
68 #include "core/layout/compositing/CompositedLayerMapping.h" | 66 #include "core/layout/compositing/CompositedLayerMapping.h" |
69 #include "core/layout/compositing/PaintLayerCompositor.h" | 67 #include "core/layout/compositing/PaintLayerCompositor.h" |
70 #include "core/layout/svg/LayoutSVGResourceClipper.h" | 68 #include "core/layout/svg/LayoutSVGResourceClipper.h" |
71 #include "core/layout/svg/LayoutSVGRoot.h" | 69 #include "core/layout/svg/LayoutSVGRoot.h" |
72 #include "core/page/Page.h" | 70 #include "core/page/Page.h" |
73 #include "core/page/scrolling/ScrollingCoordinator.h" | 71 #include "core/page/scrolling/ScrollingCoordinator.h" |
74 #include "core/paint/BoxReflectionUtils.h" | 72 #include "core/paint/BoxReflectionUtils.h" |
75 #include "core/paint/FilterEffectBuilder.h" | 73 #include "core/paint/FilterEffectBuilder.h" |
76 #include "core/paint/ObjectPaintInvalidator.h" | 74 #include "core/paint/ObjectPaintInvalidator.h" |
77 #include "core/paint/PaintTiming.h" | 75 #include "core/paint/PaintTiming.h" |
78 #include "platform/LengthFunctions.h" | 76 #include "platform/LengthFunctions.h" |
79 #include "platform/RuntimeEnabledFeatures.h" | 77 #include "platform/RuntimeEnabledFeatures.h" |
80 #include "platform/geometry/FloatPoint3D.h" | 78 #include "platform/geometry/FloatPoint3D.h" |
81 #include "platform/geometry/FloatRect.h" | 79 #include "platform/geometry/FloatRect.h" |
82 #include "platform/geometry/TransformState.h" | 80 #include "platform/geometry/TransformState.h" |
83 #include "platform/graphics/CompositorFilterOperations.h" | 81 #include "platform/graphics/CompositorFilterOperations.h" |
84 #include "platform/graphics/filters/Filter.h" | 82 #include "platform/graphics/filters/Filter.h" |
85 #include "platform/graphics/filters/SkiaImageFilterBuilder.h" | |
86 #include "platform/tracing/TraceEvent.h" | 83 #include "platform/tracing/TraceEvent.h" |
87 #include "platform/transforms/ScaleTransformOperation.h" | |
88 #include "platform/transforms/TransformationMatrix.h" | 84 #include "platform/transforms/TransformationMatrix.h" |
89 #include "platform/transforms/TranslateTransformOperation.h" | |
90 #include "wtf/PtrUtil.h" | 85 #include "wtf/PtrUtil.h" |
91 #include "wtf/StdLibExtras.h" | 86 #include "wtf/StdLibExtras.h" |
92 #include "wtf/allocator/Partitions.h" | 87 #include "wtf/allocator/Partitions.h" |
93 #include "wtf/text/CString.h" | 88 #include "wtf/text/CString.h" |
94 | 89 |
95 namespace blink { | 90 namespace blink { |
96 | 91 |
97 namespace { | 92 namespace { |
98 | 93 |
99 static CompositingQueryMode gCompositingQueryMode = | 94 static CompositingQueryMode gCompositingQueryMode = |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 if (!layoutObject->slowFirstChild() && layoutObject->style()) { | 172 if (!layoutObject->slowFirstChild() && layoutObject->style()) { |
178 m_isVisibleContentDirty = false; | 173 m_isVisibleContentDirty = false; |
179 m_hasVisibleContent = | 174 m_hasVisibleContent = |
180 layoutObject->style()->visibility() == EVisibility::Visible; | 175 layoutObject->style()->visibility() == EVisibility::Visible; |
181 } | 176 } |
182 | 177 |
183 updateScrollableArea(); | 178 updateScrollableArea(); |
184 } | 179 } |
185 | 180 |
186 PaintLayer::~PaintLayer() { | 181 PaintLayer::~PaintLayer() { |
187 if (m_rareData && m_rareData->filterInfo) | 182 if (m_rareData && m_rareData->filterInfo) { |
| 183 layoutObject()->styleRef().filter().removeClient(m_rareData->filterInfo); |
188 m_rareData->filterInfo->clearLayer(); | 184 m_rareData->filterInfo->clearLayer(); |
| 185 } |
189 if (layoutObject()->frame() && layoutObject()->frame()->page()) { | 186 if (layoutObject()->frame() && layoutObject()->frame()->page()) { |
190 if (ScrollingCoordinator* scrollingCoordinator = | 187 if (ScrollingCoordinator* scrollingCoordinator = |
191 layoutObject()->frame()->page()->scrollingCoordinator()) | 188 layoutObject()->frame()->page()->scrollingCoordinator()) |
192 scrollingCoordinator->willDestroyLayer(this); | 189 scrollingCoordinator->willDestroyLayer(this); |
193 } | 190 } |
194 | 191 |
195 if (groupedMapping()) { | 192 if (groupedMapping()) { |
196 DisableCompositingQueryAsserts disabler; | 193 DisableCompositingQueryAsserts disabler; |
197 setGroupedMapping(0, InvalidateLayerAndRemoveFromMapping); | 194 setGroupedMapping(0, InvalidateLayerAndRemoveFromMapping); |
198 } | 195 } |
(...skipping 2436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2635 | 2632 |
2636 void PaintLayer::ensureCompositedLayerMapping() { | 2633 void PaintLayer::ensureCompositedLayerMapping() { |
2637 if (m_rareData && m_rareData->compositedLayerMapping) | 2634 if (m_rareData && m_rareData->compositedLayerMapping) |
2638 return; | 2635 return; |
2639 | 2636 |
2640 ensureRareData().compositedLayerMapping = | 2637 ensureRareData().compositedLayerMapping = |
2641 wrapUnique(new CompositedLayerMapping(*this)); | 2638 wrapUnique(new CompositedLayerMapping(*this)); |
2642 m_rareData->compositedLayerMapping->setNeedsGraphicsLayerUpdate( | 2639 m_rareData->compositedLayerMapping->setNeedsGraphicsLayerUpdate( |
2643 GraphicsLayerUpdateSubtree); | 2640 GraphicsLayerUpdateSubtree); |
2644 | 2641 |
2645 updateOrRemoveFilterEffect(); | 2642 if (PaintLayerFilterInfo* filterInfo = this->filterInfo()) |
| 2643 filterInfo->invalidateFilterChain(); |
2646 } | 2644 } |
2647 | 2645 |
2648 void PaintLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) { | 2646 void PaintLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) { |
2649 if (!layerBeingDestroyed) { | 2647 if (!layerBeingDestroyed) { |
2650 // We need to make sure our decendants get a geometry update. In principle, | 2648 // We need to make sure our decendants get a geometry update. In principle, |
2651 // we could call setNeedsGraphicsLayerUpdate on our children, but that would | 2649 // we could call setNeedsGraphicsLayerUpdate on our children, but that would |
2652 // require walking the z-order lists to find them. Instead, we | 2650 // require walking the z-order lists to find them. Instead, we |
2653 // over-invalidate by marking our parent as needing a geometry update. | 2651 // over-invalidate by marking our parent as needing a geometry update. |
2654 if (PaintLayer* compositingParent = | 2652 if (PaintLayer* compositingParent = |
2655 enclosingLayerWithCompositedLayerMapping(ExcludeSelf)) | 2653 enclosingLayerWithCompositedLayerMapping(ExcludeSelf)) |
2656 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUpdate( | 2654 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUpdate( |
2657 GraphicsLayerUpdateSubtree); | 2655 GraphicsLayerUpdateSubtree); |
2658 } | 2656 } |
2659 | 2657 |
2660 if (m_rareData) | 2658 if (m_rareData) |
2661 m_rareData->compositedLayerMapping.reset(); | 2659 m_rareData->compositedLayerMapping.reset(); |
2662 | 2660 |
2663 if (!layerBeingDestroyed) | 2661 if (layerBeingDestroyed) |
2664 updateOrRemoveFilterEffect(); | 2662 return; |
| 2663 |
| 2664 if (PaintLayerFilterInfo* filterInfo = this->filterInfo()) |
| 2665 filterInfo->invalidateFilterChain(); |
2665 } | 2666 } |
2666 | 2667 |
2667 void PaintLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping, | 2668 void PaintLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping, |
2668 SetGroupMappingOptions options) { | 2669 SetGroupMappingOptions options) { |
2669 CompositedLayerMapping* oldGroupedMapping = this->groupedMapping(); | 2670 CompositedLayerMapping* oldGroupedMapping = this->groupedMapping(); |
2670 if (groupedMapping == oldGroupedMapping) | 2671 if (groupedMapping == oldGroupedMapping) |
2671 return; | 2672 return; |
2672 | 2673 |
2673 if (options == InvalidateLayerAndRemoveFromMapping && oldGroupedMapping) { | 2674 if (options == InvalidateLayerAndRemoveFromMapping && oldGroupedMapping) { |
2674 oldGroupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree); | 2675 oldGroupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree); |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2857 return false; | 2858 return false; |
2858 | 2859 |
2859 return hasBoxDecorationsOrBackground() || hasOverflowControls(); | 2860 return hasBoxDecorationsOrBackground() || hasOverflowControls(); |
2860 } | 2861 } |
2861 | 2862 |
2862 void PaintLayer::updateFilters(const ComputedStyle* oldStyle, | 2863 void PaintLayer::updateFilters(const ComputedStyle* oldStyle, |
2863 const ComputedStyle& newStyle) { | 2864 const ComputedStyle& newStyle) { |
2864 if (!newStyle.hasFilterInducingProperty() && | 2865 if (!newStyle.hasFilterInducingProperty() && |
2865 (!oldStyle || !oldStyle->hasFilterInducingProperty())) | 2866 (!oldStyle || !oldStyle->hasFilterInducingProperty())) |
2866 return; | 2867 return; |
2867 | 2868 const bool hadFilterInfo = filterInfo(); |
2868 updateOrRemoveFilterClients(); | 2869 if (newStyle.hasFilterInducingProperty()) |
2869 updateOrRemoveFilterEffect(); | 2870 newStyle.filter().addClient(&ensureFilterInfo()); |
| 2871 if (hadFilterInfo && oldStyle) |
| 2872 oldStyle->filter().removeClient(filterInfo()); |
| 2873 if (!newStyle.hasFilterInducingProperty()) { |
| 2874 removeFilterInfo(); |
| 2875 return; |
| 2876 } |
| 2877 if (PaintLayerFilterInfo* filterInfo = this->filterInfo()) |
| 2878 filterInfo->invalidateFilterChain(); |
2870 } | 2879 } |
2871 | 2880 |
2872 bool PaintLayer::attemptDirectCompositingUpdate(StyleDifference diff, | 2881 bool PaintLayer::attemptDirectCompositingUpdate(StyleDifference diff, |
2873 const ComputedStyle* oldStyle) { | 2882 const ComputedStyle* oldStyle) { |
2874 CompositingReasons oldPotentialCompositingReasonsFromStyle = | 2883 CompositingReasons oldPotentialCompositingReasonsFromStyle = |
2875 potentialCompositingReasonsFromStyle(); | 2884 potentialCompositingReasonsFromStyle(); |
2876 compositor()->updatePotentialCompositingReasonsFromStyle(this); | 2885 compositor()->updatePotentialCompositingReasonsFromStyle(this); |
2877 | 2886 |
2878 // This function implements an optimization for transforms and opacity. | 2887 // This function implements an optimization for transforms and opacity. |
2879 // A common pattern is for a touchmove handler to update the transform | 2888 // A common pattern is for a touchmove handler to update the transform |
2880 // and/or an opacity of an element every frame while the user moves their | 2889 // and/or an opacity of an element every frame while the user moves their |
2881 // finger across the screen. The conditions below recognize when the | 2890 // finger across the screen. The conditions below recognize when the |
2882 // compositing state is set up to receive a direct transform or opacity | 2891 // compositing state is set up to receive a direct transform or opacity |
2883 // update. | 2892 // update. |
2884 | 2893 |
2885 if (!diff.hasAtMostPropertySpecificDifferences( | 2894 if (!diff.hasAtMostPropertySpecificDifferences( |
2886 StyleDifference::TransformChanged | StyleDifference::OpacityChanged)) | 2895 StyleDifference::TransformChanged | StyleDifference::OpacityChanged)) |
2887 return false; | 2896 return false; |
2888 // The potentialCompositingReasonsFromStyle could have changed without | 2897 // The potentialCompositingReasonsFromStyle could have changed without |
2889 // a corresponding StyleDifference if an animation started or ended. | 2898 // a corresponding StyleDifference if an animation started or ended. |
2890 if (potentialCompositingReasonsFromStyle() != | 2899 if (potentialCompositingReasonsFromStyle() != |
2891 oldPotentialCompositingReasonsFromStyle) | 2900 oldPotentialCompositingReasonsFromStyle) |
2892 return false; | 2901 return false; |
2893 // If we're unwinding a scheduleSVGFilterLayerUpdateHack(), then we can't | |
2894 // perform a direct compositing update because the filters code is going | |
2895 // to produce different output this time around. We can remove this code | |
2896 // once we fix the chicken/egg bugs in the filters code and delete the | |
2897 // scheduleSVGFilterLayerUpdateHack(). | |
2898 if (layoutObject()->node() && | |
2899 layoutObject()->node()->svgFilterNeedsLayerUpdate()) | |
2900 return false; | |
2901 if (!m_rareData || !m_rareData->compositedLayerMapping) | 2902 if (!m_rareData || !m_rareData->compositedLayerMapping) |
2902 return false; | 2903 return false; |
2903 | 2904 |
2904 // To cut off almost all the work in the compositing update for | 2905 // To cut off almost all the work in the compositing update for |
2905 // this case, we treat inline transforms has having assumed overlap | 2906 // this case, we treat inline transforms has having assumed overlap |
2906 // (similar to how we treat animated transforms). Notice that we read | 2907 // (similar to how we treat animated transforms). Notice that we read |
2907 // CompositingReasonInlineTransform from the m_compositingReasons, which | 2908 // CompositingReasonInlineTransform from the m_compositingReasons, which |
2908 // means that the inline transform actually triggered assumed overlap in | 2909 // means that the inline transform actually triggered assumed overlap in |
2909 // the overlap map. | 2910 // the overlap map. |
2910 if (diff.transformChanged() && | 2911 if (diff.transformChanged() && |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3004 return builder.buildFilterOperations(style.backdropFilter()); | 3005 return builder.buildFilterOperations(style.backdropFilter()); |
3005 } | 3006 } |
3006 | 3007 |
3007 PaintLayerFilterInfo& PaintLayer::ensureFilterInfo() { | 3008 PaintLayerFilterInfo& PaintLayer::ensureFilterInfo() { |
3008 PaintLayerRareData& rareData = ensureRareData(); | 3009 PaintLayerRareData& rareData = ensureRareData(); |
3009 if (!rareData.filterInfo) | 3010 if (!rareData.filterInfo) |
3010 rareData.filterInfo = new PaintLayerFilterInfo(this); | 3011 rareData.filterInfo = new PaintLayerFilterInfo(this); |
3011 return *rareData.filterInfo; | 3012 return *rareData.filterInfo; |
3012 } | 3013 } |
3013 | 3014 |
| 3015 void PaintLayer::removeFilterInfo() { |
| 3016 if (!m_rareData || !m_rareData->filterInfo) |
| 3017 return; |
| 3018 m_rareData->filterInfo->clearLayer(); |
| 3019 m_rareData->filterInfo = nullptr; |
| 3020 } |
| 3021 |
3014 void PaintLayer::removeAncestorOverflowLayer(const PaintLayer* removedLayer) { | 3022 void PaintLayer::removeAncestorOverflowLayer(const PaintLayer* removedLayer) { |
3015 // If the current ancestor overflow layer does not match the removed layer | 3023 // If the current ancestor overflow layer does not match the removed layer |
3016 // the ancestor overflow layer has changed so we can stop searching. | 3024 // the ancestor overflow layer has changed so we can stop searching. |
3017 if (ancestorOverflowLayer() && ancestorOverflowLayer() != removedLayer) | 3025 if (ancestorOverflowLayer() && ancestorOverflowLayer() != removedLayer) |
3018 return; | 3026 return; |
3019 | 3027 |
3020 if (ancestorOverflowLayer()) { | 3028 if (ancestorOverflowLayer()) { |
3021 // TODO(pdr): When slimming paint v2 is enabled, we will need to | 3029 // TODO(pdr): When slimming paint v2 is enabled, we will need to |
3022 // invalidate the scroll paint property subtree for this so main | 3030 // invalidate the scroll paint property subtree for this so main |
3023 // thread scroll reasons are recomputed. | 3031 // thread scroll reasons are recomputed. |
3024 ancestorOverflowLayer() | 3032 ancestorOverflowLayer() |
3025 ->getScrollableArea() | 3033 ->getScrollableArea() |
3026 ->invalidateStickyConstraintsFor(this); | 3034 ->invalidateStickyConstraintsFor(this); |
3027 } | 3035 } |
3028 updateAncestorOverflowLayer(nullptr); | 3036 updateAncestorOverflowLayer(nullptr); |
3029 PaintLayer* current = m_first; | 3037 PaintLayer* current = m_first; |
3030 while (current) { | 3038 while (current) { |
3031 current->removeAncestorOverflowLayer(removedLayer); | 3039 current->removeAncestorOverflowLayer(removedLayer); |
3032 current = current->nextSibling(); | 3040 current = current->nextSibling(); |
3033 } | 3041 } |
3034 } | 3042 } |
3035 | 3043 |
3036 void PaintLayer::updateOrRemoveFilterClients() { | 3044 FilterEffect* PaintLayer::lastFilterEffect() const { |
3037 const auto& filter = layoutObject()->style()->filter(); | |
3038 if (filter.isEmpty() && m_rareData && m_rareData->filterInfo) { | |
3039 m_rareData->filterInfo->clearLayer(); | |
3040 m_rareData->filterInfo = nullptr; | |
3041 } else if (filter.hasReferenceFilter()) { | |
3042 ensureFilterInfo().updateReferenceFilterClients(filter); | |
3043 } else if (filterInfo()) { | |
3044 filterInfo()->clearFilterReferences(); | |
3045 } | |
3046 } | |
3047 | |
3048 FilterEffect* PaintLayer::updateFilterEffect() const { | |
3049 // TODO(chrishtr): ensure (and assert) that compositing is clean here. | 3045 // TODO(chrishtr): ensure (and assert) that compositing is clean here. |
3050 | |
3051 if (!paintsWithFilters()) | 3046 if (!paintsWithFilters()) |
3052 return nullptr; | 3047 return nullptr; |
3053 | |
3054 PaintLayerFilterInfo* filterInfo = this->filterInfo(); | 3048 PaintLayerFilterInfo* filterInfo = this->filterInfo(); |
3055 | |
3056 // Should have been added by updateOrRemoveFilterEffect(). | |
3057 DCHECK(filterInfo); | 3049 DCHECK(filterInfo); |
3058 | 3050 |
3059 if (filterInfo->lastEffect()) | 3051 if (filterInfo->lastEffect()) |
3060 return filterInfo->lastEffect(); | 3052 return filterInfo->lastEffect(); |
3061 | 3053 |
3062 const ComputedStyle& style = layoutObject()->styleRef(); | 3054 const ComputedStyle& style = layoutObject()->styleRef(); |
3063 FloatRect zoomedReferenceBox; | 3055 FloatRect zoomedReferenceBox; |
3064 if (style.filter().hasReferenceFilter()) | 3056 if (style.filter().hasReferenceFilter()) |
3065 zoomedReferenceBox = boxForFilter(); | 3057 zoomedReferenceBox = boxForFilter(); |
3066 FilterEffectBuilder builder(enclosingNode(), zoomedReferenceBox, | 3058 FilterEffectBuilder builder(enclosingNode(), zoomedReferenceBox, |
3067 style.effectiveZoom()); | 3059 style.effectiveZoom()); |
3068 filterInfo->setLastEffect( | 3060 filterInfo->setLastEffect( |
3069 builder.buildFilterEffect(addReflectionToFilterOperations(style))); | 3061 builder.buildFilterEffect(addReflectionToFilterOperations(style))); |
3070 return filterInfo->lastEffect(); | 3062 return filterInfo->lastEffect(); |
3071 } | 3063 } |
3072 | 3064 |
3073 FilterEffect* PaintLayer::lastFilterEffect() const { | |
3074 return updateFilterEffect(); | |
3075 } | |
3076 | |
3077 FloatRect PaintLayer::mapRectForFilter(const FloatRect& rect) const { | 3065 FloatRect PaintLayer::mapRectForFilter(const FloatRect& rect) const { |
3078 if (!hasFilterThatMovesPixels()) | 3066 if (!hasFilterThatMovesPixels()) |
3079 return rect; | 3067 return rect; |
3080 | 3068 |
3081 // Ensure the filter-chain is refreshed wrt reference filters. | 3069 // Ensure the filter-chain is refreshed wrt reference filters. |
3082 updateFilterEffect(); | 3070 // TODO(fs): Avoid having this side-effect inducing call. |
| 3071 lastFilterEffect(); |
3083 | 3072 |
3084 FilterOperations filterOperations = | 3073 FilterOperations filterOperations = |
3085 addReflectionToFilterOperations(layoutObject()->styleRef()); | 3074 addReflectionToFilterOperations(layoutObject()->styleRef()); |
3086 return filterOperations.mapRect(rect); | 3075 return filterOperations.mapRect(rect); |
3087 } | 3076 } |
3088 | 3077 |
3089 LayoutRect PaintLayer::mapLayoutRectForFilter(const LayoutRect& rect) const { | 3078 LayoutRect PaintLayer::mapLayoutRectForFilter(const LayoutRect& rect) const { |
3090 if (!hasFilterThatMovesPixels()) | 3079 if (!hasFilterThatMovesPixels()) |
3091 return rect; | 3080 return rect; |
3092 return enclosingLayoutRect(mapRectForFilter(FloatRect(rect))); | 3081 return enclosingLayoutRect(mapRectForFilter(FloatRect(rect))); |
3093 } | 3082 } |
3094 | 3083 |
3095 bool PaintLayer::hasFilterThatMovesPixels() const { | 3084 bool PaintLayer::hasFilterThatMovesPixels() const { |
3096 if (!hasFilterInducingProperty()) | 3085 if (!hasFilterInducingProperty()) |
3097 return false; | 3086 return false; |
3098 const ComputedStyle& style = layoutObject()->styleRef(); | 3087 const ComputedStyle& style = layoutObject()->styleRef(); |
3099 if (style.hasFilter() && style.filter().hasFilterThatMovesPixels()) | 3088 if (style.hasFilter() && style.filter().hasFilterThatMovesPixels()) |
3100 return true; | 3089 return true; |
3101 if (style.hasBoxReflect()) | 3090 if (style.hasBoxReflect()) |
3102 return true; | 3091 return true; |
3103 return false; | 3092 return false; |
3104 } | 3093 } |
3105 | 3094 |
3106 void PaintLayer::updateOrRemoveFilterEffect() { | |
3107 // FilterEffectBuilder is only used to render the filters in software mode, | |
3108 // so we always need to run updateOrRemoveFilterEffect after the composited | |
3109 // mode might have changed for this layer. | |
3110 if (!paintsWithFilters()) { | |
3111 if (PaintLayerFilterInfo* filterInfo = this->filterInfo()) | |
3112 filterInfo->setLastEffect(nullptr); | |
3113 return; | |
3114 } | |
3115 | |
3116 ensureFilterInfo().setLastEffect(nullptr); | |
3117 } | |
3118 | |
3119 void PaintLayer::filterNeedsPaintInvalidation() { | |
3120 { | |
3121 DeprecatedScheduleStyleRecalcDuringLayout marker( | |
3122 layoutObject()->document().lifecycle()); | |
3123 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a style | |
3124 // recalc, which is a problem because this function can be called right | |
3125 // before performing layout but after style recalc. | |
3126 // | |
3127 // See LayoutView::layout() and the call to | |
3128 // invalidateSVGRootsWithRelativeLengthDescendents(). This violation is | |
3129 // worked around in FrameView::updateStyleAndLayoutIfNeededRecursive() by | |
3130 // doing an extra style recalc and layout in case it's needed. | |
3131 toElement(layoutObject()->node())->scheduleSVGFilterLayerUpdateHack(); | |
3132 } | |
3133 | |
3134 layoutObject()->setShouldDoFullPaintInvalidation(); | |
3135 } | |
3136 | |
3137 void PaintLayer::addLayerHitTestRects(LayerHitTestRects& rects) const { | 3095 void PaintLayer::addLayerHitTestRects(LayerHitTestRects& rects) const { |
3138 computeSelfHitTestRects(rects); | 3096 computeSelfHitTestRects(rects); |
3139 for (PaintLayer* child = firstChild(); child; child = child->nextSibling()) | 3097 for (PaintLayer* child = firstChild(); child; child = child->nextSibling()) |
3140 child->addLayerHitTestRects(rects); | 3098 child->addLayerHitTestRects(rects); |
3141 } | 3099 } |
3142 | 3100 |
3143 void PaintLayer::computeSelfHitTestRects(LayerHitTestRects& rects) const { | 3101 void PaintLayer::computeSelfHitTestRects(LayerHitTestRects& rects) const { |
3144 if (!size().isEmpty()) { | 3102 if (!size().isEmpty()) { |
3145 Vector<LayoutRect> rect; | 3103 Vector<LayoutRect> rect; |
3146 | 3104 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3265 } | 3223 } |
3266 | 3224 |
3267 void showLayerTree(const blink::LayoutObject* layoutObject) { | 3225 void showLayerTree(const blink::LayoutObject* layoutObject) { |
3268 if (!layoutObject) { | 3226 if (!layoutObject) { |
3269 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n"); | 3227 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n"); |
3270 return; | 3228 return; |
3271 } | 3229 } |
3272 showLayerTree(layoutObject->enclosingLayer()); | 3230 showLayerTree(layoutObject->enclosingLayer()); |
3273 } | 3231 } |
3274 #endif | 3232 #endif |
OLD | NEW |