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

Side by Side 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, 1 month 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) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed. 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed.
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 exploringBackwards = !next && (next != stop); 507 exploringBackwards = !next && (next != stop);
508 if (exploringBackwards) { 508 if (exploringBackwards) {
509 next = stop->previousInPreOrder(); 509 next = stop->previousInPreOrder();
510 continueExploring = next && !next->isRenderView(); 510 continueExploring = next && !next->isRenderView();
511 } 511 }
512 } 512 }
513 513
514 return next; 514 return next;
515 } 515 }
516 516
517 static void invalidateSelectionForRenderer(RenderObject* object)
518 {
519 object->setShouldInvalidateSelection();
520 if (object->isBox()) {
dsinclair 2014/10/31 14:03:16 if (!object->isBox()) return; I dislike inden
521 RenderBox* box = toRenderBox(object);
522 // FIXME(jchaffraix): ShapeOutside can trigger SVGImage loading, which r eruns the whole state machine
523 // in FrameView::updateLayoutAndStyleForPaint. It's allowed to do it in the post-layout hook (why?)
524 // but not during the invalidation phase so we just match the current co de 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
525 if (ShapeOutsideInfo* shapeInfo = box->shapeOutsideInfo())
526 shapeInfo->computedShape();
527 }
528 }
529
517 void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e nd, int endPos, SelectionPaintInvalidationMode blockPaintInvalidationMode) 530 void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e nd, int endPos, SelectionPaintInvalidationMode blockPaintInvalidationMode)
518 { 531 {
519 // This code makes no assumptions as to if the rendering tree is up to date or not 532 // This code makes no assumptions as to if the rendering tree is up to date or not
520 // and will not try to update it. Currently clearSelection calls this 533 // and will not try to update it. Currently clearSelection calls this
521 // (intentionally) without updating the rendering tree as it doesn't care. 534 // (intentionally) without updating the rendering tree as it doesn't care.
522 // Other callers may want to force recalc style before calling this. 535 // Other callers may want to force recalc style before calling this.
523 536
524 // Make sure both our start and end objects are defined. 537 // Make sure both our start and end objects are defined.
525 // Check www.msnbc.com and try clicking around to find the case where this h appened. 538 // Check www.msnbc.com and try clicking around to find the case where this h appened.
526 if ((start && !end) || (end && !start)) 539 if ((start && !end) || (end && !start))
527 return; 540 return;
528 541
529 // Just return if the selection hasn't changed. 542 // Just return if the selection hasn't changed.
530 if (m_selectionStart == start && m_selectionStartPos == startPos && 543 if (m_selectionStart == start && m_selectionStartPos == startPos &&
531 m_selectionEnd == end && m_selectionEndPos == endPos) 544 m_selectionEnd == end && m_selectionEndPos == endPos)
532 return; 545 return;
533 546
534 // Record the old selected objects. These will be used later 547 // Record the old selected objects. These will be used later
535 // when we compare against the new selected objects. 548 // when we compare against the new selected objects.
536 int oldStartPos = m_selectionStartPos; 549 int oldStartPos = m_selectionStartPos;
537 int oldEndPos = m_selectionEndPos; 550 int oldEndPos = m_selectionEndPos;
538 551
539 // Objects each have a single selection rect to examine. 552 // Objects each have a single selection rect to examine.
540 typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderObject>, OwnPtrWillBeMemb er<RenderSelectionInfo> > SelectedObjectMap; 553 typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderObject>, SelectionState > SelectedObjectMap;
dsinclair 2014/10/31 14:03:16 nit: Don't need the space between SelectionState a
541 SelectedObjectMap oldSelectedObjects; 554 SelectedObjectMap oldSelectedObjects;
555 // FIXME: |newSelectedObjects| doesn't really need to store the SelectionSta te, it's just more convenient
556 // to have it use the same data structure as |oldSelectedObjects|.
542 SelectedObjectMap newSelectedObjects; 557 SelectedObjectMap newSelectedObjects;
543 558
544 // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks. 559 // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.
545 // In order to get the paint invalidation rect right, we have to examine lef t, middle, and right rects individually, since otherwise 560 // In order to get the paint invalidation rect right, we have to examine lef t, middle, and right rects individually, since otherwise
546 // the union of those rects might remain the same even when changes have occ urred. 561 // the union of those rects might remain the same even when changes have occ urred.
547 typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderBlock>, OwnPtrWillBeMembe r<RenderBlockSelectionInfo> > SelectedBlockMap; 562 typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderBlock>, SelectionState > SelectedBlockMap;
548 SelectedBlockMap oldSelectedBlocks; 563 SelectedBlockMap oldSelectedBlocks;
564 // FIXME: |newSelectedBlocks| doesn't really need to store the SelectionStat e, it's just more convenient
565 // to have it use the same data structure as |oldSelectedBlocks|.
549 SelectedBlockMap newSelectedBlocks; 566 SelectedBlockMap newSelectedBlocks;
550 567
551 RenderObject* os = m_selectionStart; 568 RenderObject* os = m_selectionStart;
552 RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos ); 569 RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos );
553 bool exploringBackwards = false; 570 bool exploringBackwards = false;
554 bool continueExploring = os && (os != stop); 571 bool continueExploring = os && (os != stop);
555 while (continueExploring) { 572 while (continueExploring) {
556 if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selec tionEnd) && os->selectionState() != SelectionNone) { 573 if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selec tionEnd) && os->selectionState() != SelectionNone) {
557 // Blocks are responsible for painting line gaps and margin gaps. T hey must be examined as well. 574 // Blocks are responsible for painting line gaps and margin gaps. T hey must be examined as well.
558 oldSelectedObjects.set(os, adoptPtrWillBeNoop(new RenderSelectionInf o(os))); 575 oldSelectedObjects.set(os, os->selectionState());
559 if (blockPaintInvalidationMode == PaintInvalidationNewXOROld) { 576 if (blockPaintInvalidationMode == PaintInvalidationNewXOROld) {
560 RenderBlock* cb = os->containingBlock(); 577 RenderBlock* cb = os->containingBlock();
561 while (cb && !cb->isRenderView()) { 578 while (cb && !cb->isRenderView()) {
562 OwnPtrWillBeMember<RenderBlockSelectionInfo>& blockInfo = ol dSelectedBlocks.add(cb, nullptr).storedValue->value; 579 SelectedBlockMap::AddResult result = oldSelectedBlocks.add(c b, cb->selectionState());
563 if (blockInfo) 580 if (!result.isNewEntry)
564 break; 581 break;
565 blockInfo = adoptPtrWillBeNoop(new RenderBlockSelectionInfo( cb));
566 cb = cb->containingBlock(); 582 cb = cb->containingBlock();
567 } 583 }
568 } 584 }
569 } 585 }
570 586
571 os = getNextOrPrevRenderObjectBasedOnDirection(os, stop, continueExplori ng, exploringBackwards); 587 os = getNextOrPrevRenderObjectBasedOnDirection(os, stop, continueExplori ng, exploringBackwards);
572 } 588 }
573 589
574 // Now clear the selection. 590 // Now clear the selection.
575 SelectedObjectMap::iterator oldObjectsEnd = oldSelectedObjects.end(); 591 SelectedObjectMap::iterator oldObjectsEnd = oldSelectedObjects.end();
(...skipping 27 matching lines...) Expand all
603 619
604 layer()->clearBlockSelectionGapsBounds(); 620 layer()->clearBlockSelectionGapsBounds();
605 621
606 // Now that the selection state has been updated for the new objects, walk t hem again and 622 // Now that the selection state has been updated for the new objects, walk t hem again and
607 // put them in the new objects list. 623 // put them in the new objects list.
608 o = start; 624 o = start;
609 exploringBackwards = false; 625 exploringBackwards = false;
610 continueExploring = o && (o != stop); 626 continueExploring = o && (o != stop);
611 while (continueExploring) { 627 while (continueExploring) {
612 if ((o->canBeSelectionLeaf() || o == start || o == end) && o->selectionS tate() != SelectionNone) { 628 if ((o->canBeSelectionLeaf() || o == start || o == end) && o->selectionS tate() != SelectionNone) {
613 newSelectedObjects.set(o, adoptPtrWillBeNoop(new RenderSelectionInfo (o))); 629 newSelectedObjects.set(o, o->selectionState());
614 RenderBlock* cb = o->containingBlock(); 630 RenderBlock* cb = o->containingBlock();
615 while (cb && !cb->isRenderView()) { 631 while (cb && !cb->isRenderView()) {
616 OwnPtrWillBeMember<RenderBlockSelectionInfo>& blockInfo = newSel ectedBlocks.add(cb, nullptr).storedValue->value; 632 SelectedBlockMap::AddResult result = newSelectedBlocks.add(cb, c b->selectionState());
617 if (blockInfo) 633 if (!result.isNewEntry)
618 break; 634 break;
619 blockInfo = adoptPtrWillBeNoop(new RenderBlockSelectionInfo(cb)) ;
620 cb = cb->containingBlock(); 635 cb = cb->containingBlock();
621 } 636 }
622 } 637 }
623 638
624 o = getNextOrPrevRenderObjectBasedOnDirection(o, stop, continueExploring , exploringBackwards); 639 o = getNextOrPrevRenderObjectBasedOnDirection(o, stop, continueExploring , exploringBackwards);
625 } 640 }
626 641
627 if (!m_frameView) 642 if (!m_frameView)
628 return; 643 return;
629 644
630 // Have any of the old selected objects changed compared to the new selectio n? 645 // Have any of the old selected objects changed compared to the new selectio n?
631 for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObj ectsEnd; ++i) { 646 for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObj ectsEnd; ++i) {
632 RenderObject* obj = i->key; 647 RenderObject* obj = i->key;
633 RenderSelectionInfo* newInfo = newSelectedObjects.get(obj); 648 SelectionState newSelectionState = obj->selectionState();
634 RenderSelectionInfo* oldInfo = i->value.get(); 649 SelectionState oldSelectionState = i->value;
635 if (!newInfo || newInfo->hasChangedFrom(*oldInfo) 650 if (newSelectionState != oldSelectionState
636 || (m_selectionStart == obj && oldStartPos != m_selectionStartPos) 651 || (m_selectionStart == obj && oldStartPos != m_selectionStartPos)
637 || (m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) { 652 || (m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) {
638 oldInfo->invalidatePaint(); 653 invalidateSelectionForRenderer(obj);
639 if (newInfo) { 654 newSelectedObjects.remove(obj);
640 newInfo->object()->setShouldInvalidateSelection();
641 newSelectedObjects.remove(obj);
642 }
643 } 655 }
644 } 656 }
645 657
646 // Any new objects that remain were not found in the old objects dict, and s o they need to be updated. 658 // Any new objects that remain were not found in the old objects dict, and s o they need to be updated.
647 SelectedObjectMap::iterator newObjectsEnd = newSelectedObjects.end(); 659 SelectedObjectMap::iterator newObjectsEnd = newSelectedObjects.end();
648 for (SelectedObjectMap::iterator i = newSelectedObjects.begin(); i != newObj ectsEnd; ++i) 660 for (SelectedObjectMap::iterator i = newSelectedObjects.begin(); i != newObj ectsEnd; ++i)
649 i->value->object()->setShouldInvalidateSelection(); 661 invalidateSelectionForRenderer(i->key);
650 662
651 // Have any of the old blocks changed? 663 // Have any of the old blocks changed?
652 SelectedBlockMap::iterator oldBlocksEnd = oldSelectedBlocks.end(); 664 SelectedBlockMap::iterator oldBlocksEnd = oldSelectedBlocks.end();
653 for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlock sEnd; ++i) { 665 for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlock sEnd; ++i)
654 RenderBlock* block = i->key; 666 invalidateSelectionForRenderer(i->key);
655 RenderBlockSelectionInfo* newInfo = newSelectedBlocks.get(block);
656 RenderBlockSelectionInfo* oldInfo = i->value.get();
657 if (!newInfo || newInfo->hasChangedFrom(*oldInfo)) {
658 oldInfo->invalidatePaint();
659 if (newInfo) {
660 newInfo->object()->setShouldInvalidateSelection();
661 newSelectedBlocks.remove(block);
662 }
663 }
664 }
665 667
666 // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated. 668 // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.
667 SelectedBlockMap::iterator newBlocksEnd = newSelectedBlocks.end(); 669 SelectedBlockMap::iterator newBlocksEnd = newSelectedBlocks.end();
668 for (SelectedBlockMap::iterator i = newSelectedBlocks.begin(); i != newBlock sEnd; ++i) 670 for (SelectedBlockMap::iterator i = newSelectedBlocks.begin(); i != newBlock sEnd; ++i)
669 i->value->object()->setShouldInvalidateSelection(); 671 invalidateSelectionForRenderer(i->key);
670 } 672 }
671 673
672 void RenderView::clearSelection() 674 void RenderView::clearSelection()
673 { 675 {
674 // For querying RenderLayer::compositingState() 676 // For querying RenderLayer::compositingState()
675 // This is correct, since destroying render objects needs to cause eager pai nt invalidations. 677 // This is correct, since destroying render objects needs to cause eager pai nt invalidations.
676 DisableCompositingQueryAsserts disabler; 678 DisableCompositingQueryAsserts disabler;
677 679
678 layer()->invalidatePaintForBlockSelectionGaps(); 680 layer()->invalidatePaintForBlockSelectionGaps();
679 setSelection(0, -1, 0, -1, PaintInvalidationNewMinusOld); 681 setSelection(0, -1, 0, -1, PaintInvalidationNewMinusOld);
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 return viewWidth(IncludeScrollbars) / scale; 874 return viewWidth(IncludeScrollbars) / scale;
873 } 875 }
874 876
875 double RenderView::layoutViewportHeight() const 877 double RenderView::layoutViewportHeight() const
876 { 878 {
877 float scale = m_frameView ? m_frameView->frame().pageZoomFactor() : 1; 879 float scale = m_frameView ? m_frameView->frame().pageZoomFactor() : 1;
878 return viewHeight(IncludeScrollbars) / scale; 880 return viewHeight(IncludeScrollbars) / scale;
879 } 881 }
880 882
881 } // namespace blink 883 } // namespace blink
OLDNEW
« 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