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

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

Issue 2208463003: First step of PaintInvalidator implementation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: - Created 4 years, 4 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
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/PaintInvalidator.h" 5 #include "core/paint/PaintInvalidator.h"
6 6
7 #include "core/editing/FrameSelection.h"
7 #include "core/frame/FrameView.h" 8 #include "core/frame/FrameView.h"
9 #include "core/frame/LocalFrame.h"
10 #include "core/frame/Settings.h"
8 #include "core/layout/LayoutObject.h" 11 #include "core/layout/LayoutObject.h"
12 #include "core/layout/svg/SVGLayoutSupport.h"
13 #include "core/paint/PaintLayer.h"
14 #include "core/paint/PaintLayerScrollableArea.h"
9 15
10 namespace blink { 16 namespace blink {
11 17
12 void PaintInvalidator::invalidatePaintIfNeeded(FrameView& frameView, const Paint PropertyTreeBuilderContext& treeContext, Optional<PaintInvalidatorContext>& pain tInvalidatorContext) 18 void PaintInvalidatorContext::mapLocalRectToPaintInvalidationBacking(const Layou tObject& object, LayoutRect& rect) const
13 { 19 {
14 paintInvalidatorContext.emplace(*frameView.layoutView(), m_pendingDelayedPai ntInvalidations); 20 // TODO(wangxianzhu): For now this is the same as the slow path in PaintInva lidationState.
15 frameView.invalidatePaintIfNeeded(*paintInvalidatorContext); 21 // Should implement this with GeometryMapper.
16 } 22 if (object.isBox())
17 23 toLayoutBox(object).flipForWritingMode(rect);
18 void PaintInvalidator::invalidatePaintIfNeeded(const LayoutObject& layoutObject, const PaintPropertyTreeBuilderContext& treeContext, const PaintInvalidatorConte xt& parentPaintInvalidatorContext, Optional<PaintInvalidatorContext>& paintInval idatorContext) 24
19 { 25 if (object.isLayoutView())
20 if (!layoutObject.shouldCheckForPaintInvalidation(parentPaintInvalidatorCont ext)) 26 toLayoutView(object).mapToVisualRectInAncestorSpace(paintInvalidationCon tainer, rect, InputIsInFrameCoordinates, DefaultVisualRectFlags);
27 else
28 object.mapToVisualRectInAncestorSpace(paintInvalidationContainer, rect);
29 }
30
31 static LayoutRect computePaintInvalidationRectInBacking(const LayoutObject& obje ct, const PaintInvalidatorContext& context)
32 {
33 // TODO(wangxianzhu): For now this is the same as the slow path in PaintInva lidationState.
34 // Should implement this with GeometryMapper.
35 if (object.isSVG() && !object.isSVGRoot()) {
36 LayoutRect rect = SVGLayoutSupport::clippedOverflowRectForPaintInvalidat ion(object, *context.paintInvalidationContainer);
37 if (context.paintInvalidationContainer->layer()->groupedMapping())
38 PaintLayer::mapRectInPaintInvalidationContainerToBacking(*context.pa intInvalidationContainer, rect);
39 return rect;
40 }
41
42 LayoutRect rect = object.localOverflowRectForPaintInvalidation();
43 context.mapLocalRectToPaintInvalidationBacking(object, rect);
44 return rect;
45 }
46
47 static LayoutPoint computeLocationFromPaintInvalidationBacking(const LayoutObjec t& object, const PaintInvalidatorContext& context)
48 {
49 // TODO(wangxianzhu): For now this is the same as the slow path in PaintInva lidationState.
50 // Should implement this with GeometryMapper.
51 FloatPoint point;
52 if (object != context.paintInvalidationContainer) {
53 if (object.isLayoutView())
54 point = toLayoutView(object).localToAncestorPoint(point, context.pai ntInvalidationContainer, TraverseDocumentBoundaries | InputIsInFrameCoordinates) ;
55 else
56 point = object.localToAncestorPoint(point, context.paintInvalidation Container, TraverseDocumentBoundaries);
57 }
58
59 if (context.paintInvalidationContainer->layer()->groupedMapping())
60 PaintLayer::mapPointInPaintInvalidationContainerToBacking(*context.paint InvalidationContainer, point);
61
62 return LayoutPoint(point);
63 }
64
65 static void updatePaintingLayer(const LayoutObject& object, PaintInvalidatorCont ext& context)
66 {
67 if (object.hasLayer() && toLayoutBoxModelObject(object).hasSelfPaintingLayer ())
68 context.paintingLayer = toLayoutBoxModelObject(object).layer();
69
70 if (object.isLayoutBlockFlow() && toLayoutBlockFlow(object).containsFloats() )
71 context.paintingLayer->setNeedsPaintPhaseFloat();
72
73 if (object == context.paintingLayer->layoutObject())
21 return; 74 return;
22 75
23 paintInvalidatorContext.emplace(parentPaintInvalidatorContext, layoutObject) ; 76 if (object.styleRef().hasOutline())
24 77 context.paintingLayer->setNeedsPaintPhaseDescendantOutlines();
25 if (layoutObject.mayNeedPaintInvalidationSubtree()) 78
26 paintInvalidatorContext->setForceSubtreeInvalidationCheckingWithinContai ner(); 79 if (object.hasBoxDecorationBackground()
27 80 // We also paint overflow controls in background phase.
28 PaintInvalidationReason reason = layoutObject.getMutableForPainting().invali datePaintIfNeeded(*paintInvalidatorContext); 81 || (object.hasOverflowClip() && toLayoutBox(object).getScrollableArea()- >hasOverflowControls())) {
29 layoutObject.getMutableForPainting().clearPaintInvalidationFlags(*paintInval idatorContext); 82 context.paintingLayer->setNeedsPaintPhaseDescendantBlockBackgrounds();
30 83 }
31 paintInvalidatorContext->updateForChildren(reason); 84 }
85
86 static void updateContext(const LayoutObject& object, PaintInvalidatorContext& c ontext)
87 {
88 if (object.isPaintInvalidationContainer()) {
89 context.paintInvalidationContainer = toLayoutBoxModelObject(&object);
90 if (object.styleRef().isStackingContext())
91 context.paintInvalidationContainerForStackedContents = toLayoutBoxMo delObject(&object);
92 } else if (object.isLayoutView()) {
93 // paintInvalidationContainerForStackedContents is only for stacked desc endants in its own frame,
94 // because it doesn't establish stacking context for stacked contents in sub-frames.
chrishtr 2016/08/10 20:47:33 I know you're copying this comment, but is this re
Xianzhu 2016/08/10 22:16:43 No. It means a frame breaks the relationship betwe
chrishtr 2016/08/10 23:23:22 Isn't this equivalent to the situation in line 91
Xianzhu 2016/08/10 23:48:31 The case at line 91 is for a paint invalidation co
95 // Contents stacked in the root stacking context in this frame should us e this frame's paintInvalidationContainer.
96 context.paintInvalidationContainerForStackedContents = context.paintInva lidationContainer;
97 } else if (object.styleRef().isStacked()
98 // This is to exclude some objects (e.g. LayoutText) inheriting stacked style from parent but aren't actually stacked.
99 && object.hasLayer()
100 && context.paintInvalidationContainer != context.paintInvalidationContai nerForStackedContents) {
101 // The current object is stacked, so we should use m_paintInvalidationCo ntainerForStackedContents as its
102 // paint invalidation container on which the current object is painted.
103 context.paintInvalidationContainer = context.paintInvalidationContainerF orStackedContents;
104 if (context.forcedSubtreeInvalidationFlags & PaintInvalidatorContext::Fo rcedSubtreeFullInvalidationForStackedContents)
105 context.forcedSubtreeInvalidationFlags |= PaintInvalidatorContext::F orcedSubtreeFullInvalidation;
106 }
107
108 if (object == context.paintInvalidationContainer) {
109 // When we hit a new paint invalidation container, we don't need to
110 // continue forcing a check for paint invalidation, since we're
111 // descending into a different invalidation container. (For instance if
112 // our parents were moved, the entire container will just move.)
113 if (object != context.paintInvalidationContainerForStackedContents) {
114 // However, we need to keep the ForcedSubtreeFullInvalidationForStac kedContents flag
115 // if the current object isn't the paint invalidation container of s tacked contents.
116 context.forcedSubtreeInvalidationFlags &= PaintInvalidatorContext::F orcedSubtreeFullInvalidationForStackedContents;
117 } else {
118 context.forcedSubtreeInvalidationFlags = 0;
119 }
120 }
121
122 DCHECK(context.paintInvalidationContainer == object.containerForPaintInvalid ation());
123 DCHECK(context.paintingLayer == object.paintingLayer());
124
125 if (object.mayNeedPaintInvalidationSubtree())
chrishtr 2016/08/10 20:47:33 This is previously in LayoutBoxModelObject::invali
Xianzhu 2016/08/10 22:16:43 The reason was that mayNeedPaintInvalidationSubtre
126 context.forcedSubtreeInvalidationFlags |= PaintInvalidatorContext::Force dSubtreeInvalidationChecking;
127
128 context.oldBounds = object.previousPaintInvalidationRect();
129 context.oldLocation = object.previousPositionFromPaintInvalidationBacking();
130 context.newBounds = computePaintInvalidationRectInBacking(object, context);
131 context.newLocation = computeLocationFromPaintInvalidationBacking(object, co ntext);
132
133 // Composited scrolling should not be included in the bounds and position tr acking, because the graphics layer backing the scroller
134 // does not move on scroll.
135 // TODO(chrishtr): can we just avoid adding in the scroll in the first place in LayoutBox::mapScrollingContentsRectToBoxSpace?
chrishtr 2016/08/10 20:47:33 I landed the patch to remove this...
Xianzhu 2016/08/10 22:16:43 My fault when dealing with conflicts. Fixed.
136 if (object.compositedScrollsWithRespectTo(*context.paintInvalidationContaine r)) {
137 LayoutSize inverseOffset(toLayoutBox(context.paintInvalidationContainer) ->scrolledContentOffset());
138 context.newLocation.move(inverseOffset);
139 context.newBounds.move(inverseOffset);
140 }
141
142 object.getMutableForPainting().setPreviousPaintInvalidationRect(context.newB ounds);
143 object.getMutableForPainting().setPreviousPositionFromPaintInvalidationBacki ng(context.newLocation);
144 }
145
146 void PaintInvalidator::invalidatePaintIfNeeded(FrameView& frameView, PaintInvali datorContext& context)
147 {
148 LayoutView* layoutView = frameView.layoutView();
149 CHECK(layoutView);
150
151 context.paintInvalidationContainer = context.paintInvalidationContainerForSt ackedContents = &layoutView->containerForPaintInvalidation();
152 context.paintingLayer = layoutView->layer();
153
154 if (!frameView.frame().settings() || !frameView.frame().settings()->rootLaye rScrolls())
155 frameView.invalidatePaintOfScrollControlsIfNeeded(context);
156
157 if (frameView.frame().selection().isCaretBoundsDirty())
158 frameView.frame().selection().invalidateCaretRect();
159
160 // Temporary callback for crbug.com/487345,402044
161 // TODO(ojan): Make this more general to be used by PositionObserver
162 // and rAF throttling.
163 IntRect visibleRect = frameView.rootFrameToContents(frameView.computeVisible Area());
164 layoutView->sendMediaPositionChangeNotifications(visibleRect);
165 }
166
167 void PaintInvalidator::invalidatePaintIfNeeded(const LayoutObject& object, Paint InvalidatorContext& context)
168 {
169 if (!context.forcedSubtreeInvalidationFlags && !object.shouldCheckForPaintIn validationRegardlessOfPaintInvalidationState())
170 return;
171
172 updatePaintingLayer(object, context);
173
174 if (object.document().printing())
175 return; // Don't invalidate paints if we're printing.
176
177 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), "PaintInvalida tor::invalidatePaintIfNeeded()", "object", object.debugName().ascii());
178
179 updateContext(object, context);
180
181 if (!object.shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationStat e() && context.forcedSubtreeInvalidationFlags == PaintInvalidatorContext::Forced SubtreeInvalidationRectUpdate) {
182 // We are done updating the paint invalidation rect. No other paint inva lidation work to do for this object.
183 return;
184 }
185
186 switch (object.invalidatePaintIfNeeded(context)) {
187 case PaintInvalidationDelayedFull:
188 m_pendingDelayedPaintInvalidations.append(&object);
189 break;
190 case PaintInvalidationSubtree:
191 context.forcedSubtreeInvalidationFlags |= (PaintInvalidatorContext::Forc edSubtreeFullInvalidation | PaintInvalidatorContext::ForcedSubtreeFullInvalidati onForStackedContents);
192 break;
193 case PaintInvalidationSVGResourceChange:
194 context.forcedSubtreeInvalidationFlags |= PaintInvalidatorContext::Force dSubtreeInvalidationChecking;
195 break;
196 default:
197 break;
198 }
199
200 if (context.oldLocation != context.newLocation)
201 context.forcedSubtreeInvalidationFlags |= PaintInvalidatorContext::Force dSubtreeInvalidationChecking;
202
203 object.getMutableForPainting().clearPaintInvalidationFlags();
32 } 204 }
33 205
34 void PaintInvalidator::processPendingDelayedPaintInvalidations() 206 void PaintInvalidator::processPendingDelayedPaintInvalidations()
35 { 207 {
36 for (auto target : m_pendingDelayedPaintInvalidations) 208 for (auto target : m_pendingDelayedPaintInvalidations)
37 target->getMutableForPainting().setShouldDoDelayedFullPaintInvalidation( ); 209 target->getMutableForPainting().setShouldDoFullPaintInvalidation(PaintIn validationDelayedFull);
38 } 210 }
39 211
40 } // namespace blink 212 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698