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

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

Issue 2706063003: Reduce the requirement for saving previousLocation (Closed)
Patch Set: - Created 3 years, 10 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 | « third_party/WebKit/Source/core/paint/BoxPaintInvalidatorTest.cpp ('k') | no next file » | 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/PaintInvalidator.h" 5 #include "core/paint/PaintInvalidator.h"
6 6
7 #include "core/editing/FrameSelection.h" 7 #include "core/editing/FrameSelection.h"
8 #include "core/frame/FrameView.h" 8 #include "core/frame/FrameView.h"
9 #include "core/frame/LocalFrame.h" 9 #include "core/frame/LocalFrame.h"
10 #include "core/frame/Settings.h" 10 #include "core/frame/Settings.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 // PaintInvalidator::mapLocalRectToBacking() when removing 45 // PaintInvalidator::mapLocalRectToBacking() when removing
46 // PaintInvalidationState. 46 // PaintInvalidationState.
47 // This function is templatized to avoid FloatRect<->LayoutRect conversions 47 // This function is templatized to avoid FloatRect<->LayoutRect conversions
48 // which affect performance. 48 // which affect performance.
49 template <typename Rect, typename Point> 49 template <typename Rect, typename Point>
50 static LayoutRect mapLocalRectToPaintInvalidationBacking( 50 static LayoutRect mapLocalRectToPaintInvalidationBacking(
51 const LayoutObject& object, 51 const LayoutObject& object,
52 const Rect& localRect, 52 const Rect& localRect,
53 const PaintInvalidatorContext& context, 53 const PaintInvalidatorContext& context,
54 GeometryMapper& geometryMapper) { 54 GeometryMapper& geometryMapper) {
55 if (localRect.isEmpty())
56 return LayoutRect();
57
55 bool isSVGChild = object.isSVGChild(); 58 bool isSVGChild = object.isSVGChild();
56 59
57 // TODO(wkorman): The flip below is required because visual rects are 60 // TODO(wkorman): The flip below is required because visual rects are
58 // currently in "physical coordinates with flipped block-flow direction" 61 // currently in "physical coordinates with flipped block-flow direction"
59 // (see LayoutBoxModelObject.h) but we need them to be in physical 62 // (see LayoutBoxModelObject.h) but we need them to be in physical
60 // coordinates. 63 // coordinates.
61 Rect rect = localRect; 64 Rect rect = localRect;
62 // Writing-mode flipping doesn't apply to non-root SVG. 65 // Writing-mode flipping doesn't apply to non-root SVG.
63 if (!isSVGChild) { 66 if (!isSVGChild) {
64 if (object.isBox()) { 67 if (object.isBox()) {
(...skipping 25 matching lines...) Expand all
90 LayoutRect result; 93 LayoutRect result;
91 if (context.forcedSubtreeInvalidationFlags & 94 if (context.forcedSubtreeInvalidationFlags &
92 PaintInvalidatorContext::ForcedSubtreeSlowPathRect) { 95 PaintInvalidatorContext::ForcedSubtreeSlowPathRect) {
93 result = slowMapToVisualRectInAncestorSpace( 96 result = slowMapToVisualRectInAncestorSpace(
94 object, *context.paintInvalidationContainer, rect); 97 object, *context.paintInvalidationContainer, rect);
95 } else if (object == context.paintInvalidationContainer) { 98 } else if (object == context.paintInvalidationContainer) {
96 result = LayoutRect(rect); 99 result = LayoutRect(rect);
97 } else { 100 } else {
98 // For non-root SVG, the input rect is in local SVG coordinates in which 101 // For non-root SVG, the input rect is in local SVG coordinates in which
99 // paint offset doesn't apply. 102 // paint offset doesn't apply.
100 if (!isSVGChild) { 103 if (!isSVGChild)
101 rect.moveBy(Point(object.paintOffset())); 104 rect.moveBy(Point(object.paintOffset()));
102 // Use enclosingIntRect to ensure the final visual rect will cover the
103 // rect in source coordinates no matter if the painting will use pixel
104 // snapping.
105 rect = Rect(enclosingIntRect(rect));
106 }
107 105
108 const auto* containerContentsProperties = 106 const auto* containerContentsProperties =
109 context.paintInvalidationContainer->paintProperties() 107 context.paintInvalidationContainer->paintProperties()
110 ->contentsProperties(); 108 ->contentsProperties();
109
111 if (context.treeBuilderContext.current.transform == 110 if (context.treeBuilderContext.current.transform ==
112 containerContentsProperties->transform() && 111 containerContentsProperties->transform() &&
113 context.treeBuilderContext.current.clip == 112 context.treeBuilderContext.current.clip ==
114 containerContentsProperties->clip()) { 113 containerContentsProperties->clip()) {
115 result = LayoutRect(rect); 114 result = LayoutRect(rect);
116 } else { 115 } else {
116 // Use enclosingIntRect to ensure the final visual rect will cover the
117 // rect in source coordinates no matter if the painting will use pixel
118 // snapping, when transforms are applied. If there is no transform,
119 // enclosingIntRect is applied in the last step of paint invalidation
120 // (see CompositedLayerMapping::setContentsNeedDisplayInRect()).
121 if (!isSVGChild &&
122 context.treeBuilderContext.current.transform !=
123 containerContentsProperties->transform())
124 rect = Rect(enclosingIntRect(rect));
125
117 PropertyTreeState currentTreeState( 126 PropertyTreeState currentTreeState(
118 context.treeBuilderContext.current.transform, 127 context.treeBuilderContext.current.transform,
119 context.treeBuilderContext.current.clip, nullptr); 128 context.treeBuilderContext.current.clip, nullptr);
120 result = LayoutRect( 129 result = LayoutRect(
121 geometryMapper 130 geometryMapper
122 .sourceToDestinationVisualRect(FloatRect(rect), currentTreeState, 131 .sourceToDestinationVisualRect(FloatRect(rect), currentTreeState,
123 *containerContentsProperties) 132 *containerContentsProperties)
124 .rect()); 133 .rect());
125 } 134 }
126 135
(...skipping 25 matching lines...) Expand all
152 return mapLocalRectToPaintInvalidationBacking<FloatRect, FloatPoint>( 161 return mapLocalRectToPaintInvalidationBacking<FloatRect, FloatPoint>(
153 object, localRect, context, m_geometryMapper); 162 object, localRect, context, m_geometryMapper);
154 } 163 }
155 return mapLocalRectToPaintInvalidationBacking<LayoutRect, LayoutPoint>( 164 return mapLocalRectToPaintInvalidationBacking<LayoutRect, LayoutPoint>(
156 object, object.localVisualRect(), context, m_geometryMapper); 165 object, object.localVisualRect(), context, m_geometryMapper);
157 } 166 }
158 167
159 LayoutPoint PaintInvalidator::computeLocationInBacking( 168 LayoutPoint PaintInvalidator::computeLocationInBacking(
160 const LayoutObject& object, 169 const LayoutObject& object,
161 const PaintInvalidatorContext& context) { 170 const PaintInvalidatorContext& context) {
162 // Use visual rect location for LayoutTexts because it suffices to check
163 // visual rect change for layout caused invalidation.
164 if (object.isText())
165 return context.newVisualRect.location();
166
167 LayoutPoint point; 171 LayoutPoint point;
168 if (object != context.paintInvalidationContainer) { 172 if (object != context.paintInvalidationContainer) {
169 point.moveBy(object.paintOffset()); 173 point.moveBy(object.paintOffset());
170 174
171 const auto* containerTransform = 175 const auto* containerTransform =
172 context.paintInvalidationContainer->paintProperties() 176 context.paintInvalidationContainer->paintProperties()
173 ->contentsProperties() 177 ->contentsProperties()
174 ->transform(); 178 ->transform();
175 if (context.treeBuilderContext.current.transform != containerTransform) { 179 if (context.treeBuilderContext.current.transform != containerTransform) {
176 point = LayoutPoint(m_geometryMapper 180 point = LayoutPoint(m_geometryMapper
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 // geometry effects, after skia optimizes filter's mapRect operation. 343 // geometry effects, after skia optimizes filter's mapRect operation.
340 // TODO(crbug.com/648274): This is a workaround for multi-column contents. 344 // TODO(crbug.com/648274): This is a workaround for multi-column contents.
341 if (object.hasFilterInducingProperty() || object.isLayoutFlowThread()) { 345 if (object.hasFilterInducingProperty() || object.isLayoutFlowThread()) {
342 context.forcedSubtreeInvalidationFlags |= 346 context.forcedSubtreeInvalidationFlags |=
343 PaintInvalidatorContext::ForcedSubtreeSlowPathRect; 347 PaintInvalidatorContext::ForcedSubtreeSlowPathRect;
344 } 348 }
345 349
346 ObjectPaintInvalidator objectPaintInvalidator(object); 350 ObjectPaintInvalidator objectPaintInvalidator(object);
347 context.oldVisualRect = object.previousVisualRect(); 351 context.oldVisualRect = object.previousVisualRect();
348 context.oldLocation = objectPaintInvalidator.previousLocationInBacking(); 352 context.oldLocation = objectPaintInvalidator.previousLocationInBacking();
349 context.newVisualRect = computeVisualRectInBacking(object, context);
350 context.newLocation = computeLocationInBacking(object, context);
351 353
352 IntSize adjustment = object.scrollAdjustmentForPaintInvalidation( 354 IntSize adjustment = object.scrollAdjustmentForPaintInvalidation(
353 *context.paintInvalidationContainer); 355 *context.paintInvalidationContainer);
354 context.newLocation.move(adjustment); 356 context.newVisualRect = computeVisualRectInBacking(object, context);
355 context.newVisualRect.move(adjustment); 357 context.newVisualRect.move(adjustment);
356 358
359 if (object.isText()) {
360 // Use visual rect location for LayoutTexts because it suffices to check
361 // whether a visual rect changes for layout caused invalidation.
362 context.newLocation = context.newVisualRect.location();
363 } else {
364 context.newLocation = computeLocationInBacking(object, context);
365 context.newLocation.move(adjustment);
366
367 // Location of empty visual rect doesn't affect paint invalidation. Set it
368 // to newLocation to avoid saving the previous location separately in
369 // ObjectPaintInvalidator.
370 if (context.newVisualRect.isEmpty())
371 context.newVisualRect.setLocation(context.newLocation);
372 }
373
357 object.getMutableForPainting().setPreviousVisualRect(context.newVisualRect); 374 object.getMutableForPainting().setPreviousVisualRect(context.newVisualRect);
358 objectPaintInvalidator.setPreviousLocationInBacking(context.newLocation); 375 objectPaintInvalidator.setPreviousLocationInBacking(context.newLocation);
359 } 376 }
360 377
361 void PaintInvalidator::invalidatePaintIfNeeded( 378 void PaintInvalidator::invalidatePaintIfNeeded(
362 FrameView& frameView, 379 FrameView& frameView,
363 PaintInvalidatorContext& context) { 380 PaintInvalidatorContext& context) {
364 LayoutView* layoutView = frameView.layoutView(); 381 LayoutView* layoutView = frameView.layoutView();
365 CHECK(layoutView); 382 CHECK(layoutView);
366 383
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; 464 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate;
448 } 465 }
449 466
450 void PaintInvalidator::processPendingDelayedPaintInvalidations() { 467 void PaintInvalidator::processPendingDelayedPaintInvalidations() {
451 for (auto target : m_pendingDelayedPaintInvalidations) 468 for (auto target : m_pendingDelayedPaintInvalidations)
452 target->getMutableForPainting().setShouldDoFullPaintInvalidation( 469 target->getMutableForPainting().setShouldDoFullPaintInvalidation(
453 PaintInvalidationDelayedFull); 470 PaintInvalidationDelayedFull);
454 } 471 }
455 472
456 } // namespace blink 473 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/paint/BoxPaintInvalidatorTest.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698