Changeset 111480 in webkit
- Timestamp:
- Mar 20, 2012 6:19:23 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r111478 r111480 1 2012-03-18 Tim Horton <timothy_horton@apple.com> 2 3 Infinite repaint loop with SVGImageCache and deferred repaint timers 4 https://bugs.webkit.org/show_bug.cgi?id=78315 5 <rdar://problem/10651634> 6 7 Reviewed by Nikolas Zimmermann. 8 9 Only defer image redraw on a timer if we're in layout. This breaks 10 the repaint loop while still preventing us from drawing inside layout. 11 12 Completely disable repaint during relayout inside SVGImage::drawSVGToImageBuffer, 13 preventing deferred repaint timers from being started during that process. 14 15 No new tests, as the problem only occurs in a nonstandard configuration. 16 17 * page/FrameView.cpp: 18 (WebCore::FrameView::FrameView): 19 (WebCore::FrameView::reset): 20 (WebCore::FrameView::repaintContentRectangle): 21 (WebCore::FrameView::endDeferredRepaints): 22 (WebCore::FrameView::startDeferredRepaintTimer): 23 (WebCore): 24 (WebCore::FrameView::doDeferredRepaints): 25 (WebCore::FrameView::deferredRepaintTimerFired): 26 (WebCore::FrameView::beginDisableRepaints): 27 (WebCore::FrameView::endDisableRepaints): 28 * page/FrameView.h: 29 (FrameView): 30 (WebCore::FrameView::repaintsDisabled): 31 * rendering/RenderView.cpp: 32 (WebCore::RenderView::shouldRepaint): 33 * svg/graphics/SVGImage.cpp: 34 (WebCore::SVGImage::drawSVGToImageBuffer): 35 (WebCore::SVGImage::draw): 36 (WebCore::SVGImage::frameView): 37 (WebCore): 38 * svg/graphics/SVGImage.h: 39 (WebCore): 40 * svg/graphics/SVGImageCache.cpp: 41 (WebCore::SVGImageCache::imageContentChanged): 42 (WebCore::SVGImageCache::redraw): 43 (WebCore::SVGImageCache::redrawTimerFired): 44 (WebCore): 45 * svg/graphics/SVGImageCache.h: 46 (SVGImageCache): 47 1 48 2012-03-20 Adam Klein <adamk@chromium.org> 2 49 -
trunk/Source/WebCore/page/FrameView.cpp
r111471 r111480 140 140 , m_inProgrammaticScroll(false) 141 141 , m_deferredRepaintTimer(this, &FrameView::deferredRepaintTimerFired) 142 , m_disableRepaints(0) 142 143 , m_isTrackingRepaints(false) 143 144 , m_shouldUpdateWhileOffscreen(true) … … 246 247 m_firstVisuallyNonEmptyLayoutCallbackPending = true; 247 248 m_maintainScrollPositionAnchor = 0; 249 m_disableRepaints = 0; 248 250 } 249 251 … … 1782 1784 { 1783 1785 ASSERT(!m_frame->ownerElement()); 1784 1786 1785 1787 if (m_isTrackingRepaints) { 1786 1788 IntRect repaintRect = r; … … 1808 1810 m_repaintRects[0].unite(paintRect); 1809 1811 m_repaintCount++; 1810 1811 if (!m_deferringRepaints && !m_deferredRepaintTimer.isActive()) 1812 m_deferredRepaintTimer.startOneShot(delay); 1812 1813 if (!m_deferringRepaints) 1814 startDeferredRepaintTimer(delay); 1815 1813 1816 return; 1814 1817 } … … 1863 1866 } 1864 1867 1865 1866 1868 void FrameView::endDeferredRepaints() 1867 1869 { … … 1876 1878 if (--m_deferringRepaints) 1877 1879 return; 1878 1880 1879 1881 if (m_deferredRepaintTimer.isActive()) 1880 1882 return; 1881 1883 1882 1884 if (double delay = adjustedDeferredRepaintDelay()) { 1883 m_deferredRepaintTimer.startOneShot(delay);1885 startDeferredRepaintTimer(delay); 1884 1886 return; 1885 1887 } 1886 1888 1887 1889 doDeferredRepaints(); 1890 } 1891 1892 void FrameView::startDeferredRepaintTimer(double delay) 1893 { 1894 if (m_deferredRepaintTimer.isActive()) 1895 return; 1896 1897 if (m_disableRepaints) 1898 return; 1899 1900 m_deferredRepaintTimer.startOneShot(delay); 1888 1901 } 1889 1902 … … 1904 1917 void FrameView::doDeferredRepaints() 1905 1918 { 1919 if (m_disableRepaints) 1920 return; 1921 1906 1922 ASSERT(!m_deferringRepaints); 1907 1923 if (!shouldUpdate()) { … … 1962 1978 { 1963 1979 doDeferredRepaints(); 1964 } 1980 } 1981 1982 void FrameView::beginDisableRepaints() 1983 { 1984 m_disableRepaints++; 1985 } 1986 1987 void FrameView::endDisableRepaints() 1988 { 1989 ASSERT(m_disableRepaints > 0); 1990 m_disableRepaints--; 1991 } 1965 1992 1966 1993 void FrameView::layoutTimerFired(Timer<FrameView>*) -
trunk/Source/WebCore/page/FrameView.h
r111471 r111480 209 209 void endDeferredRepaints(); 210 210 void checkStopDelayingDeferredRepaints(); 211 void startDeferredRepaintTimer(double delay); 211 212 void resetDeferredRepaintDelay(); 213 214 void beginDisableRepaints(); 215 void endDisableRepaints(); 216 bool repaintsDisabled() { return m_disableRepaints > 0; } 212 217 213 218 #if ENABLE(DASHBOARD_SUPPORT) … … 476 481 double m_deferredRepaintDelay; 477 482 double m_lastPaintTime; 478 483 484 unsigned m_disableRepaints; 485 479 486 bool m_isTrackingRepaints; // Used for testing. 480 487 Vector<IntRect> m_trackedRepaintRects; -
trunk/Source/WebCore/rendering/RenderView.cpp
r111279 r111480 302 302 if (!m_frameView) 303 303 return false; 304 304 305 if (m_frameView->repaintsDisabled()) 306 return false; 307 305 308 return true; 306 309 } -
trunk/Source/WebCore/svg/graphics/SVGImage.cpp
r111126 r111480 178 178 ASSERT(observer); 179 179 180 // Temporarily reset image observer, we don't want to receive any changeInRect() calls due t his relayout.180 // Temporarily reset image observer, we don't want to receive any changeInRect() calls due to this relayout. 181 181 setImageObserver(0); 182 183 // Disable repainting; we don't want deferred repaints to schedule any timers due to this relayout. 184 frame->view()->beginDisableRepaints(); 185 182 186 renderer->setContainerSize(size); 183 187 frame->view()->resize(this->size()); 188 184 189 if (zoom != 1) 185 190 frame->setPageZoomFactor(zoom); … … 203 208 frame->view()->layout(); 204 209 205 setImageObserver(observer); 210 setImageObserver(observer); 211 212 frame->view()->endDisableRepaints(); 206 213 } 207 214 … … 211 218 return; 212 219 213 FrameView* view = m_page->mainFrame()->view();220 FrameView* view = frameView(); 214 221 215 222 GraphicsContextStateSaver stateSaver(*context); … … 254 261 return 0; 255 262 return toRenderBox(rootElement->renderer()); 263 } 264 265 FrameView* SVGImage::frameView() const 266 { 267 if (!m_page) 268 return 0; 269 270 return m_page->mainFrame()->view(); 256 271 } 257 272 -
trunk/Source/WebCore/svg/graphics/SVGImage.h
r110581 r111480 35 35 namespace WebCore { 36 36 37 class FrameView; 37 38 class ImageBuffer; 38 39 class Page; … … 54 55 void drawSVGToImageBuffer(ImageBuffer*, const IntSize&, float zoom, ShouldClearBuffer); 55 56 RenderBox* embeddedContentBox() const; 57 FrameView* frameView() const; 56 58 57 59 virtual bool isSVGImage() const { return true; } -
trunk/Source/WebCore/svg/graphics/SVGImageCache.cpp
r110581 r111480 22 22 23 23 #if ENABLE(SVG) 24 #include "FrameView.h" 24 25 #include "GraphicsContext.h" 25 26 #include "ImageBuffer.h" … … 82 83 it->second.imageNeedsUpdate = true; 83 84 84 // Start redrawing dirty images with a timer, as imageContentChanged() may be called 85 // by the FrameView of the SVGImage which is currently in FrameView::layout(). 86 if (!m_redrawTimer.isActive()) 87 m_redrawTimer.startOneShot(0); 85 // If we're in the middle of layout, start redrawing dirty 86 // images on a timer; otherwise it's safe to draw immediately. 87 88 FrameView* frameView = m_svgImage->frameView(); 89 if (frameView && frameView->needsLayout()) { 90 if (!m_redrawTimer.isActive()) 91 m_redrawTimer.startOneShot(0); 92 } else 93 redraw(); 88 94 } 89 95 90 void SVGImageCache::redraw TimerFired(Timer<SVGImageCache>*)96 void SVGImageCache::redraw() 91 97 { 92 98 ImageDataMap::iterator end = m_imageDataMap.end(); … … 104 110 ASSERT(m_svgImage->imageObserver()); 105 111 m_svgImage->imageObserver()->animationAdvanced(m_svgImage); 112 } 113 114 void SVGImageCache::redrawTimerFired(Timer<SVGImageCache>*) 115 { 116 redraw(); 106 117 } 107 118 -
trunk/Source/WebCore/svg/graphics/SVGImageCache.h
r110581 r111480 71 71 private: 72 72 SVGImageCache(SVGImage*); 73 void redraw(); 73 74 void redrawTimerFired(Timer<SVGImageCache>*); 74 75
Note: See TracChangeset
for help on using the changeset viewer.