| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/paint/PrePaintTreeWalk.h" | 5 #include "core/paint/PrePaintTreeWalk.h" |
| 6 | 6 |
| 7 #include "core/dom/DocumentLifecycle.h" | 7 #include "core/dom/DocumentLifecycle.h" |
| 8 #include "core/frame/FrameView.h" | 8 #include "core/frame/FrameView.h" |
| 9 #include "core/frame/LocalFrame.h" | 9 #include "core/frame/LocalFrame.h" |
| 10 #include "core/layout/LayoutMultiColumnSpannerPlaceholder.h" | 10 #include "core/layout/LayoutMultiColumnSpannerPlaceholder.h" |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 // sticky layer position, so we need to update it again here. | 104 // sticky layer position, so we need to update it again here. |
| 105 // TODO(flackr): This should be refactored in the future to be clearer (i.e. | 105 // TODO(flackr): This should be refactored in the future to be clearer (i.e. |
| 106 // update layer position and ancestor inputs updates in the same walk). | 106 // update layer position and ancestor inputs updates in the same walk). |
| 107 paintLayer->updateLayerPosition(); | 107 paintLayer->updateLayerPosition(); |
| 108 } | 108 } |
| 109 | 109 |
| 110 if (paintLayer->isRootLayer() || object.hasOverflowClip()) | 110 if (paintLayer->isRootLayer() || object.hasOverflowClip()) |
| 111 context.ancestorOverflowPaintLayer = paintLayer; | 111 context.ancestorOverflowPaintLayer = paintLayer; |
| 112 } | 112 } |
| 113 | 113 |
| 114 // Returns whether |a| is an ancestor of or equal to |b|. |
| 115 static bool isAncestorOfOrEqualTo(const ClipPaintPropertyNode* a, |
| 116 const ClipPaintPropertyNode* b) { |
| 117 while (b && b != a) { |
| 118 b = b->parent(); |
| 119 } |
| 120 return b == a; |
| 121 } |
| 122 |
| 114 void PrePaintTreeWalk::computeClipRectForContext( | 123 void PrePaintTreeWalk::computeClipRectForContext( |
| 115 const PaintPropertyTreeBuilderContext::ContainingBlockContext& context, | 124 const PaintPropertyTreeBuilderContext::ContainingBlockContext& context, |
| 116 const EffectPaintPropertyNode* effect, | 125 const EffectPaintPropertyNode* effect, |
| 117 const PropertyTreeState& ancestorState, | 126 const PropertyTreeState& ancestorState, |
| 118 const LayoutPoint& ancestorPaintOffset, | 127 const LayoutPoint& ancestorPaintOffset, |
| 128 bool& hasClip, |
| 119 FloatClipRect& clipRect) { | 129 FloatClipRect& clipRect) { |
| 130 // Only return a non-infinite clip if clips differ, or the "ancestor" state is |
| 131 // actually an ancestor clip. This ensures no accuracy issues due to |
| 132 // transforms applied to infinite rects. |
| 133 if (isAncestorOfOrEqualTo(context.clip, ancestorState.clip())) |
| 134 clipRect = FloatClipRect(); |
| 135 |
| 136 hasClip = true; |
| 120 PropertyTreeState localState(context.transform, context.clip, effect); | 137 PropertyTreeState localState(context.transform, context.clip, effect); |
| 138 |
| 121 clipRect = | 139 clipRect = |
| 122 m_geometryMapper.sourceToDestinationClipRect(localState, ancestorState); | 140 m_geometryMapper.sourceToDestinationClipRect(localState, ancestorState); |
| 123 clipRect.moveBy(-FloatPoint(ancestorPaintOffset)); | 141 clipRect.moveBy(-FloatPoint(ancestorPaintOffset)); |
| 124 } | 142 } |
| 125 | 143 |
| 126 void PrePaintTreeWalk::invalidatePaintLayerOptimizationsIfNeeded( | 144 void PrePaintTreeWalk::invalidatePaintLayerOptimizationsIfNeeded( |
| 127 const LayoutObject& object, | 145 const LayoutObject& object, |
| 128 PrePaintTreeWalkContext& context) { | 146 PrePaintTreeWalkContext& context) { |
| 129 if (!object.hasLayer()) | 147 if (!object.hasLayer()) |
| 130 return; | 148 return; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 153 #endif | 171 #endif |
| 154 } | 172 } |
| 155 | 173 |
| 156 #ifdef CHECK_CLIP_RECTS | 174 #ifdef CHECK_CLIP_RECTS |
| 157 ClipRects& oldClipRects = | 175 ClipRects& oldClipRects = |
| 158 paintLayer.clipper(PaintLayer::DoNotUseGeometryMapper) | 176 paintLayer.clipper(PaintLayer::DoNotUseGeometryMapper) |
| 159 .paintingClipRects(&ancestorTransformedOrRootPaintLayer, | 177 .paintingClipRects(&ancestorTransformedOrRootPaintLayer, |
| 160 respectOverflowClip, LayoutSize()); | 178 respectOverflowClip, LayoutSize()); |
| 161 #endif | 179 #endif |
| 162 | 180 |
| 163 ClipRects clipRects; | 181 bool hasClip = false; |
| 182 RefPtr<ClipRects> clipRects = ClipRects::create(); |
| 164 const LayoutPoint& ancestorPaintOffset = | 183 const LayoutPoint& ancestorPaintOffset = |
| 165 context.ancestorTransformedOrRootPaintLayer->layoutObject().paintOffset(); | 184 context.ancestorTransformedOrRootPaintLayer->layoutObject().paintOffset(); |
| 166 | 185 |
| 167 FloatClipRect clipRect; | 186 FloatClipRect clipRect; |
| 168 const EffectPaintPropertyNode* effect = | 187 const EffectPaintPropertyNode* effect = |
| 169 context.treeBuilderContext->currentEffect; | 188 context.treeBuilderContext->currentEffect; |
| 170 computeClipRectForContext(context.treeBuilderContext->current, effect, | 189 computeClipRectForContext(context.treeBuilderContext->current, effect, |
| 171 ancestorState, ancestorPaintOffset, clipRect); | 190 ancestorState, ancestorPaintOffset, hasClip, |
| 172 clipRects.setOverflowClipRect(clipRect); | 191 clipRect); |
| 192 clipRects->setOverflowClipRect(clipRect); |
| 173 #ifdef CHECK_CLIP_RECTS | 193 #ifdef CHECK_CLIP_RECTS |
| 174 CHECK(clipRects->overflowClipRect() == oldClipRects.overflowClipRect()) | 194 CHECK(!hasClip || |
| 195 clipRects->overflowClipRect() == oldClipRects.overflowClipRect()) |
| 175 << "rect= " << clipRects->overflowClipRect().toString(); | 196 << "rect= " << clipRects->overflowClipRect().toString(); |
| 176 #endif | 197 #endif |
| 177 | 198 |
| 178 computeClipRectForContext(context.treeBuilderContext->fixedPosition, effect, | 199 computeClipRectForContext(context.treeBuilderContext->fixedPosition, effect, |
| 179 ancestorState, ancestorPaintOffset, clipRect); | 200 ancestorState, ancestorPaintOffset, hasClip, |
| 180 clipRects.setFixedClipRect(clipRect); | 201 clipRect); |
| 202 clipRects->setFixedClipRect(clipRect); |
| 181 #ifdef CHECK_CLIP_RECTS | 203 #ifdef CHECK_CLIP_RECTS |
| 182 CHECK(clipRects->fixedClipRect() == oldClipRects.fixedClipRect()) | 204 CHECK(hasClip || clipRects->fixedClipRect() == oldClipRects.fixedClipRect()) |
| 183 << " fixed=" << clipRects->fixedClipRect().toString(); | 205 << " fixed=" << clipRects->fixedClipRect().toString(); |
| 184 #endif | 206 #endif |
| 185 | 207 |
| 186 computeClipRectForContext(context.treeBuilderContext->absolutePosition, | 208 computeClipRectForContext(context.treeBuilderContext->absolutePosition, |
| 187 effect, ancestorState, ancestorPaintOffset, | 209 effect, ancestorState, ancestorPaintOffset, hasClip, |
| 188 clipRect); | 210 clipRect); |
| 189 clipRects.setPosClipRect(clipRect); | 211 clipRects->setPosClipRect(clipRect); |
| 190 #ifdef CHECK_CLIP_RECTS | 212 #ifdef CHECK_CLIP_RECTS |
| 191 CHECK(clipRects->posClipRect() == oldClipRects.posClipRect()) | 213 CHECK(!hasClip || clipRects->posClipRect() == oldClipRects.posClipRect()) |
| 192 << " abs=" << clipRects->posClipRect().toString(); | 214 << " abs=" << clipRects->posClipRect().toString(); |
| 193 #endif | 215 #endif |
| 194 | 216 |
| 195 if (!paintLayer.hasPreviousPaintingClipRects() || | 217 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects(); |
| 196 clipRects != paintLayer.previousPaintingClipRects()) { | 218 |
| 219 if (!previousClipRects || *clipRects != *previousClipRects) { |
| 197 paintLayer.setNeedsRepaint(); | 220 paintLayer.setNeedsRepaint(); |
| 198 paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(false); | 221 paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(false); |
| 199 paintLayer.setPreviousPaintPhaseFloatEmpty(false); | 222 paintLayer.setPreviousPaintPhaseFloatEmpty(false); |
| 200 paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false); | 223 paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false); |
| 201 // All subsequences which are contained below this paintLayer must also | 224 // All subsequences which are contained below this paintLayer must also |
| 202 // be checked. | 225 // be checked. |
| 203 context.paintInvalidatorContext.forcedSubtreeInvalidationFlags |= | 226 context.paintInvalidatorContext.forcedSubtreeInvalidationFlags |= |
| 204 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; | 227 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; |
| 205 } | 228 } |
| 206 | 229 |
| 207 paintLayer.setPreviousPaintingClipRects(clipRects); | 230 paintLayer.setPreviousPaintingClipRects(*clipRects); |
| 208 } | 231 } |
| 209 | 232 |
| 210 bool PrePaintTreeWalk::shouldEndWalkBefore( | 233 bool PrePaintTreeWalk::shouldEndWalkBefore( |
| 211 const LayoutObject& object, | 234 const LayoutObject& object, |
| 212 const PrePaintTreeWalkContext& context) { | 235 const PrePaintTreeWalkContext& context) { |
| 213 return !object.needsPaintPropertyUpdate() && | 236 return !object.needsPaintPropertyUpdate() && |
| 214 !object.descendantNeedsPaintPropertyUpdate() && | 237 !object.descendantNeedsPaintPropertyUpdate() && |
| 215 !context.treeBuilderContext->forceSubtreeUpdate && | 238 !context.treeBuilderContext->forceSubtreeUpdate && |
| 216 !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags && | 239 !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags && |
| 217 !object.shouldCheckForPaintInvalidation(); | 240 !object.shouldCheckForPaintInvalidation(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 roundedIntPoint(context.treeBuilderContext->current.paintOffset); | 280 roundedIntPoint(context.treeBuilderContext->current.paintOffset); |
| 258 walk(*toFrameView(frameViewBase), context); | 281 walk(*toFrameView(frameViewBase), context); |
| 259 } | 282 } |
| 260 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). | 283 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). |
| 261 } | 284 } |
| 262 | 285 |
| 263 object.getMutableForPainting().clearPaintFlags(); | 286 object.getMutableForPainting().clearPaintFlags(); |
| 264 } | 287 } |
| 265 | 288 |
| 266 } // namespace blink | 289 } // namespace blink |
| OLD | NEW |