Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2014 Google Inc. All rights reserved. | 3 * Copyright (C) 2014 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 70 | 70 |
| 71 public: | 71 public: |
| 72 OverlapMap() { | 72 OverlapMap() { |
| 73 // Begin by assuming the root layer will be composited so that there | 73 // Begin by assuming the root layer will be composited so that there |
| 74 // is something on the stack. The root layer should also never get a | 74 // is something on the stack. The root layer should also never get a |
| 75 // finishCurrentOverlapTestingContext() call. | 75 // finishCurrentOverlapTestingContext() call. |
| 76 beginNewOverlapTestingContext(); | 76 beginNewOverlapTestingContext(); |
| 77 } | 77 } |
| 78 | 78 |
| 79 void add(PaintLayer* layer, const IntRect& bounds) { | 79 void add(PaintLayer* layer, const IntRect& bounds) { |
| 80 ASSERT(!layer->isRootLayer()); | 80 DCHECK(!layer->isRootLayer()); |
| 81 if (bounds.isEmpty()) | 81 if (bounds.isEmpty()) |
| 82 return; | 82 return; |
| 83 | 83 |
| 84 // Layers do not contribute to overlap immediately--instead, they will | 84 // Layers do not contribute to overlap immediately--instead, they will |
| 85 // contribute to overlap as soon as they have been recursively processed | 85 // contribute to overlap as soon as they have been recursively processed |
| 86 // and popped off the stack. | 86 // and popped off the stack. |
| 87 ASSERT(m_overlapStack.size() >= 2); | 87 DCHECK_GE(m_overlapStack.size(), 2ul); |
| 88 m_overlapStack[m_overlapStack.size() - 2].add(bounds); | 88 m_overlapStack[m_overlapStack.size() - 2].add(bounds); |
| 89 } | 89 } |
| 90 | 90 |
| 91 bool overlapsLayers(const IntRect& bounds) const { | 91 bool overlapsLayers(const IntRect& bounds) const { |
| 92 return m_overlapStack.last().overlapsLayers(bounds); | 92 return m_overlapStack.last().overlapsLayers(bounds); |
| 93 } | 93 } |
| 94 | 94 |
| 95 void beginNewOverlapTestingContext() { | 95 void beginNewOverlapTestingContext() { |
| 96 // This effectively creates a new "clean slate" for overlap state. | 96 // This effectively creates a new "clean slate" for overlap state. |
| 97 // This is used when we know that a subtree or remaining set of | 97 // This is used when we know that a subtree or remaining set of |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 128 bool m_subtreeIsCompositing; | 128 bool m_subtreeIsCompositing; |
| 129 bool m_hasUnisolatedCompositedBlendingDescendant; | 129 bool m_hasUnisolatedCompositedBlendingDescendant; |
| 130 bool m_testingOverlap; | 130 bool m_testingOverlap; |
| 131 bool m_hasCompositedScrollingAncestor; | 131 bool m_hasCompositedScrollingAncestor; |
| 132 }; | 132 }; |
| 133 | 133 |
| 134 static bool requiresCompositingOrSquashing(CompositingReasons reasons) { | 134 static bool requiresCompositingOrSquashing(CompositingReasons reasons) { |
| 135 #if ENABLE(ASSERT) | 135 #if ENABLE(ASSERT) |
| 136 bool fastAnswer = reasons != CompositingReasonNone; | 136 bool fastAnswer = reasons != CompositingReasonNone; |
| 137 bool slowAnswer = requiresCompositing(reasons) || requiresSquashing(reasons); | 137 bool slowAnswer = requiresCompositing(reasons) || requiresSquashing(reasons); |
| 138 ASSERT(fastAnswer == slowAnswer); | 138 DCHECK_EQ(fastAnswer, slowAnswer); |
|
flackr
2016/10/06 17:23:44
nit: expected value should come first for equality
| |
| 139 #endif | 139 #endif |
| 140 return reasons != CompositingReasonNone; | 140 return reasons != CompositingReasonNone; |
| 141 } | 141 } |
| 142 | 142 |
| 143 static CompositingReasons subtreeReasonsForCompositing( | 143 static CompositingReasons subtreeReasonsForCompositing( |
| 144 PaintLayer* layer, | 144 PaintLayer* layer, |
| 145 bool hasCompositedDescendants, | 145 bool hasCompositedDescendants, |
| 146 bool has3DTransformedDescendants) { | 146 bool has3DTransformedDescendants) { |
| 147 CompositingReasons subtreeReasons = CompositingReasonNone; | 147 CompositingReasons subtreeReasons = CompositingReasonNone; |
| 148 | 148 |
| 149 // When a layer has composited descendants, some effects, like 2d transforms, | 149 // When a layer has composited descendants, some effects, like 2d transforms, |
| 150 // filters, masks etc must be implemented via compositing so that they also | 150 // filters, masks etc must be implemented via compositing so that they also |
| 151 // apply to those composited descendants. | 151 // apply to those composited descendants. |
| 152 if (hasCompositedDescendants) { | 152 if (hasCompositedDescendants) { |
| 153 subtreeReasons |= layer->potentialCompositingReasonsFromStyle() & | 153 subtreeReasons |= layer->potentialCompositingReasonsFromStyle() & |
| 154 CompositingReasonComboCompositedDescendants; | 154 CompositingReasonComboCompositedDescendants; |
| 155 | 155 |
| 156 if (layer->shouldIsolateCompositedDescendants()) { | 156 if (layer->shouldIsolateCompositedDescendants()) { |
| 157 ASSERT(layer->stackingNode()->isStackingContext()); | 157 DCHECK(layer->stackingNode()->isStackingContext()); |
| 158 subtreeReasons |= CompositingReasonIsolateCompositedDescendants; | 158 subtreeReasons |= CompositingReasonIsolateCompositedDescendants; |
| 159 } | 159 } |
| 160 | 160 |
| 161 // FIXME: This should move into | 161 // FIXME: This should move into |
| 162 // CompositingReasonFinder::potentialCompositingReasonsFromStyle, but theres | 162 // CompositingReasonFinder::potentialCompositingReasonsFromStyle, but theres |
| 163 // a poor interaction with LayoutTextControlSingleLine, which sets this | 163 // a poor interaction with LayoutTextControlSingleLine, which sets this |
| 164 // hasOverflowClip directly. | 164 // hasOverflowClip directly. |
| 165 if (layer->layoutObject()->hasClipRelatedProperty()) | 165 if (layer->layoutObject()->hasClipRelatedProperty()) |
| 166 subtreeReasons |= CompositingReasonClipsCompositingDescendants; | 166 subtreeReasons |= CompositingReasonClipsCompositingDescendants; |
| 167 | 167 |
| 168 if (layer->layoutObject()->style()->position() == FixedPosition) | 168 if (layer->layoutObject()->style()->position() == FixedPosition) |
| 169 subtreeReasons |= CompositingReasonPositionFixedWithCompositedDescendants; | 169 subtreeReasons |= CompositingReasonPositionFixedWithCompositedDescendants; |
| 170 } | 170 } |
| 171 | 171 |
| 172 // A layer with preserve-3d or perspective only needs to be composited if | 172 // A layer with preserve-3d or perspective only needs to be composited if |
| 173 // there are descendant layers that will be affected by the preserve-3d or | 173 // there are descendant layers that will be affected by the preserve-3d or |
| 174 // perspective. | 174 // perspective. |
| 175 if (has3DTransformedDescendants) | 175 if (has3DTransformedDescendants) { |
| 176 subtreeReasons |= layer->potentialCompositingReasonsFromStyle() & | 176 subtreeReasons |= layer->potentialCompositingReasonsFromStyle() & |
| 177 CompositingReasonCombo3DDescendants; | 177 CompositingReasonCombo3DDescendants; |
| 178 } | |
| 178 | 179 |
| 179 return subtreeReasons; | 180 return subtreeReasons; |
| 180 } | 181 } |
| 181 | 182 |
| 182 CompositingRequirementsUpdater::CompositingRequirementsUpdater( | 183 CompositingRequirementsUpdater::CompositingRequirementsUpdater( |
| 183 LayoutView& layoutView, | 184 LayoutView& layoutView, |
| 184 CompositingReasonFinder& compositingReasonFinder) | 185 CompositingReasonFinder& compositingReasonFinder) |
| 185 : m_layoutView(layoutView), | 186 : m_layoutView(layoutView), |
| 186 m_compositingReasonFinder(compositingReasonFinder) {} | 187 m_compositingReasonFinder(compositingReasonFinder) {} |
| 187 | 188 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 289 layer->layoutObject()) { | 290 layer->layoutObject()) { |
| 290 unclippedDescendantsToRemove.append(i); | 291 unclippedDescendantsToRemove.append(i); |
| 291 continue; | 292 continue; |
| 292 } | 293 } |
| 293 if (layer->scrollsWithRespectTo(unclippedDescendant)) | 294 if (layer->scrollsWithRespectTo(unclippedDescendant)) |
| 294 reasonsToComposite |= CompositingReasonAssumedOverlap; | 295 reasonsToComposite |= CompositingReasonAssumedOverlap; |
| 295 } | 296 } |
| 296 | 297 |
| 297 // Remove irrelevant unclipped descendants in reverse order so our stored | 298 // Remove irrelevant unclipped descendants in reverse order so our stored |
| 298 // indices remain valid. | 299 // indices remain valid. |
| 299 for (size_t i = 0; i < unclippedDescendantsToRemove.size(); i++) | 300 for (size_t i = 0; i < unclippedDescendantsToRemove.size(); i++) { |
| 300 unclippedDescendants.remove(unclippedDescendantsToRemove.at( | 301 unclippedDescendants.remove(unclippedDescendantsToRemove.at( |
| 301 unclippedDescendantsToRemove.size() - i - 1)); | 302 unclippedDescendantsToRemove.size() - i - 1)); |
| 303 } | |
| 302 | 304 |
| 303 if (layer->clipParent()) { | 305 if (reasonsToComposite & CompositingReasonOutOfFlowClipping) { |
| 304 // TODO(schenney): We only need to promote when the clipParent is not a | 306 // TODO(schenney): We only need to promote when the clipParent is not a |
| 305 // descendant of the ancestor scroller, which we do not check for here. | 307 // descendant of the ancestor scroller, which we do not check for here. |
| 306 // Hence we might be promoting needlessly. | 308 // Hence we might be promoting needlessly. |
| 307 unclippedDescendants.append(layer); | 309 unclippedDescendants.append(layer); |
| 308 } | 310 } |
| 309 } | 311 } |
| 310 | 312 |
| 311 const IntRect& absBounds = layer->clippedAbsoluteBoundingBox(); | 313 const IntRect& absBounds = layer->clippedAbsoluteBoundingBox(); |
| 312 absoluteDescendantBoundingBox = absBounds; | 314 absoluteDescendantBoundingBox = absBounds; |
| 313 | 315 |
| 314 if (currentRecursionData.m_testingOverlap && | 316 if (currentRecursionData.m_testingOverlap && |
| 315 !requiresCompositingOrSquashing(directReasons)) | 317 !requiresCompositingOrSquashing(directReasons)) { |
| 316 overlapCompositingReason = overlapMap.overlapsLayers(absBounds) | 318 overlapCompositingReason = overlapMap.overlapsLayers(absBounds) |
| 317 ? CompositingReasonOverlap | 319 ? CompositingReasonOverlap |
| 318 : CompositingReasonNone; | 320 : CompositingReasonNone; |
| 321 } | |
| 319 | 322 |
| 320 reasonsToComposite |= overlapCompositingReason; | 323 reasonsToComposite |= overlapCompositingReason; |
| 321 | 324 |
| 322 // The children of this layer don't need to composite, unless there is | 325 // The children of this layer don't need to composite, unless there is |
| 323 // a compositing layer among them, so start by inheriting the compositing | 326 // a compositing layer among them, so start by inheriting the compositing |
| 324 // ancestor with m_subtreeIsCompositing set to false. | 327 // ancestor with m_subtreeIsCompositing set to false. |
| 325 RecursionData childRecursionData = currentRecursionData; | 328 RecursionData childRecursionData = currentRecursionData; |
| 326 childRecursionData.m_subtreeIsCompositing = false; | 329 childRecursionData.m_subtreeIsCompositing = false; |
| 327 | 330 |
| 328 bool willBeCompositedOrSquashed = | 331 bool willBeCompositedOrSquashed = |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 377 overlapMap.beginNewOverlapTestingContext(); | 380 overlapMap.beginNewOverlapTestingContext(); |
| 378 overlapMap.add(curNode->layer(), | 381 overlapMap.add(curNode->layer(), |
| 379 curNode->layer()->clippedAbsoluteBoundingBox()); | 382 curNode->layer()->clippedAbsoluteBoundingBox()); |
| 380 overlapMap.finishCurrentOverlapTestingContext(); | 383 overlapMap.finishCurrentOverlapTestingContext(); |
| 381 } | 384 } |
| 382 } | 385 } |
| 383 } | 386 } |
| 384 } | 387 } |
| 385 | 388 |
| 386 if (willHaveForegroundLayer) { | 389 if (willHaveForegroundLayer) { |
| 387 ASSERT(willBeCompositedOrSquashed); | 390 DCHECK(willBeCompositedOrSquashed); |
| 388 // A foreground layer effectively is a new backing for all subsequent | 391 // A foreground layer effectively is a new backing for all subsequent |
| 389 // children, so we don't need to test for overlap with anything behind this. | 392 // children, so we don't need to test for overlap with anything behind this. |
| 390 // So, we can finish the previous context that was accumulating rects for | 393 // So, we can finish the previous context that was accumulating rects for |
| 391 // the negative z-index children, and start with a fresh new empty context. | 394 // the negative z-index children, and start with a fresh new empty context. |
| 392 overlapMap.finishCurrentOverlapTestingContext(); | 395 overlapMap.finishCurrentOverlapTestingContext(); |
| 393 overlapMap.beginNewOverlapTestingContext(); | 396 overlapMap.beginNewOverlapTestingContext(); |
| 394 // This layer is going to be composited, so children can safely ignore the | 397 // This layer is going to be composited, so children can safely ignore the |
| 395 // fact that there's an animation running behind this layer, meaning they | 398 // fact that there's an animation running behind this layer, meaning they |
| 396 // can rely on the overlap map testing again. | 399 // can rely on the overlap map testing again. |
| 397 childRecursionData.m_testingOverlap = true; | 400 childRecursionData.m_testingOverlap = true; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 458 requiresCompositingOrSquashing(subtreeCompositingReasons)) { | 461 requiresCompositingOrSquashing(subtreeCompositingReasons)) { |
| 459 childRecursionData.m_compositingAncestor = layer; | 462 childRecursionData.m_compositingAncestor = layer; |
| 460 // FIXME: this context push is effectively a no-op but needs to exist for | 463 // FIXME: this context push is effectively a no-op but needs to exist for |
| 461 // now, because the code is designed to push overlap information to the | 464 // now, because the code is designed to push overlap information to the |
| 462 // second-from-top context of the stack. | 465 // second-from-top context of the stack. |
| 463 overlapMap.beginNewOverlapTestingContext(); | 466 overlapMap.beginNewOverlapTestingContext(); |
| 464 overlapMap.add(layer, absoluteDescendantBoundingBox); | 467 overlapMap.add(layer, absoluteDescendantBoundingBox); |
| 465 willBeCompositedOrSquashed = true; | 468 willBeCompositedOrSquashed = true; |
| 466 } | 469 } |
| 467 | 470 |
| 468 if (willBeCompositedOrSquashed) | 471 if (willBeCompositedOrSquashed) { |
| 469 reasonsToComposite |= layer->potentialCompositingReasonsFromStyle() & | 472 reasonsToComposite |= layer->potentialCompositingReasonsFromStyle() & |
| 470 CompositingReasonInlineTransform; | 473 CompositingReasonInlineTransform; |
| 474 } | |
| 471 | 475 |
| 472 if (willBeCompositedOrSquashed && | 476 if (willBeCompositedOrSquashed && |
| 473 layer->layoutObject()->style()->hasBlendMode()) | 477 layer->layoutObject()->style()->hasBlendMode()) |
| 474 currentRecursionData.m_hasUnisolatedCompositedBlendingDescendant = true; | 478 currentRecursionData.m_hasUnisolatedCompositedBlendingDescendant = true; |
| 475 | 479 |
| 476 // Tell the parent it has compositing descendants. | 480 // Tell the parent it has compositing descendants. |
| 477 if (willBeCompositedOrSquashed) | 481 if (willBeCompositedOrSquashed) |
| 478 currentRecursionData.m_subtreeIsCompositing = true; | 482 currentRecursionData.m_subtreeIsCompositing = true; |
| 479 | 483 |
| 480 // Turn overlap testing off for later layers if it's already off, or if we | 484 // Turn overlap testing off for later layers if it's already off, or if we |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 498 descendantHas3DTransform |= | 502 descendantHas3DTransform |= |
| 499 anyDescendantHas3DTransform || layer->has3DTransform(); | 503 anyDescendantHas3DTransform || layer->has3DTransform(); |
| 500 } | 504 } |
| 501 | 505 |
| 502 // At this point we have finished collecting all reasons to composite this | 506 // At this point we have finished collecting all reasons to composite this |
| 503 // layer. | 507 // layer. |
| 504 layer->setCompositingReasons(reasonsToComposite); | 508 layer->setCompositingReasons(reasonsToComposite); |
| 505 } | 509 } |
| 506 | 510 |
| 507 } // namespace blink | 511 } // namespace blink |
| OLD | NEW |