OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
reserved. |
3 * | 3 * |
4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. | 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. |
5 * | 5 * |
6 * Other contributors: | 6 * Other contributors: |
7 * Robert O'Callahan <roc+@cs.cmu.edu> | 7 * Robert O'Callahan <roc+@cs.cmu.edu> |
8 * David Baron <dbaron@fas.harvard.edu> | 8 * David Baron <dbaron@fas.harvard.edu> |
9 * Christian Biesinger <cbiesinger@web.de> | 9 * Christian Biesinger <cbiesinger@web.de> |
10 * Randall Jesup <rjesup@wgate.com> | 10 * Randall Jesup <rjesup@wgate.com> |
(...skipping 2362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2373 } | 2373 } |
2374 | 2374 |
2375 void PaintLayer::ensureCompositedLayerMapping() | 2375 void PaintLayer::ensureCompositedLayerMapping() |
2376 { | 2376 { |
2377 if (m_rareData && m_rareData->compositedLayerMapping) | 2377 if (m_rareData && m_rareData->compositedLayerMapping) |
2378 return; | 2378 return; |
2379 | 2379 |
2380 ensureRareData().compositedLayerMapping = wrapUnique(new CompositedLayerMapp
ing(*this)); | 2380 ensureRareData().compositedLayerMapping = wrapUnique(new CompositedLayerMapp
ing(*this)); |
2381 m_rareData->compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLaye
rUpdateSubtree); | 2381 m_rareData->compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLaye
rUpdateSubtree); |
2382 | 2382 |
2383 updateOrRemoveFilterEffectBuilder(); | 2383 updateOrRemoveFilterEffect(); |
2384 } | 2384 } |
2385 | 2385 |
2386 void PaintLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) | 2386 void PaintLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) |
2387 { | 2387 { |
2388 if (!layerBeingDestroyed) { | 2388 if (!layerBeingDestroyed) { |
2389 // We need to make sure our decendants get a geometry update. In princip
le, | 2389 // We need to make sure our decendants get a geometry update. In princip
le, |
2390 // we could call setNeedsGraphicsLayerUpdate on our children, but that w
ould | 2390 // we could call setNeedsGraphicsLayerUpdate on our children, but that w
ould |
2391 // require walking the z-order lists to find them. Instead, we over-inva
lidate | 2391 // require walking the z-order lists to find them. Instead, we over-inva
lidate |
2392 // by marking our parent as needing a geometry update. | 2392 // by marking our parent as needing a geometry update. |
2393 if (PaintLayer* compositingParent = enclosingLayerWithCompositedLayerMap
ping(ExcludeSelf)) | 2393 if (PaintLayer* compositingParent = enclosingLayerWithCompositedLayerMap
ping(ExcludeSelf)) |
2394 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUp
date(GraphicsLayerUpdateSubtree); | 2394 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUp
date(GraphicsLayerUpdateSubtree); |
2395 } | 2395 } |
2396 | 2396 |
2397 if (m_rareData) | 2397 if (m_rareData) |
2398 m_rareData->compositedLayerMapping.reset(); | 2398 m_rareData->compositedLayerMapping.reset(); |
2399 | 2399 |
2400 if (!layerBeingDestroyed) | 2400 if (!layerBeingDestroyed) |
2401 updateOrRemoveFilterEffectBuilder(); | 2401 updateOrRemoveFilterEffect(); |
2402 } | 2402 } |
2403 | 2403 |
2404 void PaintLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping, SetGr
oupMappingOptions options) | 2404 void PaintLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping, SetGr
oupMappingOptions options) |
2405 { | 2405 { |
2406 CompositedLayerMapping* oldGroupedMapping = this->groupedMapping(); | 2406 CompositedLayerMapping* oldGroupedMapping = this->groupedMapping(); |
2407 if (groupedMapping == oldGroupedMapping) | 2407 if (groupedMapping == oldGroupedMapping) |
2408 return; | 2408 return; |
2409 | 2409 |
2410 if (options == InvalidateLayerAndRemoveFromMapping && oldGroupedMapping) { | 2410 if (options == InvalidateLayerAndRemoveFromMapping && oldGroupedMapping) { |
2411 oldGroupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtre
e); | 2411 oldGroupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtre
e); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2575 | 2575 |
2576 return hasBoxDecorationsOrBackground() || hasOverflowControls(); | 2576 return hasBoxDecorationsOrBackground() || hasOverflowControls(); |
2577 } | 2577 } |
2578 | 2578 |
2579 void PaintLayer::updateFilters(const ComputedStyle* oldStyle, const ComputedStyl
e& newStyle) | 2579 void PaintLayer::updateFilters(const ComputedStyle* oldStyle, const ComputedStyl
e& newStyle) |
2580 { | 2580 { |
2581 if (!newStyle.hasFilterInducingProperty() && (!oldStyle || !oldStyle->hasFil
terInducingProperty())) | 2581 if (!newStyle.hasFilterInducingProperty() && (!oldStyle || !oldStyle->hasFil
terInducingProperty())) |
2582 return; | 2582 return; |
2583 | 2583 |
2584 updateOrRemoveFilterClients(); | 2584 updateOrRemoveFilterClients(); |
2585 updateOrRemoveFilterEffectBuilder(); | 2585 updateOrRemoveFilterEffect(); |
2586 } | 2586 } |
2587 | 2587 |
2588 bool PaintLayer::attemptDirectCompositingUpdate(StyleDifference diff, const Comp
utedStyle* oldStyle) | 2588 bool PaintLayer::attemptDirectCompositingUpdate(StyleDifference diff, const Comp
utedStyle* oldStyle) |
2589 { | 2589 { |
2590 CompositingReasons oldPotentialCompositingReasonsFromStyle = potentialCompos
itingReasonsFromStyle(); | 2590 CompositingReasons oldPotentialCompositingReasonsFromStyle = potentialCompos
itingReasonsFromStyle(); |
2591 compositor()->updatePotentialCompositingReasonsFromStyle(this); | 2591 compositor()->updatePotentialCompositingReasonsFromStyle(this); |
2592 | 2592 |
2593 // This function implements an optimization for transforms and opacity. | 2593 // This function implements an optimization for transforms and opacity. |
2594 // A common pattern is for a touchmove handler to update the transform | 2594 // A common pattern is for a touchmove handler to update the transform |
2595 // and/or an opacity of an element every frame while the user moves their | 2595 // and/or an opacity of an element every frame while the user moves their |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2684 bool PaintLayer::scrollsOverflow() const | 2684 bool PaintLayer::scrollsOverflow() const |
2685 { | 2685 { |
2686 if (PaintLayerScrollableArea* scrollableArea = this->getScrollableArea()) | 2686 if (PaintLayerScrollableArea* scrollableArea = this->getScrollableArea()) |
2687 return scrollableArea->scrollsOverflow(); | 2687 return scrollableArea->scrollsOverflow(); |
2688 | 2688 |
2689 return false; | 2689 return false; |
2690 } | 2690 } |
2691 | 2691 |
2692 namespace { | 2692 namespace { |
2693 | 2693 |
2694 FilterOperations resolveReferenceFilters( | 2694 FilterOperations resolveReferenceFilters(const FilterEffectBuilder& builder, con
st FilterOperations& filters) |
2695 const FilterOperations& filters, float effectiveZoom, Element& element, cons
t FloatRect& zoomedReferenceBox) | |
2696 { | 2695 { |
2697 DCHECK(filters.hasReferenceFilter()); | 2696 DCHECK(filters.hasReferenceFilter()); |
2698 | 2697 |
2699 for (FilterOperation* filterOperation : filters.operations()) { | 2698 for (FilterOperation* filterOperation : filters.operations()) { |
2700 if (filterOperation->type() != FilterOperation::REFERENCE) | 2699 if (filterOperation->type() != FilterOperation::REFERENCE) |
2701 continue; | 2700 continue; |
2702 ReferenceFilterOperation& referenceOperation = toReferenceFilterOperatio
n(*filterOperation); | 2701 ReferenceFilterOperation& referenceOperation = toReferenceFilterOperatio
n(*filterOperation); |
2703 // TODO(fs): Cache the Filter if it didn't change. | 2702 // TODO(fs): Cache the Filter if it didn't change. |
2704 Filter* referenceFilter = FilterEffectBuilder::buildReferenceFilter(refe
renceOperation, zoomedReferenceBox, nullptr, nullptr, element, nullptr, effectiv
eZoom); | 2703 referenceOperation.setFilter(builder.buildReferenceFilter(referenceOpera
tion)); |
2705 referenceOperation.setFilter(referenceFilter); | |
2706 } | 2704 } |
2707 return filters; | 2705 return filters; |
2708 } | 2706 } |
2709 | 2707 |
2710 } // unnamed namespace | 2708 } // unnamed namespace |
2711 | 2709 |
2712 FilterOperations PaintLayer::addReflectionToFilterOperations(const ComputedStyle
& style) const | 2710 FilterOperations PaintLayer::addReflectionToFilterOperations(const ComputedStyle
& style) const |
2713 { | 2711 { |
2714 FilterOperations filterOperations = style.filter(); | 2712 FilterOperations filterOperations = style.filter(); |
2715 if (RuntimeEnabledFeatures::cssBoxReflectFilterEnabled() && layoutObject()->
hasReflection() && layoutObject()->isBox()) { | 2713 if (RuntimeEnabledFeatures::cssBoxReflectFilterEnabled() && layoutObject()->
hasReflection() && layoutObject()->isBox()) { |
2716 BoxReflection reflection = boxReflectionForPaintLayer(*this, style); | 2714 BoxReflection reflection = boxReflectionForPaintLayer(*this, style); |
2717 filterOperations.operations().append(BoxReflectFilterOperation::create(r
eflection)); | 2715 filterOperations.operations().append(BoxReflectFilterOperation::create(r
eflection)); |
2718 } | 2716 } |
2719 return filterOperations; | 2717 return filterOperations; |
2720 } | 2718 } |
2721 | 2719 |
2722 CompositorFilterOperations PaintLayer::createCompositorFilterOperationsForFilter
(const ComputedStyle& style) | 2720 CompositorFilterOperations PaintLayer::createCompositorFilterOperationsForFilter
(const ComputedStyle& style) |
2723 { | 2721 { |
2724 FilterOperations filterOperations = addReflectionToFilterOperations(style); | 2722 FilterOperations filterOperations = addReflectionToFilterOperations(style); |
2725 if (filterOperations.hasReferenceFilter()) | 2723 if (filterOperations.hasReferenceFilter()) { |
2726 filterOperations = resolveReferenceFilters(filterOperations, style.effec
tiveZoom(), toElement(*enclosingNode()), boxForFilter()); | 2724 FilterEffectBuilder builder(toElement(enclosingNode()), boxForFilter(),
style.effectiveZoom()); |
| 2725 filterOperations = resolveReferenceFilters(builder, filterOperations); |
| 2726 } |
2727 return SkiaImageFilterBuilder::buildFilterOperations(filterOperations); | 2727 return SkiaImageFilterBuilder::buildFilterOperations(filterOperations); |
2728 } | 2728 } |
2729 | 2729 |
2730 CompositorFilterOperations PaintLayer::createCompositorFilterOperationsForBackdr
opFilter(const ComputedStyle& style) | 2730 CompositorFilterOperations PaintLayer::createCompositorFilterOperationsForBackdr
opFilter(const ComputedStyle& style) |
2731 { | 2731 { |
2732 FilterOperations operations = style.backdropFilter(); | 2732 FilterOperations operations = style.backdropFilter(); |
2733 if (operations.hasReferenceFilter()) | 2733 if (operations.hasReferenceFilter()) { |
2734 operations = resolveReferenceFilters(operations, style.effectiveZoom(),
toElement(*enclosingNode()), boxForFilter()); | 2734 FilterEffectBuilder builder(toElement(enclosingNode()), boxForFilter(),
style.effectiveZoom()); |
| 2735 operations = resolveReferenceFilters(builder, operations); |
| 2736 } |
2735 return SkiaImageFilterBuilder::buildFilterOperations(operations); | 2737 return SkiaImageFilterBuilder::buildFilterOperations(operations); |
2736 } | 2738 } |
2737 | 2739 |
2738 PaintLayerFilterInfo& PaintLayer::ensureFilterInfo() | 2740 PaintLayerFilterInfo& PaintLayer::ensureFilterInfo() |
2739 { | 2741 { |
2740 PaintLayerRareData& rareData = ensureRareData(); | 2742 PaintLayerRareData& rareData = ensureRareData(); |
2741 if (!rareData.filterInfo) | 2743 if (!rareData.filterInfo) |
2742 rareData.filterInfo = new PaintLayerFilterInfo(this); | 2744 rareData.filterInfo = new PaintLayerFilterInfo(this); |
2743 return *rareData.filterInfo; | 2745 return *rareData.filterInfo; |
2744 } | 2746 } |
(...skipping 21 matching lines...) Expand all Loading... |
2766 if (filter.isEmpty() && m_rareData && m_rareData->filterInfo) { | 2768 if (filter.isEmpty() && m_rareData && m_rareData->filterInfo) { |
2767 m_rareData->filterInfo->clearLayer(); | 2769 m_rareData->filterInfo->clearLayer(); |
2768 m_rareData->filterInfo = nullptr; | 2770 m_rareData->filterInfo = nullptr; |
2769 } else if (filter.hasReferenceFilter()) { | 2771 } else if (filter.hasReferenceFilter()) { |
2770 ensureFilterInfo().updateReferenceFilterClients(filter); | 2772 ensureFilterInfo().updateReferenceFilterClients(filter); |
2771 } else if (filterInfo()) { | 2773 } else if (filterInfo()) { |
2772 filterInfo()->clearFilterReferences(); | 2774 filterInfo()->clearFilterReferences(); |
2773 } | 2775 } |
2774 } | 2776 } |
2775 | 2777 |
2776 FilterEffectBuilder* PaintLayer::updateFilterEffectBuilder() const | 2778 FilterEffect* PaintLayer::updateFilterEffect() const |
2777 { | 2779 { |
2778 // TODO(chrishtr): ensure (and assert) that compositing is clean here. | 2780 // TODO(chrishtr): ensure (and assert) that compositing is clean here. |
2779 | 2781 |
2780 if (!paintsWithFilters()) | 2782 if (!paintsWithFilters()) |
2781 return nullptr; | 2783 return nullptr; |
2782 | 2784 |
2783 PaintLayerFilterInfo* filterInfo = this->filterInfo(); | 2785 PaintLayerFilterInfo* filterInfo = this->filterInfo(); |
2784 | 2786 |
2785 // Should have been added by updateOrRemoveFilterEffectBuilder(). | 2787 // Should have been added by updateOrRemoveFilterEffect(). |
2786 ASSERT(filterInfo); | 2788 ASSERT(filterInfo); |
2787 | 2789 |
2788 if (filterInfo->builder()) | 2790 if (filterInfo->lastEffect()) |
2789 return filterInfo->builder(); | 2791 return filterInfo->lastEffect(); |
2790 | |
2791 filterInfo->setBuilder(FilterEffectBuilder::create()); | |
2792 | 2792 |
2793 const ComputedStyle& style = layoutObject()->styleRef(); | 2793 const ComputedStyle& style = layoutObject()->styleRef(); |
2794 Element* element = toElement(enclosingNode()); | 2794 const bool hasReferenceFilter = style.filter().hasReferenceFilter(); |
| 2795 FloatRect zoomedReferenceBox; |
| 2796 if (hasReferenceFilter) |
| 2797 zoomedReferenceBox = boxForFilter(); |
| 2798 |
2795 FilterOperations operations = addReflectionToFilterOperations(style); | 2799 FilterOperations operations = addReflectionToFilterOperations(style); |
2796 FloatRect zoomedReferenceBox; | 2800 FilterEffectBuilder builder(toElement(enclosingNode()), zoomedReferenceBox,
style.effectiveZoom()); |
2797 if (style.filter().hasReferenceFilter()) { | 2801 if (hasReferenceFilter) |
2798 zoomedReferenceBox = boxForFilter(); | 2802 operations = resolveReferenceFilters(builder, operations); |
2799 operations = resolveReferenceFilters(operations, style.effectiveZoom(),
*element, zoomedReferenceBox); | |
2800 } | |
2801 if (!filterInfo->builder()->build(element, operations, style.effectiveZoom()
, zoomedReferenceBox)) | |
2802 filterInfo->setBuilder(nullptr); | |
2803 | 2803 |
2804 return filterInfo->builder(); | 2804 filterInfo->setLastEffect(builder.buildFilterEffect(operations)); |
| 2805 return filterInfo->lastEffect(); |
2805 } | 2806 } |
2806 | 2807 |
2807 FilterEffect* PaintLayer::lastFilterEffect() const | 2808 FilterEffect* PaintLayer::lastFilterEffect() const |
2808 { | 2809 { |
2809 FilterEffectBuilder* builder = updateFilterEffectBuilder(); | 2810 return updateFilterEffect(); |
2810 if (!builder) | |
2811 return nullptr; | |
2812 return builder->lastEffect(); | |
2813 } | 2811 } |
2814 | 2812 |
2815 FloatRect PaintLayer::mapRectForFilter(const FloatRect& rect) const | 2813 FloatRect PaintLayer::mapRectForFilter(const FloatRect& rect) const |
2816 { | 2814 { |
2817 if (!hasFilterThatMovesPixels()) | 2815 if (!hasFilterThatMovesPixels()) |
2818 return rect; | 2816 return rect; |
2819 | 2817 |
2820 // Ensure the filter-chain is refreshed wrt reference filters. | 2818 // Ensure the filter-chain is refreshed wrt reference filters. |
2821 updateFilterEffectBuilder(); | 2819 updateFilterEffect(); |
2822 | 2820 |
2823 FilterOperations filterOperations = addReflectionToFilterOperations(layoutOb
ject()->styleRef()); | 2821 FilterOperations filterOperations = addReflectionToFilterOperations(layoutOb
ject()->styleRef()); |
2824 return filterOperations.mapRect(rect); | 2822 return filterOperations.mapRect(rect); |
2825 } | 2823 } |
2826 | 2824 |
2827 LayoutRect PaintLayer::mapLayoutRectForFilter(const LayoutRect& rect) const | 2825 LayoutRect PaintLayer::mapLayoutRectForFilter(const LayoutRect& rect) const |
2828 { | 2826 { |
2829 if (!hasFilterThatMovesPixels()) | 2827 if (!hasFilterThatMovesPixels()) |
2830 return rect; | 2828 return rect; |
2831 return enclosingLayoutRect(mapRectForFilter(FloatRect(rect))); | 2829 return enclosingLayoutRect(mapRectForFilter(FloatRect(rect))); |
2832 } | 2830 } |
2833 | 2831 |
2834 bool PaintLayer::hasFilterThatMovesPixels() const | 2832 bool PaintLayer::hasFilterThatMovesPixels() const |
2835 { | 2833 { |
2836 if (!hasFilterInducingProperty()) | 2834 if (!hasFilterInducingProperty()) |
2837 return false; | 2835 return false; |
2838 const ComputedStyle& style = layoutObject()->styleRef(); | 2836 const ComputedStyle& style = layoutObject()->styleRef(); |
2839 if (style.hasFilter() && style.filter().hasFilterThatMovesPixels()) | 2837 if (style.hasFilter() && style.filter().hasFilterThatMovesPixels()) |
2840 return true; | 2838 return true; |
2841 if (RuntimeEnabledFeatures::cssBoxReflectFilterEnabled() && style.hasBoxRefl
ect()) | 2839 if (RuntimeEnabledFeatures::cssBoxReflectFilterEnabled() && style.hasBoxRefl
ect()) |
2842 return true; | 2840 return true; |
2843 return false; | 2841 return false; |
2844 } | 2842 } |
2845 | 2843 |
2846 void PaintLayer::updateOrRemoveFilterEffectBuilder() | 2844 void PaintLayer::updateOrRemoveFilterEffect() |
2847 { | 2845 { |
2848 // FilterEffectBuilder is only used to render the filters in software mode, | 2846 // FilterEffectBuilder is only used to render the filters in software mode, |
2849 // so we always need to run updateOrRemoveFilterEffectBuilder after the comp
osited | 2847 // so we always need to run updateOrRemoveFilterEffect after the composited |
2850 // mode might have changed for this layer. | 2848 // mode might have changed for this layer. |
2851 if (!paintsWithFilters()) { | 2849 if (!paintsWithFilters()) { |
2852 // Don't delete the whole filter info here, because we might use it | |
2853 // for loading CSS shader files. | |
2854 if (PaintLayerFilterInfo* filterInfo = this->filterInfo()) | 2850 if (PaintLayerFilterInfo* filterInfo = this->filterInfo()) |
2855 filterInfo->setBuilder(nullptr); | 2851 filterInfo->setLastEffect(nullptr); |
2856 | |
2857 return; | 2852 return; |
2858 } | 2853 } |
2859 | 2854 |
2860 ensureFilterInfo().setBuilder(nullptr); | 2855 ensureFilterInfo().setLastEffect(nullptr); |
2861 } | 2856 } |
2862 | 2857 |
2863 void PaintLayer::filterNeedsPaintInvalidation() | 2858 void PaintLayer::filterNeedsPaintInvalidation() |
2864 { | 2859 { |
2865 { | 2860 { |
2866 DeprecatedScheduleStyleRecalcDuringLayout marker(layoutObject()->documen
t().lifecycle()); | 2861 DeprecatedScheduleStyleRecalcDuringLayout marker(layoutObject()->documen
t().lifecycle()); |
2867 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a styl
e recalc, which | 2862 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a styl
e recalc, which |
2868 // is a problem because this function can be called right before perform
ing layout but | 2863 // is a problem because this function can be called right before perform
ing layout but |
2869 // after style recalc. | 2864 // after style recalc. |
2870 // | 2865 // |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3007 | 3002 |
3008 void showLayerTree(const blink::LayoutObject* layoutObject) | 3003 void showLayerTree(const blink::LayoutObject* layoutObject) |
3009 { | 3004 { |
3010 if (!layoutObject) { | 3005 if (!layoutObject) { |
3011 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n"); | 3006 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n"); |
3012 return; | 3007 return; |
3013 } | 3008 } |
3014 showLayerTree(layoutObject->enclosingLayer()); | 3009 showLayerTree(layoutObject->enclosingLayer()); |
3015 } | 3010 } |
3016 #endif | 3011 #endif |
OLD | NEW |