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

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: make msvc dbg happy 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 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/paint/PaintLayer.h ('k') | third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698