OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> | 2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> |
3 * 1999 Lars Knoll <knoll@kde.org> | 3 * 1999 Lars Knoll <knoll@kde.org> |
4 * 1999 Antti Koivisto <koivisto@kde.org> | 4 * 1999 Antti Koivisto <koivisto@kde.org> |
5 * 2000 Dirk Mueller <mueller@kde.org> | 5 * 2000 Dirk Mueller <mueller@kde.org> |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. |
7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com) | 7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com) |
8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
9 * Copyright (C) 2009 Google Inc. All rights reserved. | 9 * Copyright (C) 2009 Google Inc. All rights reserved. |
10 * | 10 * |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 #include "wtf/CurrentTime.h" | 82 #include "wtf/CurrentTime.h" |
83 #include "wtf/TemporaryChange.h" | 83 #include "wtf/TemporaryChange.h" |
84 | 84 |
85 namespace WebCore { | 85 namespace WebCore { |
86 | 86 |
87 using namespace HTMLNames; | 87 using namespace HTMLNames; |
88 | 88 |
89 double FrameView::s_currentFrameTimeStamp = 0.0; | 89 double FrameView::s_currentFrameTimeStamp = 0.0; |
90 bool FrameView::s_inPaintContents = false; | 90 bool FrameView::s_inPaintContents = false; |
91 | 91 |
92 | |
93 // REPAINT_THROTTLING now chooses default values for throttling parameters. | |
94 // Should be removed when applications start using runtime configuration. | |
95 #if ENABLE(REPAINT_THROTTLING) | |
96 // Normal delay | |
97 static const double s_normalDeferredRepaintDelay = 0.016; | |
98 // Negative value would mean that first few repaints happen without a delay | |
99 static const double s_initialDeferredRepaintDelayDuringLoading = 0; | |
100 // The delay grows on each repaint to this maximum value | |
101 static const double s_maxDeferredRepaintDelayDuringLoading = 2.5; | |
102 // On each repaint the delay increses by this amount | |
103 static const double s_deferredRepaintDelayIncrementDuringLoading = 0.5; | |
104 #else | |
105 // FIXME: Repaint throttling could be good to have on all platform. | |
106 // The balance between CPU use and repaint frequency will need some tuning for d
esktop. | |
107 // More hooks may be needed to reset the delay on things like GIF and CSS animat
ions. | |
108 static const double s_normalDeferredRepaintDelay = 0; | |
109 static const double s_initialDeferredRepaintDelayDuringLoading = 0; | |
110 static const double s_maxDeferredRepaintDelayDuringLoading = 0; | |
111 static const double s_deferredRepaintDelayIncrementDuringLoading = 0; | |
112 #endif | |
113 | |
114 // The maximum number of updateWidgets iterations that should be done before ret
urning. | 92 // The maximum number of updateWidgets iterations that should be done before ret
urning. |
115 static const unsigned maxUpdateWidgetsIterations = 2; | 93 static const unsigned maxUpdateWidgetsIterations = 2; |
116 | 94 |
117 static RenderLayer::UpdateLayerPositionsFlags updateLayerPositionFlags(RenderLay
er* layer, bool isRelayoutingSubtree, bool didFullRepaint) | 95 static RenderLayer::UpdateLayerPositionsFlags updateLayerPositionFlags(RenderLay
er* layer, bool isRelayoutingSubtree, bool didFullRepaint) |
118 { | 96 { |
119 RenderLayer::UpdateLayerPositionsFlags flags = RenderLayer::defaultFlags; | 97 RenderLayer::UpdateLayerPositionsFlags flags = RenderLayer::defaultFlags; |
120 | 98 |
121 if (didFullRepaint) { | 99 if (didFullRepaint) { |
122 flags &= ~RenderLayer::CheckForRepaint; | 100 flags &= ~RenderLayer::CheckForRepaint; |
123 flags |= RenderLayer::NeedsFullRepaintInBacking; | 101 flags |= RenderLayer::NeedsFullRepaintInBacking; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired) | 142 , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired) |
165 , m_updateWidgetsTimer(this, &FrameView::updateWidgetsTimerFired) | 143 , m_updateWidgetsTimer(this, &FrameView::updateWidgetsTimerFired) |
166 , m_isTransparent(false) | 144 , m_isTransparent(false) |
167 , m_baseBackgroundColor(Color::white) | 145 , m_baseBackgroundColor(Color::white) |
168 , m_mediaType("screen") | 146 , m_mediaType("screen") |
169 , m_overflowStatusDirty(true) | 147 , m_overflowStatusDirty(true) |
170 , m_viewportRenderer(0) | 148 , m_viewportRenderer(0) |
171 , m_wasScrolledByUser(false) | 149 , m_wasScrolledByUser(false) |
172 , m_inProgrammaticScroll(false) | 150 , m_inProgrammaticScroll(false) |
173 , m_safeToPropagateScrollToParent(true) | 151 , m_safeToPropagateScrollToParent(true) |
174 , m_deferredRepaintTimer(this, &FrameView::deferredRepaintTimerFired) | |
175 , m_isTrackingRepaints(false) | 152 , m_isTrackingRepaints(false) |
176 , m_scrollCorner(0) | 153 , m_scrollCorner(0) |
177 , m_shouldAutoSize(false) | 154 , m_shouldAutoSize(false) |
178 , m_inAutoSize(false) | 155 , m_inAutoSize(false) |
179 , m_didRunAutosize(false) | 156 , m_didRunAutosize(false) |
180 , m_hasSoftwareFilters(false) | 157 , m_hasSoftwareFilters(false) |
181 , m_visibleContentScaleFactor(1) | 158 , m_visibleContentScaleFactor(1) |
182 , m_inputEventsScaleFactorForEmulation(1) | 159 , m_inputEventsScaleFactorForEmulation(1) |
183 , m_partialLayout() | 160 , m_partialLayout() |
184 , m_layoutSizeFixedToFrameSize(true) | 161 , m_layoutSizeFixedToFrameSize(true) |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 m_layoutCount = 0; | 227 m_layoutCount = 0; |
251 m_nestedLayoutCount = 0; | 228 m_nestedLayoutCount = 0; |
252 m_postLayoutTasksTimer.stop(); | 229 m_postLayoutTasksTimer.stop(); |
253 m_updateWidgetsTimer.stop(); | 230 m_updateWidgetsTimer.stop(); |
254 m_firstLayout = true; | 231 m_firstLayout = true; |
255 m_firstLayoutCallbackPending = false; | 232 m_firstLayoutCallbackPending = false; |
256 m_wasScrolledByUser = false; | 233 m_wasScrolledByUser = false; |
257 m_safeToPropagateScrollToParent = true; | 234 m_safeToPropagateScrollToParent = true; |
258 m_lastViewportSize = IntSize(); | 235 m_lastViewportSize = IntSize(); |
259 m_lastZoomFactor = 1.0f; | 236 m_lastZoomFactor = 1.0f; |
260 m_repaintCount = 0; | |
261 m_repaintRects.clear(); | |
262 m_deferredRepaintDelay = s_initialDeferredRepaintDelayDuringLoading; | |
263 m_deferredRepaintTimer.stop(); | |
264 m_isTrackingRepaints = false; | 237 m_isTrackingRepaints = false; |
265 m_trackedRepaintRects.clear(); | 238 m_trackedRepaintRects.clear(); |
266 m_lastPaintTime = 0; | 239 m_lastPaintTime = 0; |
267 m_paintBehavior = PaintBehaviorNormal; | 240 m_paintBehavior = PaintBehaviorNormal; |
268 m_isPainting = false; | 241 m_isPainting = false; |
269 m_visuallyNonEmptyCharacterCount = 0; | 242 m_visuallyNonEmptyCharacterCount = 0; |
270 m_visuallyNonEmptyPixelCount = 0; | 243 m_visuallyNonEmptyPixelCount = 0; |
271 m_isVisuallyNonEmpty = false; | 244 m_isVisuallyNonEmpty = false; |
272 m_firstVisuallyNonEmptyLayoutCallbackPending = true; | 245 m_firstVisuallyNonEmptyLayoutCallbackPending = true; |
273 m_maintainScrollPositionAnchor = 0; | 246 m_maintainScrollPositionAnchor = 0; |
(...skipping 1460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1734 } | 1707 } |
1735 | 1708 |
1736 HostWindow* FrameView::hostWindow() const | 1709 HostWindow* FrameView::hostWindow() const |
1737 { | 1710 { |
1738 Page* page = frame().page(); | 1711 Page* page = frame().page(); |
1739 if (!page) | 1712 if (!page) |
1740 return 0; | 1713 return 0; |
1741 return &page->chrome(); | 1714 return &page->chrome(); |
1742 } | 1715 } |
1743 | 1716 |
1744 const unsigned cRepaintRectUnionThreshold = 25; | |
1745 | |
1746 void FrameView::repaintContentRectangle(const IntRect& r) | 1717 void FrameView::repaintContentRectangle(const IntRect& r) |
1747 { | 1718 { |
1748 ASSERT(!m_frame->ownerElement()); | 1719 ASSERT(!m_frame->ownerElement()); |
1749 | 1720 |
1750 if (m_isTrackingRepaints) { | 1721 if (m_isTrackingRepaints) { |
1751 IntRect repaintRect = r; | 1722 IntRect repaintRect = r; |
1752 repaintRect.move(-scrollOffset()); | 1723 repaintRect.move(-scrollOffset()); |
1753 m_trackedRepaintRects.append(repaintRect); | 1724 m_trackedRepaintRects.append(repaintRect); |
1754 } | 1725 } |
1755 | 1726 |
1756 double delay = adjustedDeferredRepaintDelay(); | |
1757 if (m_deferredRepaintTimer.isActive() || delay) { | |
1758 IntRect paintRect = r; | |
1759 if (clipsRepaints() && !paintsEntireContents()) | |
1760 paintRect.intersect(visibleContentRect()); | |
1761 if (paintRect.isEmpty()) | |
1762 return; | |
1763 if (m_repaintCount == cRepaintRectUnionThreshold) { | |
1764 IntRect unionedRect; | |
1765 for (unsigned i = 0; i < cRepaintRectUnionThreshold; ++i) | |
1766 unionedRect.unite(pixelSnappedIntRect(m_repaintRects[i])); | |
1767 m_repaintRects.clear(); | |
1768 m_repaintRects.append(unionedRect); | |
1769 } | |
1770 if (m_repaintCount < cRepaintRectUnionThreshold) | |
1771 m_repaintRects.append(paintRect); | |
1772 else | |
1773 m_repaintRects[0].unite(paintRect); | |
1774 m_repaintCount++; | |
1775 | |
1776 startDeferredRepaintTimer(delay); | |
1777 | |
1778 return; | |
1779 } | |
1780 | |
1781 ScrollView::repaintContentRectangle(r); | 1727 ScrollView::repaintContentRectangle(r); |
1782 } | 1728 } |
1783 | 1729 |
1784 void FrameView::contentsResized() | 1730 void FrameView::contentsResized() |
1785 { | 1731 { |
1786 ScrollView::contentsResized(); | 1732 ScrollView::contentsResized(); |
1787 setNeedsLayout(); | 1733 setNeedsLayout(); |
1788 } | 1734 } |
1789 | 1735 |
1790 void FrameView::scrollbarExistenceDidChange() | 1736 void FrameView::scrollbarExistenceDidChange() |
(...skipping 16 matching lines...) Expand all Loading... |
1807 layout(); | 1753 layout(); |
1808 | 1754 |
1809 if (renderView() && renderView()->usesCompositing()) { | 1755 if (renderView() && renderView()->usesCompositing()) { |
1810 renderView()->compositor()->frameViewScrollbarsExistenceDidChange(); | 1756 renderView()->compositor()->frameViewScrollbarsExistenceDidChange(); |
1811 | 1757 |
1812 if (!useOverlayScrollbars) | 1758 if (!useOverlayScrollbars) |
1813 renderView()->compositor()->frameViewDidChangeSize(); | 1759 renderView()->compositor()->frameViewDidChangeSize(); |
1814 } | 1760 } |
1815 } | 1761 } |
1816 | 1762 |
1817 void FrameView::startDeferredRepaintTimer(double delay) | |
1818 { | |
1819 if (m_deferredRepaintTimer.isActive()) | |
1820 return; | |
1821 | |
1822 m_deferredRepaintTimer.startOneShot(delay); | |
1823 } | |
1824 | |
1825 void FrameView::handleLoadCompleted() | 1763 void FrameView::handleLoadCompleted() |
1826 { | 1764 { |
1827 // Once loading has completed, allow autoSize one last opportunity to | 1765 // Once loading has completed, allow autoSize one last opportunity to |
1828 // reduce the size of the frame. | 1766 // reduce the size of the frame. |
1829 autoSizeIfEnabled(); | 1767 autoSizeIfEnabled(); |
1830 if (shouldUseLoadTimeDeferredRepaintDelay()) | |
1831 return; | |
1832 m_deferredRepaintDelay = s_normalDeferredRepaintDelay; | |
1833 flushDeferredRepaints(); | |
1834 } | |
1835 | |
1836 void FrameView::flushDeferredRepaints() | |
1837 { | |
1838 if (!m_deferredRepaintTimer.isActive()) | |
1839 return; | |
1840 m_deferredRepaintTimer.stop(); | |
1841 doDeferredRepaints(); | |
1842 } | |
1843 | |
1844 void FrameView::doDeferredRepaints() | |
1845 { | |
1846 unsigned size = m_repaintRects.size(); | |
1847 for (unsigned i = 0; i < size; i++) { | |
1848 ScrollView::repaintContentRectangle(pixelSnappedIntRect(m_repaintRects[i
])); | |
1849 } | |
1850 m_repaintRects.clear(); | |
1851 m_repaintCount = 0; | |
1852 | |
1853 updateDeferredRepaintDelayAfterRepaint(); | |
1854 } | |
1855 | |
1856 bool FrameView::shouldUseLoadTimeDeferredRepaintDelay() const | |
1857 { | |
1858 // Don't defer after the initial load of the page has been completed. | |
1859 if (m_frame->tree().top()->document()->loadEventFinished()) | |
1860 return false; | |
1861 Document* document = m_frame->document(); | |
1862 if (!document) | |
1863 return false; | |
1864 if (document->parsing()) | |
1865 return true; | |
1866 if (document->fetcher()->requestCount()) | |
1867 return true; | |
1868 return false; | |
1869 } | |
1870 | |
1871 void FrameView::updateDeferredRepaintDelayAfterRepaint() | |
1872 { | |
1873 if (!shouldUseLoadTimeDeferredRepaintDelay()) { | |
1874 m_deferredRepaintDelay = s_normalDeferredRepaintDelay; | |
1875 return; | |
1876 } | |
1877 double incrementedRepaintDelay = m_deferredRepaintDelay + s_deferredRepaintD
elayIncrementDuringLoading; | |
1878 m_deferredRepaintDelay = std::min(incrementedRepaintDelay, s_maxDeferredRepa
intDelayDuringLoading); | |
1879 } | |
1880 | |
1881 void FrameView::resetDeferredRepaintDelay() | |
1882 { | |
1883 m_deferredRepaintDelay = 0; | |
1884 if (m_deferredRepaintTimer.isActive()) { | |
1885 m_deferredRepaintTimer.stop(); | |
1886 doDeferredRepaints(); | |
1887 } | |
1888 } | |
1889 | |
1890 double FrameView::adjustedDeferredRepaintDelay() const | |
1891 { | |
1892 if (!m_deferredRepaintDelay) | |
1893 return 0; | |
1894 double timeSinceLastPaint = currentTime() - m_lastPaintTime; | |
1895 return max(0., m_deferredRepaintDelay - timeSinceLastPaint); | |
1896 } | |
1897 | |
1898 void FrameView::deferredRepaintTimerFired(Timer<FrameView>*) | |
1899 { | |
1900 doDeferredRepaints(); | |
1901 } | 1768 } |
1902 | 1769 |
1903 void FrameView::layoutTimerFired(Timer<FrameView>*) | 1770 void FrameView::layoutTimerFired(Timer<FrameView>*) |
1904 { | 1771 { |
1905 layout(); | 1772 layout(); |
1906 } | 1773 } |
1907 | 1774 |
1908 void FrameView::scheduleRelayout() | 1775 void FrameView::scheduleRelayout() |
1909 { | 1776 { |
1910 ASSERT(m_frame->view() == this); | 1777 ASSERT(m_frame->view() == this); |
(...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2949 // Grab a copy of the children() set, as it may be mutated by the following
updateLayoutAndStyleIfNeededRecursive | 2816 // Grab a copy of the children() set, as it may be mutated by the following
updateLayoutAndStyleIfNeededRecursive |
2950 // calls, as they can potentially re-enter a layout of the parent frame view
, which may add/remove scrollbars | 2817 // calls, as they can potentially re-enter a layout of the parent frame view
, which may add/remove scrollbars |
2951 // and thus mutates the children() set. | 2818 // and thus mutates the children() set. |
2952 Vector<RefPtr<FrameView> > frameViews; | 2819 Vector<RefPtr<FrameView> > frameViews; |
2953 collectFrameViewChildren(this, frameViews); | 2820 collectFrameViewChildren(this, frameViews); |
2954 | 2821 |
2955 const Vector<RefPtr<FrameView> >::iterator end = frameViews.end(); | 2822 const Vector<RefPtr<FrameView> >::iterator end = frameViews.end(); |
2956 for (Vector<RefPtr<FrameView> >::iterator it = frameViews.begin(); it != end
; ++it) | 2823 for (Vector<RefPtr<FrameView> >::iterator it = frameViews.begin(); it != end
; ++it) |
2957 (*it)->updateLayoutAndStyleIfNeededRecursive(); | 2824 (*it)->updateLayoutAndStyleIfNeededRecursive(); |
2958 | 2825 |
2959 // updateLayoutAndStyleIfNeededRecursive is called when we need to make sure
style and layout are up-to-date before | |
2960 // painting, so we need to flush out any deferred repaints too. | |
2961 flushDeferredRepaints(); | |
2962 | |
2963 // When seamless is on, child frame can mark parent frame dirty. In such cas
e, child frame | 2826 // When seamless is on, child frame can mark parent frame dirty. In such cas
e, child frame |
2964 // needs to call layout on parent frame recursively. | 2827 // needs to call layout on parent frame recursively. |
2965 // This assert ensures that parent frames are clean, when child frames finis
hed updating layout and style. | 2828 // This assert ensures that parent frames are clean, when child frames finis
hed updating layout and style. |
2966 ASSERT(!needsLayout()); | 2829 ASSERT(!needsLayout()); |
2967 } | 2830 } |
2968 | 2831 |
2969 void FrameView::enableAutoSizeMode(bool enable, const IntSize& minSize, const In
tSize& maxSize) | 2832 void FrameView::enableAutoSizeMode(bool enable, const IntSize& minSize, const In
tSize& maxSize) |
2970 { | 2833 { |
2971 ASSERT(!enable || !minSize.isEmpty()); | 2834 ASSERT(!enable || !minSize.isEmpty()); |
2972 ASSERT(minSize.width() <= maxSize.width()); | 2835 ASSERT(minSize.width() <= maxSize.width()); |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3360 void FrameView::willRemoveScrollbar(Scrollbar* scrollbar, ScrollbarOrientation o
rientation) | 3223 void FrameView::willRemoveScrollbar(Scrollbar* scrollbar, ScrollbarOrientation o
rientation) |
3361 { | 3224 { |
3362 ScrollableArea::willRemoveScrollbar(scrollbar, orientation); | 3225 ScrollableArea::willRemoveScrollbar(scrollbar, orientation); |
3363 if (AXObjectCache* cache = axObjectCache()) { | 3226 if (AXObjectCache* cache = axObjectCache()) { |
3364 cache->remove(scrollbar); | 3227 cache->remove(scrollbar); |
3365 cache->handleScrollbarUpdate(this); | 3228 cache->handleScrollbarUpdate(this); |
3366 } | 3229 } |
3367 } | 3230 } |
3368 | 3231 |
3369 } // namespace WebCore | 3232 } // namespace WebCore |
OLD | NEW |