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 3280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3291 return gModifyLayoutTreeStructureAnyState; | 3291 return gModifyLayoutTreeStructureAnyState; |
| 3292 } | 3292 } |
| 3293 | 3293 |
| 3294 DisablePaintInvalidationStateAsserts::DisablePaintInvalidationStateAsserts() | 3294 DisablePaintInvalidationStateAsserts::DisablePaintInvalidationStateAsserts() |
| 3295 : m_disabler(gDisablePaintInvalidationStateAsserts, true) | 3295 : m_disabler(gDisablePaintInvalidationStateAsserts, true) |
| 3296 { | 3296 { |
| 3297 } | 3297 } |
| 3298 | 3298 |
| 3299 namespace { | 3299 namespace { |
| 3300 | 3300 |
| 3301 // TODO(trchen): Use std::function<void, LayoutObject&> and lambda when availabl e. | 3301 // TODO(trchen): Use std::function<void, LayoutObject&> when available. |
| 3302 class LayoutObjectTraversalFunctor { | 3302 template <typename LayoutObjectTraversalFunctor> |
| 3303 public: | |
| 3304 virtual void operator()(LayoutObject&) const = 0; | |
| 3305 }; | |
| 3306 | |
| 3307 void traverseNonCompositingDescendants(LayoutObject&, const LayoutObjectTraversa lFunctor&); | 3303 void traverseNonCompositingDescendants(LayoutObject&, const LayoutObjectTraversa lFunctor&); |
| 3308 | 3304 |
| 3305 template <typename LayoutObjectTraversalFunctor> | |
| 3309 void findNonCompositedDescendantLayerToTraverse(LayoutObject& object, const Layo utObjectTraversalFunctor& functor) | 3306 void findNonCompositedDescendantLayerToTraverse(LayoutObject& object, const Layo utObjectTraversalFunctor& functor) |
| 3310 { | 3307 { |
| 3311 LayoutObject* descendant = object.nextInPreOrder(&object); | 3308 LayoutObject* descendant = object.nextInPreOrder(&object); |
| 3312 while (descendant) { | 3309 while (descendant) { |
| 3313 // Case 1: If the descendant has no layer, keep searching until we find a layer. | 3310 // Case 1: If the descendant has no layer, keep searching until we find a layer. |
| 3314 if (!descendant->hasLayer()) { | 3311 if (!descendant->hasLayer()) { |
| 3315 descendant = descendant->nextInPreOrder(&object); | 3312 descendant = descendant->nextInPreOrder(&object); |
| 3316 continue; | 3313 continue; |
| 3317 } | 3314 } |
| 3318 // Case 2: The descendant has a layer and is not composited. | 3315 // Case 2: The descendant has a layer and is not composited. |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 3329 if (descendant->styleRef().isStackingContext()) { | 3326 if (descendant->styleRef().isStackingContext()) { |
| 3330 descendant = descendant->nextInPreOrderAfterChildren(&object); | 3327 descendant = descendant->nextInPreOrderAfterChildren(&object); |
| 3331 continue; | 3328 continue; |
| 3332 } | 3329 } |
| 3333 // Case 4: The descendant is an invalidation container but not a stackin g context. | 3330 // Case 4: The descendant is an invalidation container but not a stackin g context. |
| 3334 // This is the same situation as the root, thus keep searching. | 3331 // This is the same situation as the root, thus keep searching. |
| 3335 descendant = descendant->nextInPreOrder(&object); | 3332 descendant = descendant->nextInPreOrder(&object); |
| 3336 } | 3333 } |
| 3337 } | 3334 } |
| 3338 | 3335 |
| 3336 template <typename LayoutObjectTraversalFunctor> | |
| 3339 void traverseNonCompositingDescendants(LayoutObject& object, const LayoutObjectT raversalFunctor& functor) | 3337 void traverseNonCompositingDescendants(LayoutObject& object, const LayoutObjectT raversalFunctor& functor) |
| 3340 { | 3338 { |
| 3341 functor(object); | 3339 functor(object); |
| 3342 LayoutObject* descendant = object.nextInPreOrder(&object); | 3340 LayoutObject* descendant = object.nextInPreOrder(&object); |
| 3343 while (descendant) { | 3341 while (descendant) { |
| 3344 if (!descendant->isPaintInvalidationContainer()) { | 3342 if (!descendant->isPaintInvalidationContainer()) { |
| 3345 functor(*descendant); | 3343 functor(*descendant); |
| 3346 descendant = descendant->nextInPreOrder(&object); | 3344 descendant = descendant->nextInPreOrder(&object); |
| 3347 continue; | 3345 continue; |
| 3348 } | 3346 } |
| 3349 if (descendant->styleRef().isStackingContext()) { | 3347 if (descendant->styleRef().isStackingContext()) { |
| 3350 descendant = descendant->nextInPreOrderAfterChildren(&object); | 3348 descendant = descendant->nextInPreOrderAfterChildren(&object); |
| 3351 continue; | 3349 continue; |
| 3352 } | 3350 } |
| 3353 | 3351 |
| 3354 // If a paint invalidation container is not a stacking context, | 3352 // If a paint invalidation container is not a stacking context, |
| 3355 // some of its descendants may belong to the parent container. | 3353 // some of its descendants may belong to the parent container. |
| 3356 findNonCompositedDescendantLayerToTraverse(*descendant, functor); | 3354 findNonCompositedDescendantLayerToTraverse(*descendant, functor); |
| 3357 descendant = descendant->nextInPreOrderAfterChildren(&object); | 3355 descendant = descendant->nextInPreOrderAfterChildren(&object); |
| 3358 } | 3356 } |
| 3359 } | 3357 } |
| 3360 | 3358 |
| 3361 } // unnamed namespace | 3359 } // unnamed namespace |
| 3362 | 3360 |
| 3363 void LayoutObject::invalidateDisplayItemClientForNonCompositingDescendantsOf(con st LayoutObject& object) const | 3361 void LayoutObject::invalidateDisplayItemClientsIncludingNonCompositingDescendant s(const LayoutBoxModelObject* paintInvalidationContainer, PaintInvalidationReaso n paintInvalidationReason, const LayoutRect* paintInvalidationRect) const |
| 3364 { | 3362 { |
| 3365 // Not using enclosingCompositedContainer() directly because this object may be in an orphaned subtree. | |
| 3366 PaintLayer* enclosingLayer = this->enclosingLayer(); | |
| 3367 if (!enclosingLayer) | |
| 3368 return; | |
| 3369 | |
| 3370 // TODO(wangxianzhu): This is a workaround for invalidation of detached cust om scrollbar parts which can't find | |
| 3371 // their own enclosing layers. May remove this when fixing crbug.com/547119 for scrollbars. | |
| 3372 enclosingLayer->setNeedsRepaint(); | |
| 3373 | |
| 3374 // This is valid because we want to invalidate the client in the display ite m list of the current backing. | 3363 // This is valid because we want to invalidate the client in the display ite m list of the current backing. |
| 3375 DisableCompositingQueryAsserts disabler; | 3364 DisableCompositingQueryAsserts disabler; |
| 3376 const PaintLayer* paintInvalidationLayer = enclosingLayer->enclosingLayerFor PaintInvalidationCrossingFrameBoundaries(); | 3365 if (!paintInvalidationContainer) { |
| 3377 if (!paintInvalidationLayer) | 3366 // Not using enclosingCompositedContainer() directly because this object may be in an orphaned subtree. |
| 3378 return; | 3367 PaintLayer* enclosingLayer = this->enclosingLayer(); |
| 3368 if (!enclosingLayer) | |
| 3369 return; | |
| 3370 const PaintLayer* paintInvalidationLayer = enclosingLayer->enclosingLaye rForPaintInvalidationCrossingFrameBoundaries(); | |
| 3371 if (!paintInvalidationLayer) | |
| 3372 return; | |
| 3373 paintInvalidationContainer = paintInvalidationLayer->layoutObject(); | |
| 3374 } | |
| 3379 | 3375 |
| 3380 class Functor : public LayoutObjectTraversalFunctor { | 3376 traverseNonCompositingDescendants(const_cast<LayoutObject&>(*this), [&paintI nvalidationContainer, paintInvalidationReason, paintInvalidationRect](LayoutObje ct& object) { |
| 3381 public: | 3377 object.invalidateDisplayItemClients(*paintInvalidationContainer, paintIn validationReason, paintInvalidationRect); |
| 3382 explicit Functor(const LayoutBoxModelObject& paintInvalidationContainer) : m_paintInvalidationContainer(paintInvalidationContainer) { } | 3378 }); |
| 3383 void operator()(LayoutObject& object) const override | |
| 3384 { | |
| 3385 // TODO(wangxianzhu): Ensure correct bounds for the client will be o r has been passed to PaintController. crbug.com/547119. | |
| 3386 object.invalidateDisplayItemClients(m_paintInvalidationContainer, Pa intInvalidationFull, nullptr); | |
| 3387 } | |
| 3388 private: | |
| 3389 const LayoutBoxModelObject& m_paintInvalidationContainer; | |
| 3390 }; | |
| 3391 | |
| 3392 const LayoutBoxModelObject& paintInvalidationContainer = *paintInvalidationL ayer->layoutObject(); | |
| 3393 traverseNonCompositingDescendants(const_cast<LayoutObject&>(object), Functor (paintInvalidationContainer)); | |
| 3394 } | 3379 } |
| 3395 | 3380 |
| 3396 void LayoutObject::invalidatePaintOfPreviousPaintInvalidationRect(const LayoutBo xModelObject& paintInvalidationContainer, PaintInvalidationReason reason) | 3381 void LayoutObject::invalidatePaintOfPreviousPaintInvalidationRect(const LayoutBo xModelObject& paintInvalidationContainer, PaintInvalidationReason reason) |
| 3397 { | 3382 { |
| 3398 // These disablers are valid because we want to use the current compositing/ invalidation status. | 3383 // These disablers are valid because we want to use the current compositing/ invalidation status. |
| 3399 DisablePaintInvalidationStateAsserts invalidationDisabler; | 3384 DisablePaintInvalidationStateAsserts invalidationDisabler; |
| 3400 DisableCompositingQueryAsserts compositingDisabler; | 3385 DisableCompositingQueryAsserts compositingDisabler; |
| 3401 | 3386 |
| 3402 LayoutRect invalidationRect = previousPaintInvalidationRect(); | 3387 LayoutRect invalidationRect = previousPaintInvalidationRect(); |
| 3403 adjustInvalidationRectForCompositedScrolling(invalidationRect, paintInvalida tionContainer); | 3388 adjustInvalidationRectForCompositedScrolling(invalidationRect, paintInvalida tionContainer); |
| 3404 invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect, PaintInvalidationLayer); | 3389 invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect, PaintInvalidationLayer); |
| 3405 | 3390 |
| 3406 // The PaintController may have changed. Pass the previous paint invalidatio n rect to the new PaintController. | 3391 // The PaintController may have changed. Pass the previous paint invalidatio n rect to the new PaintController. |
| 3407 // The rect will be updated if it changes during the next paint invalidation . | 3392 // The rect will be updated if it changes during the next paint invalidation . |
| 3408 invalidateDisplayItemClients(paintInvalidationContainer, PaintInvalidationLa yer, &invalidationRect); | 3393 invalidateDisplayItemClients(paintInvalidationContainer, PaintInvalidationLa yer, &invalidationRect); |
| 3409 | 3394 |
| 3410 // This method may be used to invalidate paint of an object changing paint i nvalidation container. | 3395 // This method may be used to invalidate paint of an object changing paint i nvalidation container. |
| 3411 // Clear previous paint invalidation rect on the original paint invalidation container to avoid | 3396 // Clear previous paint invalidation rect on the original paint invalidation container to avoid |
| 3412 // under-invalidation if the new paint invalidation rect on the new paint in validation container | 3397 // under-invalidation if the new paint invalidation rect on the new paint in validation container |
| 3413 // happens to be the same as the old one. | 3398 // happens to be the same as the old one. |
| 3414 setPreviousPaintInvalidationRect(LayoutRect()); | 3399 setPreviousPaintInvalidationRect(LayoutRect()); |
| 3415 } | 3400 } |
| 3416 | 3401 |
| 3417 void LayoutObject::invalidatePaintIncludingNonCompositingDescendants() | 3402 void LayoutObject::invalidatePaintIncludingNonCompositingDescendants() |
| 3418 { | 3403 { |
| 3419 class Functor : public LayoutObjectTraversalFunctor { | |
| 3420 public: | |
| 3421 explicit Functor(const LayoutBoxModelObject& paintInvalidationContainer) : m_paintInvalidationContainer(paintInvalidationContainer) { } | |
| 3422 void operator()(LayoutObject& object) const override | |
| 3423 { | |
| 3424 object.invalidatePaintOfPreviousPaintInvalidationRect(m_paintInvalid ationContainer, PaintInvalidationLayer); | |
| 3425 } | |
| 3426 private: | |
| 3427 const LayoutBoxModelObject& m_paintInvalidationContainer; | |
| 3428 }; | |
| 3429 | |
| 3430 // Since we're only painting non-composited layers, we know that they all sh are the same paintInvalidationContainer. | 3404 // Since we're only painting non-composited layers, we know that they all sh are the same paintInvalidationContainer. |
| 3431 const LayoutBoxModelObject& paintInvalidationContainer = containerForPaintIn validationOnRootedTree(); | 3405 const LayoutBoxModelObject& paintInvalidationContainer = containerForPaintIn validationOnRootedTree(); |
| 3432 traverseNonCompositingDescendants(*this, Functor(paintInvalidationContainer) ); | 3406 traverseNonCompositingDescendants(*this, [&paintInvalidationContainer](Layou tObject& object) { |
| 3407 object.invalidatePaintOfPreviousPaintInvalidationRect(paintInvalidationC ontainer, PaintInvalidationLayer); | |
| 3408 }); | |
| 3433 } | 3409 } |
| 3434 | 3410 |
| 3435 // FIXME: If we had a flag to force invalidations in a whole subtree, we could g et rid of this function (crbug.com/410097). | 3411 // FIXME: If we had a flag to force invalidations in a whole subtree, we could g et rid of this function (crbug.com/410097). |
| 3436 void LayoutObject::setShouldDoFullPaintInvalidationIncludingNonCompositingDescen dants() | 3412 void LayoutObject::setShouldDoFullPaintInvalidationIncludingNonCompositingDescen dants() |
| 3437 { | 3413 { |
| 3438 class Functor : public LayoutObjectTraversalFunctor { | |
| 3439 public: | |
| 3440 void operator()(LayoutObject& object) const override | |
| 3441 { | |
| 3442 object.setShouldDoFullPaintInvalidation(); | |
| 3443 } | |
| 3444 }; | |
| 3445 | |
| 3446 // Need to access the current compositing status. | 3414 // Need to access the current compositing status. |
| 3447 DisableCompositingQueryAsserts disabler; | 3415 DisableCompositingQueryAsserts disabler; |
|
chrishtr
2015/11/17 01:34:20
This is still necessary for some other use case?
Xianzhu
2015/11/17 18:31:36
Yes. Most of the callers calls this before composi
| |
| 3448 traverseNonCompositingDescendants(*this, Functor()); | 3416 traverseNonCompositingDescendants(*this, [](LayoutObject& object) { |
| 3417 object.setShouldDoFullPaintInvalidation(); | |
| 3418 }); | |
| 3449 } | 3419 } |
| 3450 | 3420 |
| 3451 void LayoutObject::invalidatePaintIncludingNonSelfPaintingLayerDescendants(const LayoutBoxModelObject& paintInvalidationContainer) | 3421 void LayoutObject::invalidatePaintIncludingNonSelfPaintingLayerDescendants(const LayoutBoxModelObject& paintInvalidationContainer) |
| 3452 { | 3422 { |
| 3453 invalidatePaintOfPreviousPaintInvalidationRect(paintInvalidationContainer, P aintInvalidationLayer); | 3423 invalidatePaintOfPreviousPaintInvalidationRect(paintInvalidationContainer, P aintInvalidationLayer); |
| 3454 for (LayoutObject* child = slowFirstChild(); child; child = child->nextSibli ng()) { | 3424 for (LayoutObject* child = slowFirstChild(); child; child = child->nextSibli ng()) { |
| 3455 if (!child->hasLayer() || !toLayoutBoxModelObject(child)->layer()->isSel fPaintingLayer()) | 3425 if (!child->hasLayer() || !toLayoutBoxModelObject(child)->layer()->isSel fPaintingLayer()) |
| 3456 child->invalidatePaintIncludingNonSelfPaintingLayerDescendants(paint InvalidationContainer); | 3426 child->invalidatePaintIncludingNonSelfPaintingLayerDescendants(paint InvalidationContainer); |
| 3457 } | 3427 } |
| 3458 } | 3428 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3518 const blink::LayoutObject* root = object1; | 3488 const blink::LayoutObject* root = object1; |
| 3519 while (root->parent()) | 3489 while (root->parent()) |
| 3520 root = root->parent(); | 3490 root = root->parent(); |
| 3521 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); | 3491 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); |
| 3522 } else { | 3492 } else { |
| 3523 fprintf(stderr, "Cannot showLayoutTree. Root is (nil)\n"); | 3493 fprintf(stderr, "Cannot showLayoutTree. Root is (nil)\n"); |
| 3524 } | 3494 } |
| 3525 } | 3495 } |
| 3526 | 3496 |
| 3527 #endif | 3497 #endif |
| OLD | NEW |