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

Side by Side Diff: third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp

Issue 2736213002: 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 LayoutBlockItem caretPainterItem = 110 LayoutBlockItem caretPainterItem =
111 LayoutBlockItem(caretLayoutBlock(caretPosition.anchorNode())); 111 LayoutBlockItem(caretLayoutBlock(caretPosition.anchorNode()));
112 LayoutRect caretLocalRectWithWritingMode = caretLocalRect; 112 LayoutRect caretLocalRectWithWritingMode = caretLocalRect;
113 caretPainterItem.flipForWritingMode(caretLocalRectWithWritingMode); 113 caretPainterItem.flipForWritingMode(caretLocalRectWithWritingMode);
114 return mapCaretRectToCaretPainter(LayoutItem(layoutObject), caretPainterItem, 114 return mapCaretRectToCaretPainter(LayoutItem(layoutObject), caretPainterItem,
115 caretLocalRectWithWritingMode); 115 caretLocalRectWithWritingMode);
116 } 116 }
117 117
118 void CaretDisplayItemClient::updateStyleAndLayoutIfNeeded( 118 void CaretDisplayItemClient::updateStyleAndLayoutIfNeeded(
119 const PositionWithAffinity& caretPosition) { 119 const PositionWithAffinity& caretPosition) {
120 m_previousLayoutBlock = m_layoutBlock; 120 // This method may be called multiple times (e.g. in partial lifecycle
121 m_previousVisualRect = m_visualRect; 121 // updates) before a paint invalidation. We should save m_previousLayoutBlock
122 // and m_visualRectInPreviousLayoutBlock only if they have not been saved
123 // since the last paint invalidation to ensure the caret painted in the
124 // previous paint invalidated block will be invalidated. We don't care about
125 // intermediate changes of layoutBlock because they are not painted.
126 if (!m_previousLayoutBlock) {
127 m_previousLayoutBlock = m_layoutBlock;
128 m_visualRectInPreviousLayoutBlock = m_visualRect;
129 }
122 130
123 LayoutBlock* newLayoutBlock = caretLayoutBlock(caretPosition.anchorNode()); 131 LayoutBlock* newLayoutBlock = caretLayoutBlock(caretPosition.anchorNode());
124 if (newLayoutBlock != m_layoutBlock) { 132 if (newLayoutBlock != m_layoutBlock) {
125 if (m_layoutBlock) 133 if (m_layoutBlock)
126 m_layoutBlock->setMayNeedPaintInvalidation(); 134 m_layoutBlock->setMayNeedPaintInvalidation();
127 m_layoutBlock = newLayoutBlock; 135 m_layoutBlock = newLayoutBlock;
128 if (newLayoutBlock) 136 if (newLayoutBlock)
129 m_needsPaintInvalidation = true; 137 m_needsPaintInvalidation = true;
130 m_visualRect = LayoutRect(); 138 m_visualRect = LayoutRect();
131 } 139 }
(...skipping 19 matching lines...) Expand all
151 m_needsPaintInvalidation = true; 159 m_needsPaintInvalidation = true;
152 m_localRect = newLocalRect; 160 m_localRect = newLocalRect;
153 } 161 }
154 162
155 if (m_needsPaintInvalidation) 163 if (m_needsPaintInvalidation)
156 newLayoutBlock->setMayNeedPaintInvalidation(); 164 newLayoutBlock->setMayNeedPaintInvalidation();
157 } 165 }
158 166
159 void CaretDisplayItemClient::invalidatePaintIfNeeded( 167 void CaretDisplayItemClient::invalidatePaintIfNeeded(
160 const LayoutBlock& block, 168 const LayoutBlock& block,
161 const PaintInvalidatorContext& context, 169 const PaintInvalidatorContext& context) {
162 PaintInvalidationReason layoutBlockPaintInvalidationReason) {
163 if (block == m_layoutBlock) { 170 if (block == m_layoutBlock) {
164 invalidatePaintInCurrentLayoutBlock(context, 171 invalidatePaintInCurrentLayoutBlock(context);
165 layoutBlockPaintInvalidationReason);
166 return; 172 return;
167 } 173 }
168 174
169 if (block == m_previousLayoutBlock) { 175 if (block == m_previousLayoutBlock)
170 invalidatePaintInPreviousLayoutBlock(context, 176 invalidatePaintInPreviousLayoutBlock(context);
171 layoutBlockPaintInvalidationReason);
172 }
173 } 177 }
174 178
175 void CaretDisplayItemClient::invalidatePaintInPreviousLayoutBlock( 179 void CaretDisplayItemClient::invalidatePaintInPreviousLayoutBlock(
176 const PaintInvalidatorContext& context, 180 const PaintInvalidatorContext& context) {
177 PaintInvalidationReason layoutBlockPaintInvalidationReason) {
178 DCHECK(m_previousLayoutBlock); 181 DCHECK(m_previousLayoutBlock);
179 182
180 ObjectPaintInvalidatorWithContext objectInvalidator(*m_previousLayoutBlock, 183 ObjectPaintInvalidatorWithContext objectInvalidator(*m_previousLayoutBlock,
181 context); 184 context);
182 if (!isImmediateFullPaintInvalidationReason( 185 if (!isImmediateFullPaintInvalidationReason(
183 layoutBlockPaintInvalidationReason)) { 186 m_previousLayoutBlock->fullPaintInvalidationReason())) {
184 objectInvalidator.invalidatePaintRectangleWithContext( 187 objectInvalidator.invalidatePaintRectangleWithContext(
185 m_previousVisualRect, PaintInvalidationCaret); 188 m_visualRectInPreviousLayoutBlock, PaintInvalidationCaret);
186 } 189 }
187 190
188 context.paintingLayer->setNeedsRepaint(); 191 context.paintingLayer->setNeedsRepaint();
189 objectInvalidator.invalidateDisplayItemClient(*this, PaintInvalidationCaret); 192 objectInvalidator.invalidateDisplayItemClient(*this, PaintInvalidationCaret);
190 m_previousLayoutBlock = nullptr; 193 m_previousLayoutBlock = nullptr;
191 } 194 }
192 195
193 void CaretDisplayItemClient::invalidatePaintInCurrentLayoutBlock( 196 void CaretDisplayItemClient::invalidatePaintInCurrentLayoutBlock(
194 const PaintInvalidatorContext& context, 197 const PaintInvalidatorContext& context) {
195 PaintInvalidationReason layoutBlockPaintInvalidationReason) {
196 DCHECK(m_layoutBlock); 198 DCHECK(m_layoutBlock);
197 199
198 LayoutRect newVisualRect; 200 LayoutRect newVisualRect;
199 if (!m_localRect.isEmpty()) { 201 if (!m_localRect.isEmpty()) {
200 newVisualRect = m_localRect; 202 newVisualRect = m_localRect;
201 context.mapLocalRectToPaintInvalidationBacking(*m_layoutBlock, 203 context.mapLocalRectToPaintInvalidationBacking(*m_layoutBlock,
202 newVisualRect); 204 newVisualRect);
203 newVisualRect.move(m_layoutBlock->scrollAdjustmentForPaintInvalidation( 205 newVisualRect.move(m_layoutBlock->scrollAdjustmentForPaintInvalidation(
204 *context.paintInvalidationContainer)); 206 *context.paintInvalidationContainer));
205 207
206 if (m_layoutBlock->usesCompositedScrolling()) { 208 if (m_layoutBlock->usesCompositedScrolling()) {
207 // The caret should use scrolling coordinate space. 209 // The caret should use scrolling coordinate space.
208 DCHECK(m_layoutBlock == context.paintInvalidationContainer); 210 DCHECK(m_layoutBlock == context.paintInvalidationContainer);
209 newVisualRect.move(LayoutSize(m_layoutBlock->scrolledContentOffset())); 211 newVisualRect.move(LayoutSize(m_layoutBlock->scrolledContentOffset()));
210 } 212 }
211 } 213 }
212 214
213 if (!m_needsPaintInvalidation && newVisualRect == m_visualRect) 215 if (m_layoutBlock == m_previousLayoutBlock)
216 m_previousLayoutBlock = nullptr;
217
218 ObjectPaintInvalidatorWithContext objectInvalidator(*m_layoutBlock, context);
219 if (!m_needsPaintInvalidation && newVisualRect == m_visualRect) {
220 // The caret may change paint offset without changing visual rect, and we
221 // need to invalidate the display item client if the block is doing full
222 // paint invalidation.
223 if (isImmediateFullPaintInvalidationReason(
224 m_layoutBlock->fullPaintInvalidationReason()) ||
225 // For non-SPv2, ForcedSubtreeInvalidationChecking may hint change of
226 // paint offset. See ObjectPaintInvalidatorWithContext::
227 // invalidatePaintIfNeededWithComputedReason().
228 (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() &&
229 (context.forcedSubtreeInvalidationFlags &
230 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking))) {
231 objectInvalidator.invalidateDisplayItemClient(*this,
232 PaintInvalidationCaret);
233 }
214 return; 234 return;
235 }
215 236
216 m_needsPaintInvalidation = false; 237 m_needsPaintInvalidation = false;
217 238
218 ObjectPaintInvalidatorWithContext objectInvalidator(*m_layoutBlock, context);
219 if (!isImmediateFullPaintInvalidationReason( 239 if (!isImmediateFullPaintInvalidationReason(
220 layoutBlockPaintInvalidationReason)) { 240 m_layoutBlock->fullPaintInvalidationReason())) {
221 objectInvalidator.fullyInvalidatePaint(PaintInvalidationCaret, m_visualRect, 241 objectInvalidator.fullyInvalidatePaint(PaintInvalidationCaret, m_visualRect,
222 newVisualRect); 242 newVisualRect);
223 } 243 }
224 244
225 context.paintingLayer->setNeedsRepaint(); 245 context.paintingLayer->setNeedsRepaint();
226 objectInvalidator.invalidateDisplayItemClient(*this, PaintInvalidationCaret); 246 objectInvalidator.invalidateDisplayItemClient(*this, PaintInvalidationCaret);
227 247
228 m_visualRect = newVisualRect; 248 m_visualRect = newVisualRect;
229 } 249 }
230 250
(...skipping 16 matching lines...) Expand all
247 267
248 String CaretDisplayItemClient::debugName() const { 268 String CaretDisplayItemClient::debugName() const {
249 return "Caret"; 269 return "Caret";
250 } 270 }
251 271
252 LayoutRect CaretDisplayItemClient::visualRect() const { 272 LayoutRect CaretDisplayItemClient::visualRect() const {
253 return m_visualRect; 273 return m_visualRect;
254 } 274 }
255 275
256 } // namespace blink 276 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698