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

Side by Side Diff: third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp

Issue 2639283003: Fix traverseNonCompositingDescendantsInPaintOrder for float-under-inline cases (Closed)
Patch Set: Fix Created 3 years, 11 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
« no previous file with comments | « no previous file | third_party/WebKit/Source/core/paint/ObjectPaintInvalidatorTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/paint/ObjectPaintInvalidator.h" 5 #include "core/paint/ObjectPaintInvalidator.h"
6 6
7 #include "core/frame/FrameView.h" 7 #include "core/frame/FrameView.h"
8 #include "core/frame/LocalFrame.h" 8 #include "core/frame/LocalFrame.h"
9 #include "core/layout/LayoutView.h" 9 #include "core/layout/LayoutView.h"
10 #include "core/layout/api/LayoutPartItem.h" 10 #include "core/layout/api/LayoutPartItem.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 selectionVisualRectMap().contains(&object)); 50 selectionVisualRectMap().contains(&object));
51 if (object.hasPreviousSelectionVisualRect()) 51 if (object.hasPreviousSelectionVisualRect())
52 selectionVisualRectMap().remove(&object); 52 selectionVisualRectMap().remove(&object);
53 53
54 DCHECK(object.hasPreviousLocationInBacking() == 54 DCHECK(object.hasPreviousLocationInBacking() ==
55 locationInBackingMap().contains(&object)); 55 locationInBackingMap().contains(&object));
56 if (object.hasPreviousLocationInBacking()) 56 if (object.hasPreviousLocationInBacking())
57 locationInBackingMap().remove(&object); 57 locationInBackingMap().remove(&object);
58 } 58 }
59 59
60 // TODO(trchen): Use std::function<void, LayoutObject&> when available. 60 using LayoutObjectTraversalFunctor = std::function<void(const LayoutObject&)>;
61 template <typename LayoutObjectTraversalFunctor> 61
62 void traverseNonCompositingDescendantsInPaintOrder( 62 static void traverseNonCompositingDescendantsInPaintOrder(
63 const LayoutObject&, 63 const LayoutObject&,
64 const LayoutObjectTraversalFunctor&); 64 const LayoutObjectTraversalFunctor&);
65 65
66 template <typename LayoutObjectTraversalFunctor> 66 static void
67 void traverseNonCompositingDescendantsBelongingToAncestorPaintInvalidationContai ner( 67 traverseNonCompositingDescendantsBelongingToAncestorPaintInvalidationContainer(
68 const LayoutObject& object, 68 const LayoutObject& object,
69 const LayoutObjectTraversalFunctor& functor) { 69 const LayoutObjectTraversalFunctor& functor) {
70 // |object| is a paint invalidation container but is not a stacking context, 70 // |object| is a paint invalidation container, but is not a stacking context
71 // so the paint invalidation container of stacked descendants don't belong to 71 // or is a non-block-flow, so the paint invalidation container of stacked
72 // |object| but belong to an ancestor. This function traverses all such 72 // descendants may not belong to |object| but belong to an ancestor. This
73 // descendants. 73 // function traverses all such descendants.
74 DCHECK(object.isPaintInvalidationContainer() && 74 DCHECK(
75 !object.styleRef().isStackingContext()); 75 object.isPaintInvalidationContainer() &&
76 (!object.styleRef().isStackingContext() || !object.isLayoutBlockFlow()));
76 77
77 LayoutObject* descendant = object.nextInPreOrder(&object); 78 LayoutObject* descendant = object.nextInPreOrder(&object);
78 while (descendant) { 79 while (descendant) {
79 if (!descendant->hasLayer() || !descendant->styleRef().isStacked()) { 80 if (!object.isLayoutBlockFlow() && descendant->isFloating()) {
chrishtr 2017/01/19 21:22:26 && !isStacked() ? See https://codereview.chromium.
Xianzhu 2017/01/20 17:38:12 Yes. Moved the case under the condition at new lin
80 // Case 1: The descendant is not stacked (or is stacked but has not been 81 // Case 1 (rare): The descendant is a floating object below a composited
82 // non-block-flow object. The floating object subtree belongs to an
83 // ancestor in paint order, thus recur into the subtree.
84 traverseNonCompositingDescendantsInPaintOrder(*descendant, functor);
85 descendant = descendant->nextInPreOrderAfterChildren(&object);
86 } else if (!descendant->hasLayer() || !descendant->styleRef().isStacked()) {
87 // Case 2: The descendant is not stacked (or is stacked but has not been
81 // allocated a layer yet during style change), so either it's a paint 88 // allocated a layer yet during style change), so either it's a paint
82 // invalidation container in the same situation as |object|, or its paint 89 // invalidation container in the same situation as |object|, or its paint
83 // invalidation container is in such situation. Keep searching until a 90 // invalidation container is in such situation. Keep searching until a
84 // stacked layer is found. 91 // stacked layer is found.
85 descendant = descendant->nextInPreOrder(&object); 92 descendant = descendant->nextInPreOrder(&object);
86 } else if (!descendant->isPaintInvalidationContainer()) { 93 } else if (!descendant->isPaintInvalidationContainer()) {
87 // Case 2: The descendant is stacked and is not composited. 94 // Case 3: The descendant is stacked and is not composited.
88 // The invalidation container of its subtree is our ancestor, 95 // The invalidation container of its subtree is our ancestor,
89 // thus recur into the subtree. 96 // thus recur into the subtree.
90 traverseNonCompositingDescendantsInPaintOrder(*descendant, functor); 97 traverseNonCompositingDescendantsInPaintOrder(*descendant, functor);
91 descendant = descendant->nextInPreOrderAfterChildren(&object); 98 descendant = descendant->nextInPreOrderAfterChildren(&object);
92 } else if (descendant->styleRef().isStackingContext()) { 99 } else if (descendant->styleRef().isStackingContext() &&
93 // Case 3: The descendant is an invalidation container and is a stacking 100 descendant->isLayoutBlockFlow()) {
101 // Case 4: The descendant is an invalidation container and is a stacking
94 // context. No objects in the subtree can have invalidation container 102 // context. No objects in the subtree can have invalidation container
95 // outside of it, thus skip the whole subtree. 103 // outside of it, thus skip the whole subtree.
104 // This excludes non-block-flow because there might be floating objects
105 // under the descendant belonging to some ancestor in paint order.
96 descendant = descendant->nextInPreOrderAfterChildren(&object); 106 descendant = descendant->nextInPreOrderAfterChildren(&object);
97 } else { 107 } else {
98 // Case 4: The descendant is an invalidation container but not a stacking 108 // Case 5: The descendant is an invalidation container but not a stacking
99 // context. This is the same situation as |object|, thus keep searching. 109 // context, or the descendant is a non-block-flow stacking context.
110 // This is the same situation as |object|, thus keep searching.
100 descendant = descendant->nextInPreOrder(&object); 111 descendant = descendant->nextInPreOrder(&object);
101 } 112 }
102 } 113 }
103 } 114 }
104 115
105 template <typename LayoutObjectTraversalFunctor> 116 static void traverseNonCompositingDescendantsInPaintOrder(
106 void traverseNonCompositingDescendantsInPaintOrder(
107 const LayoutObject& object, 117 const LayoutObject& object,
108 const LayoutObjectTraversalFunctor& functor) { 118 const LayoutObjectTraversalFunctor& functor) {
109 functor(object); 119 functor(object);
110 LayoutObject* descendant = object.nextInPreOrder(&object); 120 LayoutObject* descendant = object.nextInPreOrder(&object);
111 while (descendant) { 121 while (descendant) {
112 if (!descendant->isPaintInvalidationContainer()) { 122 if (!descendant->isPaintInvalidationContainer()) {
113 functor(*descendant); 123 functor(*descendant);
114 descendant = descendant->nextInPreOrder(&object); 124 descendant = descendant->nextInPreOrder(&object);
115 } else if (descendant->styleRef().isStackingContext()) { 125 } else if (descendant->styleRef().isStackingContext() &&
126 descendant->isLayoutBlockFlow()) {
116 // The descendant is an invalidation container and is a stacking context. 127 // The descendant is an invalidation container and is a stacking context.
117 // No objects in the subtree can have invalidation container outside of 128 // No objects in the subtree can have invalidation container outside of
118 // it, thus skip the whole subtree. 129 // it, thus skip the whole subtree.
130 // This excludes non-block-flow because there might be floating objects
131 // under the descendant belonging to some ancestor in paint order.
119 descendant = descendant->nextInPreOrderAfterChildren(&object); 132 descendant = descendant->nextInPreOrderAfterChildren(&object);
120 } else { 133 } else {
121 // If a paint invalidation container is not a stacking context, 134 // If a paint invalidation container is not a stacking context, or the
122 // some of its descendants may belong to the parent container. 135 // descendant is a non-block-flow stacking context, some of its
136 // descendants may belong to the parent container.
123 traverseNonCompositingDescendantsBelongingToAncestorPaintInvalidationConta iner( 137 traverseNonCompositingDescendantsBelongingToAncestorPaintInvalidationConta iner(
124 *descendant, functor); 138 *descendant, functor);
125 descendant = descendant->nextInPreOrderAfterChildren(&object); 139 descendant = descendant->nextInPreOrderAfterChildren(&object);
126 } 140 }
127 } 141 }
128 } 142 }
129 143
144 static void setPaintingLayerNeedsRepaintDuringTraverse(
145 const LayoutObject& object) {
146 if (object.hasLayer() &&
147 toLayoutBoxModelObject(object).hasSelfPaintingLayer()) {
148 toLayoutBoxModelObject(object).layer()->setNeedsRepaint();
149 } else if (object.isFloating() && object.parent() &&
chrishtr 2017/01/19 21:22:26 Same here: skip isStacked() objects?
Xianzhu 2017/01/20 17:38:12 Now rebased on https://codereview.chromium.org/264
150 !object.parent()->isLayoutBlockFlow()) {
151 object.paintingLayer()->setNeedsRepaint();
152 }
153 }
154
130 void ObjectPaintInvalidator:: 155 void ObjectPaintInvalidator::
131 invalidateDisplayItemClientsIncludingNonCompositingDescendants( 156 invalidateDisplayItemClientsIncludingNonCompositingDescendants(
132 PaintInvalidationReason reason) { 157 PaintInvalidationReason reason) {
133 // This is valid because we want to invalidate the client in the display item 158 // This is valid because we want to invalidate the client in the display item
134 // list of the current backing. 159 // list of the current backing.
135 DisableCompositingQueryAsserts disabler; 160 DisableCompositingQueryAsserts disabler;
136 161
137 slowSetPaintingLayerNeedsRepaint(); 162 slowSetPaintingLayerNeedsRepaint();
138 traverseNonCompositingDescendantsInPaintOrder( 163 traverseNonCompositingDescendantsInPaintOrder(
139 m_object, [reason](const LayoutObject& object) { 164 m_object, [reason](const LayoutObject& object) {
140 if (object.hasLayer() && 165 setPaintingLayerNeedsRepaintDuringTraverse(object);
141 toLayoutBoxModelObject(object).hasSelfPaintingLayer())
142 toLayoutBoxModelObject(object).layer()->setNeedsRepaint();
143 object.invalidateDisplayItemClients(reason); 166 object.invalidateDisplayItemClients(reason);
144 }); 167 });
145 } 168 }
146 169
147 DISABLE_CFI_PERF 170 DISABLE_CFI_PERF
148 void ObjectPaintInvalidator::invalidatePaintOfPreviousVisualRect( 171 void ObjectPaintInvalidator::invalidatePaintOfPreviousVisualRect(
149 const LayoutBoxModelObject& paintInvalidationContainer, 172 const LayoutBoxModelObject& paintInvalidationContainer,
150 PaintInvalidationReason reason) { 173 PaintInvalidationReason reason) {
151 // It's caller's responsibility to ensure enclosingSelfPaintingLayer's 174 // It's caller's responsibility to ensure enclosingSelfPaintingLayer's
152 // needsRepaint is set. Don't set the flag here because getting 175 // needsRepaint is set. Don't set the flag here because getting
(...skipping 17 matching lines...) Expand all
170 // the new paint invalidation container happens to be the same as the old one. 193 // the new paint invalidation container happens to be the same as the old one.
171 m_object.getMutableForPainting().clearPreviousVisualRects(); 194 m_object.getMutableForPainting().clearPreviousVisualRects();
172 } 195 }
173 196
174 void ObjectPaintInvalidator:: 197 void ObjectPaintInvalidator::
175 invalidatePaintIncludingNonCompositingDescendants() { 198 invalidatePaintIncludingNonCompositingDescendants() {
176 // Since we're only painting non-composited layers, we know that they all 199 // Since we're only painting non-composited layers, we know that they all
177 // share the same paintInvalidationContainer. 200 // share the same paintInvalidationContainer.
178 const LayoutBoxModelObject& paintInvalidationContainer = 201 const LayoutBoxModelObject& paintInvalidationContainer =
179 m_object.containerForPaintInvalidation(); 202 m_object.containerForPaintInvalidation();
203 slowSetPaintingLayerNeedsRepaint();
180 traverseNonCompositingDescendantsInPaintOrder( 204 traverseNonCompositingDescendantsInPaintOrder(
181 m_object, [&paintInvalidationContainer](const LayoutObject& object) { 205 m_object, [&paintInvalidationContainer](const LayoutObject& object) {
182 if (object.hasLayer()) 206 setPaintingLayerNeedsRepaintDuringTraverse(object);
183 toLayoutBoxModelObject(object).layer()->setNeedsRepaint();
184 ObjectPaintInvalidator(object).invalidatePaintOfPreviousVisualRect( 207 ObjectPaintInvalidator(object).invalidatePaintOfPreviousVisualRect(
185 paintInvalidationContainer, PaintInvalidationSubtree); 208 paintInvalidationContainer, PaintInvalidationSubtree);
186 }); 209 });
187 } 210 }
188 211
189 void ObjectPaintInvalidator:: 212 void ObjectPaintInvalidator::
190 invalidatePaintIncludingNonSelfPaintingLayerDescendantsInternal( 213 invalidatePaintIncludingNonSelfPaintingLayerDescendantsInternal(
191 const LayoutBoxModelObject& paintInvalidationContainer) { 214 const LayoutBoxModelObject& paintInvalidationContainer) {
192 invalidatePaintOfPreviousVisualRect(paintInvalidationContainer, 215 invalidatePaintOfPreviousVisualRect(paintInvalidationContainer,
193 PaintInvalidationSubtree); 216 PaintInvalidationSubtree);
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 596
574 m_context.paintingLayer->setNeedsRepaint(); 597 m_context.paintingLayer->setNeedsRepaint();
575 m_object.invalidateDisplayItemClients(reason); 598 m_object.invalidateDisplayItemClients(reason);
576 return reason; 599 return reason;
577 } 600 }
578 601
579 DisablePaintInvalidationStateAsserts::DisablePaintInvalidationStateAsserts() 602 DisablePaintInvalidationStateAsserts::DisablePaintInvalidationStateAsserts()
580 : m_disabler(&gDisablePaintInvalidationStateAsserts, true) {} 603 : m_disabler(&gDisablePaintInvalidationStateAsserts, true) {}
581 604
582 } // namespace blink 605 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Source/core/paint/ObjectPaintInvalidatorTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698