| 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" |
| 11 #include "core/layout/LayoutPart.h" | 11 #include "core/layout/LayoutPart.h" |
| 12 #include "core/layout/LayoutView.h" | 12 #include "core/layout/LayoutView.h" |
| 13 #include "core/paint/PaintLayer.h" | 13 #include "core/paint/PaintLayer.h" |
| 14 | 14 |
| 15 namespace blink { | 15 namespace blink { |
| 16 | 16 |
| 17 struct PrePaintTreeWalkContext { | 17 struct PrePaintTreeWalkContext { |
| 18 PrePaintTreeWalkContext() | 18 PrePaintTreeWalkContext() |
| 19 : paintInvalidatorContext(treeBuilderContext), | 19 : paintInvalidatorContext(treeBuilderContext), |
| 20 ancestorOverflowPaintLayer(nullptr) {} | 20 ancestorOverflowPaintLayer(nullptr), |
| 21 ancestorTransformedOrRootPaintLayer(nullptr) {} |
| 21 PrePaintTreeWalkContext(const PrePaintTreeWalkContext& parentContext) | 22 PrePaintTreeWalkContext(const PrePaintTreeWalkContext& parentContext) |
| 22 : treeBuilderContext(parentContext.treeBuilderContext), | 23 : treeBuilderContext(parentContext.treeBuilderContext), |
| 23 paintInvalidatorContext(treeBuilderContext, | 24 paintInvalidatorContext(treeBuilderContext, |
| 24 parentContext.paintInvalidatorContext), | 25 parentContext.paintInvalidatorContext), |
| 25 ancestorOverflowPaintLayer(parentContext.ancestorOverflowPaintLayer), | 26 ancestorOverflowPaintLayer(parentContext.ancestorOverflowPaintLayer), |
| 26 ancestorTransformedOrRootPaintLayer( | 27 ancestorTransformedOrRootPaintLayer( |
| 27 parentContext.ancestorTransformedOrRootPaintLayer) {} | 28 parentContext.ancestorTransformedOrRootPaintLayer) {} |
| 28 | 29 |
| 29 PaintPropertyTreeBuilderContext treeBuilderContext; | 30 PaintPropertyTreeBuilderContext treeBuilderContext; |
| 30 PaintInvalidatorContext paintInvalidatorContext; | 31 PaintInvalidatorContext paintInvalidatorContext; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 | 124 |
| 124 FloatClipRect rect( | 125 FloatClipRect rect( |
| 125 m_geometryMapper.sourceToDestinationClipRect(localState, ancestorState)); | 126 m_geometryMapper.sourceToDestinationClipRect(localState, ancestorState)); |
| 126 | 127 |
| 127 rect.moveBy(-FloatPoint(ancestorPaintOffset)); | 128 rect.moveBy(-FloatPoint(ancestorPaintOffset)); |
| 128 return rect; | 129 return rect; |
| 129 } | 130 } |
| 130 | 131 |
| 131 void PrePaintTreeWalk::invalidatePaintLayerOptimizationsIfNeeded( | 132 void PrePaintTreeWalk::invalidatePaintLayerOptimizationsIfNeeded( |
| 132 const LayoutObject& object, | 133 const LayoutObject& object, |
| 133 const PaintLayer& ancestorTransformedOrRootPaintLayer, | 134 PrePaintTreeWalkContext& context) { |
| 134 PaintPropertyTreeBuilderContext& context) { | |
| 135 if (!object.hasLayer()) | 135 if (!object.hasLayer()) |
| 136 return; | 136 return; |
| 137 | 137 |
| 138 PaintLayer& paintLayer = *toLayoutBoxModelObject(object).layer(); | 138 PaintLayer& paintLayer = *toLayoutBoxModelObject(object).layer(); |
| 139 if (object.styleRef().hasTransform() || |
| 140 &object == context.paintInvalidatorContext.paintInvalidationContainer) { |
| 141 context.ancestorTransformedOrRootPaintLayer = &paintLayer; |
| 142 } |
| 143 |
| 139 const ObjectPaintProperties& ancestorPaintProperties = | 144 const ObjectPaintProperties& ancestorPaintProperties = |
| 140 *ancestorTransformedOrRootPaintLayer.layoutObject().paintProperties(); | 145 *context.ancestorTransformedOrRootPaintLayer->layoutObject() |
| 146 .paintProperties(); |
| 141 PropertyTreeState ancestorState = | 147 PropertyTreeState ancestorState = |
| 142 *ancestorPaintProperties.localBorderBoxProperties(); | 148 *ancestorPaintProperties.localBorderBoxProperties(); |
| 149 const EffectPaintPropertyNode* effect = |
| 150 context.treeBuilderContext.currentEffect; |
| 143 | 151 |
| 144 #ifdef CHECK_CLIP_RECTS | 152 #ifdef CHECK_CLIP_RECTS |
| 145 ShouldRespectOverflowClipType respectOverflowClip = RespectOverflowClip; | 153 ShouldRespectOverflowClipType respectOverflowClip = RespectOverflowClip; |
| 146 #endif | 154 #endif |
| 147 if (ancestorTransformedOrRootPaintLayer.compositingState() == | 155 if (context.ancestorTransformedOrRootPaintLayer->compositingState() == |
| 148 PaintsIntoOwnBacking && | 156 PaintsIntoOwnBacking && |
| 149 ancestorPaintProperties.overflowClip()) { | 157 ancestorPaintProperties.overflowClip()) { |
| 150 ancestorState.setClip(ancestorPaintProperties.overflowClip()); | 158 ancestorState.setClip(ancestorPaintProperties.overflowClip()); |
| 151 #ifdef CHECK_CLIP_RECTS | 159 #ifdef CHECK_CLIP_RECTS |
| 152 respectOverflowClip = IgnoreOverflowClip; | 160 respectOverflowClip = IgnoreOverflowClip; |
| 153 #endif | 161 #endif |
| 154 } | 162 } |
| 155 | 163 |
| 156 #ifdef CHECK_CLIP_RECTS | 164 #ifdef CHECK_CLIP_RECTS |
| 157 ClipRects& oldClipRects = paintLayer.clipper().paintingClipRects( | 165 ClipRects& oldClipRects = |
| 158 &ancestorTransformedOrRootPaintLayer, respectOverflowClip, LayoutSize()); | 166 paintLayer.clipper(PaintLayer::DoNotUseGeometryMapper) |
| 167 .paintingClipRects(&ancestorTransformedOrRootPaintLayer, |
| 168 respectOverflowClip, LayoutSize()); |
| 159 #endif | 169 #endif |
| 160 | 170 |
| 161 bool hasClip = false; | 171 bool hasClip = false; |
| 162 RefPtr<ClipRects> clipRects = ClipRects::create(); | 172 RefPtr<ClipRects> clipRects = ClipRects::create(); |
| 163 const LayoutPoint& ancestorPaintOffset = | 173 const LayoutPoint& ancestorPaintOffset = |
| 164 ancestorTransformedOrRootPaintLayer.layoutObject().paintOffset(); | 174 context.ancestorTransformedOrRootPaintLayer->layoutObject().paintOffset(); |
| 165 clipRects->setOverflowClipRect( | 175 clipRects->setOverflowClipRect( |
| 166 clipRectForContext(context.current, context.currentEffect, ancestorState, | 176 clipRectForContext(context.treeBuilderContext.current, effect, |
| 167 ancestorPaintOffset, hasClip)); | 177 ancestorState, ancestorPaintOffset, hasClip)); |
| 168 #ifdef CHECK_CLIP_RECTS | 178 #ifdef CHECK_CLIP_RECTS |
| 169 CHECK(!hasClip || | 179 CHECK(!hasClip || |
| 170 clipRects->overflowClipRect() == oldClipRects.overflowClipRect()) | 180 clipRects->overflowClipRect() == oldClipRects.overflowClipRect()) |
| 171 << "rect= " << clipRects->overflowClipRect().toString(); | 181 << "rect= " << clipRects->overflowClipRect().toString(); |
| 172 #endif | 182 #endif |
| 173 | 183 |
| 174 clipRects->setFixedClipRect( | 184 clipRects->setFixedClipRect( |
| 175 clipRectForContext(context.fixedPosition, context.currentEffect, | 185 clipRectForContext(context.treeBuilderContext.fixedPosition, effect, |
| 176 ancestorState, ancestorPaintOffset, hasClip)); | 186 ancestorState, ancestorPaintOffset, hasClip)); |
| 177 #ifdef CHECK_CLIP_RECTS | 187 #ifdef CHECK_CLIP_RECTS |
| 178 CHECK(hasClip || clipRects->fixedClipRect() == oldClipRects.fixedClipRect()) | 188 CHECK(hasClip || clipRects->fixedClipRect() == oldClipRects.fixedClipRect()) |
| 179 << " fixed=" << clipRects->fixedClipRect().toString(); | 189 << " fixed=" << clipRects->fixedClipRect().toString(); |
| 180 #endif | 190 #endif |
| 181 | 191 |
| 182 clipRects->setPosClipRect( | 192 clipRects->setPosClipRect( |
| 183 clipRectForContext(context.absolutePosition, context.currentEffect, | 193 clipRectForContext(context.treeBuilderContext.absolutePosition, effect, |
| 184 ancestorState, ancestorPaintOffset, hasClip)); | 194 ancestorState, ancestorPaintOffset, hasClip)); |
| 185 #ifdef CHECK_CLIP_RECTS | 195 #ifdef CHECK_CLIP_RECTS |
| 186 CHECK(!hasClip || clipRects->posClipRect() == oldClipRects.posClipRect()) | 196 CHECK(!hasClip || clipRects->posClipRect() == oldClipRects.posClipRect()) |
| 187 << " abs=" << clipRects->posClipRect().toString(); | 197 << " abs=" << clipRects->posClipRect().toString(); |
| 188 #endif | 198 #endif |
| 189 | 199 |
| 190 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects(); | 200 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects(); |
| 191 | 201 |
| 192 if (!previousClipRects || *clipRects != *previousClipRects) { | 202 if (!previousClipRects || *clipRects != *previousClipRects) { |
| 193 paintLayer.setNeedsRepaint(); | 203 paintLayer.setNeedsRepaint(); |
| 194 paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(false); | 204 paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(false); |
| 195 paintLayer.setPreviousPaintPhaseFloatEmpty(false); | 205 paintLayer.setPreviousPaintPhaseFloatEmpty(false); |
| 196 paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false); | 206 paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false); |
| 197 // All subsequences which are contained below this paintLayer must also | 207 // All subsequences which are contained below this paintLayer must also |
| 198 // be checked. | 208 // be checked. |
| 199 context.forceSubtreeUpdate = true; | 209 context.paintInvalidatorContext.forcedSubtreeInvalidationFlags |= |
| 210 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; |
| 200 } | 211 } |
| 201 | 212 |
| 202 paintLayer.setPreviousPaintingClipRects(*clipRects); | 213 paintLayer.setPreviousPaintingClipRects(*clipRects); |
| 203 } | 214 } |
| 204 | 215 |
| 205 void PrePaintTreeWalk::walk(const LayoutObject& object, | 216 void PrePaintTreeWalk::walk(const LayoutObject& object, |
| 206 const PrePaintTreeWalkContext& parentContext) { | 217 const PrePaintTreeWalkContext& parentContext) { |
| 207 PrePaintTreeWalkContext context(parentContext); | 218 PrePaintTreeWalkContext context(parentContext); |
| 208 | 219 |
| 209 // Early out from the treewalk if possible. | 220 // Early out from the treewalk if possible. |
| 210 if (!object.needsPaintPropertyUpdate() && | 221 if (!object.needsPaintPropertyUpdate() && |
| 211 !object.descendantNeedsPaintPropertyUpdate() && | 222 !object.descendantNeedsPaintPropertyUpdate() && |
| 212 !context.treeBuilderContext.forceSubtreeUpdate && | 223 !context.treeBuilderContext.forceSubtreeUpdate && |
| 213 !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags && | 224 !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags && |
| 214 !object | 225 !object |
| 215 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()) | 226 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()) |
| 216 return; | 227 return; |
| 217 | 228 |
| 218 // This must happen before updatePropertiesForSelf, because the latter reads | 229 // This must happen before updatePropertiesForSelf, because the latter reads |
| 219 // some of the state computed here. | 230 // some of the state computed here. |
| 220 updateAuxiliaryObjectProperties(object, context); | 231 updateAuxiliaryObjectProperties(object, context); |
| 221 | 232 |
| 222 m_propertyTreeBuilder.updatePropertiesForSelf(object, | 233 m_propertyTreeBuilder.updatePropertiesForSelf(object, |
| 223 context.treeBuilderContext); | 234 context.treeBuilderContext); |
| 224 m_paintInvalidator.invalidatePaintIfNeeded(object, | 235 m_paintInvalidator.invalidatePaintIfNeeded(object, |
| 225 context.paintInvalidatorContext); | 236 context.paintInvalidatorContext); |
| 226 m_propertyTreeBuilder.updatePropertiesForChildren(object, | 237 m_propertyTreeBuilder.updatePropertiesForChildren(object, |
| 227 context.treeBuilderContext); | 238 context.treeBuilderContext); |
| 228 | 239 |
| 229 if (object.isBoxModelObject() && object.hasLayer()) { | 240 invalidatePaintLayerOptimizationsIfNeeded(object, context); |
| 230 if (object.styleRef().hasTransform() || | |
| 231 &object == context.paintInvalidatorContext.paintInvalidationContainer) { | |
| 232 context.ancestorTransformedOrRootPaintLayer = | |
| 233 toLayoutBoxModelObject(object).layer(); | |
| 234 } | |
| 235 } | |
| 236 | |
| 237 invalidatePaintLayerOptimizationsIfNeeded( | |
| 238 object, *context.ancestorTransformedOrRootPaintLayer, | |
| 239 context.treeBuilderContext); | |
| 240 | 241 |
| 241 for (const LayoutObject* child = object.slowFirstChild(); child; | 242 for (const LayoutObject* child = object.slowFirstChild(); child; |
| 242 child = child->nextSibling()) { | 243 child = child->nextSibling()) { |
| 243 if (child->isLayoutMultiColumnSpannerPlaceholder()) { | 244 if (child->isLayoutMultiColumnSpannerPlaceholder()) { |
| 244 child->getMutableForPainting().clearPaintFlags(); | 245 child->getMutableForPainting().clearPaintFlags(); |
| 245 continue; | 246 continue; |
| 246 } | 247 } |
| 247 walk(*child, context); | 248 walk(*child, context); |
| 248 } | 249 } |
| 249 | 250 |
| 250 if (object.isLayoutPart()) { | 251 if (object.isLayoutPart()) { |
| 251 const LayoutPart& layoutPart = toLayoutPart(object); | 252 const LayoutPart& layoutPart = toLayoutPart(object); |
| 252 Widget* widget = layoutPart.widget(); | 253 Widget* widget = layoutPart.widget(); |
| 253 if (widget && widget->isFrameView()) { | 254 if (widget && widget->isFrameView()) { |
| 254 context.treeBuilderContext.current.paintOffset += | 255 context.treeBuilderContext.current.paintOffset += |
| 255 layoutPart.replacedContentRect().location() - | 256 layoutPart.replacedContentRect().location() - |
| 256 widget->frameRect().location(); | 257 widget->frameRect().location(); |
| 257 context.treeBuilderContext.current.paintOffset = | 258 context.treeBuilderContext.current.paintOffset = |
| 258 roundedIntPoint(context.treeBuilderContext.current.paintOffset); | 259 roundedIntPoint(context.treeBuilderContext.current.paintOffset); |
| 259 walk(*toFrameView(widget), context); | 260 walk(*toFrameView(widget), context); |
| 260 } | 261 } |
| 261 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). | 262 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). |
| 262 } | 263 } |
| 263 | 264 |
| 264 object.getMutableForPainting().clearPaintFlags(); | 265 object.getMutableForPainting().clearPaintFlags(); |
| 265 } | 266 } |
| 266 | 267 |
| 267 } // namespace blink | 268 } // namespace blink |
| OLD | NEW |