Changeset 237255 in webkit
- Timestamp:
- Oct 18, 2018 6:50:55 AM (6 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 27 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r237245 r237255 1 2018-10-18 Ali Juma <ajuma@chromium.org> 2 3 [IntersectionObserver] Factor out rect mapping and clipping logic from computeRectForRepaint 4 https://bugs.webkit.org/show_bug.cgi?id=189833 5 6 Reviewed by Simon Fraser. 7 8 Factor out the rect mapping and clipping logic from computeRectForRepaint to a new 9 computeVisibleRectInContainer method that computeRectForRepaint now calls. Make 10 computeVisibleRectInContainer take a VisibleRectContext with options to use 11 edge-inclusive intersection and to apply all clips and scrolls rather than only 12 the clips and scrolls that are currently applied by the repaint logic. These 13 options will be used by IntersectionObserver in a future patch. 14 15 No new tests, no change in behavior. 16 17 * platform/graphics/FloatRect.cpp: 18 (WebCore::FloatRect::edgeInclusiveIntersect): 19 * platform/graphics/FloatRect.h: 20 * platform/graphics/LayoutRect.cpp: 21 (WebCore::LayoutRect::edgeInclusiveIntersect): 22 * platform/graphics/LayoutRect.h: 23 * rendering/RenderBox.cpp: 24 (WebCore::RenderBox::applyCachedClipAndScrollPosition const): 25 (WebCore::RenderBox::computeVisibleRectUsingPaintOffset const): 26 (WebCore::RenderBox::computeVisibleRectInContainer const): 27 (WebCore::RenderBox::applyCachedClipAndScrollPositionForRepaint const): Deleted. 28 (WebCore::RenderBox::shouldApplyClipAndScrollPositionForRepaint const): Deleted. 29 The iOS-specific logic in this method has moved to RenderObject::shouldApplyCompositedContainerScrollsForRepaint. 30 (WebCore::RenderBox::computeRectForRepaint const): Deleted. 31 * rendering/RenderBox.h: 32 (WebCore::RenderBox::computeRectForRepaint): Deleted. 33 * rendering/RenderInline.cpp: 34 (WebCore::RenderInline::clippedOverflowRectForRepaint const): 35 (WebCore::RenderInline::computeVisibleRectUsingPaintOffset const): 36 (WebCore::RenderInline::computeVisibleRectInContainer const): 37 (WebCore::RenderInline::computeRectForRepaint const): Deleted. 38 * rendering/RenderInline.h: 39 (WebCore::RenderInline::computeRectForRepaint): Deleted. 40 * rendering/RenderObject.cpp: 41 (WebCore::RenderObject::shouldApplyCompositedContainerScrollsForRepaint): 42 (WebCore::RenderObject::visibleRectContextForRepaint): 43 (WebCore::RenderObject::computeRectForRepaint const): 44 (WebCore::RenderObject::computeFloatRectForRepaint const): 45 (WebCore::RenderObject::computeVisibleRectInContainer const): 46 (WebCore::RenderObject::computeFloatVisibleRectInContainer const): 47 * rendering/RenderObject.h: 48 (WebCore::RenderObject::computeAbsoluteRepaintRect const): 49 (WebCore::RenderObject::VisibleRectContext::VisibleRectContext): 50 (WebCore::RenderObject::RepaintContext::RepaintContext): Deleted. 51 (WebCore::RenderObject::computeRectForRepaint): Deleted. 52 * rendering/RenderTableCell.cpp: 53 (WebCore::RenderTableCell::computeVisibleRectInContainer const): 54 (WebCore::RenderTableCell::computeRectForRepaint const): Deleted. 55 * rendering/RenderTableCell.h: 56 * rendering/RenderView.cpp: 57 (WebCore::RenderView::computeVisibleRectInContainer const): 58 (WebCore::RenderView::computeRectForRepaint const): Deleted. 59 * rendering/RenderView.h: 60 * rendering/svg/RenderSVGForeignObject.cpp: 61 (WebCore::RenderSVGForeignObject::computeFloatVisibleRectInContainer const): 62 (WebCore::RenderSVGForeignObject::computeVisibleRectInContainer const): 63 (WebCore::RenderSVGForeignObject::computeFloatRectForRepaint const): Deleted. 64 (WebCore::RenderSVGForeignObject::computeRectForRepaint const): Deleted. 65 * rendering/svg/RenderSVGForeignObject.h: 66 * rendering/svg/RenderSVGInline.cpp: 67 (WebCore::RenderSVGInline::computeFloatVisibleRectInContainer const): 68 (WebCore::RenderSVGInline::computeFloatRectForRepaint const): Deleted. 69 * rendering/svg/RenderSVGInline.h: 70 * rendering/svg/RenderSVGModelObject.cpp: 71 (WebCore::RenderSVGModelObject::computeFloatVisibleRectInContainer const): 72 (WebCore::RenderSVGModelObject::computeFloatRectForRepaint const): Deleted. 73 * rendering/svg/RenderSVGModelObject.h: 74 * rendering/svg/RenderSVGRoot.cpp: 75 (WebCore::RenderSVGRoot::computeFloatVisibleRectInContainer const): 76 (WebCore::RenderSVGRoot::computeFloatRectForRepaint const): Deleted. 77 * rendering/svg/RenderSVGRoot.h: 78 * rendering/svg/RenderSVGText.cpp: 79 (WebCore::RenderSVGText::computeVisibleRectInContainer const): 80 (WebCore::RenderSVGText::computeFloatVisibleRectInContainer const): 81 (WebCore::RenderSVGText::computeRectForRepaint const): Deleted. 82 (WebCore::RenderSVGText::computeFloatRectForRepaint const): Deleted. 83 * rendering/svg/RenderSVGText.h: 84 * rendering/svg/SVGRenderSupport.cpp: 85 (WebCore::SVGRenderSupport::clippedOverflowRectForRepaint): 86 (WebCore::SVGRenderSupport::computeFloatVisibleRectInContainer): 87 (WebCore::SVGRenderSupport::computeFloatRectForRepaint): Deleted. 88 * rendering/svg/SVGRenderSupport.h: 89 1 90 2018-10-17 Wenson Hsieh <wenson_hsieh@apple.com> 2 91 -
trunk/Source/WebCore/platform/graphics/FloatRect.cpp
r220503 r237255 94 94 } 95 95 96 bool FloatRect::edgeInclusiveIntersect(const FloatRect& other) 97 { 98 FloatPoint newLocation(std::max(x(), other.x()), std::max(y(), other.y())); 99 FloatPoint newMaxPoint(std::min(maxX(), other.maxX()), std::min(maxY(), other.maxY())); 100 101 bool intersects = true; 102 103 // Return a clean empty rectangle for non-intersecting cases. 104 if (newLocation.x() > newMaxPoint.x() || newLocation.y() > newMaxPoint.y()) { 105 newLocation = { }; 106 newMaxPoint = { }; 107 intersects = false; 108 } 109 110 m_location = newLocation; 111 m_size = newMaxPoint - newLocation; 112 return intersects; 113 } 114 96 115 void FloatRect::unite(const FloatRect& other) 97 116 { -
trunk/Source/WebCore/platform/graphics/FloatRect.h
r235943 r237255 152 152 153 153 WEBCORE_EXPORT void intersect(const FloatRect&); 154 bool edgeInclusiveIntersect(const FloatRect&); 154 155 WEBCORE_EXPORT void unite(const FloatRect&); 155 156 void uniteEvenIfEmpty(const FloatRect&); -
trunk/Source/WebCore/platform/graphics/LayoutRect.cpp
r220503 r237255 72 72 } 73 73 74 bool LayoutRect::edgeInclusiveIntersect(const LayoutRect& other) 75 { 76 LayoutPoint newLocation(std::max(x(), other.x()), std::max(y(), other.y())); 77 LayoutPoint newMaxPoint(std::min(maxX(), other.maxX()), std::min(maxY(), other.maxY())); 78 79 bool intersects = true; 80 81 // Return a clean empty rectangle for non-intersecting cases. 82 if (newLocation.x() > newMaxPoint.x() || newLocation.y() > newMaxPoint.y()) { 83 newLocation = { }; 84 newMaxPoint = { }; 85 intersects = false; 86 } 87 88 m_location = newLocation; 89 m_size = newMaxPoint - newLocation; 90 return intersects; 91 } 92 74 93 void LayoutRect::unite(const LayoutRect& other) 75 94 { -
trunk/Source/WebCore/platform/graphics/LayoutRect.h
r226981 r237255 146 146 147 147 void intersect(const LayoutRect&); 148 bool edgeInclusiveIntersect(const LayoutRect&); 148 149 WEBCORE_EXPORT void unite(const LayoutRect&); 149 150 void uniteIfNonZero(const LayoutRect&); -
trunk/Source/WebCore/rendering/RenderBox.cpp
r236356 r237255 971 971 } 972 972 973 void RenderBox::applyCachedClipAndScrollPositionForRepaint(LayoutRect& paintRect) const 974 { 975 flipForWritingMode(paintRect); 976 paintRect.moveBy(-scrollPosition()); // For overflow:auto/scroll/hidden. 973 bool RenderBox::applyCachedClipAndScrollPosition(LayoutRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const 974 { 975 flipForWritingMode(rect); 976 977 if (context.m_options.contains(VisibleRectContextOption::ApplyCompositedContainerScrolls) || this != container || !usesCompositedScrolling()) 978 rect.moveBy(-scrollPosition()); // For overflow:auto/scroll/hidden. 977 979 978 980 // Do not clip scroll layer contents to reduce the number of repaints while scrolling. 979 if ( usesCompositedScrolling()) {980 flipForWritingMode( paintRect);981 return ;981 if (!context.m_options.contains(VisibleRectContextOption::ApplyCompositedClips) && usesCompositedScrolling()) { 982 flipForWritingMode(rect); 983 return true; 982 984 } 983 985 … … 986 988 // anyway if its size does change. 987 989 LayoutRect clipRect(LayoutPoint(), cachedSizeForOverflowClip()); 988 paintRect = intersection(paintRect, clipRect); 989 flipForWritingMode(paintRect); 990 bool intersects; 991 if (context.m_options.contains(VisibleRectContextOption::UseEdgeInclusiveIntersection)) 992 intersects = rect.edgeInclusiveIntersect(clipRect); 993 else { 994 rect.intersect(clipRect); 995 intersects = !rect.isEmpty(); 996 } 997 flipForWritingMode(rect); 998 return intersects; 990 999 } 991 1000 … … 2127 2136 } 2128 2137 2129 bool RenderBox::shouldApplyClipAndScrollPositionForRepaint(const RenderLayerModelObject* repaintContainer) const 2130 { 2131 #if PLATFORM(IOS) 2132 if (!repaintContainer || repaintContainer != this) 2133 return true; 2134 2135 return !hasLayer() || !layer()->usesCompositedScrolling(); 2136 #else 2137 UNUSED_PARAM(repaintContainer); 2138 return true; 2139 #endif 2140 } 2141 2142 LayoutRect RenderBox::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const 2138 LayoutRect RenderBox::computeVisibleRectUsingPaintOffset(const LayoutRect& rect) const 2139 { 2140 LayoutRect adjustedRect = rect; 2141 auto* layoutState = view().frameView().layoutContext().layoutState(); 2142 2143 if (layer() && layer()->transform()) 2144 adjustedRect = LayoutRect(encloseRectToDevicePixels(layer()->transform()->mapRect(adjustedRect), document().deviceScaleFactor())); 2145 2146 // We can't trust the bits on RenderObject, because this might be called while re-resolving style. 2147 if (style().hasInFlowPosition() && layer()) 2148 adjustedRect.move(layer()->offsetForInFlowPosition()); 2149 2150 adjustedRect.moveBy(location()); 2151 adjustedRect.move(layoutState->paintOffset()); 2152 if (layoutState->isClipped()) 2153 adjustedRect.intersect(layoutState->clipRect()); 2154 return adjustedRect; 2155 } 2156 2157 std::optional<LayoutRect> RenderBox::computeVisibleRectInContainer(const LayoutRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const 2143 2158 { 2144 2159 // The rect we compute at each step is shifted by our x/y offset in the parent container's coordinate space. … … 2147 2162 // properly even during layout, since the rect remains flipped all the way until the end. 2148 2163 // 2149 // RenderView::computeRectForRepaint then converts the rect to physical coordinates. We also convert to 2150 // physical when we hit a repaintContainer boundary. Therefore the final rect returned is always in the 2151 // physical coordinate space of the repaintContainer. 2152 LayoutRect adjustedRect = rect; 2164 // RenderView::computeVisibleRectInContainer then converts the rect to physical coordinates. We also convert to 2165 // physical when we hit a repaint container boundary. Therefore the final rect returned is always in the 2166 // physical coordinate space of the container. 2153 2167 const RenderStyle& styleToUse = style(); 2154 2168 // Paint offset cache is only valid for root-relative, non-fixed position repainting 2155 if (view().frameView().layoutContext().isPaintOffsetCacheEnabled() && !repaintContainer && styleToUse.position() != PositionType::Fixed) { 2156 auto* layoutState = view().frameView().layoutContext().layoutState(); 2157 2158 if (layer() && layer()->transform()) 2159 adjustedRect = LayoutRect(encloseRectToDevicePixels(layer()->transform()->mapRect(adjustedRect), document().deviceScaleFactor())); 2160 2161 // We can't trust the bits on RenderObject, because this might be called while re-resolving style. 2162 if (styleToUse.hasInFlowPosition() && layer()) 2163 adjustedRect.move(layer()->offsetForInFlowPosition()); 2164 2165 adjustedRect.moveBy(location()); 2166 adjustedRect.move(layoutState->paintOffset()); 2167 if (layoutState->isClipped()) 2168 adjustedRect.intersect(layoutState->clipRect()); 2169 return adjustedRect; 2170 } 2171 2169 if (view().frameView().layoutContext().isPaintOffsetCacheEnabled() && !container && styleToUse.position() != PositionType::Fixed && !context.m_options.contains(VisibleRectContextOption::UseEdgeInclusiveIntersection)) 2170 return computeVisibleRectUsingPaintOffset(rect); 2171 2172 LayoutRect adjustedRect = rect; 2172 2173 if (hasReflection()) 2173 2174 adjustedRect.unite(reflectedRect(adjustedRect)); 2174 2175 2175 if ( repaintContainer == this) {2176 if ( repaintContainer->style().isFlippedBlocksWritingMode())2176 if (container == this) { 2177 if (container->style().isFlippedBlocksWritingMode()) 2177 2178 flipForWritingMode(adjustedRect); 2178 2179 return adjustedRect; 2179 2180 } 2180 2181 2181 bool repaintContainerIsSkipped;2182 auto* container = this->container(repaintContainer, repaintContainerIsSkipped);2183 if (! container)2182 bool containerIsSkipped; 2183 auto* localContainer = this->container(container, containerIsSkipped); 2184 if (!localContainer) 2184 2185 return adjustedRect; 2185 2186 … … 2192 2193 // will already contain the portion rect of the fragment. 2193 2194 auto position = styleToUse.position(); 2194 if ( container->isOutOfFlowRenderFragmentedFlow() && position != PositionType::Absolute && containingBlock() != enclosingFragmentedFlow()) {2195 if (localContainer->isOutOfFlowRenderFragmentedFlow() && position != PositionType::Absolute && containingBlock() != enclosingFragmentedFlow()) { 2195 2196 RenderFragmentContainer* firstFragment = nullptr; 2196 2197 RenderFragmentContainer* lastFragment = nullptr; 2197 if (downcast<RenderFragmentedFlow>(* container).getFragmentRangeForBox(this, firstFragment, lastFragment))2198 if (downcast<RenderFragmentedFlow>(*localContainer).getFragmentRangeForBox(this, firstFragment, lastFragment)) 2198 2199 adjustedRect.moveBy(firstFragment->fragmentedFlowPortionRect().location()); 2199 2200 } … … 2215 2216 2216 2217 if (is<RenderMultiColumnFlow>(this)) { 2217 // We won't normally run this code. Only when the repaintContainer is null (i.e., we're trying2218 // to get the rect in view coordinates) will we come in here, since normally repaintContainer2218 // We won't normally run this code. Only when the container is null (i.e., we're trying 2219 // to get the rect in view coordinates) will we come in here, since normally container 2219 2220 // will be set and we'll stop at the flow thread. This case is mainly hit by the check for whether 2220 2221 // or not images should animate. … … 2224 2225 if (auto* fragment = downcast<RenderMultiColumnFlow>(*this).physicalTranslationFromFlowToFragment((physicalPoint))) { 2225 2226 adjustedRect.setLocation(fragment->flipForWritingMode(physicalPoint)); 2226 return fragment->compute RectForRepaint(adjustedRect, repaintContainer, context);2227 return fragment->computeVisibleRectInContainer(adjustedRect, container, context); 2227 2228 } 2228 2229 } … … 2241 2242 context.m_hasPositionFixedDescendant = true; 2242 2243 2243 if (position == PositionType::Absolute && container->isInFlowPositioned() && is<RenderInline>(*container))2244 topLeft += downcast<RenderInline>(* container).offsetForInFlowPositionedInline(this);2244 if (position == PositionType::Absolute && localContainer->isInFlowPositioned() && is<RenderInline>(*localContainer)) 2245 topLeft += downcast<RenderInline>(*localContainer).offsetForInFlowPositionedInline(this); 2245 2246 else if (styleToUse.hasInFlowPosition() && layer()) { 2246 2247 // Apply the relative position offset when invalidating a rectangle. The layer … … 2254 2255 // its controlClipRect will be wrong. For overflow clip we use the values cached by the layer. 2255 2256 adjustedRect.setLocation(topLeft); 2256 if (container->hasOverflowClip()) { 2257 RenderBox& containerBox = downcast<RenderBox>(*container); 2258 if (containerBox.shouldApplyClipAndScrollPositionForRepaint(repaintContainer)) { 2259 containerBox.applyCachedClipAndScrollPositionForRepaint(adjustedRect); 2260 if (adjustedRect.isEmpty()) 2261 return adjustedRect; 2262 } 2263 } 2264 2265 if (repaintContainerIsSkipped) { 2266 // If the repaintContainer is below container, then we need to map the rect into repaintContainer's coordinates. 2267 LayoutSize containerOffset = repaintContainer->offsetFromAncestorContainer(*container); 2257 if (localContainer->hasOverflowClip()) { 2258 RenderBox& containerBox = downcast<RenderBox>(*localContainer); 2259 bool isEmpty = !containerBox.applyCachedClipAndScrollPosition(adjustedRect, container, context); 2260 if (isEmpty) { 2261 if (context.m_options.contains(VisibleRectContextOption::UseEdgeInclusiveIntersection)) 2262 return std::nullopt; 2263 return adjustedRect; 2264 } 2265 } 2266 2267 if (containerIsSkipped) { 2268 // If the container is below localContainer, then we need to map the rect into container's coordinates. 2269 LayoutSize containerOffset = container->offsetFromAncestorContainer(*localContainer); 2268 2270 adjustedRect.move(-containerOffset); 2269 2271 return adjustedRect; 2270 2272 } 2271 return container->computeRectForRepaint(adjustedRect, repaintContainer, context);2273 return localContainer->computeVisibleRectInContainer(adjustedRect, container, context); 2272 2274 } 2273 2275 -
trunk/Source/WebCore/rendering/RenderBox.h
r236979 r237255 372 372 373 373 LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override; 374 LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext context = { false, false }) const override; 374 std::optional<LayoutRect> computeVisibleRectInContainer(const LayoutRect&, const RenderLayerModelObject* container, VisibleRectContext) const 375 override; 375 376 void repaintDuringLayoutIfMoved(const LayoutRect&); 376 377 virtual void repaintOverhangingFloats(bool paintAllDescendants); … … 572 573 LayoutSize cachedSizeForOverflowClip() const; 573 574 574 bool shouldApplyClipAndScrollPositionForRepaint(const RenderLayerModelObject* repaintContainer) const; 575 void applyCachedClipAndScrollPositionForRepaint(LayoutRect& paintRect) const; 575 // Returns false if the rect has no intersection with the applied clip rect. When the context specifies edge-inclusive 576 // intersection, this return value allows distinguishing between no intersection and zero-area intersection. 577 bool applyCachedClipAndScrollPosition(LayoutRect&, const RenderLayerModelObject* container, VisibleRectContext) const; 576 578 577 579 virtual bool hasRelativeDimensions() const; … … 714 716 715 717 LayoutRect frameRectForStickyPositioning() const final { return frameRect(); } 718 719 LayoutRect computeVisibleRectUsingPaintOffset(const LayoutRect&) const; 716 720 717 721 void applyTopLeftLocationOffsetWithFlipping(LayoutPoint&) const; -
trunk/Source/WebCore/rendering/RenderInline.cpp
r232178 r237255 50 50 #include "VisiblePosition.h" 51 51 #include <wtf/IsoMallocInlines.h> 52 #include <wtf/SetForScope.h> 52 53 53 54 #if ENABLE(DASHBOARD_SUPPORT) … … 846 847 return repaintRect; 847 848 848 if (containingBlock->hasOverflowClip() && containingBlock->shouldApplyClipAndScrollPositionForRepaint(repaintContainer))849 containingBlock->applyCachedClipAndScrollPosition ForRepaint(repaintRect);849 if (containingBlock->hasOverflowClip()) 850 containingBlock->applyCachedClipAndScrollPosition(repaintRect, repaintContainer, visibleRectContextForRepaint()); 850 851 851 852 repaintRect = containingBlock->computeRectForRepaint(repaintRect, repaintContainer); … … 872 873 } 873 874 874 LayoutRect RenderInline::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const 875 LayoutRect RenderInline::computeVisibleRectUsingPaintOffset(const LayoutRect& rect) const 876 { 877 LayoutRect adjustedRect = rect; 878 auto* layoutState = view().frameView().layoutContext().layoutState(); 879 if (style().hasInFlowPosition() && layer()) 880 adjustedRect.move(layer()->offsetForInFlowPosition()); 881 adjustedRect.move(layoutState->paintOffset()); 882 if (layoutState->isClipped()) 883 adjustedRect.intersect(layoutState->clipRect()); 884 return adjustedRect; 885 } 886 887 std::optional<LayoutRect> RenderInline::computeVisibleRectInContainer(const LayoutRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const 875 888 { 876 889 // Repaint offset cache is only valid for root-relative repainting 890 if (view().frameView().layoutContext().isPaintOffsetCacheEnabled() && !container && !context.m_options.contains(VisibleRectContextOption::UseEdgeInclusiveIntersection)) 891 return computeVisibleRectUsingPaintOffset(rect); 892 893 if (container == this) 894 return rect; 895 896 bool containerSkipped; 897 RenderElement* localContainer = this->container(container, containerSkipped); 898 if (!localContainer) 899 return rect; 900 877 901 LayoutRect adjustedRect = rect; 878 if (view().frameView().layoutContext().isPaintOffsetCacheEnabled() && !repaintContainer) {879 auto* layoutState = view().frameView().layoutContext().layoutState();880 if (style().hasInFlowPosition() && layer())881 adjustedRect.move(layer()->offsetForInFlowPosition());882 adjustedRect.move(layoutState->paintOffset());883 if (layoutState->isClipped())884 adjustedRect.intersect(layoutState->clipRect());885 return adjustedRect;886 }887 888 if (repaintContainer == this)889 return adjustedRect;890 891 bool containerSkipped;892 RenderElement* container = this->container(repaintContainer, containerSkipped);893 if (!container)894 return adjustedRect;895 896 902 LayoutPoint topLeft = adjustedRect.location(); 897 903 … … 907 913 // its controlClipRect will be wrong. For overflow clip we use the values cached by the layer. 908 914 adjustedRect.setLocation(topLeft); 909 if (container->hasOverflowClip()) { 910 downcast<RenderBox>(*container).applyCachedClipAndScrollPositionForRepaint(adjustedRect); 911 if (adjustedRect.isEmpty()) 915 if (localContainer->hasOverflowClip()) { 916 // FIXME: Respect the value of context.m_options. 917 SetForScope<OptionSet<VisibleRectContextOption>> change(context.m_options, context.m_options | VisibleRectContextOption::ApplyCompositedContainerScrolls); 918 bool isEmpty = !downcast<RenderBox>(*localContainer).applyCachedClipAndScrollPosition(adjustedRect, container, context); 919 if (isEmpty) { 920 if (context.m_options.contains(VisibleRectContextOption::UseEdgeInclusiveIntersection)) 921 return std::nullopt; 912 922 return adjustedRect; 923 } 913 924 } 914 925 915 926 if (containerSkipped) { 916 927 // If the repaintContainer is below o, then we need to map the rect into repaintContainer's coordinates. 917 LayoutSize containerOffset = repaintContainer->offsetFromAncestorContainer(*container);928 LayoutSize containerOffset = container->offsetFromAncestorContainer(*localContainer); 918 929 adjustedRect.move(-containerOffset); 919 930 return adjustedRect; 920 931 } 921 return container->computeRectForRepaint(adjustedRect, repaintContainer, context);932 return localContainer->computeVisibleRectInContainer(adjustedRect, container, context); 922 933 } 923 934 -
trunk/Source/WebCore/rendering/RenderInline.h
r236501 r237255 130 130 LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override; 131 131 LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const final; 132 LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }) const final; 132 133 std::optional<LayoutRect> computeVisibleRectInContainer(const LayoutRect&, const RenderLayerModelObject* container, VisibleRectContext) const final; 134 LayoutRect computeVisibleRectUsingPaintOffset(const LayoutRect&) const; 133 135 134 136 void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const override; -
trunk/Source/WebCore/rendering/RenderObject.cpp
r236087 r237255 963 963 } 964 964 965 LayoutRect RenderObject::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const 966 { 967 if (repaintContainer == this) 965 bool RenderObject::shouldApplyCompositedContainerScrollsForRepaint() 966 { 967 #if PLATFORM(IOS) 968 return false; 969 #else 970 return true; 971 #endif 972 } 973 974 RenderObject::VisibleRectContext RenderObject::visibleRectContextForRepaint() 975 { 976 VisibleRectContext context; 977 if (shouldApplyCompositedContainerScrollsForRepaint()) 978 context.m_options.add(VisibleRectContextOption::ApplyCompositedContainerScrolls); 979 return context; 980 } 981 982 LayoutRect RenderObject::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer) const 983 { 984 return *computeVisibleRectInContainer(rect, repaintContainer, visibleRectContextForRepaint()); 985 } 986 987 FloatRect RenderObject::computeFloatRectForRepaint(const FloatRect& rect, const RenderLayerModelObject* repaintContainer) const 988 { 989 return *computeFloatVisibleRectInContainer(rect, repaintContainer, visibleRectContextForRepaint()); 990 } 991 992 std::optional<LayoutRect> RenderObject::computeVisibleRectInContainer(const LayoutRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const 993 { 994 if (container == this) 968 995 return rect; 969 996 … … 974 1001 LayoutRect adjustedRect = rect; 975 1002 if (parent->hasOverflowClip()) { 976 downcast<RenderBox>(*parent).applyCachedClipAndScrollPositionForRepaint(adjustedRect); 977 if (adjustedRect.isEmpty()) 1003 bool isEmpty = downcast<RenderBox>(*parent).applyCachedClipAndScrollPosition(adjustedRect, container, context); 1004 if (isEmpty) { 1005 if (context.m_options.contains(VisibleRectContextOption::UseEdgeInclusiveIntersection)) 1006 return std::nullopt; 978 1007 return adjustedRect; 979 } 980 return parent->computeRectForRepaint(adjustedRect, repaintContainer, context); 981 } 982 983 FloatRect RenderObject::computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject*, bool) const 1008 } 1009 } 1010 return parent->computeVisibleRectInContainer(adjustedRect, container, context); 1011 } 1012 1013 std::optional<FloatRect> RenderObject::computeFloatVisibleRectInContainer(const FloatRect&, const RenderLayerModelObject*, VisibleRectContext) const 984 1014 { 985 1015 ASSERT_NOT_REACHED(); -
trunk/Source/WebCore/rendering/RenderObject.h
r236087 r237255 672 672 // Given a rect in the object's coordinate space, compute a rect suitable for repainting 673 673 // that rect in view coordinates. 674 LayoutRect computeAbsoluteRepaintRect(const LayoutRect& r , bool fixed = false) const675 { 676 return computeRectForRepaint(r, nullptr , { fixed, false });674 LayoutRect computeAbsoluteRepaintRect(const LayoutRect& r) const 675 { 676 return computeRectForRepaint(r, nullptr); 677 677 } 678 678 // Given a rect in the object's coordinate space, compute a rect suitable for repainting 679 679 // that rect in the coordinate space of repaintContainer. 680 struct RepaintContext { 681 RepaintContext(bool hasPositionFixedDescendant = false, bool dirtyRectIsFlipped = false) 680 LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer) const; 681 FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer) const; 682 683 // Given a rect in the object's coordinate space, compute the location in container space where this rect is visible, 684 // when clipping and scrolling as specified by the context. When using edge-inclusive intersection, return std::nullopt 685 // rather than an empty rect if the rect is completely clipped out in container space. 686 enum class VisibleRectContextOption { 687 UseEdgeInclusiveIntersection = 1 << 0, 688 ApplyCompositedClips = 1 << 1, 689 ApplyCompositedContainerScrolls = 1 << 2, 690 }; 691 struct VisibleRectContext { 692 VisibleRectContext(bool hasPositionFixedDescendant = false, bool dirtyRectIsFlipped = false, OptionSet<VisibleRectContextOption> options = { }) 682 693 : m_hasPositionFixedDescendant(hasPositionFixedDescendant) 683 694 , m_dirtyRectIsFlipped(dirtyRectIsFlipped) 695 , m_options(options) 684 696 { 685 697 } 686 698 bool m_hasPositionFixedDescendant; 687 699 bool m_dirtyRectIsFlipped; 700 OptionSet<VisibleRectContextOption> m_options; 688 701 }; 689 virtual LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }) const;690 virtual FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed = false) const;702 virtual std::optional<LayoutRect> computeVisibleRectInContainer(const LayoutRect&, const RenderLayerModelObject* repaintContainer, VisibleRectContext) const; 703 virtual std::optional<FloatRect> computeFloatVisibleRectInContainer(const FloatRect&, const RenderLayerModelObject* repaintContainer, VisibleRectContext) const; 691 704 692 705 virtual unsigned int length() const { return 1; } … … 805 818 806 819 static FragmentedFlowState computedFragmentedFlowState(const RenderObject&); 820 821 static bool shouldApplyCompositedContainerScrollsForRepaint(); 822 823 static VisibleRectContext visibleRectContextForRepaint(); 807 824 808 825 private: -
trunk/Source/WebCore/rendering/RenderTableCell.cpp
r234798 r237255 396 396 } 397 397 398 LayoutRect RenderTableCell::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const399 { 400 if ( repaintContainer == this)398 std::optional<LayoutRect> RenderTableCell::computeVisibleRectInContainer(const LayoutRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const 399 { 400 if (container == this) 401 401 return rect; 402 402 LayoutRect adjustedRect = rect; 403 if ((!view().frameView().layoutContext().isPaintOffsetCacheEnabled() || repaintContainer) && parent())403 if ((!view().frameView().layoutContext().isPaintOffsetCacheEnabled() || container || context.m_options.contains(VisibleRectContextOption::UseEdgeInclusiveIntersection)) && parent()) 404 404 adjustedRect.moveBy(-parentBox()->location()); // Rows are in the same coordinate space, so don't add their offset in. 405 return RenderBlockFlow::compute RectForRepaint(adjustedRect, repaintContainer, context);405 return RenderBlockFlow::computeVisibleRectInContainer(adjustedRect, container, context); 406 406 } 407 407 -
trunk/Source/WebCore/rendering/RenderTableCell.h
r232018 r237255 156 156 157 157 LayoutSize offsetFromContainer(RenderElement&, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const override; 158 LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }) const override;158 std::optional<LayoutRect> computeVisibleRectInContainer(const LayoutRect&, const RenderLayerModelObject* container, VisibleRectContext) const override; 159 159 160 160 LayoutUnit borderHalfLeft(bool outer) const; -
trunk/Source/WebCore/rendering/RenderView.cpp
r236288 r237255 578 578 } 579 579 580 LayoutRect RenderView::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const580 std::optional<LayoutRect> RenderView::computeVisibleRectInContainer(const LayoutRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const 581 581 { 582 582 // If a container was specified, and was not nullptr or the RenderView, 583 583 // then we should have found it by now. 584 ASSERT_ARG( repaintContainer, !repaintContainer || repaintContainer == this);584 ASSERT_ARG(container, !container || container == this); 585 585 586 586 if (printing()) … … 601 601 602 602 // Apply our transform if we have one (because of full page zooming). 603 if (! repaintContainer && layer() && layer()->transform())603 if (!container && layer() && layer()->transform()) 604 604 adjustedRect = LayoutRect(layer()->transform()->mapRect(snapRectToDevicePixels(adjustedRect, document().deviceScaleFactor()))); 605 605 return adjustedRect; -
trunk/Source/WebCore/rendering/RenderView.h
r228889 r237255 73 73 74 74 LayoutRect visualOverflowRect() const override; 75 LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }) const override;75 std::optional<LayoutRect> computeVisibleRectInContainer(const LayoutRect&, const RenderLayerModelObject* container, VisibleRectContext) const override; 76 76 void repaintRootContents(); 77 77 void repaintViewRectangle(const LayoutRect&) const; -
trunk/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp
r234619 r237255 99 99 } 100 100 101 FloatRect RenderSVGForeignObject::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed) const 102 { 103 return SVGRenderSupport::computeFloatRectForRepaint(*this, repaintRect, repaintContainer, fixed); 104 } 105 106 LayoutRect RenderSVGForeignObject::computeRectForRepaint(const LayoutRect& repaintRect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const 107 { 108 return enclosingLayoutRect(computeFloatRectForRepaint(repaintRect, repaintContainer, context.m_hasPositionFixedDescendant)); 101 std::optional<FloatRect> RenderSVGForeignObject::computeFloatVisibleRectInContainer(const FloatRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const 102 { 103 return SVGRenderSupport::computeFloatVisibleRectInContainer(*this, rect, container, context); 104 } 105 106 std::optional<LayoutRect> RenderSVGForeignObject::computeVisibleRectInContainer(const LayoutRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const 107 { 108 std::optional<FloatRect> adjustedRect = computeFloatVisibleRectInContainer(rect, container, context); 109 if (adjustedRect) 110 return enclosingLayoutRect(*adjustedRect); 111 return std::nullopt; 109 112 } 110 113 -
trunk/Source/WebCore/rendering/svg/RenderSVGForeignObject.h
r224537 r237255 41 41 42 42 LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override; 43 FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed = false) const override;44 LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }) const override;43 std::optional<FloatRect> computeFloatVisibleRectInContainer(const FloatRect&, const RenderLayerModelObject* container, VisibleRectContext) const override; 44 std::optional<LayoutRect> computeVisibleRectInContainer(const LayoutRect&, const RenderLayerModelObject* container, VisibleRectContext) const override; 45 45 46 46 bool requiresLayer() const override { return false; } -
trunk/Source/WebCore/rendering/svg/RenderSVGInline.cpp
r232018 r237255 76 76 } 77 77 78 FloatRect RenderSVGInline::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed) const78 std::optional<FloatRect> RenderSVGInline::computeFloatVisibleRectInContainer(const FloatRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const 79 79 { 80 return SVGRenderSupport::computeFloat RectForRepaint(*this, repaintRect, repaintContainer, fixed);80 return SVGRenderSupport::computeFloatVisibleRectInContainer(*this, rect, container, context); 81 81 } 82 82 -
trunk/Source/WebCore/rendering/svg/RenderSVGInline.h
r228908 r237255 52 52 53 53 LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const final; 54 FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed = false) const final;54 std::optional<FloatRect> computeFloatVisibleRectInContainer(const FloatRect&, const RenderLayerModelObject* container, VisibleRectContext) const final; 55 55 void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const final; 56 56 const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const final; -
trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp
r232178 r237255 54 54 } 55 55 56 FloatRect RenderSVGModelObject::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed) const56 std::optional<FloatRect> RenderSVGModelObject::computeFloatVisibleRectInContainer(const FloatRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const 57 57 { 58 return SVGRenderSupport::computeFloat RectForRepaint(*this, repaintRect, repaintContainer, fixed);58 return SVGRenderSupport::computeFloatVisibleRectInContainer(*this, rect, container, context); 59 59 } 60 60 -
trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.h
r228908 r237255 48 48 public: 49 49 LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override; 50 FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed = false) const final;50 std::optional<FloatRect> computeFloatVisibleRectInContainer(const FloatRect&, const RenderLayerModelObject* container, VisibleRectContext) const final; 51 51 LayoutRect outlineBoundsForRepaint(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap*) const final; 52 52 -
trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
r234619 r237255 343 343 } 344 344 345 FloatRect RenderSVGRoot::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed) const345 std::optional<FloatRect> RenderSVGRoot::computeFloatVisibleRectInContainer(const FloatRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const 346 346 { 347 347 // Apply our local transforms (except for x/y translation), then our shadow, 348 348 // and then call RenderBox's method to handle all the normal CSS Box model bits 349 FloatRect adjustedRect = m_localToBorderBoxTransform.mapRect(re paintRect);349 FloatRect adjustedRect = m_localToBorderBoxTransform.mapRect(rect); 350 350 351 351 const SVGRenderStyle& svgStyle = style().svgStyle(); … … 354 354 355 355 // Apply initial viewport clip 356 if (shouldApplyViewportClip()) 357 adjustedRect.intersect(snappedIntRect(borderBoxRect())); 356 if (shouldApplyViewportClip()) { 357 if (context.m_options.contains(VisibleRectContextOption::UseEdgeInclusiveIntersection)) { 358 if (!adjustedRect.edgeInclusiveIntersect(snappedIntRect(borderBoxRect()))) 359 return std::nullopt; 360 } else 361 adjustedRect.intersect(snappedIntRect(borderBoxRect())); 362 } 358 363 359 364 if (m_hasBoxDecorations || hasRenderOverflow()) { … … 363 368 adjustedRect.unite(decoratedRepaintRect); 364 369 } 365 return RenderReplaced::computeRectForRepaint(enclosingIntRect(adjustedRect), repaintContainer, {fixed, false}); 370 371 if (std::optional<LayoutRect> rectInContainer = RenderReplaced::computeVisibleRectInContainer(enclosingIntRect(adjustedRect), container, context)) 372 return FloatRect(*rectInContainer); 373 return std::nullopt; 366 374 } 367 375 -
trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h
r228908 r237255 97 97 98 98 LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override; 99 FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed) const override;99 std::optional<FloatRect> computeFloatVisibleRectInContainer(const FloatRect&, const RenderLayerModelObject* container, VisibleRectContext) const override; 100 100 101 101 void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const override; -
trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp
r234619 r237255 93 93 } 94 94 95 LayoutRect RenderSVGText::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const 96 { 97 return enclosingLayoutRect(computeFloatRectForRepaint(rect, repaintContainer, context.m_hasPositionFixedDescendant)); 98 } 99 100 FloatRect RenderSVGText::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed) const 101 { 102 return SVGRenderSupport::computeFloatRectForRepaint(*this, repaintRect, repaintContainer, fixed); 95 std::optional<LayoutRect> RenderSVGText::computeVisibleRectInContainer(const LayoutRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const 96 { 97 std::optional<FloatRect> adjustedRect = computeFloatVisibleRectInContainer(rect, container, context); 98 if (adjustedRect) 99 return enclosingLayoutRect(*adjustedRect); 100 return std::nullopt; 101 } 102 103 std::optional<FloatRect> RenderSVGText::computeFloatVisibleRectInContainer(const FloatRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const 104 { 105 return SVGRenderSupport::computeFloatVisibleRectInContainer(*this, rect, container, context); 103 106 } 104 107 -
trunk/Source/WebCore/rendering/svg/RenderSVGText.h
r228908 r237255 79 79 80 80 LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override; 81 LayoutRect computeRectForRepaint(const LayoutRect&, const RenderLayerModelObject* repaintContainer, RepaintContext = { }) const override;82 FloatRect computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed = false) const override;81 std::optional<LayoutRect> computeVisibleRectInContainer(const LayoutRect&, const RenderLayerModelObject* container, VisibleRectContext) const override; 82 std::optional<FloatRect> computeFloatVisibleRectInContainer(const FloatRect&, const RenderLayerModelObject* container, VisibleRectContext) const override; 83 83 84 84 void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const override; -
trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp
r233835 r237255 64 64 return LayoutRect(); 65 65 66 // Pass our local paint rect to compute RectForRepaint() which will66 // Pass our local paint rect to computeFloatVisibleRectInContainer() which will 67 67 // map to parent coords and recurse up the parent chain. 68 68 FloatRect repaintRect = repaintRectForRendererInLocalCoordinatesExcludingSVGShadow(renderer); … … 73 73 } 74 74 75 FloatRect SVGRenderSupport::computeFloatRectForRepaint(const RenderElement& renderer, const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed)76 { 77 FloatRect adjustedRect = re paintRect;75 std::optional<FloatRect> SVGRenderSupport::computeFloatVisibleRectInContainer(const RenderElement& renderer, const FloatRect& rect, const RenderLayerModelObject* container, RenderObject::VisibleRectContext context) 76 { 77 FloatRect adjustedRect = rect; 78 78 const SVGRenderStyle& svgStyle = renderer.style().svgStyle(); 79 79 if (const ShadowData* shadow = svgStyle.shadow()) … … 81 81 adjustedRect.inflate(renderer.style().outlineWidth()); 82 82 83 // Translate to coords in our parent renderer, and then call computeFloat RectForRepaint() on our parent.83 // Translate to coords in our parent renderer, and then call computeFloatVisibleRectInContainer() on our parent. 84 84 adjustedRect = renderer.localToParentTransform().mapRect(adjustedRect); 85 return renderer.parent()->computeFloat RectForRepaint(adjustedRect, repaintContainer, fixed);85 return renderer.parent()->computeFloatVisibleRectInContainer(adjustedRect, container, context); 86 86 } 87 87 -
trunk/Source/WebCore/rendering/svg/SVGRenderSupport.h
r233835 r237255 69 69 static FloatRect repaintRectForRendererInLocalCoordinatesExcludingSVGShadow(const RenderElement&); 70 70 static LayoutRect clippedOverflowRectForRepaint(const RenderElement&, const RenderLayerModelObject* repaintContainer); 71 static FloatRect computeFloatRectForRepaint(const RenderElement&, const FloatRect&, const RenderLayerModelObject* repaintContainer, bool fixed);71 static std::optional<FloatRect> computeFloatVisibleRectInContainer(const RenderElement&, const FloatRect&, const RenderLayerModelObject* container, RenderObject::VisibleRectContext); 72 72 static const RenderElement& localToParentTransform(const RenderElement&, AffineTransform &); 73 73 static void mapLocalToContainer(const RenderElement&, const RenderLayerModelObject* repaintContainer, TransformState&, bool* wasFixed);
Note: See TracChangeset
for help on using the changeset viewer.