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 |