Chromium Code Reviews| 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; | |
|
Xianzhu
2016/08/03 19:56:36
The "isLayoutBlockFlow() && toLayoutBlockFlow(this
| |
| 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 | |
| 709 static inline bool objectIsRelayoutBoundary(const LayoutObject* object) | 687 static inline bool objectIsRelayoutBoundary(const LayoutObject* object) |
| 710 { | 688 { |
| 711 // FIXME: In future it may be possible to broaden these conditions in order to improve performance. | 689 // FIXME: In future it may be possible to broaden these conditions in order to improve performance. |
| 712 if (object->isTextControl()) | 690 if (object->isTextControl()) |
| 713 return true; | 691 return true; |
| 714 | 692 |
| 715 if (object->isSVGRoot()) | 693 if (object->isSVGRoot()) |
| 716 return true; | 694 return true; |
| 717 | 695 |
| 718 // Table parts can't be relayout roots since the table is responsible for la youting all the parts. | 696 // 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... | |
| 1323 return; | 1301 return; |
| 1324 selectionPaintInvalidationMap = new SelectionPaintInvalidationMap(); | 1302 selectionPaintInvalidationMap = new SelectionPaintInvalidationMap(); |
| 1325 } | 1303 } |
| 1326 | 1304 |
| 1327 if (selectionRect.isEmpty()) | 1305 if (selectionRect.isEmpty()) |
| 1328 selectionPaintInvalidationMap->remove(this); | 1306 selectionPaintInvalidationMap->remove(this); |
| 1329 else | 1307 else |
| 1330 selectionPaintInvalidationMap->set(this, selectionRect); | 1308 selectionPaintInvalidationMap->set(this, selectionRect); |
| 1331 } | 1309 } |
| 1332 | 1310 |
| 1333 // TODO(wangxianzhu): Remove this for slimming paint v2 because we won't care ab out paint invalidation rects. | |
| 1334 inline void LayoutObject::invalidateSelectionIfNeeded(const LayoutBoxModelObject & paintInvalidationContainer, const PaintInvalidationState& paintInvalidationSta te, PaintInvalidationReason invalidationReason) | 1311 inline void LayoutObject::invalidateSelectionIfNeeded(const LayoutBoxModelObject & paintInvalidationContainer, const PaintInvalidationState& paintInvalidationSta te, PaintInvalidationReason invalidationReason) |
| 1335 { | 1312 { |
| 1336 // Update selection rect when we are doing full invalidation (in case that t he object is moved, composite status changed, etc.) | 1313 // Update selection rect when we are doing full invalidation (in case that t he object is moved, composite status changed, etc.) |
| 1337 // or shouldInvalidationSelection is set (in case that the selection itself changed). | 1314 // or shouldInvalidationSelection is set (in case that the selection itself changed). |
| 1338 bool fullInvalidation = isFullPaintInvalidationReason(invalidationReason); | 1315 bool fullInvalidation = isFullPaintInvalidationReason(invalidationReason); |
| 1339 if (!fullInvalidation && !shouldInvalidateSelection()) | 1316 if (!fullInvalidation && !shouldInvalidateSelection()) |
| 1340 return; | 1317 return; |
| 1341 | 1318 |
| 1342 LayoutRect oldSelectionRect = previousSelectionRectForPaintInvalidation(); | 1319 LayoutRect oldSelectionRect = previousSelectionRectForPaintInvalidation(); |
| 1343 LayoutRect newSelectionRect = localSelectionRect(); | 1320 LayoutRect newSelectionRect = localSelectionRect(); |
| 1344 if (!newSelectionRect.isEmpty()) { | 1321 if (!newSelectionRect.isEmpty()) { |
| 1345 paintInvalidationState.mapLocalRectToPaintInvalidationBacking(newSelecti onRect); | 1322 paintInvalidationState.mapLocalRectToPaintInvalidationBacking(newSelecti onRect); |
| 1346 | 1323 |
| 1347 // Composited scrolling should not be included in the bounds and positio n tracking, because the graphics layer backing the scroller | 1324 // Composited scrolling should not be included in the bounds and positio n tracking, because the graphics layer backing the scroller |
| 1348 // does not move on scroll. | 1325 // does not move on scroll. |
| 1349 if (compositedScrollsWithRespectTo(paintInvalidationContainer)) { | 1326 if (compositedScrollsWithRespectTo(paintInvalidationContainer)) { |
| 1350 LayoutSize inverseOffset(toLayoutBox(&paintInvalidationContainer)->s crolledContentOffset()); | 1327 LayoutSize inverseOffset(toLayoutBox(&paintInvalidationContainer)->s crolledContentOffset()); |
| 1351 newSelectionRect.move(inverseOffset); | 1328 newSelectionRect.move(inverseOffset); |
| 1352 } | 1329 } |
| 1353 } | 1330 } |
| 1354 | 1331 |
| 1355 setPreviousSelectionRectForPaintInvalidation(newSelectionRect); | 1332 setPreviousSelectionRectForPaintInvalidation(newSelectionRect); |
| 1356 | 1333 |
| 1357 // TODO(wangxianzhu): Combine the following two conditions when removing Lay outView::doingFullPaintInvalidation(). | 1334 if (!fullInvalidation) { |
| 1358 if (!fullInvalidation) | |
| 1359 fullyInvalidatePaint(paintInvalidationContainer, PaintInvalidationSelect ion, oldSelectionRect, newSelectionRect); | 1335 fullyInvalidatePaint(paintInvalidationContainer, PaintInvalidationSelect ion, oldSelectionRect, newSelectionRect); |
| 1360 if (shouldInvalidateSelection()) | |
| 1361 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidation State, PaintInvalidationSelection); | 1336 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidation State, PaintInvalidationSelection); |
| 1337 } | |
| 1362 } | 1338 } |
| 1363 | 1339 |
| 1364 PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded(const PaintInvalid ationState& paintInvalidationState) | 1340 PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded(const PaintInvalid ationState& paintInvalidationState) |
| 1365 { | 1341 { |
| 1366 ASSERT(&paintInvalidationState.currentObject() == this); | 1342 ASSERT(&paintInvalidationState.currentObject() == this); |
| 1367 | 1343 |
| 1368 if (styleRef().hasOutline()) { | 1344 if (styleRef().hasOutline()) { |
| 1369 PaintLayer& layer = paintInvalidationState.paintingLayer(); | 1345 PaintLayer& layer = paintInvalidationState.paintingLayer(); |
| 1370 if (layer.layoutObject() != this) | 1346 if (layer.layoutObject() != this) |
| 1371 layer.setNeedsPaintPhaseDescendantOutlines(); | 1347 layer.setNeedsPaintPhaseDescendantOutlines(); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1416 invalidationReason = PaintInvalidationBackgroundObscurationChange; | 1392 invalidationReason = PaintInvalidationBackgroundObscurationChange; |
| 1417 m_bitfields.setLastBoxDecorationBackgroundObscured(boxDecorationBackgroundOb scured); | 1393 m_bitfields.setLastBoxDecorationBackgroundObscured(boxDecorationBackgroundOb scured); |
| 1418 | 1394 |
| 1419 if (invalidationReason == PaintInvalidationNone) { | 1395 if (invalidationReason == PaintInvalidationNone) { |
| 1420 // TODO(trchen): Currently we don't keep track of paint offset of layout objects. | 1396 // TODO(trchen): Currently we don't keep track of paint offset of layout objects. |
| 1421 // There are corner cases that the display items need to be invalidated for paint offset | 1397 // There are corner cases that the display items need to be invalidated for paint offset |
| 1422 // mutation, but incurs no pixel difference (i.e. bounds stay the same) so no rect-based | 1398 // mutation, but incurs no pixel difference (i.e. bounds stay the same) so no rect-based |
| 1423 // invalidation is issued. See crbug.com/508383 and crbug.com/515977. | 1399 // invalidation is issued. See crbug.com/508383 and crbug.com/515977. |
| 1424 // This is a workaround to force display items to update paint offset. | 1400 // This is a workaround to force display items to update paint offset. |
| 1425 if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && paint InvalidationState.forcedSubtreeInvalidationCheckingWithinContainer()) | 1401 if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && paint InvalidationState.forcedSubtreeInvalidationCheckingWithinContainer()) |
| 1426 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalida tionState, invalidationReason); | 1402 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalida tionState, PaintInvalidationLocationChange); |
| 1427 | 1403 |
| 1428 return invalidationReason; | 1404 return invalidationReason; |
| 1429 } | 1405 } |
| 1430 | 1406 |
| 1431 if (invalidationReason == PaintInvalidationIncremental) | 1407 if (invalidationReason == PaintInvalidationIncremental) |
| 1432 incrementallyInvalidatePaint(paintInvalidationContainer, oldBounds, newB ounds, newLocation); | 1408 incrementallyInvalidatePaint(paintInvalidationContainer, oldBounds, newB ounds, newLocation); |
| 1433 else | 1409 else |
| 1434 fullyInvalidatePaint(paintInvalidationContainer, invalidationReason, old Bounds, newBounds); | 1410 fullyInvalidatePaint(paintInvalidationContainer, invalidationReason, old Bounds, newBounds); |
| 1435 | 1411 |
| 1436 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationStat e, invalidationReason); | 1412 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationStat e, invalidationReason); |
| 1437 return invalidationReason; | 1413 return invalidationReason; |
| 1438 } | 1414 } |
| 1439 | 1415 |
| 1440 PaintInvalidationReason LayoutObject::getPaintInvalidationReason(const PaintInva lidationState& paintInvalidationState, | 1416 PaintInvalidationReason LayoutObject::getPaintInvalidationReason(const PaintInva lidationState& paintInvalidationState, |
| 1441 const LayoutRect& oldBounds, const LayoutPoint& oldPositionFromPaintInvalida tionBacking, | 1417 const LayoutRect& oldBounds, const LayoutPoint& oldPositionFromPaintInvalida tionBacking, |
| 1442 const LayoutRect& newBounds, const LayoutPoint& newPositionFromPaintInvalida tionBacking) const | 1418 const LayoutRect& newBounds, const LayoutPoint& newPositionFromPaintInvalida tionBacking) const |
| 1443 { | 1419 { |
| 1444 if (paintInvalidationState.forcedSubtreeFullInvalidationWithinContainer()) | 1420 if (paintInvalidationState.forcedSubtreeFullInvalidationWithinContainer()) |
| 1445 return PaintInvalidationSubtree; | 1421 return PaintInvalidationSubtree; |
| 1446 | 1422 |
| 1447 if (shouldDoFullPaintInvalidation()) | 1423 if (shouldDoFullPaintInvalidation()) |
| 1448 return m_bitfields.fullPaintInvalidationReason(); | 1424 return m_bitfields.fullPaintInvalidationReason(); |
| 1449 | 1425 |
| 1426 if (canSkipUnforcedPaintInvalidation()) | |
|
chrishtr
2016/08/03 20:33:51
What is the main use case of this optimization? Is
Xianzhu
2016/08/03 21:30:35
It avoids invalidation if the geometry change affe
chrishtr
2016/08/03 21:34:56
How about restricting the optimization to the body
Xianzhu
2016/08/03 22:09:02
This optimization also reduces unnecessary rasteri
| |
| 1427 return PaintInvalidationNone; | |
| 1428 | |
| 1450 // The outline may change shape because of position change of descendants. F or simplicity, | 1429 // The outline may change shape because of position change of descendants. F or simplicity, |
| 1451 // just force full paint invalidation if this object is marked for checking paint invalidation | 1430 // just force full paint invalidation if this object is marked for checking paint invalidation |
| 1452 // for any reason. | 1431 // for any reason. |
| 1453 if (styleRef().hasOutline()) | 1432 if (styleRef().hasOutline()) |
| 1454 return PaintInvalidationOutline; | 1433 return PaintInvalidationOutline; |
| 1455 | 1434 |
| 1456 bool locationChanged = newPositionFromPaintInvalidationBacking != oldPositio nFromPaintInvalidationBacking; | 1435 bool locationChanged = newPositionFromPaintInvalidationBacking != oldPositio nFromPaintInvalidationBacking; |
| 1457 | 1436 |
| 1458 // If the bounds are the same then we know that none of the statements below | 1437 // If the bounds are the same then we know that none of the statements below |
| 1459 // can match, so we can early out. | 1438 // can match, so we can early out. |
| 1460 if (oldBounds == newBounds) | 1439 if (oldBounds == newBounds) |
| 1461 return locationChanged && !oldBounds.isEmpty() ? PaintInvalidationLocati onChange : PaintInvalidationNone; | 1440 return locationChanged && !oldBounds.isEmpty() ? PaintInvalidationLocati onChange : PaintInvalidationNone; |
| 1462 | 1441 |
| 1463 // If we shifted, we don't know the exact reason so we are conservative and trigger a full invalidation. Shifting could | 1442 // If we shifted, we don't know the exact reason so we are conservative and trigger a full invalidation. Shifting could |
| 1464 // be caused by some layout property (left / top) or some in-flow layoutObje ct inserted / removed before us in the tree. | 1443 // be caused by some layout property (left / top) or some in-flow layoutObje ct inserted / removed before us in the tree. |
| 1465 if (newBounds.location() != oldBounds.location()) | 1444 if (newBounds.location() != oldBounds.location()) |
| 1466 return PaintInvalidationBoundsChange; | 1445 return PaintInvalidationBoundsChange; |
| 1467 | 1446 |
| 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 | |
| 1475 // If the size is zero on one of our bounds then we know we're going to have | 1447 // If the size is zero on one of our bounds then we know we're going to have |
| 1476 // to do a full invalidation of either old bounds or new bounds. If we fall | 1448 // to do a full invalidation of either old bounds or new bounds. If we fall |
| 1477 // into the incremental invalidation we'll issue two invalidations instead | 1449 // into the incremental invalidation we'll issue two invalidations instead |
| 1478 // of one. | 1450 // of one. |
| 1479 if (oldBounds.isEmpty()) | 1451 if (oldBounds.isEmpty()) |
| 1480 return PaintInvalidationBecameVisible; | 1452 return PaintInvalidationBecameVisible; |
| 1481 if (newBounds.isEmpty()) | 1453 if (newBounds.isEmpty()) |
| 1482 return PaintInvalidationBecameInvisible; | 1454 return PaintInvalidationBecameInvisible; |
| 1483 | 1455 |
| 1484 if (locationChanged) | 1456 if (locationChanged) |
| (...skipping 1966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3451 setMayNeedPaintInvalidation(); | 3423 setMayNeedPaintInvalidation(); |
| 3452 } | 3424 } |
| 3453 | 3425 |
| 3454 void LayoutObject::clearPaintInvalidationFlags(const PaintInvalidationState& pai ntInvalidationState) | 3426 void LayoutObject::clearPaintInvalidationFlags(const PaintInvalidationState& pai ntInvalidationState) |
| 3455 { | 3427 { |
| 3456 // paintInvalidationStateIsDirty should be kept in sync with the | 3428 // paintInvalidationStateIsDirty should be kept in sync with the |
| 3457 // booleans that are cleared below. | 3429 // booleans that are cleared below. |
| 3458 ASSERT(!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() || paintInvalidationStateIsDirty()); | 3430 ASSERT(!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() || paintInvalidationStateIsDirty()); |
| 3459 clearShouldDoFullPaintInvalidation(); | 3431 clearShouldDoFullPaintInvalidation(); |
| 3460 m_bitfields.setChildShouldCheckForPaintInvalidation(false); | 3432 m_bitfields.setChildShouldCheckForPaintInvalidation(false); |
| 3461 m_bitfields.setNeededLayoutBecauseOfChildren(false); | |
| 3462 m_bitfields.setMayNeedPaintInvalidation(false); | 3433 m_bitfields.setMayNeedPaintInvalidation(false); |
| 3463 m_bitfields.setMayNeedPaintInvalidationSubtree(false); | 3434 m_bitfields.setMayNeedPaintInvalidationSubtree(false); |
| 3464 m_bitfields.setShouldInvalidateSelection(false); | 3435 m_bitfields.setShouldInvalidateSelection(false); |
| 3465 } | 3436 } |
| 3466 | 3437 |
| 3467 bool LayoutObject::isAllowedToModifyLayoutTreeStructure(Document& document) | 3438 bool LayoutObject::isAllowedToModifyLayoutTreeStructure(Document& document) |
| 3468 { | 3439 { |
| 3469 return DeprecatedDisableModifyLayoutTreeStructureAsserts::canModifyLayoutTre eStateInAnyState() | 3440 return DeprecatedDisableModifyLayoutTreeStructureAsserts::canModifyLayoutTre eStateInAnyState() |
| 3470 || document.lifecycle().stateAllowsLayoutTreeMutations(); | 3441 || document.lifecycle().stateAllowsLayoutTreeMutations(); |
| 3471 } | 3442 } |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3674 const blink::LayoutObject* root = object1; | 3645 const blink::LayoutObject* root = object1; |
| 3675 while (root->parent()) | 3646 while (root->parent()) |
| 3676 root = root->parent(); | 3647 root = root->parent(); |
| 3677 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); | 3648 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); |
| 3678 } else { | 3649 } else { |
| 3679 WTFLogAlways("%s", "Cannot showLayoutTree. Root is (nil)"); | 3650 WTFLogAlways("%s", "Cannot showLayoutTree. Root is (nil)"); |
| 3680 } | 3651 } |
| 3681 } | 3652 } |
| 3682 | 3653 |
| 3683 #endif | 3654 #endif |
| OLD | NEW |