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

Side by Side Diff: third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp

Issue 1857373002: Fix PaintInvalidationState mapping for absolute whose container is above paintInvalidationContainer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@VisualRectMappingTest
Patch Set: Created 4 years, 8 months 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 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/layout/PaintInvalidationState.h" 5 #include "core/layout/PaintInvalidationState.h"
6 6
7 #include "core/frame/FrameView.h" 7 #include "core/frame/FrameView.h"
8 #include "core/frame/Settings.h" 8 #include "core/frame/Settings.h"
9 #include "core/layout/LayoutInline.h" 9 #include "core/layout/LayoutInline.h"
10 #include "core/layout/LayoutPart.h" 10 #include "core/layout/LayoutPart.h"
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 // (e.g. LayoutView, and the HorriblySlowRectMapping cases in LayoutBloc k::invalidatePaintOfSubtreesIfNeeded()). 127 // (e.g. LayoutView, and the HorriblySlowRectMapping cases in LayoutBloc k::invalidatePaintOfSubtreesIfNeeded()).
128 // TODO(wangxianzhu): Avoid this for RuntimeEnabledFeatures::slimmingPai ntInvalidationEnabled(). 128 // TODO(wangxianzhu): Avoid this for RuntimeEnabledFeatures::slimmingPai ntInvalidationEnabled().
129 #if ENABLE(ASSERT) 129 #if ENABLE(ASSERT)
130 m_didUpdateForChildren = parentState.m_didUpdateForChildren; 130 m_didUpdateForChildren = parentState.m_didUpdateForChildren;
131 #endif 131 #endif
132 return; 132 return;
133 } 133 }
134 134
135 ASSERT(parentState.m_didUpdateForChildren); 135 ASSERT(parentState.m_didUpdateForChildren);
136 136
137 EPosition position = currentObject.styleRef().position();
138
139 if (currentObject.isPaintInvalidationContainer()) { 137 if (currentObject.isPaintInvalidationContainer()) {
140 m_paintInvalidationContainer = toLayoutBoxModelObject(&currentObject); 138 m_paintInvalidationContainer = toLayoutBoxModelObject(&currentObject);
141 if (currentObject.styleRef().isStackingContext()) { 139 if (currentObject.styleRef().isStackingContext())
142 m_paintInvalidationContainerForStackedContents = toLayoutBoxModelObj ect(&currentObject); 140 m_paintInvalidationContainerForStackedContents = toLayoutBoxModelObj ect(&currentObject);
143 // Adjust cached offsets for absolute-position to be relative to thi s new paintInvalidationContainer.
144 if (m_cachedOffsetsForAbsolutePositionEnabled && m_cachedOffsetsEnab led) {
145 m_paintOffsetForAbsolutePosition -= m_paintOffset;
146 if (m_clippedForAbsolutePosition)
147 m_clipRectForAbsolutePosition.move(-m_paintOffset);
148 }
149 }
150 } else if (currentObject.isLayoutView()) { 141 } else if (currentObject.isLayoutView()) {
151 // m_paintInvalidationContainerForStackedContents is only for stacked de scendants in its own frame, 142 // m_paintInvalidationContainerForStackedContents is only for stacked de scendants in its own frame,
152 // because it doesn't establish stacking context for stacked contents in sub-frames. 143 // because it doesn't establish stacking context for stacked contents in sub-frames.
153 // Contents stacked in the root stacking context in this frame should us e this frame's paintInvalidationContainer. 144 // Contents stacked in the root stacking context in this frame should us e this frame's paintInvalidationContainer.
154 m_paintInvalidationContainerForStackedContents = m_paintInvalidationCont ainer; 145 m_paintInvalidationContainerForStackedContents = m_paintInvalidationCont ainer;
155 } else if (currentObject.styleRef().isStacked() 146 } else if (currentObject.styleRef().isStacked()
156 // This is to exclude some objects (e.g. LayoutText) inheriting stacked style from parent but aren't actually stacked. 147 // This is to exclude some objects (e.g. LayoutText) inheriting stacked style from parent but aren't actually stacked.
157 && currentObject.hasLayer() 148 && currentObject.hasLayer()
158 && m_paintInvalidationContainer != m_paintInvalidationContainerForStacke dContents) { 149 && m_paintInvalidationContainer != m_paintInvalidationContainerForStacke dContents) {
159 // The current object is stacked, so we should use m_paintInvalidationCo ntainerForStackedContents as its 150 // The current object is stacked, so we should use m_paintInvalidationCo ntainerForStackedContents as its
(...skipping 27 matching lines...) Expand all
187 } 178 }
188 179
189 if (currentObject == m_paintInvalidationContainer) { 180 if (currentObject == m_paintInvalidationContainer) {
190 // When we hit a new paint invalidation container, we don't need to 181 // When we hit a new paint invalidation container, we don't need to
191 // continue forcing a check for paint invalidation, since we're 182 // continue forcing a check for paint invalidation, since we're
192 // descending into a different invalidation container. (For instance if 183 // descending into a different invalidation container. (For instance if
193 // our parents were moved, the entire container will just move.) 184 // our parents were moved, the entire container will just move.)
194 m_forcedSubtreeInvalidationWithinContainer = false; 185 m_forcedSubtreeInvalidationWithinContainer = false;
195 m_forcedSubtreeInvalidationRectUpdateWithinContainer = false; 186 m_forcedSubtreeInvalidationRectUpdateWithinContainer = false;
196 187
188 if (currentObject == m_paintInvalidationContainerForStackedContents
189 && currentObject != m_containerForAbsolutePosition
190 && m_cachedOffsetsForAbsolutePositionEnabled
191 && m_cachedOffsetsEnabled) {
192 // The current object is the new paintInvalidationContainer for abso lute-position descendants but is not their container.
193 // Call updateForCurrentObject() before resetting m_paintOffset to g et paint offset of the current object
194 // from the original paintInvalidationContainerForStackingContents, then use this paint offset to adjust
195 // m_paintOffsetForAbsolutePosition.
196 updateForCurrentObject(parentState);
197 m_paintOffsetForAbsolutePosition -= m_paintOffset;
198 if (m_clippedForAbsolutePosition)
199 m_clipRectForAbsolutePosition.move(-m_paintOffset);
200 }
201
197 m_clipped = false; // Will be updated in updateForChildren(). 202 m_clipped = false; // Will be updated in updateForChildren().
198 m_paintOffset = LayoutSize(); 203 m_paintOffset = LayoutSize();
199 return; 204 return;
200 } 205 }
201 206
207 updateForCurrentObject(parentState);
208 }
209
210 void PaintInvalidationState::updateForCurrentObject(const PaintInvalidationState & parentState)
211 {
202 if (!m_cachedOffsetsEnabled) 212 if (!m_cachedOffsetsEnabled)
203 return; 213 return;
204 214
205 if (currentObject.isLayoutView()) { 215 if (m_currentObject.isLayoutView()) {
206 ASSERT(&parentState.m_currentObject == toLayoutView(currentObject).frame ()->ownerLayoutObject()); 216 ASSERT(&parentState.m_currentObject == toLayoutView(m_currentObject).fra me()->ownerLayoutObject());
207 m_paintOffset += toLayoutBox(parentState.m_currentObject).contentBoxOffs et(); 217 m_paintOffset += toLayoutBox(parentState.m_currentObject).contentBoxOffs et();
208 // a LayoutView paints with a defined size but a pixel-rounded offset. 218 // a LayoutView paints with a defined size but a pixel-rounded offset.
209 m_paintOffset = LayoutSize(roundedIntSize(m_paintOffset)); 219 m_paintOffset = LayoutSize(roundedIntSize(m_paintOffset));
210 return; 220 return;
211 } 221 }
212 222
223 EPosition position = m_currentObject.styleRef().position();
224
213 if (position == FixedPosition) { 225 if (position == FixedPosition) {
214 if (m_paintInvalidationContainer != currentObject.view() && m_paintInval idationContainer->view() == currentObject.view()) { 226 if (m_paintInvalidationContainer != m_currentObject.view() && m_paintInv alidationContainer->view() == m_currentObject.view()) {
215 // TODO(crbug.com/598762): localToAncestorPoint() is incorrect for f ixed-position when paintInvalidationContainer 227 // TODO(crbug.com/598762): localToAncestorPoint() is incorrect for f ixed-position when paintInvalidationContainer
216 // is under the containing LayoutView. 228 // is under the containing LayoutView.
217 m_cachedOffsetsEnabled = false; 229 m_cachedOffsetsEnabled = false;
218 return; 230 return;
219 } 231 }
220 // Use slow path to get the offset of the fixed-position, and enable fas t path for descendants. 232 // Use slow path to get the offset of the fixed-position, and enable fas t path for descendants.
221 FloatPoint fixedOffset = currentObject.localToAncestorPoint(FloatPoint() , m_paintInvalidationContainer, TraverseDocumentBoundaries); 233 FloatPoint fixedOffset = m_currentObject.localToAncestorPoint(FloatPoint (), m_paintInvalidationContainer, TraverseDocumentBoundaries);
222 m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()); 234 m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y());
223 // In the above way to get paint offset, we can't get accurate clip rect , so just assume no clip. 235 // In the above way to get paint offset, we can't get accurate clip rect , so just assume no clip.
224 // Clip on fixed-position is rare, in case that paintInvalidationContain er crosses frame boundary 236 // Clip on fixed-position is rare, in case that paintInvalidationContain er crosses frame boundary
225 // and the LayoutView is clipped by something in owner document. 237 // and the LayoutView is clipped by something in owner document.
226 m_clipped = false; 238 m_clipped = false;
227 return; 239 return;
228 } 240 }
229 241
230 if (position == AbsolutePosition) { 242 if (position == AbsolutePosition) {
231 m_cachedOffsetsEnabled = m_cachedOffsetsForAbsolutePositionEnabled; 243 m_cachedOffsetsEnabled = m_cachedOffsetsForAbsolutePositionEnabled;
232 if (!m_cachedOffsetsEnabled) 244 if (!m_cachedOffsetsEnabled)
233 return; 245 return;
234 246
235 m_paintOffset = m_paintOffsetForAbsolutePosition; 247 m_paintOffset = m_paintOffsetForAbsolutePosition;
236 m_clipped = m_clippedForAbsolutePosition; 248 m_clipped = m_clippedForAbsolutePosition;
237 m_clipRect = m_clipRectForAbsolutePosition; 249 m_clipRect = m_clipRectForAbsolutePosition;
238 250
239 // Handle absolute-position block under relative-position inline. 251 // Handle absolute-position block under relative-position inline.
240 const LayoutObject& container = parentState.m_containerForAbsolutePositi on; 252 const LayoutObject& container = parentState.m_containerForAbsolutePositi on;
241 if (container.isInFlowPositioned() && container.isLayoutInline()) 253 if (container.isInFlowPositioned() && container.isLayoutInline())
242 m_paintOffset += toLayoutInline(container).offsetForInFlowPositioned Inline(toLayoutBox(m_currentObject)); 254 m_paintOffset += toLayoutInline(container).offsetForInFlowPositioned Inline(toLayoutBox(m_currentObject));
243 } 255 }
244 256
245 if (currentObject.isBox()) 257 if (m_currentObject.isBox())
246 m_paintOffset += toLayoutBox(currentObject).locationOffset(); 258 m_paintOffset += toLayoutBox(m_currentObject).locationOffset();
247 259
248 if (currentObject.isInFlowPositioned() && currentObject.hasLayer()) 260 if (m_currentObject.isInFlowPositioned() && m_currentObject.hasLayer())
249 m_paintOffset += toLayoutBoxModelObject(currentObject).layer()->offsetFo rInFlowPosition(); 261 m_paintOffset += toLayoutBoxModelObject(m_currentObject).layer()->offset ForInFlowPosition();
250 } 262 }
251 263
252 void PaintInvalidationState::updateForChildren() 264 void PaintInvalidationState::updateForChildren()
253 { 265 {
254 #if ENABLE(ASSERT) 266 #if ENABLE(ASSERT)
255 ASSERT(!m_didUpdateForChildren); 267 ASSERT(!m_didUpdateForChildren);
256 m_didUpdateForChildren = true; 268 m_didUpdateForChildren = true;
257 #endif 269 #endif
258 270
259 updateForNormalChildren(); 271 updateForNormalChildren();
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 404
393 static void slowMapToVisualRectInAncestorSpace(const LayoutObject& object, const LayoutBoxModelObject& ancestor, LayoutRect& rect) 405 static void slowMapToVisualRectInAncestorSpace(const LayoutObject& object, const LayoutBoxModelObject& ancestor, LayoutRect& rect)
394 { 406 {
395 if (object.isLayoutView()) { 407 if (object.isLayoutView()) {
396 toLayoutView(object).mapToVisualRectInAncestorSpace(&ancestor, rect, Inp utIsInFrameCoordinates, DefaultVisualRectFlags); 408 toLayoutView(object).mapToVisualRectInAncestorSpace(&ancestor, rect, Inp utIsInFrameCoordinates, DefaultVisualRectFlags);
397 } else { 409 } else {
398 object.mapToVisualRectInAncestorSpace(&ancestor, rect); 410 object.mapToVisualRectInAncestorSpace(&ancestor, rect);
399 } 411 }
400 } 412 }
401 413
402 void PaintInvalidationState::mapLocalRectToPaintInvalidationBacking(LayoutRect& rect) const 414 void PaintInvalidationState::mapLocalRectToPaintInvalidationContainer(LayoutRect & rect) const
403 { 415 {
404 ASSERT(!m_didUpdateForChildren); 416 ASSERT(!m_didUpdateForChildren);
405 417
406 if (m_cachedOffsetsEnabled) { 418 if (m_cachedOffsetsEnabled) {
407 #if ASSERT_SAME_RESULT_SLOW_AND_FAST_PATH 419 #if ASSERT_SAME_RESULT_SLOW_AND_FAST_PATH
408 LayoutRect slowPathRect(rect); 420 LayoutRect slowPathRect(rect);
409 slowMapToVisualRectInAncestorSpace(m_currentObject, *m_paintInvalidation Container, slowPathRect); 421 slowMapToVisualRectInAncestorSpace(m_currentObject, *m_paintInvalidation Container, slowPathRect);
410 #endif 422 #endif
411 rect.move(m_paintOffset); 423 rect.move(m_paintOffset);
412 if (m_clipped) 424 if (m_clipped)
413 rect.intersect(m_clipRect); 425 rect.intersect(m_clipRect);
414 #if ASSERT_SAME_RESULT_SLOW_AND_FAST_PATH 426 #if ASSERT_SAME_RESULT_SLOW_AND_FAST_PATH
415 // TODO(crbug.com/597902): Slow path misses clipping of paintInvalidatio nContainer. 427 // TODO(crbug.com/597902): Slow path misses clipping of paintInvalidatio nContainer.
416 if (m_clipped) 428 if (m_clipped)
417 slowPathRect.intersect(m_clipRect); 429 slowPathRect.intersect(m_clipRect);
418 assertRectsEqual(m_currentObject, *m_paintInvalidationContainer, rect, s lowPathRect); 430 assertRectsEqual(m_currentObject, *m_paintInvalidationContainer, rect, s lowPathRect);
419 #endif 431 #endif
420 } else { 432 } else {
421 slowMapToVisualRectInAncestorSpace(m_currentObject, *m_paintInvalidation Container, rect); 433 slowMapToVisualRectInAncestorSpace(m_currentObject, *m_paintInvalidation Container, rect);
422 } 434 }
435 }
436
437 void PaintInvalidationState::mapLocalRectToPaintInvalidationBacking(LayoutRect& rect) const
438 {
439 mapLocalRectToPaintInvalidationContainer(rect);
423 440
424 if (m_paintInvalidationContainer->layer()->groupedMapping()) 441 if (m_paintInvalidationContainer->layer()->groupedMapping())
425 PaintLayer::mapRectInPaintInvalidationContainerToBacking(*m_paintInvalid ationContainer, rect); 442 PaintLayer::mapRectInPaintInvalidationContainerToBacking(*m_paintInvalid ationContainer, rect);
426 } 443 }
427 444
428 void PaintInvalidationState::addClipRectRelativeToPaintOffset(const LayoutRect& localClipRect) 445 void PaintInvalidationState::addClipRectRelativeToPaintOffset(const LayoutRect& localClipRect)
429 { 446 {
430 LayoutRect clipRect = localClipRect; 447 LayoutRect clipRect = localClipRect;
431 clipRect.move(m_paintOffset); 448 clipRect.move(m_paintOffset);
432 if (m_clipped) { 449 if (m_clipped) {
433 m_clipRect.intersect(clipRect); 450 m_clipRect.intersect(clipRect);
434 } else { 451 } else {
435 m_clipRect = clipRect; 452 m_clipRect = clipRect;
436 m_clipped = true; 453 m_clipped = true;
437 } 454 }
438 } 455 }
439 456
440 PaintLayer& PaintInvalidationState::enclosingSelfPaintingLayer(const LayoutObjec t& layoutObject) const 457 PaintLayer& PaintInvalidationState::enclosingSelfPaintingLayer(const LayoutObjec t& layoutObject) const
441 { 458 {
442 if (layoutObject.hasLayer() && toLayoutBoxModelObject(layoutObject).hasSelfP aintingLayer()) 459 if (layoutObject.hasLayer() && toLayoutBoxModelObject(layoutObject).hasSelfP aintingLayer())
443 return *toLayoutBoxModelObject(layoutObject).layer(); 460 return *toLayoutBoxModelObject(layoutObject).layer();
444 461
445 return m_enclosingSelfPaintingLayer; 462 return m_enclosingSelfPaintingLayer;
446 } 463 }
447 464
448 } // namespace blink 465 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698