| 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" |
| 52 #include "core/frame/FrameView.h" | 53 #include "core/frame/FrameView.h" |
| 53 #include "core/frame/LocalFrame.h" | 54 #include "core/frame/LocalFrame.h" |
| 54 #include "core/frame/Settings.h" | 55 #include "core/frame/Settings.h" |
| 56 #include "core/html/HTMLFrameElement.h" |
| 55 #include "core/layout/FragmentainerIterator.h" | 57 #include "core/layout/FragmentainerIterator.h" |
| 56 #include "core/layout/HitTestRequest.h" | 58 #include "core/layout/HitTestRequest.h" |
| 57 #include "core/layout/HitTestResult.h" | 59 #include "core/layout/HitTestResult.h" |
| 58 #include "core/layout/HitTestingTransformState.h" | 60 #include "core/layout/HitTestingTransformState.h" |
| 59 #include "core/layout/LayoutFlowThread.h" | 61 #include "core/layout/LayoutFlowThread.h" |
| 60 #include "core/layout/LayoutInline.h" | 62 #include "core/layout/LayoutInline.h" |
| 61 #include "core/layout/LayoutPart.h" | 63 #include "core/layout/LayoutPart.h" |
| 62 #include "core/layout/LayoutTreeAsText.h" | 64 #include "core/layout/LayoutTreeAsText.h" |
| 63 #include "core/layout/LayoutView.h" | 65 #include "core/layout/LayoutView.h" |
| 64 #include "core/layout/api/LayoutPartItem.h" | 66 #include "core/layout/api/LayoutPartItem.h" |
| 65 #include "core/layout/api/LayoutViewItem.h" | 67 #include "core/layout/api/LayoutViewItem.h" |
| 66 #include "core/layout/compositing/CompositedLayerMapping.h" | 68 #include "core/layout/compositing/CompositedLayerMapping.h" |
| 67 #include "core/layout/compositing/PaintLayerCompositor.h" | 69 #include "core/layout/compositing/PaintLayerCompositor.h" |
| 68 #include "core/layout/svg/LayoutSVGResourceClipper.h" | 70 #include "core/layout/svg/LayoutSVGResourceClipper.h" |
| 69 #include "core/layout/svg/LayoutSVGRoot.h" | 71 #include "core/layout/svg/LayoutSVGRoot.h" |
| 70 #include "core/page/Page.h" | 72 #include "core/page/Page.h" |
| 71 #include "core/page/scrolling/ScrollingCoordinator.h" | 73 #include "core/page/scrolling/ScrollingCoordinator.h" |
| 72 #include "core/paint/BoxReflectionUtils.h" | 74 #include "core/paint/BoxReflectionUtils.h" |
| 73 #include "core/paint/FilterEffectBuilder.h" | 75 #include "core/paint/FilterEffectBuilder.h" |
| 74 #include "core/paint/ObjectPaintInvalidator.h" | 76 #include "core/paint/ObjectPaintInvalidator.h" |
| 75 #include "core/paint/PaintTiming.h" | 77 #include "core/paint/PaintTiming.h" |
| 76 #include "platform/LengthFunctions.h" | 78 #include "platform/LengthFunctions.h" |
| 77 #include "platform/RuntimeEnabledFeatures.h" | 79 #include "platform/RuntimeEnabledFeatures.h" |
| 78 #include "platform/geometry/FloatPoint3D.h" | 80 #include "platform/geometry/FloatPoint3D.h" |
| 79 #include "platform/geometry/FloatRect.h" | 81 #include "platform/geometry/FloatRect.h" |
| 80 #include "platform/geometry/TransformState.h" | 82 #include "platform/geometry/TransformState.h" |
| 81 #include "platform/graphics/CompositorFilterOperations.h" | 83 #include "platform/graphics/CompositorFilterOperations.h" |
| 82 #include "platform/graphics/filters/Filter.h" | 84 #include "platform/graphics/filters/Filter.h" |
| 85 #include "platform/graphics/filters/SkiaImageFilterBuilder.h" |
| 83 #include "platform/tracing/TraceEvent.h" | 86 #include "platform/tracing/TraceEvent.h" |
| 87 #include "platform/transforms/ScaleTransformOperation.h" |
| 84 #include "platform/transforms/TransformationMatrix.h" | 88 #include "platform/transforms/TransformationMatrix.h" |
| 89 #include "platform/transforms/TranslateTransformOperation.h" |
| 85 #include "wtf/PtrUtil.h" | 90 #include "wtf/PtrUtil.h" |
| 86 #include "wtf/StdLibExtras.h" | 91 #include "wtf/StdLibExtras.h" |
| 87 #include "wtf/allocator/Partitions.h" | 92 #include "wtf/allocator/Partitions.h" |
| 88 #include "wtf/text/CString.h" | 93 #include "wtf/text/CString.h" |
| 89 | 94 |
| 90 namespace blink { | 95 namespace blink { |
| 91 | 96 |
| 92 namespace { | 97 namespace { |
| 93 | 98 |
| 94 static CompositingQueryMode gCompositingQueryMode = | 99 static CompositingQueryMode gCompositingQueryMode = |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 if (!layoutObject->slowFirstChild() && layoutObject->style()) { | 181 if (!layoutObject->slowFirstChild() && layoutObject->style()) { |
| 177 m_isVisibleContentDirty = false; | 182 m_isVisibleContentDirty = false; |
| 178 m_hasVisibleContent = | 183 m_hasVisibleContent = |
| 179 layoutObject->style()->visibility() == EVisibility::Visible; | 184 layoutObject->style()->visibility() == EVisibility::Visible; |
| 180 } | 185 } |
| 181 | 186 |
| 182 updateScrollableArea(); | 187 updateScrollableArea(); |
| 183 } | 188 } |
| 184 | 189 |
| 185 PaintLayer::~PaintLayer() { | 190 PaintLayer::~PaintLayer() { |
| 186 if (m_rareData && m_rareData->filterInfo) { | 191 if (m_rareData && m_rareData->filterInfo) |
| 187 layoutObject()->styleRef().filter().removeClient(m_rareData->filterInfo); | |
| 188 m_rareData->filterInfo->clearLayer(); | 192 m_rareData->filterInfo->clearLayer(); |
| 189 } | |
| 190 if (layoutObject()->frame() && layoutObject()->frame()->page()) { | 193 if (layoutObject()->frame() && layoutObject()->frame()->page()) { |
| 191 if (ScrollingCoordinator* scrollingCoordinator = | 194 if (ScrollingCoordinator* scrollingCoordinator = |
| 192 layoutObject()->frame()->page()->scrollingCoordinator()) | 195 layoutObject()->frame()->page()->scrollingCoordinator()) |
| 193 scrollingCoordinator->willDestroyLayer(this); | 196 scrollingCoordinator->willDestroyLayer(this); |
| 194 } | 197 } |
| 195 | 198 |
| 196 if (groupedMapping()) { | 199 if (groupedMapping()) { |
| 197 DisableCompositingQueryAsserts disabler; | 200 DisableCompositingQueryAsserts disabler; |
| 198 setGroupedMapping(0, InvalidateLayerAndRemoveFromMapping); | 201 setGroupedMapping(0, InvalidateLayerAndRemoveFromMapping); |
| 199 } | 202 } |
| (...skipping 2447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2647 | 2650 |
| 2648 void PaintLayer::ensureCompositedLayerMapping() { | 2651 void PaintLayer::ensureCompositedLayerMapping() { |
| 2649 if (m_rareData && m_rareData->compositedLayerMapping) | 2652 if (m_rareData && m_rareData->compositedLayerMapping) |
| 2650 return; | 2653 return; |
| 2651 | 2654 |
| 2652 ensureRareData().compositedLayerMapping = | 2655 ensureRareData().compositedLayerMapping = |
| 2653 wrapUnique(new CompositedLayerMapping(*this)); | 2656 wrapUnique(new CompositedLayerMapping(*this)); |
| 2654 m_rareData->compositedLayerMapping->setNeedsGraphicsLayerUpdate( | 2657 m_rareData->compositedLayerMapping->setNeedsGraphicsLayerUpdate( |
| 2655 GraphicsLayerUpdateSubtree); | 2658 GraphicsLayerUpdateSubtree); |
| 2656 | 2659 |
| 2657 if (PaintLayerFilterInfo* filterInfo = this->filterInfo()) | 2660 updateOrRemoveFilterEffect(); |
| 2658 filterInfo->invalidateFilterChain(); | |
| 2659 } | 2661 } |
| 2660 | 2662 |
| 2661 void PaintLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) { | 2663 void PaintLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) { |
| 2662 if (!layerBeingDestroyed) { | 2664 if (!layerBeingDestroyed) { |
| 2663 // 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, |
| 2664 // we could call setNeedsGraphicsLayerUpdate on our children, but that would | 2666 // we could call setNeedsGraphicsLayerUpdate on our children, but that would |
| 2665 // require walking the z-order lists to find them. Instead, we | 2667 // require walking the z-order lists to find them. Instead, we |
| 2666 // over-invalidate by marking our parent as needing a geometry update. | 2668 // over-invalidate by marking our parent as needing a geometry update. |
| 2667 if (PaintLayer* compositingParent = | 2669 if (PaintLayer* compositingParent = |
| 2668 enclosingLayerWithCompositedLayerMapping(ExcludeSelf)) | 2670 enclosingLayerWithCompositedLayerMapping(ExcludeSelf)) |
| 2669 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUpdate( | 2671 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUpdate( |
| 2670 GraphicsLayerUpdateSubtree); | 2672 GraphicsLayerUpdateSubtree); |
| 2671 } | 2673 } |
| 2672 | 2674 |
| 2673 if (m_rareData) | 2675 if (m_rareData) |
| 2674 m_rareData->compositedLayerMapping.reset(); | 2676 m_rareData->compositedLayerMapping.reset(); |
| 2675 | 2677 |
| 2676 if (layerBeingDestroyed) | 2678 if (!layerBeingDestroyed) |
| 2677 return; | 2679 updateOrRemoveFilterEffect(); |
| 2678 | |
| 2679 if (PaintLayerFilterInfo* filterInfo = this->filterInfo()) | |
| 2680 filterInfo->invalidateFilterChain(); | |
| 2681 } | 2680 } |
| 2682 | 2681 |
| 2683 void PaintLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping, | 2682 void PaintLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping, |
| 2684 SetGroupMappingOptions options) { | 2683 SetGroupMappingOptions options) { |
| 2685 CompositedLayerMapping* oldGroupedMapping = this->groupedMapping(); | 2684 CompositedLayerMapping* oldGroupedMapping = this->groupedMapping(); |
| 2686 if (groupedMapping == oldGroupedMapping) | 2685 if (groupedMapping == oldGroupedMapping) |
| 2687 return; | 2686 return; |
| 2688 | 2687 |
| 2689 if (options == InvalidateLayerAndRemoveFromMapping && oldGroupedMapping) { | 2688 if (options == InvalidateLayerAndRemoveFromMapping && oldGroupedMapping) { |
| 2690 oldGroupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree); | 2689 oldGroupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2873 return false; | 2872 return false; |
| 2874 | 2873 |
| 2875 return hasBoxDecorationsOrBackground() || hasOverflowControls(); | 2874 return hasBoxDecorationsOrBackground() || hasOverflowControls(); |
| 2876 } | 2875 } |
| 2877 | 2876 |
| 2878 void PaintLayer::updateFilters(const ComputedStyle* oldStyle, | 2877 void PaintLayer::updateFilters(const ComputedStyle* oldStyle, |
| 2879 const ComputedStyle& newStyle) { | 2878 const ComputedStyle& newStyle) { |
| 2880 if (!newStyle.hasFilterInducingProperty() && | 2879 if (!newStyle.hasFilterInducingProperty() && |
| 2881 (!oldStyle || !oldStyle->hasFilterInducingProperty())) | 2880 (!oldStyle || !oldStyle->hasFilterInducingProperty())) |
| 2882 return; | 2881 return; |
| 2883 const bool hadFilterInfo = filterInfo(); | 2882 |
| 2884 if (newStyle.hasFilterInducingProperty()) | 2883 updateOrRemoveFilterClients(); |
| 2885 newStyle.filter().addClient(&ensureFilterInfo()); | 2884 updateOrRemoveFilterEffect(); |
| 2886 if (hadFilterInfo && oldStyle) | |
| 2887 oldStyle->filter().removeClient(filterInfo()); | |
| 2888 if (!newStyle.hasFilterInducingProperty()) { | |
| 2889 removeFilterInfo(); | |
| 2890 return; | |
| 2891 } | |
| 2892 if (PaintLayerFilterInfo* filterInfo = this->filterInfo()) | |
| 2893 filterInfo->invalidateFilterChain(); | |
| 2894 } | 2885 } |
| 2895 | 2886 |
| 2896 bool PaintLayer::attemptDirectCompositingUpdate(StyleDifference diff, | 2887 bool PaintLayer::attemptDirectCompositingUpdate(StyleDifference diff, |
| 2897 const ComputedStyle* oldStyle) { | 2888 const ComputedStyle* oldStyle) { |
| 2898 CompositingReasons oldPotentialCompositingReasonsFromStyle = | 2889 CompositingReasons oldPotentialCompositingReasonsFromStyle = |
| 2899 potentialCompositingReasonsFromStyle(); | 2890 potentialCompositingReasonsFromStyle(); |
| 2900 compositor()->updatePotentialCompositingReasonsFromStyle(this); | 2891 compositor()->updatePotentialCompositingReasonsFromStyle(this); |
| 2901 | 2892 |
| 2902 // This function implements an optimization for transforms and opacity. | 2893 // This function implements an optimization for transforms and opacity. |
| 2903 // 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 |
| 2904 // 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 |
| 2905 // finger across the screen. The conditions below recognize when the | 2896 // finger across the screen. The conditions below recognize when the |
| 2906 // 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 |
| 2907 // update. | 2898 // update. |
| 2908 | 2899 |
| 2909 if (!diff.hasAtMostPropertySpecificDifferences( | 2900 if (!diff.hasAtMostPropertySpecificDifferences( |
| 2910 StyleDifference::TransformChanged | StyleDifference::OpacityChanged)) | 2901 StyleDifference::TransformChanged | StyleDifference::OpacityChanged)) |
| 2911 return false; | 2902 return false; |
| 2912 // The potentialCompositingReasonsFromStyle could have changed without | 2903 // The potentialCompositingReasonsFromStyle could have changed without |
| 2913 // a corresponding StyleDifference if an animation started or ended. | 2904 // a corresponding StyleDifference if an animation started or ended. |
| 2914 if (potentialCompositingReasonsFromStyle() != | 2905 if (potentialCompositingReasonsFromStyle() != |
| 2915 oldPotentialCompositingReasonsFromStyle) | 2906 oldPotentialCompositingReasonsFromStyle) |
| 2916 return false; | 2907 return false; |
| 2908 // If we're unwinding a scheduleSVGFilterLayerUpdateHack(), then we can't |
| 2909 // perform a direct compositing update because the filters code is going |
| 2910 // to produce different output this time around. We can remove this code |
| 2911 // once we fix the chicken/egg bugs in the filters code and delete the |
| 2912 // scheduleSVGFilterLayerUpdateHack(). |
| 2913 if (layoutObject()->node() && |
| 2914 layoutObject()->node()->svgFilterNeedsLayerUpdate()) |
| 2915 return false; |
| 2917 if (!m_rareData || !m_rareData->compositedLayerMapping) | 2916 if (!m_rareData || !m_rareData->compositedLayerMapping) |
| 2918 return false; | 2917 return false; |
| 2919 | 2918 |
| 2920 // To cut off almost all the work in the compositing update for | 2919 // To cut off almost all the work in the compositing update for |
| 2921 // this case, we treat inline transforms has having assumed overlap | 2920 // this case, we treat inline transforms has having assumed overlap |
| 2922 // (similar to how we treat animated transforms). Notice that we read | 2921 // (similar to how we treat animated transforms). Notice that we read |
| 2923 // CompositingReasonInlineTransform from the m_compositingReasons, which | 2922 // CompositingReasonInlineTransform from the m_compositingReasons, which |
| 2924 // means that the inline transform actually triggered assumed overlap in | 2923 // means that the inline transform actually triggered assumed overlap in |
| 2925 // the overlap map. | 2924 // the overlap map. |
| 2926 if (diff.transformChanged() && | 2925 if (diff.transformChanged() && |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3020 return builder.buildFilterOperations(style.backdropFilter()); | 3019 return builder.buildFilterOperations(style.backdropFilter()); |
| 3021 } | 3020 } |
| 3022 | 3021 |
| 3023 PaintLayerFilterInfo& PaintLayer::ensureFilterInfo() { | 3022 PaintLayerFilterInfo& PaintLayer::ensureFilterInfo() { |
| 3024 PaintLayerRareData& rareData = ensureRareData(); | 3023 PaintLayerRareData& rareData = ensureRareData(); |
| 3025 if (!rareData.filterInfo) | 3024 if (!rareData.filterInfo) |
| 3026 rareData.filterInfo = new PaintLayerFilterInfo(this); | 3025 rareData.filterInfo = new PaintLayerFilterInfo(this); |
| 3027 return *rareData.filterInfo; | 3026 return *rareData.filterInfo; |
| 3028 } | 3027 } |
| 3029 | 3028 |
| 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 | |
| 3037 void PaintLayer::removeAncestorOverflowLayer(const PaintLayer* removedLayer) { | 3029 void PaintLayer::removeAncestorOverflowLayer(const PaintLayer* removedLayer) { |
| 3038 // If the current ancestor overflow layer does not match the removed layer | 3030 // If the current ancestor overflow layer does not match the removed layer |
| 3039 // the ancestor overflow layer has changed so we can stop searching. | 3031 // the ancestor overflow layer has changed so we can stop searching. |
| 3040 if (ancestorOverflowLayer() && ancestorOverflowLayer() != removedLayer) | 3032 if (ancestorOverflowLayer() && ancestorOverflowLayer() != removedLayer) |
| 3041 return; | 3033 return; |
| 3042 | 3034 |
| 3043 if (ancestorOverflowLayer()) { | 3035 if (ancestorOverflowLayer()) { |
| 3044 // TODO(pdr): When slimming paint v2 is enabled, we will need to | 3036 // TODO(pdr): When slimming paint v2 is enabled, we will need to |
| 3045 // invalidate the scroll paint property subtree for this so main | 3037 // invalidate the scroll paint property subtree for this so main |
| 3046 // thread scroll reasons are recomputed. | 3038 // thread scroll reasons are recomputed. |
| 3047 ancestorOverflowLayer() | 3039 ancestorOverflowLayer() |
| 3048 ->getScrollableArea() | 3040 ->getScrollableArea() |
| 3049 ->invalidateStickyConstraintsFor(this); | 3041 ->invalidateStickyConstraintsFor(this); |
| 3050 } | 3042 } |
| 3051 updateAncestorOverflowLayer(nullptr); | 3043 updateAncestorOverflowLayer(nullptr); |
| 3052 PaintLayer* current = m_first; | 3044 PaintLayer* current = m_first; |
| 3053 while (current) { | 3045 while (current) { |
| 3054 current->removeAncestorOverflowLayer(removedLayer); | 3046 current->removeAncestorOverflowLayer(removedLayer); |
| 3055 current = current->nextSibling(); | 3047 current = current->nextSibling(); |
| 3056 } | 3048 } |
| 3057 } | 3049 } |
| 3058 | 3050 |
| 3059 FilterEffect* PaintLayer::lastFilterEffect() const { | 3051 void PaintLayer::updateOrRemoveFilterClients() { |
| 3052 const auto& filter = layoutObject()->style()->filter(); |
| 3053 if (filter.isEmpty() && m_rareData && m_rareData->filterInfo) { |
| 3054 m_rareData->filterInfo->clearLayer(); |
| 3055 m_rareData->filterInfo = nullptr; |
| 3056 } else if (filter.hasReferenceFilter()) { |
| 3057 ensureFilterInfo().updateReferenceFilterClients(filter); |
| 3058 } else if (filterInfo()) { |
| 3059 filterInfo()->clearFilterReferences(); |
| 3060 } |
| 3061 } |
| 3062 |
| 3063 FilterEffect* PaintLayer::updateFilterEffect() const { |
| 3060 // TODO(chrishtr): ensure (and assert) that compositing is clean here. | 3064 // TODO(chrishtr): ensure (and assert) that compositing is clean here. |
| 3065 |
| 3061 if (!paintsWithFilters()) | 3066 if (!paintsWithFilters()) |
| 3062 return nullptr; | 3067 return nullptr; |
| 3068 |
| 3063 PaintLayerFilterInfo* filterInfo = this->filterInfo(); | 3069 PaintLayerFilterInfo* filterInfo = this->filterInfo(); |
| 3070 |
| 3071 // Should have been added by updateOrRemoveFilterEffect(). |
| 3064 DCHECK(filterInfo); | 3072 DCHECK(filterInfo); |
| 3065 | 3073 |
| 3066 if (filterInfo->lastEffect()) | 3074 if (filterInfo->lastEffect()) |
| 3067 return filterInfo->lastEffect(); | 3075 return filterInfo->lastEffect(); |
| 3068 | 3076 |
| 3069 const ComputedStyle& style = layoutObject()->styleRef(); | 3077 const ComputedStyle& style = layoutObject()->styleRef(); |
| 3070 FloatRect zoomedReferenceBox; | 3078 FloatRect zoomedReferenceBox; |
| 3071 if (style.filter().hasReferenceFilter()) | 3079 if (style.filter().hasReferenceFilter()) |
| 3072 zoomedReferenceBox = boxForFilter(); | 3080 zoomedReferenceBox = boxForFilter(); |
| 3073 FilterEffectBuilder builder(enclosingNode(), zoomedReferenceBox, | 3081 FilterEffectBuilder builder(enclosingNode(), zoomedReferenceBox, |
| 3074 style.effectiveZoom()); | 3082 style.effectiveZoom()); |
| 3075 filterInfo->setLastEffect( | 3083 filterInfo->setLastEffect( |
| 3076 builder.buildFilterEffect(addReflectionToFilterOperations(style))); | 3084 builder.buildFilterEffect(addReflectionToFilterOperations(style))); |
| 3077 return filterInfo->lastEffect(); | 3085 return filterInfo->lastEffect(); |
| 3078 } | 3086 } |
| 3079 | 3087 |
| 3088 FilterEffect* PaintLayer::lastFilterEffect() const { |
| 3089 return updateFilterEffect(); |
| 3090 } |
| 3091 |
| 3080 FloatRect PaintLayer::mapRectForFilter(const FloatRect& rect) const { | 3092 FloatRect PaintLayer::mapRectForFilter(const FloatRect& rect) const { |
| 3081 if (!hasFilterThatMovesPixels()) | 3093 if (!hasFilterThatMovesPixels()) |
| 3082 return rect; | 3094 return rect; |
| 3083 | 3095 |
| 3084 // Ensure the filter-chain is refreshed wrt reference filters. | 3096 // Ensure the filter-chain is refreshed wrt reference filters. |
| 3085 // TODO(fs): Avoid having this side-effect inducing call. | 3097 updateFilterEffect(); |
| 3086 lastFilterEffect(); | |
| 3087 | 3098 |
| 3088 FilterOperations filterOperations = | 3099 FilterOperations filterOperations = |
| 3089 addReflectionToFilterOperations(layoutObject()->styleRef()); | 3100 addReflectionToFilterOperations(layoutObject()->styleRef()); |
| 3090 return filterOperations.mapRect(rect); | 3101 return filterOperations.mapRect(rect); |
| 3091 } | 3102 } |
| 3092 | 3103 |
| 3093 LayoutRect PaintLayer::mapLayoutRectForFilter(const LayoutRect& rect) const { | 3104 LayoutRect PaintLayer::mapLayoutRectForFilter(const LayoutRect& rect) const { |
| 3094 if (!hasFilterThatMovesPixels()) | 3105 if (!hasFilterThatMovesPixels()) |
| 3095 return rect; | 3106 return rect; |
| 3096 return enclosingLayoutRect(mapRectForFilter(FloatRect(rect))); | 3107 return enclosingLayoutRect(mapRectForFilter(FloatRect(rect))); |
| 3097 } | 3108 } |
| 3098 | 3109 |
| 3099 bool PaintLayer::hasFilterThatMovesPixels() const { | 3110 bool PaintLayer::hasFilterThatMovesPixels() const { |
| 3100 if (!hasFilterInducingProperty()) | 3111 if (!hasFilterInducingProperty()) |
| 3101 return false; | 3112 return false; |
| 3102 const ComputedStyle& style = layoutObject()->styleRef(); | 3113 const ComputedStyle& style = layoutObject()->styleRef(); |
| 3103 if (style.hasFilter() && style.filter().hasFilterThatMovesPixels()) | 3114 if (style.hasFilter() && style.filter().hasFilterThatMovesPixels()) |
| 3104 return true; | 3115 return true; |
| 3105 if (style.hasBoxReflect()) | 3116 if (style.hasBoxReflect()) |
| 3106 return true; | 3117 return true; |
| 3107 return false; | 3118 return false; |
| 3108 } | 3119 } |
| 3109 | 3120 |
| 3121 void PaintLayer::updateOrRemoveFilterEffect() { |
| 3122 // FilterEffectBuilder is only used to render the filters in software mode, |
| 3123 // so we always need to run updateOrRemoveFilterEffect after the composited |
| 3124 // mode might have changed for this layer. |
| 3125 if (!paintsWithFilters()) { |
| 3126 if (PaintLayerFilterInfo* filterInfo = this->filterInfo()) |
| 3127 filterInfo->setLastEffect(nullptr); |
| 3128 return; |
| 3129 } |
| 3130 |
| 3131 ensureFilterInfo().setLastEffect(nullptr); |
| 3132 } |
| 3133 |
| 3134 void PaintLayer::filterNeedsPaintInvalidation() { |
| 3135 { |
| 3136 DeprecatedScheduleStyleRecalcDuringLayout marker( |
| 3137 layoutObject()->document().lifecycle()); |
| 3138 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a style |
| 3139 // recalc, which is a problem because this function can be called right |
| 3140 // before performing layout but after style recalc. |
| 3141 // |
| 3142 // See LayoutView::layout() and the call to |
| 3143 // invalidateSVGRootsWithRelativeLengthDescendents(). This violation is |
| 3144 // worked around in FrameView::updateStyleAndLayoutIfNeededRecursive() by |
| 3145 // doing an extra style recalc and layout in case it's needed. |
| 3146 toElement(layoutObject()->node())->scheduleSVGFilterLayerUpdateHack(); |
| 3147 } |
| 3148 |
| 3149 layoutObject()->setShouldDoFullPaintInvalidation(); |
| 3150 } |
| 3151 |
| 3110 void PaintLayer::addLayerHitTestRects(LayerHitTestRects& rects) const { | 3152 void PaintLayer::addLayerHitTestRects(LayerHitTestRects& rects) const { |
| 3111 computeSelfHitTestRects(rects); | 3153 computeSelfHitTestRects(rects); |
| 3112 for (PaintLayer* child = firstChild(); child; child = child->nextSibling()) | 3154 for (PaintLayer* child = firstChild(); child; child = child->nextSibling()) |
| 3113 child->addLayerHitTestRects(rects); | 3155 child->addLayerHitTestRects(rects); |
| 3114 } | 3156 } |
| 3115 | 3157 |
| 3116 void PaintLayer::computeSelfHitTestRects(LayerHitTestRects& rects) const { | 3158 void PaintLayer::computeSelfHitTestRects(LayerHitTestRects& rects) const { |
| 3117 if (!size().isEmpty()) { | 3159 if (!size().isEmpty()) { |
| 3118 Vector<LayoutRect> rect; | 3160 Vector<LayoutRect> rect; |
| 3119 | 3161 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3238 } | 3280 } |
| 3239 | 3281 |
| 3240 void showLayerTree(const blink::LayoutObject* layoutObject) { | 3282 void showLayerTree(const blink::LayoutObject* layoutObject) { |
| 3241 if (!layoutObject) { | 3283 if (!layoutObject) { |
| 3242 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n"); | 3284 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n"); |
| 3243 return; | 3285 return; |
| 3244 } | 3286 } |
| 3245 showLayerTree(layoutObject->enclosingLayer()); | 3287 showLayerTree(layoutObject->enclosingLayer()); |
| 3246 } | 3288 } |
| 3247 #endif | 3289 #endif |
| OLD | NEW |