78 |
78 |
79 using namespace HTMLNames; |
79 using namespace HTMLNames; |
80 |
80 |
81 double FrameView::sCurrentPaintTimeStamp = 0.0; |
81 double FrameView::sCurrentPaintTimeStamp = 0.0; |
82 |
82 |
|
83 // REPAINT_THROTTLING now chooses default values for throttling parameters. |
|
84 // Should be removed when applications start using runtime configuration. |
83 #if ENABLE(REPAINT_THROTTLING) |
85 #if ENABLE(REPAINT_THROTTLING) |
84 // Normal delay |
86 // Normal delay |
85 static const double deferredRepaintDelay = 0.025; |
87 double FrameView::s_deferredRepaintDelay = 0.025; |
86 // Negative value would mean that first few repaints happen without a delay |
88 // Negative value would mean that first few repaints happen without a delay |
87 static const double initialDeferredRepaintDelayDuringLoading = 0; |
89 double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0; |
88 // The delay grows on each repaint to this maximum value |
90 // The delay grows on each repaint to this maximum value |
89 static const double maxDeferredRepaintDelayDuringLoading = 2.5; |
91 double FrameView::s_maxDeferredRepaintDelayDuringLoading = 2.5; |
90 // On each repaint the delay increses by this amount |
92 // On each repaint the delay increses by this amount |
91 static const double deferredRepaintDelayIncrementDuringLoading = 0.5; |
93 double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0.5; |
92 #else |
94 #else |
93 // FIXME: Repaint throttling could be good to have on all platform. |
95 // FIXME: Repaint throttling could be good to have on all platform. |
94 // The balance between CPU use and repaint frequency will need some tuning for desktop. |
96 // The balance between CPU use and repaint frequency will need some tuning for desktop. |
95 // More hooks may be needed to reset the delay on things like GIF and CSS animations. |
97 // More hooks may be needed to reset the delay on things like GIF and CSS animations. |
96 static const double deferredRepaintDelay = 0; |
98 double FrameView::s_deferredRepaintDelay = 0; |
97 static const double initialDeferredRepaintDelayDuringLoading = 0; |
99 double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0; |
98 static const double maxDeferredRepaintDelayDuringLoading = 0; |
100 double FrameView::s_maxDeferredRepaintDelayDuringLoading = 0; |
99 static const double deferredRepaintDelayIncrementDuringLoading = 0; |
101 double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0; |
100 #endif |
102 #endif |
101 |
103 |
102 // The maximum number of updateWidgets iterations that should be done before returning. |
104 // The maximum number of updateWidgets iterations that should be done before returning. |
103 static const unsigned maxUpdateWidgetsIterations = 2; |
105 static const unsigned maxUpdateWidgetsIterations = 2; |
104 |
106 |
198 m_lastLayoutSize = IntSize(); |
200 m_lastLayoutSize = IntSize(); |
199 m_lastZoomFactor = 1.0f; |
201 m_lastZoomFactor = 1.0f; |
200 m_deferringRepaints = 0; |
202 m_deferringRepaints = 0; |
201 m_repaintCount = 0; |
203 m_repaintCount = 0; |
202 m_repaintRects.clear(); |
204 m_repaintRects.clear(); |
203 m_deferredRepaintDelay = initialDeferredRepaintDelayDuringLoading; |
205 m_deferredRepaintDelay = s_initialDeferredRepaintDelayDuringLoading; |
204 m_deferredRepaintTimer.stop(); |
206 m_deferredRepaintTimer.stop(); |
205 m_lastPaintTime = 0; |
207 m_lastPaintTime = 0; |
206 m_paintBehavior = PaintBehaviorNormal; |
208 m_paintBehavior = PaintBehaviorNormal; |
207 m_isPainting = false; |
209 m_isPainting = false; |
208 m_isVisuallyNonEmpty = false; |
210 m_isVisuallyNonEmpty = false; |
880 |
882 |
881 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) |
883 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) |
882 { |
884 { |
883 const size_t fixedObjectThreshold = 5; |
885 const size_t fixedObjectThreshold = 5; |
884 |
886 |
885 ListHashSet<RenderBox*>* positionedObjects = 0; |
887 RenderBlock::PositionedObjectsListHashSet* positionedObjects = 0; |
886 if (RenderView* root = m_frame->contentRenderer()) |
888 if (RenderView* root = m_frame->contentRenderer()) |
887 positionedObjects = root->positionedObjects(); |
889 positionedObjects = root->positionedObjects(); |
888 |
890 |
889 if (!positionedObjects || positionedObjects->isEmpty()) { |
891 if (!positionedObjects || positionedObjects->isEmpty()) { |
890 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); |
892 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); |
892 } |
894 } |
893 |
895 |
894 // Get the rects of the fixed objects visible in the rectToScroll |
896 // Get the rects of the fixed objects visible in the rectToScroll |
895 Vector<IntRect, fixedObjectThreshold> subRectToUpdate; |
897 Vector<IntRect, fixedObjectThreshold> subRectToUpdate; |
896 bool updateInvalidatedSubRect = true; |
898 bool updateInvalidatedSubRect = true; |
897 ListHashSet<RenderBox*>::const_iterator end = positionedObjects->end(); |
899 RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end(); |
898 for (ListHashSet<RenderBox*>::const_iterator it = positionedObjects->begin(); it != end; ++it) { |
900 for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) { |
899 RenderBox* renderBox = *it; |
901 RenderBox* renderBox = *it; |
900 if (renderBox->style()->position() != FixedPosition) |
902 if (renderBox->style()->position() != FixedPosition) |
901 continue; |
903 continue; |
902 IntRect topLevelRect; |
904 IntRect updateRect = renderBox->layer()->repaintRectIncludingDescendants(); |
903 IntRect updateRect = renderBox->paintingRootRect(topLevelRect); |
905 updateRect = contentsToWindow(updateRect); |
904 updateRect.move(-scrollX(), -scrollY()); |
906 |
905 updateRect.intersect(rectToScroll); |
907 updateRect.intersect(rectToScroll); |
906 if (!updateRect.isEmpty()) { |
908 if (!updateRect.isEmpty()) { |
907 if (subRectToUpdate.size() >= fixedObjectThreshold) { |
909 if (subRectToUpdate.size() >= fixedObjectThreshold) { |
908 updateInvalidatedSubRect = false; |
910 updateInvalidatedSubRect = false; |
909 break; |
911 break; |
1058 } |
1060 } |
1059 |
1061 |
1060 void FrameView::scrollPositionChanged() |
1062 void FrameView::scrollPositionChanged() |
1061 { |
1063 { |
1062 frame()->eventHandler()->sendScrollEvent(); |
1064 frame()->eventHandler()->sendScrollEvent(); |
1063 |
1065 repaintFixedElementsAfterScrolling(); |
|
1066 } |
|
1067 |
|
1068 void FrameView::repaintFixedElementsAfterScrolling() |
|
1069 { |
1064 // For fixed position elements, update widget positions and compositing layers after scrolling, |
1070 // For fixed position elements, update widget positions and compositing layers after scrolling, |
1065 // but only if we're not inside of layout. |
1071 // but only if we're not inside of layout. |
1066 // FIXME: we could skip this if we knew the page had no fixed position elements. |
1072 // FIXME: we could skip this if we knew the page had no fixed position elements. |
1067 if (!m_nestedLayoutCount) { |
1073 if (!m_nestedLayoutCount) { |
1068 if (RenderView* root = m_frame->contentRenderer()) { |
1074 if (RenderView* root = m_frame->contentRenderer()) { |
1212 |
1218 |
1213 void FrameView::updateDeferredRepaintDelay() |
1219 void FrameView::updateDeferredRepaintDelay() |
1214 { |
1220 { |
1215 Document* document = m_frame->document(); |
1221 Document* document = m_frame->document(); |
1216 if (!document || (!document->parsing() && !document->docLoader()->requestCount())) { |
1222 if (!document || (!document->parsing() && !document->docLoader()->requestCount())) { |
1217 m_deferredRepaintDelay = deferredRepaintDelay; |
1223 m_deferredRepaintDelay = s_deferredRepaintDelay; |
1218 return; |
1224 return; |
1219 } |
1225 } |
1220 if (m_deferredRepaintDelay < maxDeferredRepaintDelayDuringLoading) { |
1226 if (m_deferredRepaintDelay < s_maxDeferredRepaintDelayDuringLoading) { |
1221 m_deferredRepaintDelay += deferredRepaintDelayIncrementDuringLoading; |
1227 m_deferredRepaintDelay += s_deferredRepaintDelayIncrementDuringLoading; |
1222 if (m_deferredRepaintDelay > maxDeferredRepaintDelayDuringLoading) |
1228 if (m_deferredRepaintDelay > s_maxDeferredRepaintDelayDuringLoading) |
1223 m_deferredRepaintDelay = maxDeferredRepaintDelayDuringLoading; |
1229 m_deferredRepaintDelay = s_maxDeferredRepaintDelayDuringLoading; |
1224 } |
1230 } |
1225 } |
1231 } |
1226 |
1232 |
1227 void FrameView::resetDeferredRepaintDelay() |
1233 void FrameView::resetDeferredRepaintDelay() |
1228 { |
1234 { |
1307 |
1313 |
1308 void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot) |
1314 void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot) |
1309 { |
1315 { |
1310 ASSERT(m_frame->view() == this); |
1316 ASSERT(m_frame->view() == this); |
1311 |
1317 |
1312 if (!m_layoutSchedulingEnabled || (m_frame->contentRenderer() |
1318 if (m_frame->contentRenderer() && m_frame->contentRenderer()->needsLayout()) { |
1313 && m_frame->contentRenderer()->needsLayout())) { |
|
1314 if (relayoutRoot) |
1319 if (relayoutRoot) |
1315 relayoutRoot->markContainingBlocksForLayout(false); |
1320 relayoutRoot->markContainingBlocksForLayout(false); |
1316 return; |
1321 return; |
1317 } |
1322 } |
1318 |
1323 |
1319 if (layoutPending()) { |
1324 if (layoutPending() || !m_layoutSchedulingEnabled) { |
1320 if (m_layoutRoot != relayoutRoot) { |
1325 if (m_layoutRoot != relayoutRoot) { |
1321 if (isObjectAncestorContainerOf(m_layoutRoot, relayoutRoot)) { |
1326 if (isObjectAncestorContainerOf(m_layoutRoot, relayoutRoot)) { |
1322 // Keep the current root |
1327 // Keep the current root |
1323 relayoutRoot->markContainingBlocksForLayout(false, m_layoutRoot); |
1328 relayoutRoot->markContainingBlocksForLayout(false, m_layoutRoot); |
1324 } else if (m_layoutRoot && isObjectAncestorContainerOf(relayoutRoot, m_layoutRoot)) { |
1329 } else if (m_layoutRoot && isObjectAncestorContainerOf(relayoutRoot, m_layoutRoot)) { |
1331 m_layoutRoot->markContainingBlocksForLayout(false); |
1336 m_layoutRoot->markContainingBlocksForLayout(false); |
1332 m_layoutRoot = 0; |
1337 m_layoutRoot = 0; |
1333 relayoutRoot->markContainingBlocksForLayout(false); |
1338 relayoutRoot->markContainingBlocksForLayout(false); |
1334 } |
1339 } |
1335 } |
1340 } |
1336 } else { |
1341 } else if (m_layoutSchedulingEnabled) { |
1337 int delay = m_frame->document()->minimumLayoutDelay(); |
1342 int delay = m_frame->document()->minimumLayoutDelay(); |
1338 m_layoutRoot = relayoutRoot; |
1343 m_layoutRoot = relayoutRoot; |
1339 m_delayedLayout = delay != 0; |
1344 m_delayedLayout = delay != 0; |
1340 m_layoutTimer.startOneShot(delay * 0.001); |
1345 m_layoutTimer.startOneShot(delay * 0.001); |
1341 } |
1346 } |
2137 } |
2142 } |
2138 |
2143 |
2139 return parentPoint; |
2144 return parentPoint; |
2140 } |
2145 } |
2141 |
2146 |
|
2147 // Normal delay |
|
2148 void FrameView::setRepaintThrottlingDeferredRepaintDelay(double p) |
|
2149 { |
|
2150 s_deferredRepaintDelay = p; |
|
2151 } |
|
2152 |
|
2153 // Negative value would mean that first few repaints happen without a delay |
|
2154 void FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(double p) |
|
2155 { |
|
2156 s_initialDeferredRepaintDelayDuringLoading = p; |
|
2157 } |
|
2158 |
|
2159 // The delay grows on each repaint to this maximum value |
|
2160 void FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(double p) |
|
2161 { |
|
2162 s_maxDeferredRepaintDelayDuringLoading = p; |
|
2163 } |
|
2164 |
|
2165 // On each repaint the delay increases by this amount |
|
2166 void FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p) |
|
2167 { |
|
2168 s_deferredRepaintDelayIncrementDuringLoading = p; |
|
2169 } |
|
2170 |
2142 } // namespace WebCore |
2171 } // namespace WebCore |