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

Unified Diff: Source/core/rendering/RenderView.cpp

Issue 665673004: Move selection invalidation to the invalidation phase (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Tentative fix, up for slammin' reviews Created 6 years, 2 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: Source/core/rendering/RenderView.cpp
diff --git a/Source/core/rendering/RenderView.cpp b/Source/core/rendering/RenderView.cpp
index 294735b508bd2683e1e7260aeb3c54a732808b3a..311da43cf9193d467861e15bed9d73be7c47611f 100644
--- a/Source/core/rendering/RenderView.cpp
+++ b/Source/core/rendering/RenderView.cpp
@@ -514,6 +514,19 @@ static inline RenderObject* getNextOrPrevRenderObjectBasedOnDirection(const Rend
return next;
}
+static void invalidateSelectionForRenderer(RenderObject* object)
+{
+ object->setShouldInvalidateSelection();
+ if (object->isBox()) {
dsinclair 2014/10/31 14:03:16 if (!object->isBox()) return; I dislike inden
+ RenderBox* box = toRenderBox(object);
+ // FIXME(jchaffraix): ShapeOutside can trigger SVGImage loading, which reruns the whole state machine
+ // in FrameView::updateLayoutAndStyleForPaint. It's allowed to do it in the post-layout hook (why?)
+ // but not during the invalidation phase so we just match the current code by forcing the loading to happen here.
dsinclair 2014/10/31 14:03:16 Can we add a crbug for this so we don't lose track
Julien - ping for review 2014/10/31 22:31:03 https://code.google.com/p/chromium/issues/detail?i
+ if (ShapeOutsideInfo* shapeInfo = box->shapeOutsideInfo())
+ shapeInfo->computedShape();
+ }
+}
+
void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionPaintInvalidationMode blockPaintInvalidationMode)
{
// This code makes no assumptions as to if the rendering tree is up to date or not
@@ -537,15 +550,19 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
int oldEndPos = m_selectionEndPos;
// Objects each have a single selection rect to examine.
- typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderObject>, OwnPtrWillBeMember<RenderSelectionInfo> > SelectedObjectMap;
+ typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderObject>, SelectionState > SelectedObjectMap;
dsinclair 2014/10/31 14:03:16 nit: Don't need the space between SelectionState a
SelectedObjectMap oldSelectedObjects;
+ // FIXME: |newSelectedObjects| doesn't really need to store the SelectionState, it's just more convenient
+ // to have it use the same data structure as |oldSelectedObjects|.
SelectedObjectMap newSelectedObjects;
// Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.
// In order to get the paint invalidation rect right, we have to examine left, middle, and right rects individually, since otherwise
// the union of those rects might remain the same even when changes have occurred.
- typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderBlock>, OwnPtrWillBeMember<RenderBlockSelectionInfo> > SelectedBlockMap;
+ typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderBlock>, SelectionState > SelectedBlockMap;
SelectedBlockMap oldSelectedBlocks;
+ // FIXME: |newSelectedBlocks| doesn't really need to store the SelectionState, it's just more convenient
+ // to have it use the same data structure as |oldSelectedBlocks|.
SelectedBlockMap newSelectedBlocks;
RenderObject* os = m_selectionStart;
@@ -555,14 +572,13 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
while (continueExploring) {
if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {
// Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
- oldSelectedObjects.set(os, adoptPtrWillBeNoop(new RenderSelectionInfo(os)));
+ oldSelectedObjects.set(os, os->selectionState());
if (blockPaintInvalidationMode == PaintInvalidationNewXOROld) {
RenderBlock* cb = os->containingBlock();
while (cb && !cb->isRenderView()) {
- OwnPtrWillBeMember<RenderBlockSelectionInfo>& blockInfo = oldSelectedBlocks.add(cb, nullptr).storedValue->value;
- if (blockInfo)
+ SelectedBlockMap::AddResult result = oldSelectedBlocks.add(cb, cb->selectionState());
+ if (!result.isNewEntry)
break;
- blockInfo = adoptPtrWillBeNoop(new RenderBlockSelectionInfo(cb));
cb = cb->containingBlock();
}
}
@@ -610,13 +626,12 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
continueExploring = o && (o != stop);
while (continueExploring) {
if ((o->canBeSelectionLeaf() || o == start || o == end) && o->selectionState() != SelectionNone) {
- newSelectedObjects.set(o, adoptPtrWillBeNoop(new RenderSelectionInfo(o)));
+ newSelectedObjects.set(o, o->selectionState());
RenderBlock* cb = o->containingBlock();
while (cb && !cb->isRenderView()) {
- OwnPtrWillBeMember<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(cb, nullptr).storedValue->value;
- if (blockInfo)
+ SelectedBlockMap::AddResult result = newSelectedBlocks.add(cb, cb->selectionState());
+ if (!result.isNewEntry)
break;
- blockInfo = adoptPtrWillBeNoop(new RenderBlockSelectionInfo(cb));
cb = cb->containingBlock();
}
}
@@ -630,43 +645,30 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
// Have any of the old selected objects changed compared to the new selection?
for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i) {
RenderObject* obj = i->key;
- RenderSelectionInfo* newInfo = newSelectedObjects.get(obj);
- RenderSelectionInfo* oldInfo = i->value.get();
- if (!newInfo || newInfo->hasChangedFrom(*oldInfo)
+ SelectionState newSelectionState = obj->selectionState();
+ SelectionState oldSelectionState = i->value;
+ if (newSelectionState != oldSelectionState
|| (m_selectionStart == obj && oldStartPos != m_selectionStartPos)
|| (m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) {
- oldInfo->invalidatePaint();
- if (newInfo) {
- newInfo->object()->setShouldInvalidateSelection();
- newSelectedObjects.remove(obj);
- }
+ invalidateSelectionForRenderer(obj);
+ newSelectedObjects.remove(obj);
}
}
// Any new objects that remain were not found in the old objects dict, and so they need to be updated.
SelectedObjectMap::iterator newObjectsEnd = newSelectedObjects.end();
for (SelectedObjectMap::iterator i = newSelectedObjects.begin(); i != newObjectsEnd; ++i)
- i->value->object()->setShouldInvalidateSelection();
+ invalidateSelectionForRenderer(i->key);
// Have any of the old blocks changed?
SelectedBlockMap::iterator oldBlocksEnd = oldSelectedBlocks.end();
- for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlocksEnd; ++i) {
- RenderBlock* block = i->key;
- RenderBlockSelectionInfo* newInfo = newSelectedBlocks.get(block);
- RenderBlockSelectionInfo* oldInfo = i->value.get();
- if (!newInfo || newInfo->hasChangedFrom(*oldInfo)) {
- oldInfo->invalidatePaint();
- if (newInfo) {
- newInfo->object()->setShouldInvalidateSelection();
- newSelectedBlocks.remove(block);
- }
- }
- }
+ for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlocksEnd; ++i)
+ invalidateSelectionForRenderer(i->key);
// Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.
SelectedBlockMap::iterator newBlocksEnd = newSelectedBlocks.end();
for (SelectedBlockMap::iterator i = newSelectedBlocks.begin(); i != newBlocksEnd; ++i)
- i->value->object()->setShouldInvalidateSelection();
+ invalidateSelectionForRenderer(i->key);
}
void RenderView::clearSelection()
« Source/core/rendering/RenderObject.cpp ('K') | « Source/core/rendering/RenderSelectionInfo.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698