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

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
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.
wkorman 2017/02/21 22:54:19 Are transforms the only potential cause of subpixe
Xianzhu 2017/02/21 23:15:59 Yes. We need to apply enclosingIntRect before ear
119 if (!isSVGChild &&
120 context.treeBuilderContext.current.transform !=
121 containerContentsProperties->transform())
122 rect = Rect(enclosingIntRect(rect));
123
117 PropertyTreeState currentTreeState( 124 PropertyTreeState currentTreeState(
118 context.treeBuilderContext.current.transform, 125 context.treeBuilderContext.current.transform,
119 context.treeBuilderContext.current.clip, nullptr); 126 context.treeBuilderContext.current.clip, nullptr);
120 result = LayoutRect( 127 result = LayoutRect(
121 geometryMapper 128 geometryMapper
122 .sourceToDestinationVisualRect(FloatRect(rect), currentTreeState, 129 .sourceToDestinationVisualRect(FloatRect(rect), currentTreeState,
123 *containerContentsProperties) 130 *containerContentsProperties)
124 .rect()); 131 .rect());
125 } 132 }
126 133
(...skipping 25 matching lines...) Expand all
152 return mapLocalRectToPaintInvalidationBacking<FloatRect, FloatPoint>( 159 return mapLocalRectToPaintInvalidationBacking<FloatRect, FloatPoint>(
153 object, localRect, context, m_geometryMapper); 160 object, localRect, context, m_geometryMapper);
154 } 161 }
155 return mapLocalRectToPaintInvalidationBacking<LayoutRect, LayoutPoint>( 162 return mapLocalRectToPaintInvalidationBacking<LayoutRect, LayoutPoint>(
156 object, object.localVisualRect(), context, m_geometryMapper); 163 object, object.localVisualRect(), context, m_geometryMapper);
157 } 164 }
158 165
159 LayoutPoint PaintInvalidator::computeLocationInBacking( 166 LayoutPoint PaintInvalidator::computeLocationInBacking(
160 const LayoutObject& object, 167 const LayoutObject& object,
161 const PaintInvalidatorContext& context) { 168 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; 169 LayoutPoint point;
168 if (object != context.paintInvalidationContainer) { 170 if (object != context.paintInvalidationContainer) {
169 point.moveBy(object.paintOffset()); 171 point.moveBy(object.paintOffset());
170 172
171 const auto* containerTransform = 173 const auto* containerTransform =
172 context.paintInvalidationContainer->paintProperties() 174 context.paintInvalidationContainer->paintProperties()
173 ->contentsProperties() 175 ->contentsProperties()
174 ->transform(); 176 ->transform();
175 if (context.treeBuilderContext.current.transform != containerTransform) { 177 if (context.treeBuilderContext.current.transform != containerTransform) {
176 point = LayoutPoint(m_geometryMapper 178 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. 341 // geometry effects, after skia optimizes filter's mapRect operation.
340 // TODO(crbug.com/648274): This is a workaround for multi-column contents. 342 // TODO(crbug.com/648274): This is a workaround for multi-column contents.
341 if (object.hasFilterInducingProperty() || object.isLayoutFlowThread()) { 343 if (object.hasFilterInducingProperty() || object.isLayoutFlowThread()) {
342 context.forcedSubtreeInvalidationFlags |= 344 context.forcedSubtreeInvalidationFlags |=
343 PaintInvalidatorContext::ForcedSubtreeSlowPathRect; 345 PaintInvalidatorContext::ForcedSubtreeSlowPathRect;
344 } 346 }
345 347
346 ObjectPaintInvalidator objectPaintInvalidator(object); 348 ObjectPaintInvalidator objectPaintInvalidator(object);
347 context.oldVisualRect = object.previousVisualRect(); 349 context.oldVisualRect = object.previousVisualRect();
348 context.oldLocation = objectPaintInvalidator.previousLocationInBacking(); 350 context.oldLocation = objectPaintInvalidator.previousLocationInBacking();
349 context.newVisualRect = computeVisualRectInBacking(object, context);
350 context.newLocation = computeLocationInBacking(object, context);
351 351
352 IntSize adjustment = object.scrollAdjustmentForPaintInvalidation( 352 IntSize adjustment = object.scrollAdjustmentForPaintInvalidation(
353 *context.paintInvalidationContainer); 353 *context.paintInvalidationContainer);
354 context.newLocation.move(adjustment); 354 context.newVisualRect = computeVisualRectInBacking(object, context);
355 context.newVisualRect.move(adjustment); 355 context.newVisualRect.move(adjustment);
356 356
357 if (object.isText()) {
358 // Use visual rect location for LayoutTexts because it suffices to check
359 // visual rect change for layout caused invalidation.
wkorman 2017/02/21 22:54:19 insert 'whether a' before 'visual'
Xianzhu 2017/02/21 23:15:59 Done.
360 context.newLocation = context.newVisualRect.location();
361 } else {
362 context.newLocation = computeLocationInBacking(object, context);
363 context.newLocation.move(adjustment);
wkorman 2017/02/21 22:54:19 We don't need this for the text case?
Xianzhu 2017/02/21 23:15:59 No, because context.newVisualRect.location() has a
364
365 // Location of empty visual rect doesn't affect paint invalidation. Set it
366 // to newLocation to avoid saving the previous location separately in
367 // ObjectPaintInvalidator.
368 if (context.newVisualRect.isEmpty())
369 context.newVisualRect.setLocation(context.newLocation);
370 }
371
357 object.getMutableForPainting().setPreviousVisualRect(context.newVisualRect); 372 object.getMutableForPainting().setPreviousVisualRect(context.newVisualRect);
358 objectPaintInvalidator.setPreviousLocationInBacking(context.newLocation); 373 objectPaintInvalidator.setPreviousLocationInBacking(context.newLocation);
359 } 374 }
360 375
361 void PaintInvalidator::invalidatePaintIfNeeded( 376 void PaintInvalidator::invalidatePaintIfNeeded(
362 FrameView& frameView, 377 FrameView& frameView,
363 PaintInvalidatorContext& context) { 378 PaintInvalidatorContext& context) {
364 LayoutView* layoutView = frameView.layoutView(); 379 LayoutView* layoutView = frameView.layoutView();
365 CHECK(layoutView); 380 CHECK(layoutView);
366 381
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; 462 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate;
448 } 463 }
449 464
450 void PaintInvalidator::processPendingDelayedPaintInvalidations() { 465 void PaintInvalidator::processPendingDelayedPaintInvalidations() {
451 for (auto target : m_pendingDelayedPaintInvalidations) 466 for (auto target : m_pendingDelayedPaintInvalidations)
452 target->getMutableForPainting().setShouldDoFullPaintInvalidation( 467 target->getMutableForPainting().setShouldDoFullPaintInvalidation(
453 PaintInvalidationDelayedFull); 468 PaintInvalidationDelayedFull);
454 } 469 }
455 470
456 } // namespace blink 471 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698