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 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 if (hasCompositedLayerMapping()) | 244 if (hasCompositedLayerMapping()) |
245 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerU
pdateSubtree); | 245 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerU
pdateSubtree); |
246 } | 246 } |
247 | 247 |
248 if (CompositedLayerMapping* compositedLayerMapping = this->compositedLayerMa
pping()) | 248 if (CompositedLayerMapping* compositedLayerMapping = this->compositedLayerMa
pping()) |
249 compositedLayerMapping->contentChanged(changeType); | 249 compositedLayerMapping->contentChanged(changeType); |
250 } | 250 } |
251 | 251 |
252 bool PaintLayer::paintsWithFilters() const | 252 bool PaintLayer::paintsWithFilters() const |
253 { | 253 { |
254 if (!layoutObject()->hasFilter()) | 254 if (!layoutObject()->hasFilterInducingProperty()) |
255 return false; | 255 return false; |
256 | 256 |
257 // https://code.google.com/p/chromium/issues/detail?id=343759 | 257 // https://code.google.com/p/chromium/issues/detail?id=343759 |
258 DisableCompositingQueryAsserts disabler; | 258 DisableCompositingQueryAsserts disabler; |
259 return !compositedLayerMapping() || compositingState() != PaintsIntoOwnBacki
ng; | 259 return !compositedLayerMapping() || compositingState() != PaintsIntoOwnBacki
ng; |
260 } | 260 } |
261 | 261 |
262 bool PaintLayer::paintsWithBackdropFilters() const | 262 bool PaintLayer::paintsWithBackdropFilters() const |
263 { | 263 { |
264 if (!layoutObject()->hasBackdropFilter()) | 264 if (!layoutObject()->hasBackdropFilter()) |
(...skipping 791 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1056 | 1056 |
1057 m_shouldIsolateCompositedDescendants = shouldIsolateCompositedDescendants; | 1057 m_shouldIsolateCompositedDescendants = shouldIsolateCompositedDescendants; |
1058 | 1058 |
1059 if (hasCompositedLayerMapping()) | 1059 if (hasCompositedLayerMapping()) |
1060 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdat
eLocal); | 1060 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdat
eLocal); |
1061 } | 1061 } |
1062 | 1062 |
1063 bool PaintLayer::hasAncestorWithFilterOutsets() const | 1063 bool PaintLayer::hasAncestorWithFilterOutsets() const |
1064 { | 1064 { |
1065 for (const PaintLayer* curr = this; curr; curr = curr->parent()) { | 1065 for (const PaintLayer* curr = this; curr; curr = curr->parent()) { |
1066 LayoutBoxModelObject* layoutObject = curr->layoutObject(); | 1066 if (curr->hasFilterOutsets()) |
1067 if (layoutObject->style()->hasFilterOutsets()) | |
1068 return true; | 1067 return true; |
1069 } | 1068 } |
1070 return false; | 1069 return false; |
1071 } | 1070 } |
1072 | 1071 |
1073 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, cons
t PaintLayer* layer, const PaintLayer* rootLayer, | 1072 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, cons
t PaintLayer* layer, const PaintLayer* rootLayer, |
1074 PaintLayer::TransparencyClipBoxBehavior transparencyBehavior, const LayoutSi
ze& subPixelAccumulation, GlobalPaintFlags globalPaintFlags) | 1073 PaintLayer::TransparencyClipBoxBehavior transparencyBehavior, const LayoutSi
ze& subPixelAccumulation, GlobalPaintFlags globalPaintFlags) |
1075 { | 1074 { |
1076 // If we have a mask, then the clip is limited to the border box area (and t
here is | 1075 // If we have a mask, then the clip is limited to the border box area (and t
here is |
1077 // no need to examine child layers). | 1076 // no need to examine child layers). |
(...skipping 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2124 return result; | 2123 return result; |
2125 } | 2124 } |
2126 | 2125 |
2127 LayoutRect PaintLayer::boundingBoxForCompositingOverlapTest() const | 2126 LayoutRect PaintLayer::boundingBoxForCompositingOverlapTest() const |
2128 { | 2127 { |
2129 // Apply NeverIncludeTransformForAncestorLayer, because the geometry map in
CompositingInputsUpdater will take care of applying the | 2128 // Apply NeverIncludeTransformForAncestorLayer, because the geometry map in
CompositingInputsUpdater will take care of applying the |
2130 // transform of |this| (== the ancestorLayer argument to boundingBoxForCompo
siting). | 2129 // transform of |this| (== the ancestorLayer argument to boundingBoxForCompo
siting). |
2131 return overlapBoundsIncludeChildren() ? boundingBoxForCompositing(this, Neve
rIncludeTransformForAncestorLayer) : fragmentsBoundingBox(this); | 2130 return overlapBoundsIncludeChildren() ? boundingBoxForCompositing(this, Neve
rIncludeTransformForAncestorLayer) : fragmentsBoundingBox(this); |
2132 } | 2131 } |
2133 | 2132 |
| 2133 bool PaintLayer::overlapBoundsIncludeChildren() const |
| 2134 { |
| 2135 const auto* style = layoutObject()->style(); |
| 2136 if (style && style->filter().hasFilterThatMovesPixels()) |
| 2137 return true; |
| 2138 if (RuntimeEnabledFeatures::cssBoxReflectFilterEnabled() && layoutObject()->
hasReflection()) |
| 2139 return true; |
| 2140 return false; |
| 2141 } |
| 2142 |
2134 static void expandRectForReflectionAndStackingChildren(const PaintLayer* ancesto
rLayer, LayoutRect& result) | 2143 static void expandRectForReflectionAndStackingChildren(const PaintLayer* ancesto
rLayer, LayoutRect& result) |
2135 { | 2144 { |
2136 if (ancestorLayer->reflectionInfo() && !ancestorLayer->reflectionInfo()->ref
lectionLayer()->hasCompositedLayerMapping()) | 2145 if (ancestorLayer->reflectionInfo() && !ancestorLayer->reflectionInfo()->ref
lectionLayer()->hasCompositedLayerMapping() && !RuntimeEnabledFeatures::cssBoxRe
flectFilterEnabled()) |
2137 result.unite(ancestorLayer->reflectionInfo()->reflectionLayer()->boundin
gBoxForCompositing(ancestorLayer)); | 2146 result.unite(ancestorLayer->reflectionInfo()->reflectionLayer()->boundin
gBoxForCompositing(ancestorLayer)); |
2138 | 2147 |
2139 ASSERT(ancestorLayer->stackingNode()->isStackingContext() || !ancestorLayer-
>stackingNode()->hasPositiveZOrderList()); | 2148 ASSERT(ancestorLayer->stackingNode()->isStackingContext() || !ancestorLayer-
>stackingNode()->hasPositiveZOrderList()); |
2140 | 2149 |
2141 #if ENABLE(ASSERT) | 2150 #if ENABLE(ASSERT) |
2142 LayerListMutationDetector mutationChecker(const_cast<PaintLayer*>(ancestorLa
yer)->stackingNode()); | 2151 LayerListMutationDetector mutationChecker(const_cast<PaintLayer*>(ancestorLa
yer)->stackingNode()); |
2143 #endif | 2152 #endif |
2144 | 2153 |
2145 PaintLayerStackingNodeIterator iterator(*ancestorLayer->stackingNode(), AllC
hildren); | 2154 PaintLayerStackingNodeIterator iterator(*ancestorLayer->stackingNode(), AllC
hildren); |
2146 while (PaintLayerStackingNode* node = iterator.next()) { | 2155 while (PaintLayerStackingNode* node = iterator.next()) { |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2463 bool PaintLayer::hasVisibleBoxDecorations() const | 2472 bool PaintLayer::hasVisibleBoxDecorations() const |
2464 { | 2473 { |
2465 if (!hasVisibleContent()) | 2474 if (!hasVisibleContent()) |
2466 return false; | 2475 return false; |
2467 | 2476 |
2468 return hasBoxDecorationsOrBackground() || hasOverflowControls(); | 2477 return hasBoxDecorationsOrBackground() || hasOverflowControls(); |
2469 } | 2478 } |
2470 | 2479 |
2471 void PaintLayer::updateFilters(const ComputedStyle* oldStyle, const ComputedStyl
e& newStyle) | 2480 void PaintLayer::updateFilters(const ComputedStyle* oldStyle, const ComputedStyl
e& newStyle) |
2472 { | 2481 { |
2473 if (!newStyle.hasFilter() && (!oldStyle || !oldStyle->hasFilter())) | 2482 if (!newStyle.hasFilterInducingProperty() && (!oldStyle || !oldStyle->hasFil
terInducingProperty())) |
2474 return; | 2483 return; |
2475 | 2484 |
2476 updateOrRemoveFilterClients(); | 2485 updateOrRemoveFilterClients(); |
2477 updateOrRemoveFilterEffectBuilder(); | 2486 updateOrRemoveFilterEffectBuilder(); |
2478 } | 2487 } |
2479 | 2488 |
2480 bool PaintLayer::attemptDirectCompositingUpdate(StyleDifference diff, const Comp
utedStyle* oldStyle) | 2489 bool PaintLayer::attemptDirectCompositingUpdate(StyleDifference diff, const Comp
utedStyle* oldStyle) |
2481 { | 2490 { |
2482 CompositingReasons oldPotentialCompositingReasonsFromStyle = potentialCompos
itingReasonsFromStyle(); | 2491 CompositingReasons oldPotentialCompositingReasonsFromStyle = potentialCompos
itingReasonsFromStyle(); |
2483 compositor()->updatePotentialCompositingReasonsFromStyle(this); | 2492 compositor()->updatePotentialCompositingReasonsFromStyle(this); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2596 } | 2605 } |
2597 } | 2606 } |
2598 | 2607 |
2599 return filters; | 2608 return filters; |
2600 } | 2609 } |
2601 | 2610 |
2602 } // unnamed namespace | 2611 } // unnamed namespace |
2603 | 2612 |
2604 FilterOperations PaintLayer::computeFilterOperations(const ComputedStyle& style)
const | 2613 FilterOperations PaintLayer::computeFilterOperations(const ComputedStyle& style)
const |
2605 { | 2614 { |
2606 return computeFilterOperationsHandleReferenceFilters(style.filter(), style.e
ffectiveZoom(), enclosingNode()); | 2615 FilterOperations filterOperations = style.filter(); |
| 2616 if (RuntimeEnabledFeatures::cssBoxReflectFilterEnabled() && layoutObject()->
hasReflection() && layoutObject()->isBox()) { |
| 2617 // TODO(jbroman): Incorporate the mask image. |
| 2618 const auto* reflectStyle = style.boxReflect(); |
| 2619 FloatRect frameRect(toLayoutBox(layoutObject())->frameRect()); |
| 2620 ReflectionDirection direction = VerticalReflection; |
| 2621 float offset = 0; |
| 2622 switch (reflectStyle->direction()) { |
| 2623 case ReflectionAbove: |
| 2624 direction = VerticalReflection; |
| 2625 offset = -floatValueForLength(reflectStyle->offset(), frameRect.heig
ht()); |
| 2626 break; |
| 2627 case ReflectionBelow: |
| 2628 direction = VerticalReflection; |
| 2629 offset = 2 * frameRect.height() + floatValueForLength(reflectStyle->
offset(), frameRect.height()); |
| 2630 break; |
| 2631 case ReflectionLeft: |
| 2632 direction = HorizontalReflection; |
| 2633 offset = -floatValueForLength(reflectStyle->offset(), frameRect.widt
h()); |
| 2634 break; |
| 2635 case ReflectionRight: |
| 2636 direction = HorizontalReflection; |
| 2637 offset = 2 * frameRect.width() + floatValueForLength(reflectStyle->o
ffset(), frameRect.width()); |
| 2638 break; |
| 2639 } |
| 2640 |
| 2641 // Since the filter origin is the corner of the input bounds, which may |
| 2642 // include visual overflow (e.g. due to box-shadow), we must adjust the |
| 2643 // offset to also account for this offset (this is equivalent to using |
| 2644 // SkLocalMatrixImageFilter, but simpler). |
| 2645 // The rect used here should match the one used in FilterPainter. |
| 2646 LayoutRect filterInputBounds = physicalBoundingBoxIncludingReflectionAnd
StackingChildren(LayoutPoint()); |
| 2647 offset -= 2 * (direction == VerticalReflection ? filterInputBounds.y() :
filterInputBounds.x()).toFloat(); |
| 2648 |
| 2649 filterOperations.operations().append(BoxReflectFilterOperation::create(d
irection, offset)); |
| 2650 } |
| 2651 return computeFilterOperationsHandleReferenceFilters(filterOperations, style
.effectiveZoom(), enclosingNode()); |
2607 } | 2652 } |
2608 | 2653 |
2609 FilterOperations PaintLayer::computeBackdropFilterOperations(const ComputedStyle
& style) const | 2654 FilterOperations PaintLayer::computeBackdropFilterOperations(const ComputedStyle
& style) const |
2610 { | 2655 { |
2611 return computeFilterOperationsHandleReferenceFilters(style.backdropFilter(),
style.effectiveZoom(), enclosingNode()); | 2656 return computeFilterOperationsHandleReferenceFilters(style.backdropFilter(),
style.effectiveZoom(), enclosingNode()); |
2612 } | 2657 } |
2613 | 2658 |
2614 PaintLayerFilterInfo& PaintLayer::ensureFilterInfo() | 2659 PaintLayerFilterInfo& PaintLayer::ensureFilterInfo() |
2615 { | 2660 { |
2616 PaintLayerRareData& rareData = ensureRareData(); | 2661 PaintLayerRareData& rareData = ensureRareData(); |
2617 if (!rareData.filterInfo) | 2662 if (!rareData.filterInfo) |
2618 rareData.filterInfo = adoptPtr(new PaintLayerFilterInfo(this)); | 2663 rareData.filterInfo = adoptPtr(new PaintLayerFilterInfo(this)); |
2619 return *rareData.filterInfo; | 2664 return *rareData.filterInfo; |
2620 } | 2665 } |
2621 | 2666 |
2622 void PaintLayer::updateOrRemoveFilterClients() | 2667 void PaintLayer::updateOrRemoveFilterClients() |
2623 { | 2668 { |
2624 if (!hasFilter() && m_rareData) { | 2669 const auto& filter = layoutObject()->style()->filter(); |
| 2670 if (filter.isEmpty() && m_rareData) { |
2625 m_rareData->filterInfo = nullptr; | 2671 m_rareData->filterInfo = nullptr; |
2626 } else if (layoutObject()->style()->filter().hasReferenceFilter()) { | 2672 } else if (filter.hasReferenceFilter()) { |
2627 ensureFilterInfo().updateReferenceFilterClients(layoutObject()->style()-
>filter()); | 2673 ensureFilterInfo().updateReferenceFilterClients(filter); |
2628 } else if (filterInfo()) { | 2674 } else if (filterInfo()) { |
2629 filterInfo()->clearFilterReferences(); | 2675 filterInfo()->clearFilterReferences(); |
2630 } | 2676 } |
2631 } | 2677 } |
2632 | 2678 |
2633 FilterEffectBuilder* PaintLayer::updateFilterEffectBuilder() const | 2679 FilterEffectBuilder* PaintLayer::updateFilterEffectBuilder() const |
2634 { | 2680 { |
2635 // TODO(chrishtr): ensure (and assert) that compositing is clean here. | 2681 // TODO(chrishtr): ensure (and assert) that compositing is clean here. |
2636 | 2682 |
2637 if (!paintsWithFilters()) | 2683 if (!paintsWithFilters()) |
(...skipping 17 matching lines...) Expand all Loading... |
2655 } | 2701 } |
2656 | 2702 |
2657 FilterEffect* PaintLayer::lastFilterEffect() const | 2703 FilterEffect* PaintLayer::lastFilterEffect() const |
2658 { | 2704 { |
2659 FilterEffectBuilder* builder = updateFilterEffectBuilder(); | 2705 FilterEffectBuilder* builder = updateFilterEffectBuilder(); |
2660 if (!builder) | 2706 if (!builder) |
2661 return nullptr; | 2707 return nullptr; |
2662 return builder->lastEffect().get(); | 2708 return builder->lastEffect().get(); |
2663 } | 2709 } |
2664 | 2710 |
| 2711 bool PaintLayer::hasFilterOutsets() const |
| 2712 { |
| 2713 if (!layoutObject()->hasFilterInducingProperty()) |
| 2714 return false; |
| 2715 const ComputedStyle& style = layoutObject()->styleRef(); |
| 2716 if (style.hasFilter() && style.filter().hasOutsets()) |
| 2717 return true; |
| 2718 if (RuntimeEnabledFeatures::cssBoxReflectFilterEnabled() && style.hasBoxRefl
ect()) |
| 2719 return true; |
| 2720 return false; |
| 2721 } |
| 2722 |
2665 FilterOutsets PaintLayer::filterOutsets() const | 2723 FilterOutsets PaintLayer::filterOutsets() const |
2666 { | 2724 { |
2667 if (!layoutObject()->hasFilter()) | 2725 if (!layoutObject()->hasFilterInducingProperty()) |
2668 return FilterOutsets(); | 2726 return FilterOutsets(); |
2669 | 2727 |
2670 // Ensure the filter-chain is refreshed wrt reference filters. | 2728 // Ensure the filter-chain is refreshed wrt reference filters. |
2671 updateFilterEffectBuilder(); | 2729 updateFilterEffectBuilder(); |
| 2730 |
2672 return layoutObject()->style()->filter().outsets(); | 2731 return layoutObject()->style()->filter().outsets(); |
2673 } | 2732 } |
2674 | 2733 |
2675 void PaintLayer::updateOrRemoveFilterEffectBuilder() | 2734 void PaintLayer::updateOrRemoveFilterEffectBuilder() |
2676 { | 2735 { |
2677 // FilterEffectBuilder is only used to render the filters in software mode, | 2736 // FilterEffectBuilder is only used to render the filters in software mode, |
2678 // so we always need to run updateOrRemoveFilterEffectBuilder after the comp
osited | 2737 // so we always need to run updateOrRemoveFilterEffectBuilder after the comp
osited |
2679 // mode might have changed for this layer. | 2738 // mode might have changed for this layer. |
2680 if (!paintsWithFilters()) { | 2739 if (!paintsWithFilters()) { |
2681 // Don't delete the whole filter info here, because we might use it | 2740 // Don't delete the whole filter info here, because we might use it |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2817 | 2876 |
2818 void showLayerTree(const blink::LayoutObject* layoutObject) | 2877 void showLayerTree(const blink::LayoutObject* layoutObject) |
2819 { | 2878 { |
2820 if (!layoutObject) { | 2879 if (!layoutObject) { |
2821 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n"); | 2880 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n"); |
2822 return; | 2881 return; |
2823 } | 2882 } |
2824 showLayerTree(layoutObject->enclosingLayer()); | 2883 showLayerTree(layoutObject->enclosingLayer()); |
2825 } | 2884 } |
2826 #endif | 2885 #endif |
OLD | NEW |