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

Unified Diff: third_party/WebKit/Source/core/paint/BlockPaintInvalidator.cpp

Issue 2665823002: Invalidate caret during paint invalidation (Closed)
Patch Set: Rebaseline Created 3 years, 11 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/paint/BlockPaintInvalidator.cpp
diff --git a/third_party/WebKit/Source/core/paint/BlockPaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/BlockPaintInvalidator.cpp
index b64c32efdcfffe4881adadce03d35816fc869609..1bc884200182714b91a2b864127a07e141b638a4 100644
--- a/third_party/WebKit/Source/core/paint/BlockPaintInvalidator.cpp
+++ b/third_party/WebKit/Source/core/paint/BlockPaintInvalidator.cpp
@@ -4,23 +4,146 @@
#include "core/paint/BlockPaintInvalidator.h"
+#include "core/editing/DragCaret.h"
#include "core/editing/FrameSelection.h"
#include "core/frame/LocalFrame.h"
#include "core/layout/LayoutBlock.h"
+#include "core/page/Page.h"
#include "core/paint/BoxPaintInvalidator.h"
+#include "core/paint/ObjectPaintInvalidator.h"
#include "core/paint/PaintInvalidator.h"
+#include "core/paint/PaintLayer.h"
namespace blink {
+struct CaretVisualRects {
+ bool hasCursorCaret = false;
yosin_UTC9 2017/01/31 20:12:58 It is better to move |bool| member to end of membe
+ LayoutRect cursorCaretRect;
+ bool hasDragCaret = false;
+ LayoutRect dragCaretRect;
+};
+
+typedef HashMap<const LayoutBlock*, CaretVisualRects> CaretVisualRectsMap;
yosin_UTC9 2017/01/31 20:12:58 nit: Let's use using to C++-ish. using CaretVisu
+static CaretVisualRectsMap& caretVisualRectsMap() {
+ DEFINE_STATIC_LOCAL(CaretVisualRectsMap, map, ());
chrishtr 2017/01/31 22:51:04 Why can't you store these on the block instead of
+ return map;
+}
+
+static void setPreviousCaretVisualRects(const LayoutBlock& block,
+ const CaretVisualRects& rects) {
+ DCHECK(block.hasPreviousCaretVisualRects() ==
yosin_UTC9 2017/01/31 20:12:58 nit: DCHECK_EQ
+ caretVisualRectsMap().contains(&block));
+ if (rects.cursorCaretRect.isEmpty() && rects.dragCaretRect.isEmpty()) {
+ BlockPaintInvalidator::clearPreviousCaretVisualRects(block);
yosin_UTC9 2017/01/31 20:12:58 nit: early return style to decrease indentation of
+ } else {
+ caretVisualRectsMap().set(&block, rects);
+ block.getMutableForPainting().setHasPreviousCaretVisualRects(true);
+ }
+}
+
+void BlockPaintInvalidator::blockWillBeDestroyed(const LayoutBlock& block) {
+ DCHECK(block.hasPreviousCaretVisualRects() ==
yosin_UTC9 2017/01/31 20:12:58 nit: DCHECK_EQ
+ caretVisualRectsMap().contains(&block));
+ if (block.hasPreviousCaretVisualRects())
+ caretVisualRectsMap().remove(&block);
+}
+
+void BlockPaintInvalidator::setMayNeedPaintInvalidationForCaretsIfNeeded(
+ const LocalFrame& localFrameRoot) {
+ DCHECK(&localFrameRoot == localFrameRoot.localFrameRoot());
yosin_UTC9 2017/01/31 20:12:58 nit: DCHECK_EQ
+ for (auto& item : caretVisualRectsMap()) {
yosin_UTC9 2017/01/31 20:12:58 nit: s/auto&/const auto&/ We don't never change en
+ const LayoutBlock* block = item.key;
+ const CaretVisualRects& rects = item.value;
+ DCHECK(block->hasPreviousCaretVisualRects());
+ if (block->frame()->localFrameRoot() != &localFrameRoot)
+ continue;
+ if (rects.hasCursorCaret != block->hasCursorCaret() ||
+ rects.hasDragCaret != block->hasDragCaret())
+ block->getMutableForPainting().setMayNeedPaintInvalidation();
+ }
+}
+
+void BlockPaintInvalidator::clearPreviousCaretVisualRects(
+ const LayoutBlock& block) {
+ if (block.hasPreviousCaretVisualRects()) {
yosin_UTC9 2017/01/31 20:12:58 nit: early-return style to decrease indentation.
+ caretVisualRectsMap().remove(&block);
+ block.getMutableForPainting().setHasPreviousCaretVisualRects(false);
+ }
+}
+
+LayoutRect BlockPaintInvalidator::invalidateCaretIfNeeded(
+ PaintInvalidationReason reason,
+ const LayoutRect& oldVisualRect,
+ const LayoutRect& newLocalRect,
+ const DisplayItemClient& displayItemClient) {
+ LayoutRect newVisualRect = newLocalRect;
+ if (!newVisualRect.isEmpty()) {
+ // Over-paint 1 pixel to workaround wkbug.com/108283.
+ // TODO(wangxianzhu): This might be unnecessary now.
+ newVisualRect.inflate(1);
yosin_UTC9 2017/01/31 20:12:58 Agree. Let's getting rid of this patch to see whic
+
+ m_context.mapLocalRectToPaintInvalidationBacking(m_block, newVisualRect);
+ newVisualRect.move(m_block.scrollAdjustmentForPaintInvalidation(
+ *m_context.paintInvalidationContainer));
+ }
+
+ if (m_block.caretsNeedPaintInvalidation() || newVisualRect != oldVisualRect) {
+ ObjectPaintInvalidatorWithContext objectInvalidator(m_block, m_context);
+ if (!isImmediateFullPaintInvalidationReason(reason)) {
+ objectInvalidator.fullyInvalidatePaint(PaintInvalidationCaret,
+ oldVisualRect, newVisualRect);
+ }
+
+ m_context.paintingLayer->setNeedsRepaint();
+ objectInvalidator.invalidateDisplayItemClient(displayItemClient,
+ PaintInvalidationCaret);
+ }
+
+ return newVisualRect;
+}
+
+void BlockPaintInvalidator::invalidateCaretsIfNeeded(
+ PaintInvalidationReason reason) {
+ bool hadCarets = m_block.hasPreviousCaretVisualRects();
+ DCHECK(hadCarets == caretVisualRectsMap().contains(&m_block));
yosin_UTC9 2017/01/31 20:12:58 nit: DCHECK_EQ
+
+ bool hasCursorCaret = m_block.hasCursorCaret();
yosin_UTC9 2017/01/31 20:12:58 nit: s/bool/const bool/
+ bool hasDragCaret = m_block.hasDragCaret();
yosin_UTC9 2017/01/31 20:12:58 nit: s/bool/const bool/
+ if (!hadCarets && !hasCursorCaret && !hasDragCaret)
+ return;
+
+ CaretVisualRects oldCaretVisualRects;
+ CaretVisualRects newCaretVisualRects;
+ if (hadCarets)
+ oldCaretVisualRects = caretVisualRectsMap().get(&m_block);
+
+ FrameSelection& selection = m_block.frame()->selection();
+ newCaretVisualRects.hasCursorCaret = hasCursorCaret;
+ newCaretVisualRects.cursorCaretRect = invalidateCaretIfNeeded(
+ reason, oldCaretVisualRects.cursorCaretRect,
+ hasCursorCaret ? selection.caretLocalRect() : LayoutRect(),
+ selection.getCaretDisplayItemClient());
+ if (hasCursorCaret)
+ selection.setCaretVisualRect(newCaretVisualRects.cursorCaretRect);
+
+ DragCaret& dragCaret = m_block.frame()->page()->dragCaret();
+ newCaretVisualRects.hasDragCaret = hasDragCaret;
+ newCaretVisualRects.dragCaretRect = invalidateCaretIfNeeded(
+ reason, oldCaretVisualRects.dragCaretRect,
+ hasDragCaret ? dragCaret.caretLocalRect() : LayoutRect(),
+ dragCaret.getDisplayItemClient());
+ if (hasDragCaret)
+ dragCaret.setVisualRect(newCaretVisualRects.dragCaretRect);
+
+ setPreviousCaretVisualRects(m_block, newCaretVisualRects);
+}
+
PaintInvalidationReason BlockPaintInvalidator::invalidatePaintIfNeeded() {
PaintInvalidationReason reason =
BoxPaintInvalidator(m_block, m_context).invalidatePaintIfNeeded();
- if (reason != PaintInvalidationNone && m_block.hasCaret()) {
- FrameSelection& selection = m_block.frame()->selection();
- selection.setCaretRectNeedsUpdate();
- selection.invalidateCaretRect(true);
- }
+ invalidateCaretsIfNeeded(reason);
+
return reason;
}
}

Powered by Google App Engine
This is Rietveld 408576698