src/3rdparty/webkit/WebCore/page/FrameView.cpp
branchRCL_3
changeset 8 3f74d0d4af4c
parent 0 1918ee327afb
child 10 b5b118452c7d
equal deleted inserted replaced
6:dee5afe5301f 8:3f74d0d4af4c
   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)
   733     return m_mediaType;
   734     return m_mediaType;
   734 }
   735 }
   735 
   736 
   736 bool FrameView::useSlowRepaints() const
   737 bool FrameView::useSlowRepaints() const
   737 {
   738 {
   738     return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || m_isOverlapped || !m_contentIsOpaque;
   739     return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || m_isOverlapped || !m_contentIsOpaque;
   739 }
   740 }
   740 
   741 
   741 void FrameView::setUseSlowRepaints()
   742 void FrameView::setUseSlowRepaints()
   742 {
   743 {
   743     m_useSlowRepaints = true;
   744     m_useSlowRepaints = true;
   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)