| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2000 Dirk Mueller (mueller@kde.org) | 4 * (C) 2000 Dirk Mueller (mueller@kde.org) |
| 5 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) | 5 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) |
| 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserv
ed. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserv
ed. |
| 7 * Copyright (C) 2009 Google Inc. All rights reserved. | 7 * Copyright (C) 2009 Google Inc. All rights reserved. |
| 8 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | 8 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) |
| 9 * | 9 * |
| 10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 // See if we have the thread cached because we're in the middle of layout. | 677 // See if we have the thread cached because we're in the middle of layout. |
| 678 if (LayoutState* layoutState = view()->layoutState()) { | 678 if (LayoutState* layoutState = view()->layoutState()) { |
| 679 if (LayoutFlowThread* flowThread = layoutState->flowThread()) | 679 if (LayoutFlowThread* flowThread = layoutState->flowThread()) |
| 680 return flowThread; | 680 return flowThread; |
| 681 } | 681 } |
| 682 | 682 |
| 683 // Not in the middle of layout so have to find the thread the slow way. | 683 // Not in the middle of layout so have to find the thread the slow way. |
| 684 return LayoutFlowThread::locateFlowThreadContainingBlockOf(*this); | 684 return LayoutFlowThread::locateFlowThreadContainingBlockOf(*this); |
| 685 } | 685 } |
| 686 | 686 |
| 687 bool LayoutObject::skipInvalidationWhenLaidOutChildren() const |
| 688 { |
| 689 if (!m_bitfields.neededLayoutBecauseOfChildren()) |
| 690 return false; |
| 691 |
| 692 // SVG layoutObjects need to be invalidated when their children are laid out
. |
| 693 // LayoutBlocks with line boxes are responsible to invalidate them so we can
't ignore them. |
| 694 if (isSVG() || (isLayoutBlockFlow() && toLayoutBlockFlow(this)->firstLineBox
())) |
| 695 return false; |
| 696 |
| 697 // In case scrollbars got repositioned (which will typically happen if the l
ayout object got |
| 698 // resized), we cannot skip invalidation. |
| 699 if (hasNonCompositedScrollbars()) |
| 700 return false; |
| 701 |
| 702 // We can't detect whether a plugin has box effects, so disable this optimiz
ation for that case. |
| 703 if (isEmbeddedObject()) |
| 704 return false; |
| 705 |
| 706 return !hasBoxEffect(); |
| 707 } |
| 708 |
| 687 static inline bool objectIsRelayoutBoundary(const LayoutObject* object) | 709 static inline bool objectIsRelayoutBoundary(const LayoutObject* object) |
| 688 { | 710 { |
| 689 // FIXME: In future it may be possible to broaden these conditions in order
to improve performance. | 711 // FIXME: In future it may be possible to broaden these conditions in order
to improve performance. |
| 690 if (object->isTextControl()) | 712 if (object->isTextControl()) |
| 691 return true; | 713 return true; |
| 692 | 714 |
| 693 if (object->isSVGRoot()) | 715 if (object->isSVGRoot()) |
| 694 return true; | 716 return true; |
| 695 | 717 |
| 696 // Table parts can't be relayout roots since the table is responsible for la
youting all the parts. | 718 // Table parts can't be relayout roots since the table is responsible for la
youting all the parts. |
| (...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1301 return; | 1323 return; |
| 1302 selectionPaintInvalidationMap = new SelectionPaintInvalidationMap(); | 1324 selectionPaintInvalidationMap = new SelectionPaintInvalidationMap(); |
| 1303 } | 1325 } |
| 1304 | 1326 |
| 1305 if (selectionRect.isEmpty()) | 1327 if (selectionRect.isEmpty()) |
| 1306 selectionPaintInvalidationMap->remove(this); | 1328 selectionPaintInvalidationMap->remove(this); |
| 1307 else | 1329 else |
| 1308 selectionPaintInvalidationMap->set(this, selectionRect); | 1330 selectionPaintInvalidationMap->set(this, selectionRect); |
| 1309 } | 1331 } |
| 1310 | 1332 |
| 1333 // TODO(wangxianzhu): Remove this for slimming paint v2 because we won't care ab
out paint invalidation rects. |
| 1311 inline void LayoutObject::invalidateSelectionIfNeeded(const LayoutBoxModelObject
& paintInvalidationContainer, const PaintInvalidationState& paintInvalidationSta
te, PaintInvalidationReason invalidationReason) | 1334 inline void LayoutObject::invalidateSelectionIfNeeded(const LayoutBoxModelObject
& paintInvalidationContainer, const PaintInvalidationState& paintInvalidationSta
te, PaintInvalidationReason invalidationReason) |
| 1312 { | 1335 { |
| 1313 // Update selection rect when we are doing full invalidation (in case that t
he object is moved, composite status changed, etc.) | 1336 // Update selection rect when we are doing full invalidation (in case that t
he object is moved, composite status changed, etc.) |
| 1314 // or shouldInvalidationSelection is set (in case that the selection itself
changed). | 1337 // or shouldInvalidationSelection is set (in case that the selection itself
changed). |
| 1315 bool fullInvalidation = isFullPaintInvalidationReason(invalidationReason); | 1338 bool fullInvalidation = isFullPaintInvalidationReason(invalidationReason); |
| 1316 if (!fullInvalidation && !shouldInvalidateSelection()) | 1339 if (!fullInvalidation && !shouldInvalidateSelection()) |
| 1317 return; | 1340 return; |
| 1318 | 1341 |
| 1319 LayoutRect oldSelectionRect = previousSelectionRectForPaintInvalidation(); | 1342 LayoutRect oldSelectionRect = previousSelectionRectForPaintInvalidation(); |
| 1320 LayoutRect newSelectionRect = localSelectionRect(); | 1343 LayoutRect newSelectionRect = localSelectionRect(); |
| 1321 if (!newSelectionRect.isEmpty()) { | 1344 if (!newSelectionRect.isEmpty()) { |
| 1322 paintInvalidationState.mapLocalRectToPaintInvalidationBacking(newSelecti
onRect); | 1345 paintInvalidationState.mapLocalRectToPaintInvalidationBacking(newSelecti
onRect); |
| 1323 | 1346 |
| 1324 // Composited scrolling should not be included in the bounds and positio
n tracking, because the graphics layer backing the scroller | 1347 // Composited scrolling should not be included in the bounds and positio
n tracking, because the graphics layer backing the scroller |
| 1325 // does not move on scroll. | 1348 // does not move on scroll. |
| 1326 if (compositedScrollsWithRespectTo(paintInvalidationContainer)) { | 1349 if (compositedScrollsWithRespectTo(paintInvalidationContainer)) { |
| 1327 LayoutSize inverseOffset(toLayoutBox(&paintInvalidationContainer)->s
crolledContentOffset()); | 1350 LayoutSize inverseOffset(toLayoutBox(&paintInvalidationContainer)->s
crolledContentOffset()); |
| 1328 newSelectionRect.move(inverseOffset); | 1351 newSelectionRect.move(inverseOffset); |
| 1329 } | 1352 } |
| 1330 } | 1353 } |
| 1331 | 1354 |
| 1332 setPreviousSelectionRectForPaintInvalidation(newSelectionRect); | 1355 setPreviousSelectionRectForPaintInvalidation(newSelectionRect); |
| 1333 | 1356 |
| 1334 if (!fullInvalidation) { | 1357 // TODO(wangxianzhu): Combine the following two conditions when removing Lay
outView::doingFullPaintInvalidation(). |
| 1358 if (!fullInvalidation) |
| 1335 fullyInvalidatePaint(paintInvalidationContainer, PaintInvalidationSelect
ion, oldSelectionRect, newSelectionRect); | 1359 fullyInvalidatePaint(paintInvalidationContainer, PaintInvalidationSelect
ion, oldSelectionRect, newSelectionRect); |
| 1360 if (shouldInvalidateSelection()) |
| 1336 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidation
State, PaintInvalidationSelection); | 1361 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidation
State, PaintInvalidationSelection); |
| 1337 } | |
| 1338 } | 1362 } |
| 1339 | 1363 |
| 1340 PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded(const PaintInvalid
ationState& paintInvalidationState) | 1364 PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded(const PaintInvalid
ationState& paintInvalidationState) |
| 1341 { | 1365 { |
| 1342 ASSERT(&paintInvalidationState.currentObject() == this); | 1366 ASSERT(&paintInvalidationState.currentObject() == this); |
| 1343 | 1367 |
| 1344 if (styleRef().hasOutline()) { | 1368 if (styleRef().hasOutline()) { |
| 1345 PaintLayer& layer = paintInvalidationState.paintingLayer(); | 1369 PaintLayer& layer = paintInvalidationState.paintingLayer(); |
| 1346 if (layer.layoutObject() != this) | 1370 if (layer.layoutObject() != this) |
| 1347 layer.setNeedsPaintPhaseDescendantOutlines(); | 1371 layer.setNeedsPaintPhaseDescendantOutlines(); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1392 invalidationReason = PaintInvalidationBackgroundObscurationChange; | 1416 invalidationReason = PaintInvalidationBackgroundObscurationChange; |
| 1393 m_bitfields.setLastBoxDecorationBackgroundObscured(boxDecorationBackgroundOb
scured); | 1417 m_bitfields.setLastBoxDecorationBackgroundObscured(boxDecorationBackgroundOb
scured); |
| 1394 | 1418 |
| 1395 if (invalidationReason == PaintInvalidationNone) { | 1419 if (invalidationReason == PaintInvalidationNone) { |
| 1396 // TODO(trchen): Currently we don't keep track of paint offset of layout
objects. | 1420 // TODO(trchen): Currently we don't keep track of paint offset of layout
objects. |
| 1397 // There are corner cases that the display items need to be invalidated
for paint offset | 1421 // There are corner cases that the display items need to be invalidated
for paint offset |
| 1398 // mutation, but incurs no pixel difference (i.e. bounds stay the same)
so no rect-based | 1422 // mutation, but incurs no pixel difference (i.e. bounds stay the same)
so no rect-based |
| 1399 // invalidation is issued. See crbug.com/508383 and crbug.com/515977. | 1423 // invalidation is issued. See crbug.com/508383 and crbug.com/515977. |
| 1400 // This is a workaround to force display items to update paint offset. | 1424 // This is a workaround to force display items to update paint offset. |
| 1401 if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && paint
InvalidationState.forcedSubtreeInvalidationCheckingWithinContainer()) | 1425 if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && paint
InvalidationState.forcedSubtreeInvalidationCheckingWithinContainer()) |
| 1402 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalida
tionState, PaintInvalidationLocationChange); | 1426 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalida
tionState, invalidationReason); |
| 1403 | 1427 |
| 1404 return invalidationReason; | 1428 return invalidationReason; |
| 1405 } | 1429 } |
| 1406 | 1430 |
| 1407 if (invalidationReason == PaintInvalidationIncremental) | 1431 if (invalidationReason == PaintInvalidationIncremental) |
| 1408 incrementallyInvalidatePaint(paintInvalidationContainer, oldBounds, newB
ounds, newLocation); | 1432 incrementallyInvalidatePaint(paintInvalidationContainer, oldBounds, newB
ounds, newLocation); |
| 1409 else | 1433 else |
| 1410 fullyInvalidatePaint(paintInvalidationContainer, invalidationReason, old
Bounds, newBounds); | 1434 fullyInvalidatePaint(paintInvalidationContainer, invalidationReason, old
Bounds, newBounds); |
| 1411 | 1435 |
| 1412 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationStat
e, invalidationReason); | 1436 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationStat
e, invalidationReason); |
| 1413 return invalidationReason; | 1437 return invalidationReason; |
| 1414 } | 1438 } |
| 1415 | 1439 |
| 1416 PaintInvalidationReason LayoutObject::getPaintInvalidationReason(const PaintInva
lidationState& paintInvalidationState, | 1440 PaintInvalidationReason LayoutObject::getPaintInvalidationReason(const PaintInva
lidationState& paintInvalidationState, |
| 1417 const LayoutRect& oldBounds, const LayoutPoint& oldPositionFromPaintInvalida
tionBacking, | 1441 const LayoutRect& oldBounds, const LayoutPoint& oldPositionFromPaintInvalida
tionBacking, |
| 1418 const LayoutRect& newBounds, const LayoutPoint& newPositionFromPaintInvalida
tionBacking) const | 1442 const LayoutRect& newBounds, const LayoutPoint& newPositionFromPaintInvalida
tionBacking) const |
| 1419 { | 1443 { |
| 1420 if (paintInvalidationState.forcedSubtreeFullInvalidationWithinContainer()) | 1444 if (paintInvalidationState.forcedSubtreeFullInvalidationWithinContainer()) |
| 1421 return PaintInvalidationSubtree; | 1445 return PaintInvalidationSubtree; |
| 1422 | 1446 |
| 1423 if (shouldDoFullPaintInvalidation()) | 1447 if (shouldDoFullPaintInvalidation()) |
| 1424 return m_bitfields.fullPaintInvalidationReason(); | 1448 return m_bitfields.fullPaintInvalidationReason(); |
| 1425 | 1449 |
| 1426 if (paintedOutputOfObjectHasNoEffect()) | |
| 1427 return PaintInvalidationNone; | |
| 1428 | |
| 1429 // The outline may change shape because of position change of descendants. F
or simplicity, | 1450 // The outline may change shape because of position change of descendants. F
or simplicity, |
| 1430 // just force full paint invalidation if this object is marked for checking
paint invalidation | 1451 // just force full paint invalidation if this object is marked for checking
paint invalidation |
| 1431 // for any reason. | 1452 // for any reason. |
| 1432 if (styleRef().hasOutline()) | 1453 if (styleRef().hasOutline()) |
| 1433 return PaintInvalidationOutline; | 1454 return PaintInvalidationOutline; |
| 1434 | 1455 |
| 1435 bool locationChanged = newPositionFromPaintInvalidationBacking != oldPositio
nFromPaintInvalidationBacking; | 1456 bool locationChanged = newPositionFromPaintInvalidationBacking != oldPositio
nFromPaintInvalidationBacking; |
| 1436 | 1457 |
| 1437 // If the bounds are the same then we know that none of the statements below | 1458 // If the bounds are the same then we know that none of the statements below |
| 1438 // can match, so we can early out. | 1459 // can match, so we can early out. |
| 1439 if (oldBounds == newBounds) | 1460 if (oldBounds == newBounds) |
| 1440 return locationChanged && !oldBounds.isEmpty() ? PaintInvalidationLocati
onChange : PaintInvalidationNone; | 1461 return locationChanged && !oldBounds.isEmpty() ? PaintInvalidationLocati
onChange : PaintInvalidationNone; |
| 1441 | 1462 |
| 1442 // If we shifted, we don't know the exact reason so we are conservative and
trigger a full invalidation. Shifting could | 1463 // If we shifted, we don't know the exact reason so we are conservative and
trigger a full invalidation. Shifting could |
| 1443 // be caused by some layout property (left / top) or some in-flow layoutObje
ct inserted / removed before us in the tree. | 1464 // be caused by some layout property (left / top) or some in-flow layoutObje
ct inserted / removed before us in the tree. |
| 1444 if (newBounds.location() != oldBounds.location()) | 1465 if (newBounds.location() != oldBounds.location()) |
| 1445 return PaintInvalidationBoundsChange; | 1466 return PaintInvalidationBoundsChange; |
| 1446 | 1467 |
| 1468 // This covers the case where we mark containing blocks for layout |
| 1469 // and they change size but don't have anything to paint. This is |
| 1470 // a pretty common case for <body> as we add / remove children |
| 1471 // (and the default background is done by FrameView). |
| 1472 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && skipInvalidationWhe
nLaidOutChildren()) |
| 1473 return PaintInvalidationNone; |
| 1474 |
| 1447 // If the size is zero on one of our bounds then we know we're going to have | 1475 // If the size is zero on one of our bounds then we know we're going to have |
| 1448 // to do a full invalidation of either old bounds or new bounds. If we fall | 1476 // to do a full invalidation of either old bounds or new bounds. If we fall |
| 1449 // into the incremental invalidation we'll issue two invalidations instead | 1477 // into the incremental invalidation we'll issue two invalidations instead |
| 1450 // of one. | 1478 // of one. |
| 1451 if (oldBounds.isEmpty()) | 1479 if (oldBounds.isEmpty()) |
| 1452 return PaintInvalidationBecameVisible; | 1480 return PaintInvalidationBecameVisible; |
| 1453 if (newBounds.isEmpty()) | 1481 if (newBounds.isEmpty()) |
| 1454 return PaintInvalidationBecameInvisible; | 1482 return PaintInvalidationBecameInvisible; |
| 1455 | 1483 |
| 1456 if (locationChanged) | 1484 if (locationChanged) |
| (...skipping 1966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3423 setMayNeedPaintInvalidation(); | 3451 setMayNeedPaintInvalidation(); |
| 3424 } | 3452 } |
| 3425 | 3453 |
| 3426 void LayoutObject::clearPaintInvalidationFlags(const PaintInvalidationState& pai
ntInvalidationState) | 3454 void LayoutObject::clearPaintInvalidationFlags(const PaintInvalidationState& pai
ntInvalidationState) |
| 3427 { | 3455 { |
| 3428 // paintInvalidationStateIsDirty should be kept in sync with the | 3456 // paintInvalidationStateIsDirty should be kept in sync with the |
| 3429 // booleans that are cleared below. | 3457 // booleans that are cleared below. |
| 3430 ASSERT(!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()
|| paintInvalidationStateIsDirty()); | 3458 ASSERT(!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()
|| paintInvalidationStateIsDirty()); |
| 3431 clearShouldDoFullPaintInvalidation(); | 3459 clearShouldDoFullPaintInvalidation(); |
| 3432 m_bitfields.setChildShouldCheckForPaintInvalidation(false); | 3460 m_bitfields.setChildShouldCheckForPaintInvalidation(false); |
| 3461 m_bitfields.setNeededLayoutBecauseOfChildren(false); |
| 3433 m_bitfields.setMayNeedPaintInvalidation(false); | 3462 m_bitfields.setMayNeedPaintInvalidation(false); |
| 3434 m_bitfields.setMayNeedPaintInvalidationSubtree(false); | 3463 m_bitfields.setMayNeedPaintInvalidationSubtree(false); |
| 3435 m_bitfields.setShouldInvalidateSelection(false); | 3464 m_bitfields.setShouldInvalidateSelection(false); |
| 3436 } | 3465 } |
| 3437 | 3466 |
| 3438 bool LayoutObject::isAllowedToModifyLayoutTreeStructure(Document& document) | 3467 bool LayoutObject::isAllowedToModifyLayoutTreeStructure(Document& document) |
| 3439 { | 3468 { |
| 3440 return DeprecatedDisableModifyLayoutTreeStructureAsserts::canModifyLayoutTre
eStateInAnyState() | 3469 return DeprecatedDisableModifyLayoutTreeStructureAsserts::canModifyLayoutTre
eStateInAnyState() |
| 3441 || document.lifecycle().stateAllowsLayoutTreeMutations(); | 3470 || document.lifecycle().stateAllowsLayoutTreeMutations(); |
| 3442 } | 3471 } |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3645 const blink::LayoutObject* root = object1; | 3674 const blink::LayoutObject* root = object1; |
| 3646 while (root->parent()) | 3675 while (root->parent()) |
| 3647 root = root->parent(); | 3676 root = root->parent(); |
| 3648 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); | 3677 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); |
| 3649 } else { | 3678 } else { |
| 3650 WTFLogAlways("%s", "Cannot showLayoutTree. Root is (nil)"); | 3679 WTFLogAlways("%s", "Cannot showLayoutTree. Root is (nil)"); |
| 3651 } | 3680 } |
| 3652 } | 3681 } |
| 3653 | 3682 |
| 3654 #endif | 3683 #endif |
| OLD | NEW |