Chromium Code Reviews| 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; |
| } |
| } |