Changeset 53797 in webkit
- Timestamp:
- Jan 25, 2010 4:37:37 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r53795 r53797 1 2010-01-25 Benjamin Poulain <benjamin.poulain@nokia.com> 2 3 Reviewed by Antti Koivisto. 4 5 Do not render the full frame when there is some elements with fixed positioning 6 https://bugs.webkit.org/show_bug.cgi?id=33150 7 8 Do not render the full frame when there is some elements with fixed positioning 9 https://bugs.webkit.org/show_bug.cgi?id=33150 10 11 * page/FrameView.cpp: 12 (WebCore::FrameView::useSlowRepaints): 13 (WebCore::FrameView::useSlowRepaintsIfNotOverlapped): 14 (WebCore::FrameView::registerFixedPositionedObject): 15 (WebCore::FrameView::unregisterFixedPositionedObject): 16 (WebCore::FrameView::scrollContentsFastPath): 17 * page/FrameView.h: 18 * platform/ScrollView.cpp: 19 (WebCore::ScrollView::scrollContents): 20 (WebCore::ScrollView::scrollContentsFastPath): 21 * platform/ScrollView.h: 22 * rendering/RenderObject.cpp: 23 (WebCore::RenderObject::styleWillChange): 24 (WebCore::RenderObject::destroy): 25 1 26 2010-01-24 Pavel Feldman <pfeldman@chromium.org> 2 27 -
trunk/WebCore/page/FrameView.cpp
r53713 r53797 785 785 bool FrameView::useSlowRepaints() const 786 786 { 787 return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || m_isOverlapped || !m_contentIsOpaque;787 return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && !m_fixedPositionedObjects.isEmpty()) || m_isOverlapped || !m_contentIsOpaque; 788 788 } 789 789 790 790 bool FrameView::useSlowRepaintsIfNotOverlapped() const 791 791 { 792 return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || !m_contentIsOpaque;792 return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && !m_fixedPositionedObjects.isEmpty()) || !m_contentIsOpaque; 793 793 } 794 794 … … 812 812 if (!m_slowRepaintObjectCount) 813 813 setCanBlitOnScroll(!useSlowRepaints()); 814 } 815 816 817 void FrameView::registerFixedPositionedObject(RenderObject* object) 818 { 819 if (platformWidget() && m_fixedPositionedObjects.isEmpty()) 820 setCanBlitOnScroll(false); 821 m_fixedPositionedObjects.add(object); 822 } 823 824 void FrameView::unregisterFixedPositionedObject(RenderObject* object) 825 { 826 bool wasEmpty = m_fixedPositionedObjects.isEmpty(); 827 m_fixedPositionedObjects.remove(object); 828 if (platformWidget() && !wasEmpty && m_fixedPositionedObjects.isEmpty()) 829 setCanBlitOnScroll(!useSlowRepaints()); 830 } 831 832 void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) 833 { 834 const size_t fixedObjectNumberThreshold = 5; 835 836 if (m_fixedPositionedObjects.isEmpty()) 837 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); 838 else { 839 Vector<RenderObject*, fixedObjectNumberThreshold> fixedObjectsInViewport; 840 841 bool updateInvalidatedSubRect = true; 842 // Get a list of fixed objects that are not in transformations 843 HashSet<RenderObject*>::const_iterator end = m_fixedPositionedObjects.end(); 844 HashSet<RenderObject*>::const_iterator it = m_fixedPositionedObjects.begin(); 845 for (; it != end; ++it) { 846 RenderObject* obj = *it; 847 // make sure the parent layer has not been transformed 848 if (obj->containingBlock() == obj->view()) { 849 if (fixedObjectsInViewport.size() >= fixedObjectNumberThreshold) { 850 updateInvalidatedSubRect = false; 851 break; 852 } 853 fixedObjectsInViewport.append(obj); 854 } 855 } 856 857 // scroll the content 858 if (updateInvalidatedSubRect) { 859 // 1) scroll 860 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); 861 862 // 2) update the area of fixed objets that has been invalidated 863 size_t fixObjectsCount = fixedObjectsInViewport.size(); 864 for (size_t i = 0; i < fixObjectsCount; ++i) { 865 IntRect topLevelRect; 866 IntRect updateRect = fixedObjectsInViewport[i]->paintingRootRect(topLevelRect); 867 updateRect.move(-scrollX(), -scrollY()); 868 IntRect scrolledRect = updateRect; 869 scrolledRect.move(scrollDelta); 870 updateRect.unite(scrolledRect); 871 updateRect.intersect(rectToScroll); 872 hostWindow()->repaint(updateRect, true, false, true); 873 } 874 } else { 875 // the number of fixed objects exceed the threshold, so we repaint everything. 876 IntRect updateRect = clipRect; 877 updateRect.intersect(rectToScroll); 878 hostWindow()->repaint(updateRect, true, false, true); 879 } 880 } 814 881 } 815 882 -
trunk/WebCore/page/FrameView.h
r53713 r53797 146 146 void removeSlowRepaintObject(); 147 147 148 // Methods to manage the objects that are fixed 149 // in the view when scrolling 150 void registerFixedPositionedObject(RenderObject* object); 151 void unregisterFixedPositionedObject(RenderObject* object); 152 148 153 void beginDeferredRepaints(); 149 154 void endDeferredRepaints(); … … 199 204 bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; } 200 205 void invalidateScrollCorner(); 206 207 protected: 208 virtual void scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); 201 209 202 210 private: … … 269 277 bool m_contentIsOpaque; 270 278 unsigned m_slowRepaintObjectCount; 279 HashSet<RenderObject*> m_fixedPositionedObjects; 271 280 272 281 int m_borderX, m_borderY; -
trunk/WebCore/platform/ScrollView.cpp
r53718 r53797 514 514 if (canBlitOnScroll()) { // The main frame can just blit the WebView window 515 515 // FIXME: Find a way to blit subframes without blitting overlapping content 516 hostWindow()->scroll(-scrollDelta, scrollViewRect, clipRect);516 scrollContentsFastPath(-scrollDelta, scrollViewRect, clipRect); 517 517 } else { 518 518 // We need to go ahead and repaint the entire backing store. Do it now before moving the … … 527 527 // be very fast). 528 528 hostWindow()->paint(); 529 } 530 531 void ScrollView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) 532 { 533 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); 529 534 } 530 535 -
trunk/WebCore/platform/ScrollView.h
r53713 r53797 250 250 virtual void updateScrollCorner(); 251 251 virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect); 252 253 // Scroll the content by blitting the pixels 254 virtual void scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); 252 255 253 256 private: -
trunk/WebCore/rendering/RenderObject.cpp
r53713 r53797 1648 1648 s_affectsParentBlock = false; 1649 1649 1650 if (view()->frameView()) { 1651 // FIXME: A better solution would be to only invalidate the fixed regions when scrolling. It's overkill to 1652 // prevent the entire view from blitting on a scroll. 1653 1650 FrameView* frameView = view()->frameView(); 1651 if (frameView) { 1654 1652 bool shouldBlitOnFixedBackgroundImage = false; 1655 1653 #if ENABLE(FAST_MOBILE_SCROLLING) … … 1661 1659 #endif 1662 1660 1663 bool newStyleSlowScroll = newStyle && (newStyle->position() == FixedPosition 1664 || (!shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage())); 1665 bool oldStyleSlowScroll = m_style && (m_style->position() == FixedPosition 1666 || (!shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage())); 1661 bool newStyleSlowScroll = newStyle && !shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage(); 1662 bool oldStyleSlowScroll = m_style && !shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage(); 1663 1667 1664 if (oldStyleSlowScroll != newStyleSlowScroll) { 1668 1665 if (oldStyleSlowScroll) 1669 view()->frameView()->removeSlowRepaintObject();1666 frameView->removeSlowRepaintObject(); 1670 1667 if (newStyleSlowScroll) 1671 view()->frameView()->addSlowRepaintObject(); 1668 frameView->addSlowRepaintObject(); 1669 } 1670 1671 bool newStyleHasTransform = newStyle && (newStyle->hasTransformRelatedProperty()); 1672 if (!newStyleHasTransform) { 1673 bool newStyleHasFixedPosition = newStyle && (newStyle->position() == FixedPosition); 1674 bool oldStyleHasFixedPosition = m_style && (m_style->position() == FixedPosition); 1675 1676 if (oldStyleHasFixedPosition != newStyleHasFixedPosition) { 1677 if (newStyleHasFixedPosition) 1678 frameView->registerFixedPositionedObject(this); 1679 else 1680 frameView->unregisterFixedPositionedObject(this); 1681 } else { 1682 // if previously had a fix position, but had a transform, which has been removed 1683 bool oldStyleHasTransform = m_style && (m_style->hasTransformRelatedProperty()); 1684 if (oldStyleHasTransform && newStyleHasFixedPosition) 1685 frameView->registerFixedPositionedObject(this); 1686 } 1672 1687 } 1673 1688 } … … 1932 1947 void RenderObject::destroy() 1933 1948 { 1949 // unregister from the view if the object had a fixed position 1950 if (m_style && m_style->position() == FixedPosition) { 1951 FrameView* frameView = document()->view(); 1952 if (frameView) 1953 frameView->unregisterFixedPositionedObject(this); 1954 } 1955 1934 1956 // Destroy any leftover anonymous children. 1935 1957 RenderObjectChildList* children = virtualChildren();
Note: See TracChangeset
for help on using the changeset viewer.