Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(732)

Side by Side Diff: third_party/WebKit/Source/core/paint/PaintLayer.cpp

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

Powered by Google App Engine
This is Rietveld 408576698