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

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

Issue 1459953002: Fix the reference box computation for CSS filter effects. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add TODO per review Created 5 years, 1 month 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 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 IntPoint pixelSnappedDelta = roundedIntPoint(delta); 1054 IntPoint pixelSnappedDelta = roundedIntPoint(delta);
1055 TransformationMatrix transform; 1055 TransformationMatrix transform;
1056 transform.translate(pixelSnappedDelta.x(), pixelSnappedDelta.y()); 1056 transform.translate(pixelSnappedDelta.x(), pixelSnappedDelta.y());
1057 if (layer->transform()) 1057 if (layer->transform())
1058 transform = transform * *layer->transform(); 1058 transform = transform * *layer->transform();
1059 1059
1060 // We don't use fragment boxes when collecting a transformed layer's bou nding box, since it always 1060 // We don't use fragment boxes when collecting a transformed layer's bou nding box, since it always
1061 // paints unfragmented. 1061 // paints unfragmented.
1062 LayoutRect clipRect = layer->physicalBoundingBox(layer); 1062 LayoutRect clipRect = layer->physicalBoundingBox(layer);
1063 expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transp arencyBehavior, subPixelAccumulation, globalPaintFlags); 1063 expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transp arencyBehavior, subPixelAccumulation, globalPaintFlags);
1064 clipRect.expand(layer->layoutObject()->style()->filterOutsets()); 1064 clipRect.expand(layer->filterOutsets());
1065 LayoutRect result = transform.mapRect(clipRect); 1065 LayoutRect result = transform.mapRect(clipRect);
1066 if (!paginationLayer) 1066 if (!paginationLayer)
1067 return result; 1067 return result;
1068 1068
1069 // We have to break up the transformed extent across our columns. 1069 // We have to break up the transformed extent across our columns.
1070 // Split our box up into the actual fragment boxes that layout in the co lumns/pages and unite those together to 1070 // Split our box up into the actual fragment boxes that layout in the co lumns/pages and unite those together to
1071 // get our true bounding box. 1071 // get our true bounding box.
1072 LayoutFlowThread* enclosingFlowThread = toLayoutFlowThread(paginationLay er->layoutObject()); 1072 LayoutFlowThread* enclosingFlowThread = toLayoutFlowThread(paginationLay er->layoutObject());
1073 result = enclosingFlowThread->fragmentsBoundingBox(result); 1073 result = enclosingFlowThread->fragmentsBoundingBox(result);
1074 1074
1075 LayoutPoint rootLayerDelta; 1075 LayoutPoint rootLayerDelta;
1076 paginationLayer->convertToLayerCoords(rootLayer, rootLayerDelta); 1076 paginationLayer->convertToLayerCoords(rootLayer, rootLayerDelta);
1077 result.moveBy(rootLayerDelta); 1077 result.moveBy(rootLayerDelta);
1078 return result; 1078 return result;
1079 } 1079 }
1080 1080
1081 LayoutRect clipRect = layer->fragmentsBoundingBox(rootLayer); 1081 LayoutRect clipRect = layer->fragmentsBoundingBox(rootLayer);
1082 expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transp arencyBehavior, subPixelAccumulation, globalPaintFlags); 1082 expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transp arencyBehavior, subPixelAccumulation, globalPaintFlags);
1083 clipRect.expand(layer->layoutObject()->style()->filterOutsets()); 1083 clipRect.expand(layer->filterOutsets());
1084 clipRect.move(subPixelAccumulation); 1084 clipRect.move(subPixelAccumulation);
1085 return clipRect; 1085 return clipRect;
1086 } 1086 }
1087 1087
1088 LayoutRect PaintLayer::paintingExtent(const PaintLayer* rootLayer, const LayoutS ize& subPixelAccumulation, GlobalPaintFlags globalPaintFlags) 1088 LayoutRect PaintLayer::paintingExtent(const PaintLayer* rootLayer, const LayoutS ize& subPixelAccumulation, GlobalPaintFlags globalPaintFlags)
1089 { 1089 {
1090 return transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, Roo tOfTransparencyClipBox, subPixelAccumulation, globalPaintFlags); 1090 return transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, Roo tOfTransparencyClipBox, subPixelAccumulation, globalPaintFlags);
1091 } 1091 }
1092 1092
1093 void* PaintLayer::operator new(size_t sz) 1093 void* PaintLayer::operator new(size_t sz)
(...skipping 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after
2188 // children of the parent, that need to be included in reflected composi ted bounds. 2188 // children of the parent, that need to be included in reflected composi ted bounds.
2189 // Fix this by including composited bounds of stacking children of the r eflected Layer. 2189 // Fix this by including composited bounds of stacking children of the r eflected Layer.
2190 if (hasCompositedLayerMapping() && parent() && parent()->reflectionInfo( ) && parent()->reflectionInfo()->reflectionLayer() == this) 2190 if (hasCompositedLayerMapping() && parent() && parent()->reflectionInfo( ) && parent()->reflectionInfo()->reflectionLayer() == this)
2191 expandRectForReflectionAndStackingChildren(parent(), result); 2191 expandRectForReflectionAndStackingChildren(parent(), result);
2192 else 2192 else
2193 expandRectForReflectionAndStackingChildren(this, result); 2193 expandRectForReflectionAndStackingChildren(this, result);
2194 2194
2195 // FIXME: We can optimize the size of the composited layers, by not enla rging 2195 // FIXME: We can optimize the size of the composited layers, by not enla rging
2196 // filtered areas with the outsets if we know that the filter is going t o render in hardware. 2196 // filtered areas with the outsets if we know that the filter is going t o render in hardware.
2197 // https://bugs.webkit.org/show_bug.cgi?id=81239 2197 // https://bugs.webkit.org/show_bug.cgi?id=81239
2198 result.expand(m_layoutObject->style()->filterOutsets()); 2198 result.expand(filterOutsets());
2199 } 2199 }
2200 2200
2201 if (transform() && paintsWithTransform(GlobalPaintNormalPhase) && (this != a ncestorLayer || options == MaybeIncludeTransformForAncestorLayer)) 2201 if (transform() && paintsWithTransform(GlobalPaintNormalPhase) && (this != a ncestorLayer || options == MaybeIncludeTransformForAncestorLayer))
2202 result = transform()->mapRect(result); 2202 result = transform()->mapRect(result);
2203 2203
2204 if (enclosingPaginationLayer()) { 2204 if (enclosingPaginationLayer()) {
2205 convertFromFlowThreadToVisualBoundingBoxInAncestor(this, ancestorLayer, result); 2205 convertFromFlowThreadToVisualBoundingBoxInAncestor(this, ancestorLayer, result);
2206 return result; 2206 return result;
2207 } 2207 }
2208 LayoutPoint delta; 2208 LayoutPoint delta;
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
2566 RefPtrWillBeRawPtr<Filter> referenceFilter = ReferenceFilterBuilder: :build(effectiveZoom, toElement(enclosingElement), nullptr, referenceOperation); 2566 RefPtrWillBeRawPtr<Filter> referenceFilter = ReferenceFilterBuilder: :build(effectiveZoom, toElement(enclosingElement), nullptr, referenceOperation);
2567 referenceOperation.setFilter(referenceFilter.release()); 2567 referenceOperation.setFilter(referenceFilter.release());
2568 } 2568 }
2569 } 2569 }
2570 2570
2571 return filters; 2571 return filters;
2572 } 2572 }
2573 2573
2574 } // unnamed namespace 2574 } // unnamed namespace
2575 2575
2576 FilterOperations PaintLayer::computeFilterOperations(const ComputedStyle& style) 2576 FilterOperations PaintLayer::computeFilterOperations(const ComputedStyle& style) const
2577 { 2577 {
2578 return computeFilterOperationsHandleReferenceFilters(style.filter(), style.e ffectiveZoom(), enclosingElement()); 2578 return computeFilterOperationsHandleReferenceFilters(style.filter(), style.e ffectiveZoom(), enclosingElement());
2579 } 2579 }
2580 2580
2581 FilterOperations PaintLayer::computeBackdropFilterOperations(const ComputedStyle & style) 2581 FilterOperations PaintLayer::computeBackdropFilterOperations(const ComputedStyle & style) const
2582 { 2582 {
2583 return computeFilterOperationsHandleReferenceFilters(style.backdropFilter(), style.effectiveZoom(), enclosingElement()); 2583 return computeFilterOperationsHandleReferenceFilters(style.backdropFilter(), style.effectiveZoom(), enclosingElement());
2584 } 2584 }
2585 2585
2586 void PaintLayer::updateOrRemoveFilterClients() 2586 void PaintLayer::updateOrRemoveFilterClients()
2587 { 2587 {
2588 if (!hasFilter()) { 2588 if (!hasFilter()) {
2589 removeFilterInfoIfNeeded(); 2589 removeFilterInfoIfNeeded();
2590 return; 2590 return;
2591 } 2591 }
2592 2592
2593 if (layoutObject()->style()->filter().hasReferenceFilter()) 2593 if (layoutObject()->style()->filter().hasReferenceFilter())
2594 ensureFilterInfo()->updateReferenceFilterClients(layoutObject()->style() ->filter()); 2594 ensureFilterInfo()->updateReferenceFilterClients(layoutObject()->style() ->filter());
2595 else if (hasFilterInfo()) 2595 else if (hasFilterInfo())
2596 filterInfo()->removeReferenceFilterClients(); 2596 filterInfo()->removeReferenceFilterClients();
2597 } 2597 }
2598 2598
2599 FilterEffectBuilder* PaintLayer::updateFilterEffectBuilder() const
2600 {
2601 // TODO(chrishtr): ensure (and assert) that compositing is clean here.
2602
2603 if (!paintsWithFilters())
2604 return nullptr;
2605
2606 PaintLayerFilterInfo* filterInfo = this->filterInfo();
2607
2608 // Should have been added by updateOrRemoveFilterEffectBuilder().
2609 ASSERT(filterInfo);
2610
2611 if (filterInfo->builder())
2612 return filterInfo->builder();
2613
2614 filterInfo->setBuilder(FilterEffectBuilder::create());
2615
2616 float zoom = layoutObject()->style() ? layoutObject()->style()->effectiveZoo m() : 1.0f;
2617 if (!filterInfo->builder()->build(toElement(enclosingElement()), computeFilt erOperations(layoutObject()->styleRef()), zoom))
2618 filterInfo->setBuilder(nullptr);
2619
2620 return filterInfo->builder();
2621 }
2622
2623 FilterEffect* PaintLayer::lastFilterEffect() const
2624 {
2625 FilterEffectBuilder* builder = updateFilterEffectBuilder();
2626 if (!builder)
2627 return nullptr;
2628 return builder->lastEffect().get();
2629 }
2630
2631 FilterOutsets PaintLayer::filterOutsets() const
2632 {
2633 if (!layoutObject()->hasFilter())
2634 return FilterOutsets();
2635
2636 // Ensure the filter-chain is refreshed wrt reference filters.
2637 updateFilterEffectBuilder();
2638 return layoutObject()->style()->filter().outsets();
2639 }
2640
2599 void PaintLayer::updateOrRemoveFilterEffectBuilder() 2641 void PaintLayer::updateOrRemoveFilterEffectBuilder()
2600 { 2642 {
2601 // FilterEffectBuilder is only used to render the filters in software mode, 2643 // FilterEffectBuilder is only used to render the filters in software mode,
2602 // so we always need to run updateOrRemoveFilterEffectBuilder after the comp osited 2644 // so we always need to run updateOrRemoveFilterEffectBuilder after the comp osited
2603 // mode might have changed for this layer. 2645 // mode might have changed for this layer.
2604 if (!paintsWithFilters()) { 2646 if (!paintsWithFilters()) {
2605 // Don't delete the whole filter info here, because we might use it 2647 // Don't delete the whole filter info here, because we might use it
2606 // for loading CSS shader files. 2648 // for loading CSS shader files.
2607 if (PaintLayerFilterInfo* filterInfo = this->filterInfo()) 2649 if (PaintLayerFilterInfo* filterInfo = this->filterInfo())
2608 filterInfo->setBuilder(nullptr); 2650 filterInfo->setBuilder(nullptr);
2609 2651
2610 return; 2652 return;
2611 } 2653 }
2612 2654
2613 PaintLayerFilterInfo* filterInfo = ensureFilterInfo(); 2655 ensureFilterInfo()->setBuilder(nullptr);
2614 if (!filterInfo->builder())
2615 filterInfo->setBuilder(FilterEffectBuilder::create());
2616
2617 // If the filter fails to build, remove it from the layer. It will still att empt to
2618 // go through regular processing (e.g. compositing), but never apply anythin g.
2619 float zoom = layoutObject()->style() ? layoutObject()->style()->effectiveZoo m() : 1.0f;
2620 if (!filterInfo->builder()->build(toElement(enclosingElement()), computeFilt erOperations(layoutObject()->styleRef()), zoom))
2621 filterInfo->setBuilder(nullptr);
2622 } 2656 }
2623 2657
2624 void PaintLayer::filterNeedsPaintInvalidation() 2658 void PaintLayer::filterNeedsPaintInvalidation()
2625 { 2659 {
2626 { 2660 {
2627 DeprecatedScheduleStyleRecalcDuringLayout marker(layoutObject()->documen t().lifecycle()); 2661 DeprecatedScheduleStyleRecalcDuringLayout marker(layoutObject()->documen t().lifecycle());
2628 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a styl e recalc, which 2662 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a styl e recalc, which
2629 // is a problem because this function can be called while performing lay out. 2663 // is a problem because this function can be called while performing lay out.
2630 // Presumably this represents an illegal data flow of layout or composit ing 2664 // Presumably this represents an illegal data flow of layout or composit ing
2631 // information into the style system. 2665 // information into the style system.
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
2738 2772
2739 void showLayerTree(const blink::LayoutObject* layoutObject) 2773 void showLayerTree(const blink::LayoutObject* layoutObject)
2740 { 2774 {
2741 if (!layoutObject) { 2775 if (!layoutObject) {
2742 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n"); 2776 fprintf(stderr, "Cannot showLayerTree. Root is (nil)\n");
2743 return; 2777 return;
2744 } 2778 }
2745 showLayerTree(layoutObject->enclosingLayer()); 2779 showLayerTree(layoutObject->enclosingLayer());
2746 } 2780 }
2747 #endif 2781 #endif
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/paint/PaintLayer.h ('k') | third_party/WebKit/Source/core/style/ComputedStyle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698