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

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 // We should save m_previousLayoutBlock and m_visualRectInPreviousLayoutBlock
121 m_previousVisualRect = m_visualRect; 121 // only if they have not been saved since the last paint invalidation.
chrishtr 2017/03/08 17:36:06 This conditional is needed because there may be mu
Xianzhu 2017/03/08 19:38:22 Yes. Added comment.
122 if (!m_previousLayoutBlock) {
123 m_previousLayoutBlock = m_layoutBlock;
124 m_visualRectInPreviousLayoutBlock = m_visualRect;
125 }
122 126
123 LayoutBlock* newLayoutBlock = caretLayoutBlock(caretPosition.anchorNode()); 127 LayoutBlock* newLayoutBlock = caretLayoutBlock(caretPosition.anchorNode());
124 if (newLayoutBlock != m_layoutBlock) { 128 if (newLayoutBlock != m_layoutBlock) {
125 if (m_layoutBlock) 129 if (m_layoutBlock)
126 m_layoutBlock->setMayNeedPaintInvalidation(); 130 m_layoutBlock->setMayNeedPaintInvalidation();
127 m_layoutBlock = newLayoutBlock; 131 m_layoutBlock = newLayoutBlock;
128 if (newLayoutBlock) 132 if (newLayoutBlock)
129 m_needsPaintInvalidation = true; 133 m_needsPaintInvalidation = true;
130 m_visualRect = LayoutRect(); 134 m_visualRect = LayoutRect();
131 } 135 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 void CaretDisplayItemClient::invalidatePaintInPreviousLayoutBlock( 179 void CaretDisplayItemClient::invalidatePaintInPreviousLayoutBlock(
176 const PaintInvalidatorContext& context, 180 const PaintInvalidatorContext& context,
177 PaintInvalidationReason layoutBlockPaintInvalidationReason) { 181 PaintInvalidationReason layoutBlockPaintInvalidationReason) {
178 DCHECK(m_previousLayoutBlock); 182 DCHECK(m_previousLayoutBlock);
179 183
180 ObjectPaintInvalidatorWithContext objectInvalidator(*m_previousLayoutBlock, 184 ObjectPaintInvalidatorWithContext objectInvalidator(*m_previousLayoutBlock,
181 context); 185 context);
182 if (!isImmediateFullPaintInvalidationReason( 186 if (!isImmediateFullPaintInvalidationReason(
183 layoutBlockPaintInvalidationReason)) { 187 layoutBlockPaintInvalidationReason)) {
184 objectInvalidator.invalidatePaintRectangleWithContext( 188 objectInvalidator.invalidatePaintRectangleWithContext(
185 m_previousVisualRect, PaintInvalidationCaret); 189 m_visualRectInPreviousLayoutBlock, PaintInvalidationCaret);
186 } 190 }
187 191
188 context.paintingLayer->setNeedsRepaint(); 192 context.paintingLayer->setNeedsRepaint();
189 objectInvalidator.invalidateDisplayItemClient(*this, PaintInvalidationCaret); 193 objectInvalidator.invalidateDisplayItemClient(*this, PaintInvalidationCaret);
190 m_previousLayoutBlock = nullptr; 194 m_previousLayoutBlock = nullptr;
191 } 195 }
192 196
193 void CaretDisplayItemClient::invalidatePaintInCurrentLayoutBlock( 197 void CaretDisplayItemClient::invalidatePaintInCurrentLayoutBlock(
194 const PaintInvalidatorContext& context, 198 const PaintInvalidatorContext& context,
195 PaintInvalidationReason layoutBlockPaintInvalidationReason) { 199 PaintInvalidationReason layoutBlockPaintInvalidationReason) {
196 DCHECK(m_layoutBlock); 200 DCHECK(m_layoutBlock);
197 201
198 LayoutRect newVisualRect; 202 LayoutRect newVisualRect;
199 if (!m_localRect.isEmpty()) { 203 if (!m_localRect.isEmpty()) {
200 newVisualRect = m_localRect; 204 newVisualRect = m_localRect;
201 context.mapLocalRectToPaintInvalidationBacking(*m_layoutBlock, 205 context.mapLocalRectToPaintInvalidationBacking(*m_layoutBlock,
202 newVisualRect); 206 newVisualRect);
203 newVisualRect.move(m_layoutBlock->scrollAdjustmentForPaintInvalidation( 207 newVisualRect.move(m_layoutBlock->scrollAdjustmentForPaintInvalidation(
204 *context.paintInvalidationContainer)); 208 *context.paintInvalidationContainer));
205 209
206 if (m_layoutBlock->usesCompositedScrolling()) { 210 if (m_layoutBlock->usesCompositedScrolling()) {
207 // The caret should use scrolling coordinate space. 211 // The caret should use scrolling coordinate space.
208 DCHECK(m_layoutBlock == context.paintInvalidationContainer); 212 DCHECK(m_layoutBlock == context.paintInvalidationContainer);
209 newVisualRect.move(LayoutSize(m_layoutBlock->scrolledContentOffset())); 213 newVisualRect.move(LayoutSize(m_layoutBlock->scrolledContentOffset()));
210 } 214 }
211 } 215 }
212 216
213 if (!m_needsPaintInvalidation && newVisualRect == m_visualRect) 217 if (m_layoutBlock == m_previousLayoutBlock)
218 m_previousLayoutBlock = nullptr;
219
220 ObjectPaintInvalidatorWithContext objectInvalidator(*m_layoutBlock, context);
221 if (!m_needsPaintInvalidation && newVisualRect == m_visualRect) {
222 // The caret may change paint offset without changing visual rect, and we
223 // need to invalidate the display item client.
224 if (isImmediateFullPaintInvalidationReason(
225 layoutBlockPaintInvalidationReason)) {
226 objectInvalidator.invalidateDisplayItemClient(*this,
227 PaintInvalidationCaret);
228 }
214 return; 229 return;
230 }
215 231
216 m_needsPaintInvalidation = false; 232 m_needsPaintInvalidation = false;
217 233
218 ObjectPaintInvalidatorWithContext objectInvalidator(*m_layoutBlock, context);
219 if (!isImmediateFullPaintInvalidationReason( 234 if (!isImmediateFullPaintInvalidationReason(
220 layoutBlockPaintInvalidationReason)) { 235 layoutBlockPaintInvalidationReason)) {
221 objectInvalidator.fullyInvalidatePaint(PaintInvalidationCaret, m_visualRect, 236 objectInvalidator.fullyInvalidatePaint(PaintInvalidationCaret, m_visualRect,
222 newVisualRect); 237 newVisualRect);
223 } 238 }
224 239
225 context.paintingLayer->setNeedsRepaint(); 240 context.paintingLayer->setNeedsRepaint();
226 objectInvalidator.invalidateDisplayItemClient(*this, PaintInvalidationCaret); 241 objectInvalidator.invalidateDisplayItemClient(*this, PaintInvalidationCaret);
227 242
228 m_visualRect = newVisualRect; 243 m_visualRect = newVisualRect;
(...skipping 18 matching lines...) Expand all
247 262
248 String CaretDisplayItemClient::debugName() const { 263 String CaretDisplayItemClient::debugName() const {
249 return "Caret"; 264 return "Caret";
250 } 265 }
251 266
252 LayoutRect CaretDisplayItemClient::visualRect() const { 267 LayoutRect CaretDisplayItemClient::visualRect() const {
253 return m_visualRect; 268 return m_visualRect;
254 } 269 }
255 270
256 } // namespace blink 271 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698