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

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

Issue 2732573003: Skip paint property update and visual rect update if no geometry change (Closed)
Patch Set: - Created 3 years, 9 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 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 } else { 335 } else {
336 context.forcedSubtreeInvalidationFlags = 0; 336 context.forcedSubtreeInvalidationFlags = 0;
337 } 337 }
338 } 338 }
339 339
340 DCHECK(context.paintInvalidationContainer == 340 DCHECK(context.paintInvalidationContainer ==
341 object.containerForPaintInvalidation()); 341 object.containerForPaintInvalidation());
342 DCHECK(context.paintingLayer == object.paintingLayer()); 342 DCHECK(context.paintingLayer == object.paintingLayer());
343 } 343 }
344 344
345 void PaintInvalidator::updateVisualRect(const LayoutObject& object, 345 void PaintInvalidator::updateVisualRectIfNeeded(
346 PaintInvalidatorContext& context) { 346 const LayoutObject& object,
347 Optional<ScopedUndoFrameViewContentClipAndScroll> 347 PaintInvalidatorContext& context) {
348 undoFrameViewContentClipAndScroll;
349
350 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled() &&
351 object.isLayoutView() && !object.isPaintInvalidationContainer()) {
352 undoFrameViewContentClipAndScroll.emplace(*toLayoutView(object).frameView(),
353 context);
354 }
355
356 // TODO(crbug.com/637313): Use GeometryMapper which now supports filter 348 // TODO(crbug.com/637313): Use GeometryMapper which now supports filter
357 // geometry effects, after skia optimizes filter's mapRect operation. 349 // geometry effects, after skia optimizes filter's mapRect operation.
358 // TODO(crbug.com/648274): This is a workaround for multi-column contents. 350 // TODO(crbug.com/648274): This is a workaround for multi-column contents.
359 if (object.hasFilterInducingProperty() || object.isLayoutFlowThread()) { 351 if (object.hasFilterInducingProperty() || object.isLayoutFlowThread()) {
360 context.forcedSubtreeInvalidationFlags |= 352 context.forcedSubtreeInvalidationFlags |=
361 PaintInvalidatorContext::ForcedSubtreeSlowPathRect; 353 PaintInvalidatorContext::ForcedSubtreeSlowPathRect;
362 } 354 }
363 355
364 ObjectPaintInvalidator objectPaintInvalidator(object); 356 ObjectPaintInvalidator objectPaintInvalidator(object);
365 context.oldVisualRect = object.visualRect(); 357 context.oldVisualRect = object.visualRect();
366 context.oldLocation = objectPaintInvalidator.locationInBacking(); 358 context.oldLocation = objectPaintInvalidator.locationInBacking();
367 359
360 if (!needsVisualRectUpdate(object, context)) {
361 #if CHECK_VISUAL_RECT_UPDATE
362 updateVisualRect(object, context);
363 DCHECK(
364 (context.oldVisualRect.isEmpty() && context.newVisualRect.isEmpty()) ||
365 enclosingIntRect(context.oldVisualRect) ==
366 enclosingIntRect(context.newVisualRect))
367 << "Visual rect changed without needsPaintOffsetAndVisualRectUpdate:"
368 << " object=" << object.debugName()
369 << " old=" << context.oldVisualRect.toString()
370 << " new=" << context.newVisualRect.toString();
371 DCHECK(object.isText() || context.oldLocation == context.newLocation)
372 << "Location changed without needsPaintOffsetAndVisualRectUpdate:"
373 << " old=" << context.oldLocation.toString()
374 << " new=" << context.newLocation.toString();
375 #endif
376 context.newVisualRect = context.oldVisualRect;
377 context.newLocation = context.oldLocation;
378 return;
379 }
380
381 #if DCHECK_IS_ON()
382 DCHECK(context.treeBuilderContext.updatedForSelf);
383 #endif
384 updateVisualRect(object, context);
385 object.getMutableForPainting().setVisualRect(context.newVisualRect);
386 objectPaintInvalidator.setLocationInBacking(context.newLocation);
387 }
388
389 void PaintInvalidator::updateVisualRect(const LayoutObject& object,
390 PaintInvalidatorContext& context) {
391 // The paint offset should already be updated through
392 // PaintPropertyTreeBuilder::updatePropertiesForSelf.
393 DCHECK(context.treeBuilderContext.current.paintOffset ==
394 object.paintOffset());
395
396 Optional<ScopedUndoFrameViewContentClipAndScroll>
397 undoFrameViewContentClipAndScroll;
398 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled() &&
399 object.isLayoutView() && !object.isPaintInvalidationContainer()) {
400 undoFrameViewContentClipAndScroll.emplace(*toLayoutView(object).frameView(),
401 context);
402 }
403
368 IntSize adjustment = object.scrollAdjustmentForPaintInvalidation( 404 IntSize adjustment = object.scrollAdjustmentForPaintInvalidation(
369 *context.paintInvalidationContainer); 405 *context.paintInvalidationContainer);
370 context.newVisualRect = computeVisualRectInBacking(object, context); 406 context.newVisualRect = computeVisualRectInBacking(object, context);
371 context.newVisualRect.move(adjustment); 407 context.newVisualRect.move(adjustment);
372 408
373 if (object.isText()) { 409 if (object.isText()) {
374 // Use visual rect location for LayoutTexts because it suffices to check 410 // Use visual rect location for LayoutTexts because it suffices to check
375 // whether a visual rect changes for layout caused invalidation. 411 // whether a visual rect changes for layout caused invalidation.
376 context.newLocation = context.newVisualRect.location(); 412 context.newLocation = context.newVisualRect.location();
377 } else { 413 } else {
378 context.newLocation = computeLocationInBacking(object, context); 414 context.newLocation = computeLocationInBacking(object, context);
379 context.newLocation.move(adjustment); 415 context.newLocation.move(adjustment);
380 416
381 // Location of empty visual rect doesn't affect paint invalidation. Set it 417 // Location of empty visual rect doesn't affect paint invalidation. Set it
382 // to newLocation to avoid saving the previous location separately in 418 // to newLocation to avoid saving the previous location separately in
383 // ObjectPaintInvalidator. 419 // ObjectPaintInvalidator.
384 if (context.newVisualRect.isEmpty()) 420 if (context.newVisualRect.isEmpty())
385 context.newVisualRect.setLocation(context.newLocation); 421 context.newVisualRect.setLocation(context.newLocation);
386 } 422 }
387
388 object.getMutableForPainting().setVisualRect(context.newVisualRect);
389 objectPaintInvalidator.setLocationInBacking(context.newLocation);
390 } 423 }
391 424
392 void PaintInvalidator::invalidatePaintIfNeeded( 425 void PaintInvalidator::invalidatePaintIfNeeded(
393 FrameView& frameView, 426 FrameView& frameView,
394 PaintInvalidatorContext& context) { 427 PaintInvalidatorContext& context) {
395 LayoutView* layoutView = frameView.layoutView(); 428 LayoutView* layoutView = frameView.layoutView();
396 CHECK(layoutView); 429 CHECK(layoutView);
397 430
398 context.paintInvalidationContainer = 431 context.paintInvalidationContainer =
399 context.paintInvalidationContainerForStackedContents = 432 context.paintInvalidationContainerForStackedContents =
400 &layoutView->containerForPaintInvalidation(); 433 &layoutView->containerForPaintInvalidation();
401 context.paintingLayer = layoutView->layer(); 434 context.paintingLayer = layoutView->layer();
402 435
403 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { 436 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
404 ScopedUndoFrameViewContentClipAndScroll undo(frameView, context); 437 ScopedUndoFrameViewContentClipAndScroll undo(frameView, context);
405 frameView.invalidatePaintOfScrollControlsIfNeeded(context); 438 frameView.invalidatePaintOfScrollControlsIfNeeded(context);
406 } 439 }
407 } 440 }
408 441
409 void PaintInvalidator::invalidatePaintIfNeeded( 442 void PaintInvalidator::invalidatePaintIfNeeded(
410 const LayoutObject& object, 443 const LayoutObject& object,
411 PaintInvalidatorContext& context) { 444 PaintInvalidatorContext& context) {
412 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), 445 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"),
413 "PaintInvalidator::invalidatePaintIfNeeded()", "object", 446 "PaintInvalidator::invalidatePaintIfNeeded()", "object",
414 object.debugName().ascii()); 447 object.debugName().ascii());
415 448
416 object.getMutableForPainting().ensureIsReadyForPaintInvalidation(); 449 object.getMutableForPainting().ensureIsReadyForPaintInvalidation();
417 450
418 // The paint offset should already be updated through
419 // PaintPropertyTreeBuilder::updatePropertiesForSelf.
420 DCHECK(context.treeBuilderContext.current.paintOffset ==
421 object.paintOffset());
422
423 updatePaintingLayer(object, context); 451 updatePaintingLayer(object, context);
424 452
425 if (object.document().printing() && 453 if (object.document().printing() &&
426 !RuntimeEnabledFeatures::printBrowserEnabled()) 454 !RuntimeEnabledFeatures::printBrowserEnabled())
427 return; // Don't invalidate paints if we're printing. 455 return; // Don't invalidate paints if we're printing.
428 456
429 updatePaintInvalidationContainer(object, context); 457 updatePaintInvalidationContainer(object, context);
458 updateVisualRectIfNeeded(object, context);
430 459
431 bool objectShouldCheckForPaintInvalidation = 460 if (!object
432 object 461 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() &&
433 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState(); 462 !(context.forcedSubtreeInvalidationFlags &
434 if (!context.forcedSubtreeInvalidationFlags && 463 ~PaintInvalidatorContext::ForcedSubtreeVisualRectUpdate)) {
435 !objectShouldCheckForPaintInvalidation) { 464 // We are done updating anything needed. No other paint invalidation work to
436 #if CHECK_VISUAL_RECT_UPDATE
437 updateVisualRect(object, context);
438 DCHECK(
439 (context.oldVisualRect.isEmpty() && context.newVisualRect.isEmpty()) ||
440 enclosingIntRect(context.oldVisualRect) ==
441 enclosingIntRect(context.newVisualRect))
442 << "Visual rect changed without needing paint invalidation:"
443 << " object=" << object.debugName()
444 << " old=" << context.oldVisualRect.toString()
445 << " new=" << context.newVisualRect.toString();
446 DCHECK(object.isText() || context.oldLocation == context.newLocation)
447 << "Location changed without needing paint invalidation:"
448 << " old=" << context.oldLocation.toString()
449 << " new=" << context.newLocation.toString();
450 #endif
451 return;
452 }
453
454 updateVisualRect(object, context);
455
456 if (!objectShouldCheckForPaintInvalidation &&
457 context.forcedSubtreeInvalidationFlags ==
458 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate) {
459 // We are done updating the visual rect. No other paint invalidation work to
460 // do for this object. 465 // do for this object.
461 return; 466 return;
462 } 467 }
463 468
464 PaintInvalidationReason reason = object.invalidatePaintIfNeeded(context); 469 PaintInvalidationReason reason = object.invalidatePaintIfNeeded(context);
465 switch (reason) { 470 switch (reason) {
466 case PaintInvalidationDelayedFull: 471 case PaintInvalidationDelayedFull:
467 m_pendingDelayedPaintInvalidations.push_back(&object); 472 m_pendingDelayedPaintInvalidations.push_back(&object);
468 break; 473 break;
469 case PaintInvalidationSubtree: 474 case PaintInvalidationSubtree:
(...skipping 20 matching lines...) Expand all
490 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; 495 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking;
491 } 496 }
492 } 497 }
493 498
494 void PaintInvalidator::processPendingDelayedPaintInvalidations() { 499 void PaintInvalidator::processPendingDelayedPaintInvalidations() {
495 for (auto target : m_pendingDelayedPaintInvalidations) 500 for (auto target : m_pendingDelayedPaintInvalidations)
496 target->getMutableForPainting().setShouldDoFullPaintInvalidation( 501 target->getMutableForPainting().setShouldDoFullPaintInvalidation(
497 PaintInvalidationDelayedFull); 502 PaintInvalidationDelayedFull);
498 } 503 }
499 504
505 bool PaintInvalidator::needsVisualRectUpdate(
506 const LayoutObject& object,
507 const PaintInvalidatorContext& context) {
508 return object.needsPaintOffsetAndVisualRectUpdate() ||
509 (context.forcedSubtreeInvalidationFlags &
510 ~PaintInvalidatorContext::ForcedSubtreeSlowPathRect);
511 }
512
500 } // namespace blink 513 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698