| 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 | |
| 123 void PrePaintTreeWalk::computeClipRectForContext( | 114 void PrePaintTreeWalk::computeClipRectForContext( |
| 124 const PaintPropertyTreeBuilderContext::ContainingBlockContext& context, | 115 const PaintPropertyTreeBuilderContext::ContainingBlockContext& context, |
| 125 const EffectPaintPropertyNode* effect, | 116 const EffectPaintPropertyNode* effect, |
| 126 const PropertyTreeState& ancestorState, | 117 const PropertyTreeState& ancestorState, |
| 127 const LayoutPoint& ancestorPaintOffset, | 118 const LayoutPoint& ancestorPaintOffset, |
| 128 bool& hasClip, | |
| 129 FloatClipRect& clipRect) { | 119 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; | |
| 137 PropertyTreeState localState(context.transform, context.clip, effect); | 120 PropertyTreeState localState(context.transform, context.clip, effect); |
| 138 | |
| 139 clipRect = | 121 clipRect = |
| 140 m_geometryMapper.sourceToDestinationClipRect(localState, ancestorState); | 122 m_geometryMapper.sourceToDestinationClipRect(localState, ancestorState); |
| 141 clipRect.moveBy(-FloatPoint(ancestorPaintOffset)); | 123 clipRect.moveBy(-FloatPoint(ancestorPaintOffset)); |
| 142 } | 124 } |
| 143 | 125 |
| 144 void PrePaintTreeWalk::invalidatePaintLayerOptimizationsIfNeeded( | 126 void PrePaintTreeWalk::invalidatePaintLayerOptimizationsIfNeeded( |
| 145 const LayoutObject& object, | 127 const LayoutObject& object, |
| 146 PrePaintTreeWalkContext& context) { | 128 PrePaintTreeWalkContext& context) { |
| 147 if (!object.hasLayer()) | 129 if (!object.hasLayer()) |
| 148 return; | 130 return; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 171 #endif | 153 #endif |
| 172 } | 154 } |
| 173 | 155 |
| 174 #ifdef CHECK_CLIP_RECTS | 156 #ifdef CHECK_CLIP_RECTS |
| 175 ClipRects& oldClipRects = | 157 ClipRects& oldClipRects = |
| 176 paintLayer.clipper(PaintLayer::DoNotUseGeometryMapper) | 158 paintLayer.clipper(PaintLayer::DoNotUseGeometryMapper) |
| 177 .paintingClipRects(&ancestorTransformedOrRootPaintLayer, | 159 .paintingClipRects(&ancestorTransformedOrRootPaintLayer, |
| 178 respectOverflowClip, LayoutSize()); | 160 respectOverflowClip, LayoutSize()); |
| 179 #endif | 161 #endif |
| 180 | 162 |
| 181 bool hasClip = false; | 163 ClipRects clipRects; |
| 182 RefPtr<ClipRects> clipRects = ClipRects::create(); | |
| 183 const LayoutPoint& ancestorPaintOffset = | 164 const LayoutPoint& ancestorPaintOffset = |
| 184 context.ancestorTransformedOrRootPaintLayer->layoutObject().paintOffset(); | 165 context.ancestorTransformedOrRootPaintLayer->layoutObject().paintOffset(); |
| 185 | 166 |
| 186 FloatClipRect clipRect; | 167 FloatClipRect clipRect; |
| 187 const EffectPaintPropertyNode* effect = | 168 const EffectPaintPropertyNode* effect = |
| 188 context.treeBuilderContext->currentEffect; | 169 context.treeBuilderContext->currentEffect; |
| 189 computeClipRectForContext(context.treeBuilderContext->current, effect, | 170 computeClipRectForContext(context.treeBuilderContext->current, effect, |
| 190 ancestorState, ancestorPaintOffset, hasClip, | 171 ancestorState, ancestorPaintOffset, clipRect); |
| 191 clipRect); | 172 clipRects.setOverflowClipRect(clipRect); |
| 192 clipRects->setOverflowClipRect(clipRect); | |
| 193 #ifdef CHECK_CLIP_RECTS | 173 #ifdef CHECK_CLIP_RECTS |
| 194 CHECK(!hasClip || | 174 CHECK(clipRects->overflowClipRect() == oldClipRects.overflowClipRect()) |
| 195 clipRects->overflowClipRect() == oldClipRects.overflowClipRect()) | |
| 196 << "rect= " << clipRects->overflowClipRect().toString(); | 175 << "rect= " << clipRects->overflowClipRect().toString(); |
| 197 #endif | 176 #endif |
| 198 | 177 |
| 199 computeClipRectForContext(context.treeBuilderContext->fixedPosition, effect, | 178 computeClipRectForContext(context.treeBuilderContext->fixedPosition, effect, |
| 200 ancestorState, ancestorPaintOffset, hasClip, | 179 ancestorState, ancestorPaintOffset, clipRect); |
| 201 clipRect); | 180 clipRects.setFixedClipRect(clipRect); |
| 202 clipRects->setFixedClipRect(clipRect); | |
| 203 #ifdef CHECK_CLIP_RECTS | 181 #ifdef CHECK_CLIP_RECTS |
| 204 CHECK(hasClip || clipRects->fixedClipRect() == oldClipRects.fixedClipRect()) | 182 CHECK(clipRects->fixedClipRect() == oldClipRects.fixedClipRect()) |
| 205 << " fixed=" << clipRects->fixedClipRect().toString(); | 183 << " fixed=" << clipRects->fixedClipRect().toString(); |
| 206 #endif | 184 #endif |
| 207 | 185 |
| 208 computeClipRectForContext(context.treeBuilderContext->absolutePosition, | 186 computeClipRectForContext(context.treeBuilderContext->absolutePosition, |
| 209 effect, ancestorState, ancestorPaintOffset, hasClip, | 187 effect, ancestorState, ancestorPaintOffset, |
| 210 clipRect); | 188 clipRect); |
| 211 clipRects->setPosClipRect(clipRect); | 189 clipRects.setPosClipRect(clipRect); |
| 212 #ifdef CHECK_CLIP_RECTS | 190 #ifdef CHECK_CLIP_RECTS |
| 213 CHECK(!hasClip || clipRects->posClipRect() == oldClipRects.posClipRect()) | 191 CHECK(clipRects->posClipRect() == oldClipRects.posClipRect()) |
| 214 << " abs=" << clipRects->posClipRect().toString(); | 192 << " abs=" << clipRects->posClipRect().toString(); |
| 215 #endif | 193 #endif |
| 216 | 194 |
| 217 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects(); | 195 if (!paintLayer.hasPreviousPaintingClipRects() || |
| 218 | 196 clipRects != paintLayer.previousPaintingClipRects()) { |
| 219 if (!previousClipRects || *clipRects != *previousClipRects) { | |
| 220 paintLayer.setNeedsRepaint(); | 197 paintLayer.setNeedsRepaint(); |
| 221 paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(false); | 198 paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(false); |
| 222 paintLayer.setPreviousPaintPhaseFloatEmpty(false); | 199 paintLayer.setPreviousPaintPhaseFloatEmpty(false); |
| 223 paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false); | 200 paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false); |
| 224 // All subsequences which are contained below this paintLayer must also | 201 // All subsequences which are contained below this paintLayer must also |
| 225 // be checked. | 202 // be checked. |
| 226 context.paintInvalidatorContext.forcedSubtreeInvalidationFlags |= | 203 context.paintInvalidatorContext.forcedSubtreeInvalidationFlags |= |
| 227 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; | 204 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; |
| 228 } | 205 } |
| 229 | 206 |
| 230 paintLayer.setPreviousPaintingClipRects(*clipRects); | 207 paintLayer.setPreviousPaintingClipRects(clipRects); |
| 231 } | 208 } |
| 232 | 209 |
| 233 bool PrePaintTreeWalk::shouldEndWalkBefore( | 210 bool PrePaintTreeWalk::shouldEndWalkBefore( |
| 234 const LayoutObject& object, | 211 const LayoutObject& object, |
| 235 const PrePaintTreeWalkContext& context) { | 212 const PrePaintTreeWalkContext& context) { |
| 236 return !object.needsPaintPropertyUpdate() && | 213 return !object.needsPaintPropertyUpdate() && |
| 237 !object.descendantNeedsPaintPropertyUpdate() && | 214 !object.descendantNeedsPaintPropertyUpdate() && |
| 238 !context.treeBuilderContext->forceSubtreeUpdate && | 215 !context.treeBuilderContext->forceSubtreeUpdate && |
| 239 !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags && | 216 !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags && |
| 240 !object.shouldCheckForPaintInvalidation(); | 217 !object.shouldCheckForPaintInvalidation(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 roundedIntPoint(context.treeBuilderContext->current.paintOffset); | 257 roundedIntPoint(context.treeBuilderContext->current.paintOffset); |
| 281 walk(*toFrameView(frameViewBase), context); | 258 walk(*toFrameView(frameViewBase), context); |
| 282 } | 259 } |
| 283 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). | 260 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). |
| 284 } | 261 } |
| 285 | 262 |
| 286 object.getMutableForPainting().clearPaintFlags(); | 263 object.getMutableForPainting().clearPaintFlags(); |
| 287 } | 264 } |
| 288 | 265 |
| 289 } // namespace blink | 266 } // namespace blink |
| OLD | NEW |