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

Unified Diff: third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp

Issue 2745793002: Fix caret paint invalidation issues (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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp
diff --git a/third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp b/third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp
index b5089bc6d6662368fbf3e7f2ab0dee5810393380..f31f5fcfb70735f7da1a5d512d614ec8779192e1 100644
--- a/third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp
+++ b/third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp
@@ -117,8 +117,16 @@ LayoutRect CaretDisplayItemClient::computeCaretRect(
void CaretDisplayItemClient::updateStyleAndLayoutIfNeeded(
const PositionWithAffinity& caretPosition) {
- m_previousLayoutBlock = m_layoutBlock;
- m_previousVisualRect = m_visualRect;
+ // This method may be called multiple times (e.g. in partial lifecycle
+ // updates) before a paint invalidation. We should save m_previousLayoutBlock
+ // and m_visualRectInPreviousLayoutBlock only if they have not been saved
+ // since the last paint invalidation to ensure the caret painted in the
+ // previous paint invalidated block will be invalidated. We don't care about
+ // intermediate changes of layoutBlock because they are not painted.
+ if (!m_previousLayoutBlock) {
+ m_previousLayoutBlock = m_layoutBlock;
+ m_visualRectInPreviousLayoutBlock = m_visualRect;
+ }
LayoutBlock* newLayoutBlock = caretLayoutBlock(caretPosition.anchorNode());
if (newLayoutBlock != m_layoutBlock) {
@@ -158,31 +166,26 @@ void CaretDisplayItemClient::updateStyleAndLayoutIfNeeded(
void CaretDisplayItemClient::invalidatePaintIfNeeded(
const LayoutBlock& block,
- const PaintInvalidatorContext& context,
- PaintInvalidationReason layoutBlockPaintInvalidationReason) {
+ const PaintInvalidatorContext& context) {
if (block == m_layoutBlock) {
- invalidatePaintInCurrentLayoutBlock(context,
- layoutBlockPaintInvalidationReason);
+ invalidatePaintInCurrentLayoutBlock(context);
return;
}
- if (block == m_previousLayoutBlock) {
- invalidatePaintInPreviousLayoutBlock(context,
- layoutBlockPaintInvalidationReason);
- }
+ if (block == m_previousLayoutBlock)
+ invalidatePaintInPreviousLayoutBlock(context);
}
void CaretDisplayItemClient::invalidatePaintInPreviousLayoutBlock(
- const PaintInvalidatorContext& context,
- PaintInvalidationReason layoutBlockPaintInvalidationReason) {
+ const PaintInvalidatorContext& context) {
DCHECK(m_previousLayoutBlock);
ObjectPaintInvalidatorWithContext objectInvalidator(*m_previousLayoutBlock,
context);
if (!isImmediateFullPaintInvalidationReason(
- layoutBlockPaintInvalidationReason)) {
+ m_previousLayoutBlock->fullPaintInvalidationReason())) {
objectInvalidator.invalidatePaintRectangleWithContext(
- m_previousVisualRect, PaintInvalidationCaret);
+ m_visualRectInPreviousLayoutBlock, PaintInvalidationCaret);
}
context.paintingLayer->setNeedsRepaint();
@@ -191,8 +194,7 @@ void CaretDisplayItemClient::invalidatePaintInPreviousLayoutBlock(
}
void CaretDisplayItemClient::invalidatePaintInCurrentLayoutBlock(
- const PaintInvalidatorContext& context,
- PaintInvalidationReason layoutBlockPaintInvalidationReason) {
+ const PaintInvalidatorContext& context) {
DCHECK(m_layoutBlock);
LayoutRect newVisualRect;
@@ -210,14 +212,32 @@ void CaretDisplayItemClient::invalidatePaintInCurrentLayoutBlock(
}
}
- if (!m_needsPaintInvalidation && newVisualRect == m_visualRect)
+ if (m_layoutBlock == m_previousLayoutBlock)
+ m_previousLayoutBlock = nullptr;
+
+ ObjectPaintInvalidatorWithContext objectInvalidator(*m_layoutBlock, context);
+ if (!m_needsPaintInvalidation && newVisualRect == m_visualRect) {
+ // The caret may change paint offset without changing visual rect, and we
+ // need to invalidate the display item client if the block is doing full
+ // paint invalidation.
+ if (isImmediateFullPaintInvalidationReason(
+ m_layoutBlock->fullPaintInvalidationReason()) ||
+ // For non-SPv2, ForcedSubtreeInvalidationChecking may hint change of
+ // paint offset. See ObjectPaintInvalidatorWithContext::
+ // invalidatePaintIfNeededWithComputedReason().
+ (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() &&
+ (context.forcedSubtreeInvalidationFlags &
+ PaintInvalidatorContext::ForcedSubtreeInvalidationChecking))) {
+ objectInvalidator.invalidateDisplayItemClient(*this,
+ PaintInvalidationCaret);
+ }
return;
+ }
m_needsPaintInvalidation = false;
- ObjectPaintInvalidatorWithContext objectInvalidator(*m_layoutBlock, context);
if (!isImmediateFullPaintInvalidationReason(
- layoutBlockPaintInvalidationReason)) {
+ m_layoutBlock->fullPaintInvalidationReason())) {
objectInvalidator.fullyInvalidatePaint(PaintInvalidationCaret, m_visualRect,
newVisualRect);
}

Powered by Google App Engine
This is Rietveld 408576698