Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Side by Side Diff: Source/core/rendering/compositing/RenderLayerCompositor.cpp

Issue 215063006: Separate the geometry update from rebuilding the GraphicsLayer tree (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rebase Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « Source/core/rendering/compositing/RenderLayerCompositor.h ('k') | Source/platform/graphics/CompositingReasons.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698