104 }; |
104 }; |
105 |
105 |
106 FrameView::FrameView(Frame* frame) |
106 FrameView::FrameView(Frame* frame) |
107 : m_frame(frame) |
107 : m_frame(frame) |
108 , m_slowRepaintObjectCount(0) |
108 , m_slowRepaintObjectCount(0) |
|
109 , m_fixedObjectCount(0) |
109 , m_layoutTimer(this, &FrameView::layoutTimerFired) |
110 , m_layoutTimer(this, &FrameView::layoutTimerFired) |
110 , m_layoutRoot(0) |
111 , m_layoutRoot(0) |
111 , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired) |
112 , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired) |
112 , m_isTransparent(false) |
113 , m_isTransparent(false) |
113 , m_baseBackgroundColor(Color::white) |
114 , m_baseBackgroundColor(Color::white) |
755 { |
756 { |
756 ASSERT(m_slowRepaintObjectCount > 0); |
757 ASSERT(m_slowRepaintObjectCount > 0); |
757 m_slowRepaintObjectCount--; |
758 m_slowRepaintObjectCount--; |
758 if (!m_slowRepaintObjectCount) |
759 if (!m_slowRepaintObjectCount) |
759 setCanBlitOnScroll(!useSlowRepaints()); |
760 setCanBlitOnScroll(!useSlowRepaints()); |
|
761 } |
|
762 |
|
763 void FrameView::addFixedObject() |
|
764 { |
|
765 if (!m_fixedObjectCount && platformWidget()) |
|
766 setCanBlitOnScroll(false); |
|
767 ++m_fixedObjectCount; |
|
768 } |
|
769 |
|
770 void FrameView::removeFixedObject() |
|
771 { |
|
772 ASSERT(m_fixedObjectCount > 0); |
|
773 m_fixedObjectCount--; |
|
774 if (!m_fixedObjectCount) |
|
775 setCanBlitOnScroll(!useSlowRepaints()); |
|
776 } |
|
777 |
|
778 void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) |
|
779 { |
|
780 const size_t fixedObjectThreshold = 5; |
|
781 |
|
782 ListHashSet<RenderBox*>* positionedObjects = 0; |
|
783 if (RenderView* root = m_frame->contentRenderer()) |
|
784 positionedObjects = root->positionedObjects(); |
|
785 |
|
786 if (!positionedObjects || positionedObjects->isEmpty()) { |
|
787 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); |
|
788 return; |
|
789 } |
|
790 |
|
791 // Get the rects of the fixed objects visible in the rectToScroll |
|
792 Vector<IntRect, fixedObjectThreshold> subRectToUpdate; |
|
793 bool updateInvalidatedSubRect = true; |
|
794 ListHashSet<RenderBox*>::const_iterator end = positionedObjects->end(); |
|
795 for (ListHashSet<RenderBox*>::const_iterator it = positionedObjects->begin(); it != end; ++it) { |
|
796 RenderBox* renderBox = *it; |
|
797 if (renderBox->style()->position() != FixedPosition) |
|
798 continue; |
|
799 IntRect topLevelRect; |
|
800 IntRect updateRect = renderBox->paintingRootRect(topLevelRect); |
|
801 updateRect.move(-scrollX(), -scrollY()); |
|
802 updateRect.intersect(rectToScroll); |
|
803 if (!updateRect.isEmpty()) { |
|
804 if (subRectToUpdate.size() >= fixedObjectThreshold) { |
|
805 updateInvalidatedSubRect = false; |
|
806 break; |
|
807 } |
|
808 subRectToUpdate.append(updateRect); |
|
809 } |
|
810 } |
|
811 |
|
812 // Scroll the view |
|
813 if (updateInvalidatedSubRect) { |
|
814 // 1) scroll |
|
815 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); |
|
816 |
|
817 // 2) update the area of fixed objets that has been invalidated |
|
818 size_t fixObjectsCount = subRectToUpdate.size(); |
|
819 for (size_t i = 0; i < fixObjectsCount; ++i) { |
|
820 IntRect updateRect = subRectToUpdate[i]; |
|
821 IntRect scrolledRect = updateRect; |
|
822 scrolledRect.move(scrollDelta); |
|
823 updateRect.unite(scrolledRect); |
|
824 updateRect.intersect(rectToScroll); |
|
825 hostWindow()->repaint(updateRect, true, false, true); |
|
826 } |
|
827 } else { |
|
828 // the number of fixed objects exceed the threshold, so we repaint everything. |
|
829 IntRect updateRect = clipRect; |
|
830 updateRect.intersect(rectToScroll); |
|
831 hostWindow()->repaint(updateRect, true, false, true); |
|
832 } |
760 } |
833 } |
761 |
834 |
762 void FrameView::setIsOverlapped(bool isOverlapped) |
835 void FrameView::setIsOverlapped(bool isOverlapped) |
763 { |
836 { |
764 if (isOverlapped == m_isOverlapped) |
837 if (isOverlapped == m_isOverlapped) |