| 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 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 #include "core/rendering/RenderApplet.h" | 51 #include "core/rendering/RenderApplet.h" |
| 52 #include "core/rendering/RenderEmbeddedObject.h" | 52 #include "core/rendering/RenderEmbeddedObject.h" |
| 53 #include "core/rendering/RenderFullScreen.h" | 53 #include "core/rendering/RenderFullScreen.h" |
| 54 #include "core/rendering/RenderIFrame.h" | 54 #include "core/rendering/RenderIFrame.h" |
| 55 #include "core/rendering/RenderLayerStackingNode.h" | 55 #include "core/rendering/RenderLayerStackingNode.h" |
| 56 #include "core/rendering/RenderLayerStackingNodeIterator.h" | 56 #include "core/rendering/RenderLayerStackingNodeIterator.h" |
| 57 #include "core/rendering/RenderReplica.h" | 57 #include "core/rendering/RenderReplica.h" |
| 58 #include "core/rendering/RenderVideo.h" | 58 #include "core/rendering/RenderVideo.h" |
| 59 #include "core/rendering/RenderView.h" | 59 #include "core/rendering/RenderView.h" |
| 60 #include "core/rendering/compositing/CompositedLayerMapping.h" | 60 #include "core/rendering/compositing/CompositedLayerMapping.h" |
| 61 #include "core/rendering/compositing/CompositingRequirementsUpdater.h" |
| 61 #include "core/rendering/compositing/GraphicsLayerUpdater.h" | 62 #include "core/rendering/compositing/GraphicsLayerUpdater.h" |
| 62 #include "platform/OverscrollTheme.h" | 63 #include "platform/OverscrollTheme.h" |
| 63 #include "platform/TraceEvent.h" | 64 #include "platform/TraceEvent.h" |
| 64 #include "platform/geometry/TransformState.h" | 65 #include "platform/geometry/TransformState.h" |
| 65 #include "platform/graphics/GraphicsLayer.h" | 66 #include "platform/graphics/GraphicsLayer.h" |
| 66 #include "platform/scroll/ScrollbarTheme.h" | 67 #include "platform/scroll/ScrollbarTheme.h" |
| 67 #include "public/platform/Platform.h" | 68 #include "public/platform/Platform.h" |
| 68 #include "wtf/TemporaryChange.h" | 69 #include "wtf/TemporaryChange.h" |
| 69 | 70 |
| 70 #ifndef NDEBUG | 71 #ifndef NDEBUG |
| 71 #include "core/rendering/RenderTreeAsText.h" | 72 #include "core/rendering/RenderTreeAsText.h" |
| 72 #endif | 73 #endif |
| 73 | 74 |
| 74 namespace WebCore { | 75 namespace WebCore { |
| 75 | 76 |
| 76 using namespace HTMLNames; | 77 using namespace HTMLNames; |
| 77 | 78 |
| 78 class OverlapMapContainer { | |
| 79 public: | |
| 80 void add(const IntRect& bounds) | |
| 81 { | |
| 82 m_layerRects.append(bounds); | |
| 83 m_boundingBox.unite(bounds); | |
| 84 } | |
| 85 | |
| 86 bool overlapsLayers(const IntRect& bounds) const | |
| 87 { | |
| 88 // Checking with the bounding box will quickly reject cases when | |
| 89 // layers are created for lists of items going in one direction and | |
| 90 // never overlap with each other. | |
| 91 if (!bounds.intersects(m_boundingBox)) | |
| 92 return false; | |
| 93 for (unsigned i = 0; i < m_layerRects.size(); i++) { | |
| 94 if (m_layerRects[i].intersects(bounds)) | |
| 95 return true; | |
| 96 } | |
| 97 return false; | |
| 98 } | |
| 99 | |
| 100 void unite(const OverlapMapContainer& otherContainer) | |
| 101 { | |
| 102 m_layerRects.appendVector(otherContainer.m_layerRects); | |
| 103 m_boundingBox.unite(otherContainer.m_boundingBox); | |
| 104 } | |
| 105 private: | |
| 106 Vector<IntRect, 64> m_layerRects; | |
| 107 IntRect m_boundingBox; | |
| 108 }; | |
| 109 | |
| 110 class RenderLayerCompositor::OverlapMap { | |
| 111 WTF_MAKE_NONCOPYABLE(OverlapMap); | |
| 112 public: | |
| 113 OverlapMap() | |
| 114 { | |
| 115 // Begin by assuming the root layer will be composited so that there | |
| 116 // is something on the stack. The root layer should also never get a | |
| 117 // finishCurrentOverlapTestingContext() call. | |
| 118 beginNewOverlapTestingContext(); | |
| 119 } | |
| 120 | |
| 121 void add(RenderLayer* layer, const IntRect& bounds) | |
| 122 { | |
| 123 if (layer->isRootLayer() || bounds.isEmpty()) | |
| 124 return; | |
| 125 | |
| 126 // Layers do not contribute to overlap immediately--instead, they will | |
| 127 // contribute to overlap as soon as they have been recursively processed | |
| 128 // and popped off the stack. | |
| 129 ASSERT(m_overlapStack.size() >= 2); | |
| 130 m_overlapStack[m_overlapStack.size() - 2].add(bounds); | |
| 131 } | |
| 132 | |
| 133 bool overlapsLayers(const IntRect& bounds) const | |
| 134 { | |
| 135 return m_overlapStack.last().overlapsLayers(bounds); | |
| 136 } | |
| 137 | |
| 138 void beginNewOverlapTestingContext() | |
| 139 { | |
| 140 // This effectively creates a new "clean slate" for overlap state. | |
| 141 // This is used when we know that a subtree or remaining set of | |
| 142 // siblings does not need to check overlap with things behind it. | |
| 143 m_overlapStack.append(OverlapMapContainer()); | |
| 144 } | |
| 145 | |
| 146 void finishCurrentOverlapTestingContext() | |
| 147 { | |
| 148 // The overlap information on the top of the stack is still necessary | |
| 149 // for checking overlap of any layers outside this context that may | |
| 150 // overlap things from inside this context. Therefore, we must merge | |
| 151 // the information from the top of the stack before popping the stack. | |
| 152 // | |
| 153 // FIXME: we may be able to avoid this deep copy by rearranging how | |
| 154 // overlapMap state is managed. | |
| 155 m_overlapStack[m_overlapStack.size() - 2].unite(m_overlapStack.last()); | |
| 156 m_overlapStack.removeLast(); | |
| 157 } | |
| 158 | |
| 159 private: | |
| 160 Vector<OverlapMapContainer> m_overlapStack; | |
| 161 }; | |
| 162 | |
| 163 struct CompositingRecursionData { | |
| 164 CompositingRecursionData(RenderLayer* compAncestor, RenderLayer* mostRecentC
ompositedLayer, bool testOverlap) | |
| 165 : m_compositingAncestor(compAncestor) | |
| 166 , m_mostRecentCompositedLayer(mostRecentCompositedLayer) | |
| 167 , m_subtreeIsCompositing(false) | |
| 168 , m_hasUnisolatedCompositedBlendingDescendant(false) | |
| 169 , m_testingOverlap(testOverlap) | |
| 170 #ifndef NDEBUG | |
| 171 , m_depth(0) | |
| 172 #endif | |
| 173 { | |
| 174 } | |
| 175 | |
| 176 CompositingRecursionData(const CompositingRecursionData& other) | |
| 177 : m_compositingAncestor(other.m_compositingAncestor) | |
| 178 , m_mostRecentCompositedLayer(other.m_mostRecentCompositedLayer) | |
| 179 , m_subtreeIsCompositing(other.m_subtreeIsCompositing) | |
| 180 , m_hasUnisolatedCompositedBlendingDescendant(other.m_hasUnisolatedCompo
sitedBlendingDescendant) | |
| 181 , m_testingOverlap(other.m_testingOverlap) | |
| 182 #ifndef NDEBUG | |
| 183 , m_depth(other.m_depth + 1) | |
| 184 #endif | |
| 185 { | |
| 186 } | |
| 187 | |
| 188 RenderLayer* m_compositingAncestor; | |
| 189 RenderLayer* m_mostRecentCompositedLayer; // in paint order regardless of hi
erarchy. | |
| 190 bool m_subtreeIsCompositing; | |
| 191 bool m_hasUnisolatedCompositedBlendingDescendant; | |
| 192 bool m_testingOverlap; | |
| 193 #ifndef NDEBUG | |
| 194 int m_depth; | |
| 195 #endif | |
| 196 }; | |
| 197 | |
| 198 static void clearAncestorDependentPropertyCacheRecursive(RenderLayer* layer) | |
| 199 { | |
| 200 layer->clearAncestorDependentPropertyCache(); | |
| 201 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren
); | |
| 202 for (RenderLayer* child = layer->firstChild(); child; child = child->nextSib
ling()) | |
| 203 clearAncestorDependentPropertyCacheRecursive(child); | |
| 204 } | |
| 205 | |
| 206 RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView) | 79 RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView) |
| 207 : m_renderView(renderView) | 80 : m_renderView(renderView) |
| 208 , m_compositingReasonFinder(renderView) | 81 , m_compositingReasonFinder(renderView) |
| 209 , m_pendingUpdateType(CompositingUpdateNone) | 82 , m_pendingUpdateType(CompositingUpdateNone) |
| 210 , m_hasAcceleratedCompositing(true) | 83 , m_hasAcceleratedCompositing(true) |
| 211 , m_showRepaintCounter(false) | 84 , m_showRepaintCounter(false) |
| 212 , m_needsToRecomputeCompositingRequirements(false) | 85 , m_needsToRecomputeCompositingRequirements(false) |
| 213 , m_compositing(false) | 86 , m_compositing(false) |
| 214 , m_compositingLayersNeedRebuild(false) | 87 , m_compositingLayersNeedRebuild(false) |
| 215 , m_forceCompositingMode(false) | 88 , m_forceCompositingMode(false) |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 compositingPropertyUpdateType = CompositingPropertyUpdater::ForceUpdate; | 318 compositingPropertyUpdateType = CompositingPropertyUpdater::ForceUpdate; |
| 446 } | 319 } |
| 447 | 320 |
| 448 // Only clear the flags if we're updating the entire hierarchy. | 321 // Only clear the flags if we're updating the entire hierarchy. |
| 449 m_compositingLayersNeedRebuild = false; | 322 m_compositingLayersNeedRebuild = false; |
| 450 m_needsToRecomputeCompositingRequirements = false; | 323 m_needsToRecomputeCompositingRequirements = false; |
| 451 | 324 |
| 452 RenderLayer* updateRoot = rootRenderLayer(); | 325 RenderLayer* updateRoot = rootRenderLayer(); |
| 453 | 326 |
| 454 if (needCompositingRequirementsUpdate) { | 327 if (needCompositingRequirementsUpdate) { |
| 455 // Go through the layers in presentation order, so that we can compute w
hich RenderLayers need compositing layers. | |
| 456 // FIXME: we could maybe do this and the hierarchy udpate in one pass, b
ut the parenting logic would be more complex. | |
| 457 CompositingRecursionData recursionData(updateRoot, 0, true); | |
| 458 bool layersChanged = false; | 328 bool layersChanged = false; |
| 459 bool saw3DTransform = false; | |
| 460 | 329 |
| 461 { | 330 { |
| 462 TRACE_EVENT0("blink_rendering", "CompositingPropertyUpdater::updateA
ncestorDependentProperties"); | 331 TRACE_EVENT0("blink_rendering", "CompositingPropertyUpdater::updateA
ncestorDependentProperties"); |
| 463 CompositingPropertyUpdater(updateRoot).updateAncestorDependentProper
ties(updateRoot, compositingPropertyUpdateType, 0); | 332 CompositingPropertyUpdater(updateRoot).updateAncestorDependentProper
ties(updateRoot, compositingPropertyUpdateType, 0); |
| 464 #if !ASSERT_DISABLED | 333 #if !ASSERT_DISABLED |
| 465 CompositingPropertyUpdater::assertNeedsToUpdateAncestorDependantProp
ertiesBitsCleared(updateRoot); | 334 CompositingPropertyUpdater::assertNeedsToUpdateAncestorDependantProp
ertiesBitsCleared(updateRoot); |
| 466 #endif | 335 #endif |
| 467 } | 336 } |
| 468 | 337 |
| 469 { | 338 CompositingRequirementsUpdater(m_renderView, m_compositingReasonFinder,
&m_needsToRecomputeCompositingRequirements).update(updateRoot); |
| 470 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::computeCompo
sitingRequirements"); | |
| 471 OverlapMap overlapTestRequestMap; | |
| 472 | |
| 473 // FIXME: Passing these unclippedDescendants down and keeping track | |
| 474 // of them dynamically, we are requiring a full tree walk. This | |
| 475 // should be removed as soon as proper overlap testing based on | |
| 476 // scrolling and animation bounds is implemented (crbug.com/252472). | |
| 477 Vector<RenderLayer*> unclippedDescendants; | |
| 478 IntRect absoluteDecendantBoundingBox; | |
| 479 computeCompositingRequirements(0, updateRoot, overlapTestRequestMap,
recursionData, saw3DTransform, unclippedDescendants, absoluteDecendantBoundingB
ox); | |
| 480 } | |
| 481 | 339 |
| 482 { | 340 { |
| 483 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::assignLayers
ToBackings"); | 341 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::assignLayers
ToBackings"); |
| 484 assignLayersToBackings(updateRoot, layersChanged); | 342 assignLayersToBackings(updateRoot, layersChanged); |
| 485 } | 343 } |
| 486 | 344 |
| 487 { | 345 { |
| 488 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::updateAfterC
ompositingChange"); | 346 TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::updateAfterC
ompositingChange"); |
| 489 const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView.f
rameView()->scrollableAreas(); | 347 const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView.f
rameView()->scrollableAreas(); |
| 490 if (scrollableAreas) { | 348 if (scrollableAreas) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 537 // The scrolling coordinator may realize that it needs updating while compos
iting was being updated in this function. | 395 // The scrolling coordinator may realize that it needs updating while compos
iting was being updated in this function. |
| 538 needsToUpdateScrollingCoordinator |= scrollingCoordinator() && scrollingCoor
dinator()->needsToUpdateAfterCompositingChange(); | 396 needsToUpdateScrollingCoordinator |= scrollingCoordinator() && scrollingCoor
dinator()->needsToUpdateAfterCompositingChange(); |
| 539 if (needsToUpdateScrollingCoordinator && isMainFrame() && scrollingCoordinat
or() && inCompositingMode()) | 397 if (needsToUpdateScrollingCoordinator && isMainFrame() && scrollingCoordinat
or() && inCompositingMode()) |
| 540 scrollingCoordinator()->updateAfterCompositingChange(); | 398 scrollingCoordinator()->updateAfterCompositingChange(); |
| 541 | 399 |
| 542 // Inform the inspector that the layer tree has changed. | 400 // Inform the inspector that the layer tree has changed. |
| 543 if (isMainFrame()) | 401 if (isMainFrame()) |
| 544 InspectorInstrumentation::layerTreeDidChange(page()); | 402 InspectorInstrumentation::layerTreeDidChange(page()); |
| 545 } | 403 } |
| 546 | 404 |
| 547 static bool requiresCompositing(CompositingReasons reasons) | |
| 548 { | |
| 549 // Any reasons other than overlap or assumed overlap will require the layer
to be separately compositing. | |
| 550 return reasons & ~CompositingReasonComboSquashableReasons; | |
| 551 } | |
| 552 | |
| 553 static bool requiresSquashing(CompositingReasons reasons) | |
| 554 { | |
| 555 // If the layer has overlap or assumed overlap, but no other reasons, then i
t should be squashed. | |
| 556 return !requiresCompositing(reasons) && (reasons & CompositingReasonComboSqu
ashableReasons); | |
| 557 } | |
| 558 | |
| 559 static bool requiresCompositingOrSquashing(CompositingReasons reasons) | |
| 560 { | |
| 561 #ifndef NDEBUG | |
| 562 bool fastAnswer = reasons != CompositingReasonNone; | |
| 563 bool slowAnswer = requiresCompositing(reasons) || requiresSquashing(reasons)
; | |
| 564 ASSERT(fastAnswer == slowAnswer); | |
| 565 #endif | |
| 566 return reasons != CompositingReasonNone; | |
| 567 } | |
| 568 | |
| 569 void RenderLayerCompositor::addOutOfFlowPositionedLayer(RenderLayer* layer) | 405 void RenderLayerCompositor::addOutOfFlowPositionedLayer(RenderLayer* layer) |
| 570 { | 406 { |
| 571 m_outOfFlowPositionedLayers.add(layer); | 407 m_outOfFlowPositionedLayers.add(layer); |
| 572 } | 408 } |
| 573 | 409 |
| 574 void RenderLayerCompositor::removeOutOfFlowPositionedLayer(RenderLayer* layer) | 410 void RenderLayerCompositor::removeOutOfFlowPositionedLayer(RenderLayer* layer) |
| 575 { | 411 { |
| 576 m_outOfFlowPositionedLayers.remove(layer); | 412 m_outOfFlowPositionedLayers.remove(layer); |
| 577 } | 413 } |
| 578 | 414 |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 // FIXME: This is called from within RenderLayer::removeChild, which is
called from RenderObject::RemoveChild. | 705 // FIXME: This is called from within RenderLayer::removeChild, which is
called from RenderObject::RemoveChild. |
| 870 // There's no guarantee that compositor state is up to date. | 706 // There's no guarantee that compositor state is up to date. |
| 871 DisableCompositingQueryAsserts disabler; | 707 DisableCompositingQueryAsserts disabler; |
| 872 repaintInCompositedAncestor(child, child->compositedLayerMapping()->comp
ositedBounds()); | 708 repaintInCompositedAncestor(child, child->compositedLayerMapping()->comp
ositedBounds()); |
| 873 } | 709 } |
| 874 | 710 |
| 875 setCompositingParent(child, 0); | 711 setCompositingParent(child, 0); |
| 876 setCompositingLayersNeedRebuild(); | 712 setCompositingLayersNeedRebuild(); |
| 877 } | 713 } |
| 878 | 714 |
| 879 // Recurse through the layers in z-index and overflow order (which is equivalen
t to painting order) | |
| 880 // For the z-order children of a compositing layer: | |
| 881 // If a child layers has a compositing layer, then all subsequent layers mu
st | |
| 882 // be compositing in order to render above that layer. | |
| 883 // | |
| 884 // If a child in the negative z-order list is compositing, then the layer i
tself | |
| 885 // must be compositing so that its contents render over that child. | |
| 886 // This implies that its positive z-index children must also be compositing
. | |
| 887 // | |
| 888 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
Layer, RenderLayer* layer, OverlapMap& overlapMap, CompositingRecursionData& cur
rentRecursionData, bool& descendantHas3DTransform, Vector<RenderLayer*>& unclipp
edDescendants, IntRect& absoluteDecendantBoundingBox) | |
| 889 { | |
| 890 layer->stackingNode()->updateLayerListsIfNeeded(); | |
| 891 | |
| 892 // Clear the flag | |
| 893 layer->setHasCompositingDescendant(false); | |
| 894 | |
| 895 // Start by assuming this layer will not need to composite. | |
| 896 CompositingReasons reasonsToComposite = CompositingReasonNone; | |
| 897 | |
| 898 // First accumulate the straightforward compositing reasons. | |
| 899 CompositingReasons directReasons = m_compositingReasonFinder.directReasons(l
ayer, &m_needsToRecomputeCompositingRequirements); | |
| 900 | |
| 901 // Video is special. It's the only RenderLayer type that can both have | |
| 902 // RenderLayer children and whose children can't use its backing to render | |
| 903 // into. These children (the controls) always need to be promoted into their | |
| 904 // own layers to draw on top of the accelerated video. | |
| 905 if (currentRecursionData.m_compositingAncestor && currentRecursionData.m_com
positingAncestor->renderer()->isVideo()) | |
| 906 directReasons |= CompositingReasonVideoOverlay; | |
| 907 | |
| 908 if (canBeComposited(layer)) | |
| 909 reasonsToComposite |= directReasons; | |
| 910 | |
| 911 // Next, accumulate reasons related to overlap. | |
| 912 // If overlap testing is used, this reason will be overridden. If overlap te
sting is not | |
| 913 // used, we must assume we overlap if there is anything composited behind us
in paint-order. | |
| 914 CompositingReasons overlapCompositingReason = currentRecursionData.m_subtree
IsCompositing ? CompositingReasonAssumedOverlap : CompositingReasonNone; | |
| 915 | |
| 916 if (m_renderView.compositorDrivenAcceleratedScrollingEnabled()) { | |
| 917 Vector<size_t> unclippedDescendantsToRemove; | |
| 918 for (size_t i = 0; i < unclippedDescendants.size(); i++) { | |
| 919 RenderLayer* unclippedDescendant = unclippedDescendants.at(i); | |
| 920 // If we've reached the containing block of one of the unclipped | |
| 921 // descendants, that element is no longer relevant to whether or not
we | |
| 922 // should opt in. Unfortunately we can't easily remove from the list | |
| 923 // while we're iterating, so we have to store it for later removal. | |
| 924 if (unclippedDescendant->renderer()->containingBlock() == layer->ren
derer()) { | |
| 925 unclippedDescendantsToRemove.append(i); | |
| 926 continue; | |
| 927 } | |
| 928 if (layer->scrollsWithRespectTo(unclippedDescendant)) | |
| 929 reasonsToComposite |= CompositingReasonAssumedOverlap; | |
| 930 } | |
| 931 | |
| 932 // Remove irrelevant unclipped descendants in reverse order so our store
d | |
| 933 // indices remain valid. | |
| 934 for (size_t i = 0; i < unclippedDescendantsToRemove.size(); i++) | |
| 935 unclippedDescendants.remove(unclippedDescendantsToRemove.at(unclippe
dDescendantsToRemove.size() - i - 1)); | |
| 936 | |
| 937 if (reasonsToComposite & CompositingReasonOutOfFlowClipping) | |
| 938 unclippedDescendants.append(layer); | |
| 939 } | |
| 940 | |
| 941 const IntRect& absBounds = layer->ancestorDependentProperties().clippedAbsol
uteBoundingBox; | |
| 942 absoluteDecendantBoundingBox = absBounds; | |
| 943 | |
| 944 if (currentRecursionData.m_testingOverlap && !requiresCompositingOrSquashing
(directReasons)) | |
| 945 overlapCompositingReason = overlapMap.overlapsLayers(absBounds) ? Compos
itingReasonOverlap : CompositingReasonNone; | |
| 946 | |
| 947 reasonsToComposite |= overlapCompositingReason; | |
| 948 | |
| 949 // The children of this layer don't need to composite, unless there is | |
| 950 // a compositing layer among them, so start by inheriting the compositing | |
| 951 // ancestor with m_subtreeIsCompositing set to false. | |
| 952 CompositingRecursionData childRecursionData(currentRecursionData); | |
| 953 childRecursionData.m_subtreeIsCompositing = false; | |
| 954 | |
| 955 bool willBeCompositedOrSquashed = canBeComposited(layer) && requiresComposit
ingOrSquashing(reasonsToComposite); | |
| 956 if (willBeCompositedOrSquashed) { | |
| 957 // Tell the parent it has compositing descendants. | |
| 958 currentRecursionData.m_subtreeIsCompositing = true; | |
| 959 // This layer now acts as the ancestor for kids. | |
| 960 childRecursionData.m_compositingAncestor = layer; | |
| 961 | |
| 962 // Here we know that all children and the layer's own contents can blind
ly paint into | |
| 963 // this layer's backing, until a descendant is composited. So, we don't
need to check | |
| 964 // for overlap with anything behind this layer. | |
| 965 overlapMap.beginNewOverlapTestingContext(); | |
| 966 // This layer is going to be composited, so children can safely ignore t
he fact that there's an | |
| 967 // animation running behind this layer, meaning they can rely on the ove
rlap map testing again. | |
| 968 childRecursionData.m_testingOverlap = true; | |
| 969 } | |
| 970 | |
| 971 #if !ASSERT_DISABLED | |
| 972 LayerListMutationDetector mutationChecker(layer->stackingNode()); | |
| 973 #endif | |
| 974 | |
| 975 bool anyDescendantHas3DTransform = false; | |
| 976 bool willHaveForegroundLayer = false; | |
| 977 | |
| 978 if (layer->stackingNode()->isStackingContainer()) { | |
| 979 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), Negativ
eZOrderChildren); | |
| 980 while (RenderLayerStackingNode* curNode = iterator.next()) { | |
| 981 IntRect absoluteChildDecendantBoundingBox; | |
| 982 computeCompositingRequirements(layer, curNode->layer(), overlapMap,
childRecursionData, anyDescendantHas3DTransform, unclippedDescendants, absoluteC
hildDecendantBoundingBox); | |
| 983 absoluteDecendantBoundingBox.unite(absoluteChildDecendantBoundingBox
); | |
| 984 | |
| 985 // If we have to make a layer for this child, make one now so we can
have a contents layer | |
| 986 // (since we need to ensure that the -ve z-order child renders under
neath our contents). | |
| 987 if (childRecursionData.m_subtreeIsCompositing) { | |
| 988 reasonsToComposite |= CompositingReasonNegativeZIndexChildren; | |
| 989 | |
| 990 if (!willBeCompositedOrSquashed) { | |
| 991 // make layer compositing | |
| 992 childRecursionData.m_compositingAncestor = layer; | |
| 993 overlapMap.beginNewOverlapTestingContext(); | |
| 994 willBeCompositedOrSquashed = true; | |
| 995 willHaveForegroundLayer = true; | |
| 996 | |
| 997 // FIXME: temporary solution for the first negative z-index
composited child: | |
| 998 // re-compute the absBounds for the child so that we
can add the | |
| 999 // negative z-index child's bounds to the new overlap
context. | |
| 1000 overlapMap.beginNewOverlapTestingContext(); | |
| 1001 overlapMap.add(curNode->layer(), curNode->layer()->ancestorD
ependentProperties().clippedAbsoluteBoundingBox); | |
| 1002 overlapMap.finishCurrentOverlapTestingContext(); | |
| 1003 } | |
| 1004 } | |
| 1005 } | |
| 1006 } | |
| 1007 | |
| 1008 if (willHaveForegroundLayer) { | |
| 1009 ASSERT(willBeCompositedOrSquashed); | |
| 1010 // A foreground layer effectively is a new backing for all subsequent ch
ildren, so | |
| 1011 // we don't need to test for overlap with anything behind this. So, we c
an finish | |
| 1012 // the previous context that was accumulating rects for the negative z-i
ndex | |
| 1013 // children, and start with a fresh new empty context. | |
| 1014 overlapMap.finishCurrentOverlapTestingContext(); | |
| 1015 overlapMap.beginNewOverlapTestingContext(); | |
| 1016 // This layer is going to be composited, so children can safely ignore t
he fact that there's an | |
| 1017 // animation running behind this layer, meaning they can rely on the ove
rlap map testing again | |
| 1018 childRecursionData.m_testingOverlap = true; | |
| 1019 } | |
| 1020 | |
| 1021 if (requiresCompositing(reasonsToComposite)) { | |
| 1022 currentRecursionData.m_mostRecentCompositedLayer = layer; | |
| 1023 childRecursionData.m_mostRecentCompositedLayer = layer; | |
| 1024 } | |
| 1025 | |
| 1026 RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowC
hildren | PositiveZOrderChildren); | |
| 1027 while (RenderLayerStackingNode* curNode = iterator.next()) { | |
| 1028 IntRect absoluteChildDecendantBoundingBox; | |
| 1029 computeCompositingRequirements(layer, curNode->layer(), overlapMap, chil
dRecursionData, anyDescendantHas3DTransform, unclippedDescendants, absoluteChild
DecendantBoundingBox); | |
| 1030 absoluteDecendantBoundingBox.unite(absoluteChildDecendantBoundingBox); | |
| 1031 } | |
| 1032 | |
| 1033 currentRecursionData.m_mostRecentCompositedLayer = childRecursionData.m_most
RecentCompositedLayer; | |
| 1034 | |
| 1035 // Now that the subtree has been traversed, we can check for compositing rea
sons that depended on the state of the subtree. | |
| 1036 | |
| 1037 // If we entered compositing mode during the recursion, the root will also n
eed to be composited (as long as accelerated compositing is enabled). | |
| 1038 if (layer->isRootLayer()) { | |
| 1039 if (inCompositingMode() && m_hasAcceleratedCompositing) | |
| 1040 willBeCompositedOrSquashed = true; | |
| 1041 } | |
| 1042 | |
| 1043 // All layers (even ones that aren't being composited) need to get added to | |
| 1044 // the overlap map. Layers that are not separately composited will paint int
o their | |
| 1045 // compositing ancestor's backing, and so are still considered for overlap. | |
| 1046 if (childRecursionData.m_compositingAncestor && !childRecursionData.m_compos
itingAncestor->isRootLayer()) | |
| 1047 overlapMap.add(layer, absBounds); | |
| 1048 | |
| 1049 if (layer->stackingNode()->isStackingContext()) { | |
| 1050 layer->setShouldIsolateCompositedDescendants(childRecursionData.m_hasUni
solatedCompositedBlendingDescendant); | |
| 1051 } else { | |
| 1052 layer->setShouldIsolateCompositedDescendants(false); | |
| 1053 currentRecursionData.m_hasUnisolatedCompositedBlendingDescendant = child
RecursionData.m_hasUnisolatedCompositedBlendingDescendant; | |
| 1054 } | |
| 1055 | |
| 1056 // Now check for reasons to become composited that depend on the state of de
scendant layers. | |
| 1057 CompositingReasons subtreeCompositingReasons = subtreeReasonsForCompositing(
layer->renderer(), childRecursionData.m_subtreeIsCompositing, anyDescendantHas3D
Transform); | |
| 1058 reasonsToComposite |= subtreeCompositingReasons; | |
| 1059 if (!willBeCompositedOrSquashed && canBeComposited(layer) && requiresComposi
tingOrSquashing(subtreeCompositingReasons)) { | |
| 1060 childRecursionData.m_compositingAncestor = layer; | |
| 1061 // FIXME: this context push is effectively a no-op but needs to exist fo
r | |
| 1062 // now, because the code is designed to push overlap information to the | |
| 1063 // second-from-top context of the stack. | |
| 1064 overlapMap.beginNewOverlapTestingContext(); | |
| 1065 overlapMap.add(layer, absoluteDecendantBoundingBox); | |
| 1066 willBeCompositedOrSquashed = true; | |
| 1067 } | |
| 1068 | |
| 1069 // If the original layer is composited, the reflection needs to be, too. | |
| 1070 if (layer->reflectionInfo()) { | |
| 1071 // FIXME: Shouldn't we call computeCompositingRequirements to handle a r
eflection overlapping with another renderer? | |
| 1072 RenderLayer* reflectionLayer = layer->reflectionInfo()->reflectionLayer(
); | |
| 1073 CompositingReasons reflectionCompositingReason = willBeCompositedOrSquas
hed ? CompositingReasonReflectionOfCompositedParent : CompositingReasonNone; | |
| 1074 reflectionLayer->setCompositingReasons(reflectionLayer->compositingReaso
ns() | reflectionCompositingReason); | |
| 1075 } | |
| 1076 | |
| 1077 // Subsequent layers in the parent's stacking context may also need to compo
site. | |
| 1078 if (childRecursionData.m_subtreeIsCompositing) | |
| 1079 currentRecursionData.m_subtreeIsCompositing = true; | |
| 1080 | |
| 1081 if (willBeCompositedOrSquashed && layer->blendInfo().hasBlendMode()) | |
| 1082 currentRecursionData.m_hasUnisolatedCompositedBlendingDescendant = true; | |
| 1083 | |
| 1084 // Set the flag to say that this SC has compositing children. | |
| 1085 layer->setHasCompositingDescendant(childRecursionData.m_subtreeIsCompositing
); | |
| 1086 | |
| 1087 // Turn overlap testing off for later layers if it's already off, or if we h
ave an animating transform. | |
| 1088 // Note that if the layer clips its descendants, there's no reason to propag
ate the child animation to the parent layers. That's because | |
| 1089 // we know for sure the animation is contained inside the clipping rectangle
, which is already added to the overlap map. | |
| 1090 bool isCompositedClippingLayer = canBeComposited(layer) && (reasonsToComposi
te & CompositingReasonClipsCompositingDescendants); | |
| 1091 if ((!childRecursionData.m_testingOverlap && !isCompositedClippingLayer) ||
isRunningAcceleratedTransformAnimation(layer->renderer())) | |
| 1092 currentRecursionData.m_testingOverlap = false; | |
| 1093 | |
| 1094 if (childRecursionData.m_compositingAncestor == layer && !layer->isRootLayer
()) | |
| 1095 overlapMap.finishCurrentOverlapTestingContext(); | |
| 1096 | |
| 1097 if (layer->isRootLayer()) { | |
| 1098 // The root layer needs to be composited if anything else in the tree is
composited. | |
| 1099 // Otherwise, we can disable compositing entirely. | |
| 1100 if (childRecursionData.m_subtreeIsCompositing || requiresCompositingOrSq
uashing(reasonsToComposite) || m_forceCompositingMode) { | |
| 1101 willBeCompositedOrSquashed = true; | |
| 1102 reasonsToComposite |= CompositingReasonRoot; | |
| 1103 } else { | |
| 1104 enableCompositingMode(false); | |
| 1105 willBeCompositedOrSquashed = false; | |
| 1106 reasonsToComposite = CompositingReasonNone; | |
| 1107 } | |
| 1108 } | |
| 1109 | |
| 1110 if (requiresCompositing(reasonsToComposite)) | |
| 1111 currentRecursionData.m_mostRecentCompositedLayer = layer; | |
| 1112 | |
| 1113 // At this point we have finished collecting all reasons to composite this l
ayer. | |
| 1114 layer->setCompositingReasons(reasonsToComposite); | |
| 1115 | |
| 1116 descendantHas3DTransform |= anyDescendantHas3DTransform || layer->has3DTrans
form(); | |
| 1117 } | |
| 1118 | |
| 1119 void RenderLayerCompositor::SquashingState::updateSquashingStateForNewMapping(Co
mpositedLayerMappingPtr newCompositedLayerMapping, bool hasNewCompositedLayerMap
ping, LayoutPoint newOffsetFromAbsoluteForSquashingCLM) | 715 void RenderLayerCompositor::SquashingState::updateSquashingStateForNewMapping(Co
mpositedLayerMappingPtr newCompositedLayerMapping, bool hasNewCompositedLayerMap
ping, LayoutPoint newOffsetFromAbsoluteForSquashingCLM) |
| 1120 { | 716 { |
| 1121 // The most recent backing is done accumulating any more squashing layers. | 717 // The most recent backing is done accumulating any more squashing layers. |
| 1122 if (hasMostRecentMapping) | 718 if (hasMostRecentMapping) |
| 1123 mostRecentMapping->finishAccumulatingSquashingLayers(nextSquashedLayerIn
dex); | 719 mostRecentMapping->finishAccumulatingSquashingLayers(nextSquashedLayerIn
dex); |
| 1124 | 720 |
| 1125 nextSquashedLayerIndex = 0; | 721 nextSquashedLayerIndex = 0; |
| 1126 mostRecentMapping = newCompositedLayerMapping; | 722 mostRecentMapping = newCompositedLayerMapping; |
| 1127 hasMostRecentMapping = hasNewCompositedLayerMapping; | 723 hasMostRecentMapping = hasNewCompositedLayerMapping; |
| 1128 offsetFromAbsoluteForSquashingCLM = newOffsetFromAbsoluteForSquashingCLM; | 724 offsetFromAbsoluteForSquashingCLM = newOffsetFromAbsoluteForSquashingCLM; |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1518 } | 1114 } |
| 1519 | 1115 |
| 1520 // Return true if the given layer is a stacking context and has compositing chil
d | 1116 // Return true if the given layer is a stacking context and has compositing chil
d |
| 1521 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer | 1117 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer |
| 1522 // into the hierarchy between this layer and its children in the z-order hierarc
hy. | 1118 // into the hierarchy between this layer and its children in the z-order hierarc
hy. |
| 1523 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer
) const | 1119 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer
) const |
| 1524 { | 1120 { |
| 1525 return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOver
flowClip(); | 1121 return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOver
flowClip(); |
| 1526 } | 1122 } |
| 1527 | 1123 |
| 1528 CompositingReasons RenderLayerCompositor::subtreeReasonsForCompositing(RenderObj
ect* renderer, bool hasCompositedDescendants, bool has3DTransformedDescendants)
const | |
| 1529 { | |
| 1530 CompositingReasons subtreeReasons = CompositingReasonNone; | |
| 1531 | |
| 1532 // FIXME: this seems to be a potentially different layer than the layer for
which this was called. May not be an error, but is very confusing. | |
| 1533 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer(); | |
| 1534 | |
| 1535 // When a layer has composited descendants, some effects, like 2d transforms
, filters, masks etc must be implemented | |
| 1536 // via compositing so that they also apply to those composited descdendants. | |
| 1537 if (hasCompositedDescendants) { | |
| 1538 if (layer->transform()) | |
| 1539 subtreeReasons |= CompositingReasonTransformWithCompositedDescendant
s; | |
| 1540 | |
| 1541 if (layer->shouldIsolateCompositedDescendants()) { | |
| 1542 ASSERT(layer->stackingNode()->isStackingContext()); | |
| 1543 subtreeReasons |= CompositingReasonIsolateCompositedDescendants; | |
| 1544 } | |
| 1545 | |
| 1546 // If the implementation of createsGroup changes, we need to be aware of
that in this part of code. | |
| 1547 ASSERT((renderer->isTransparent() || renderer->hasMask() || renderer->ha
sFilter() || renderer->hasBlendMode()) == renderer->createsGroup()); | |
| 1548 if (renderer->isTransparent()) | |
| 1549 subtreeReasons |= CompositingReasonOpacityWithCompositedDescendants; | |
| 1550 if (renderer->hasMask()) | |
| 1551 subtreeReasons |= CompositingReasonMaskWithCompositedDescendants; | |
| 1552 if (renderer->hasFilter()) | |
| 1553 subtreeReasons |= CompositingReasonFilterWithCompositedDescendants; | |
| 1554 if (renderer->hasBlendMode()) | |
| 1555 subtreeReasons |= CompositingReasonBlendingWithCompositedDescendants
; | |
| 1556 | |
| 1557 if (renderer->hasReflection()) | |
| 1558 subtreeReasons |= CompositingReasonReflectionWithCompositedDescendan
ts; | |
| 1559 | |
| 1560 if (renderer->hasClipOrOverflowClip()) | |
| 1561 subtreeReasons |= CompositingReasonClipsCompositingDescendants; | |
| 1562 } | |
| 1563 | |
| 1564 | |
| 1565 // A layer with preserve-3d or perspective only needs to be composited if th
ere are descendant layers that | |
| 1566 // will be affected by the preserve-3d or perspective. | |
| 1567 if (has3DTransformedDescendants) { | |
| 1568 if (renderer->style()->transformStyle3D() == TransformStyle3DPreserve3D) | |
| 1569 subtreeReasons |= CompositingReasonPreserve3DWith3DDescendants; | |
| 1570 | |
| 1571 if (renderer->style()->hasPerspective()) | |
| 1572 subtreeReasons |= CompositingReasonPerspectiveWith3DDescendants; | |
| 1573 } | |
| 1574 | |
| 1575 return subtreeReasons; | |
| 1576 } | |
| 1577 | |
| 1578 bool RenderLayerCompositor::isRunningAcceleratedTransformAnimation(RenderObject*
renderer) const | |
| 1579 { | |
| 1580 if (!m_compositingReasonFinder.hasAnimationTrigger()) | |
| 1581 return false; | |
| 1582 return renderer->style()->hasCurrentTransformAnimation(); | |
| 1583 } | |
| 1584 | |
| 1585 // If an element has negative z-index children, those children render in front o
f the | 1124 // If an element has negative z-index children, those children render in front o
f the |
| 1586 // layer background, so we need an extra 'contents' layer for the foreground of
the layer | 1125 // layer background, so we need an extra 'contents' layer for the foreground of
the layer |
| 1587 // object. | 1126 // object. |
| 1588 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* lay
er) const | 1127 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* lay
er) const |
| 1589 { | 1128 { |
| 1590 return layer->stackingNode()->hasNegativeZOrderList(); | 1129 return layer->stackingNode()->hasNegativeZOrderList(); |
| 1591 } | 1130 } |
| 1592 | 1131 |
| 1593 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const
IntRect& clip) | 1132 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const
IntRect& clip) |
| 1594 { | 1133 { |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2070 } else if (graphicsLayer == m_scrollLayer.get()) { | 1609 } else if (graphicsLayer == m_scrollLayer.get()) { |
| 2071 name = "LocalFrame Scrolling Layer"; | 1610 name = "LocalFrame Scrolling Layer"; |
| 2072 } else { | 1611 } else { |
| 2073 ASSERT_NOT_REACHED(); | 1612 ASSERT_NOT_REACHED(); |
| 2074 } | 1613 } |
| 2075 | 1614 |
| 2076 return name; | 1615 return name; |
| 2077 } | 1616 } |
| 2078 | 1617 |
| 2079 } // namespace WebCore | 1618 } // namespace WebCore |
| OLD | NEW |