RESOLVED FIXED 164340
REGRESSION (r206247): Painting milestones can be delayed until the next layer flush
https://bugs.webkit.org/show_bug.cgi?id=164340
Summary REGRESSION (r206247): Painting milestones can be delayed until the next layer...
mitz
Reported 2016-11-02 14:01:47 PDT
After <https://trac.webkit.org/r206247> (the fix for bug 162359), it is possible for the client to not get notified of a paint milestone until the next layer flush, which may or may not occur. This is because WebCore fires painting milestones on a timer, and by the time it does so, the flush for the paint that triggered it may have already happened.
Attachments
Have WebKit, not WebCore, defer sending the milestones until after the commit (7.51 KB, patch)
2016-11-02 19:09 PDT, mitz
no flags
Have WebKit, not WebCore, defer sending the milestones until after the commit (8.35 KB, patch)
2016-11-02 22:30 PDT, mitz
thorton: review+
mitz
Comment 1 2016-11-02 14:06:18 PDT
mitz
Comment 2 2016-11-02 14:20:10 PDT
Perhaps the timer is not the reason. TiledCoreAnimationDrawingArea::flushLayers is called long before RenderLayerCompositor::didPaintBacking.
Simon Fraser (smfr)
Comment 3 2016-11-02 14:34:31 PDT
If some data in the commit will change, we should schedule a commit.
mitz
Comment 4 2016-11-02 14:55:00 PDT
(In reply to comment #2) > Perhaps the timer is not the reason. > TiledCoreAnimationDrawingArea::flushLayers is called long before > RenderLayerCompositor::didPaintBacking. TiledCoreAnimationDrawingArea::flushLayers installs a commit handler, and that runs after didPaintBacking. So we need to fire the pending milestones from there.
mitz
Comment 5 2016-11-02 17:41:49 PDT
Actually, I am seeing this with the root layer, which doesn’t even rely on RenderLayerCompositor::didPaintBacking, because RenderLayerBacking::paintIntoLayer calls FrameView::didPaintContents() directly which calls firePaintRelatedMilestonesIfNeeded() without a timer delay. I am trying to understand in what cases that is not followed by a flush, so that I cam make a reliable test case for the fix that moves firing the pending milestones into the commit handler. I am also trying to understand what’s the right thing to do for OS X 10.10, which doesn’t use the commit handler code path.
mitz
Comment 6 2016-11-02 19:09:27 PDT
Created attachment 293734 [details] Have WebKit, not WebCore, defer sending the milestones until after the commit I wasn’t able to add an API test for this. I test with internal builds of macOS Mail, which were affected by the bug.
Simon Fraser (smfr)
Comment 7 2016-11-02 19:18:28 PDT
Comment on attachment 293734 [details] Have WebKit, not WebCore, defer sending the milestones until after the commit View in context: https://bugs.webkit.org/attachment.cgi?id=293734&action=review > Source/WebCore/ChangeLog:11 > + To give WebKit a chance to deliver the painting milestones to its client after the commit, > + we must tell it about them before or during the commit. To that end, we should not defer > + the call to firePaintRelatedMilestonesIfNeeded until after the commit. Was it deferred for a good reason, like coalescing? > Source/WebCore/rendering/RenderLayerCompositor.cpp:572 > + frameView.firePaintRelatedMilestonesIfNeeded(); Does one really "fire" a milestone, or just reach or pass it? > Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:428 > + if (TiledCoreAnimationDrawingArea* drawingArea = static_cast<TiledCoreAnimationDrawingArea*>(retainedPage->drawingArea())) { auto foo = downcast<TiledCoreAnimationDrawingArea>() ? When is drawingArea != this? Very confusing to fetch it here again. > Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:431 > + if (drawingArea->m_pendingNewlyReachedLayoutMilestones) > + retainedPage->send(Messages::WebPageProxy::DidReachLayoutMilestone(drawingArea->m_pendingNewlyReachedLayoutMilestones)); > + drawingArea->m_pendingNewlyReachedLayoutMilestones = 0; I would like to see this moved to a self-contained function. > Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:439 > + if (drawingArea->m_pendingNewlyReachedLayoutMilestones) > + retainedPage->send(Messages::WebPageProxy::DidReachLayoutMilestone(drawingArea->m_pendingNewlyReachedLayoutMilestones)); > + drawingArea->m_pendingNewlyReachedLayoutMilestones = 0; ...which you could also call here.
mitz
Comment 8 2016-11-02 21:06:42 PDT
Comment on attachment 293734 [details] Have WebKit, not WebCore, defer sending the milestones until after the commit View in context: https://bugs.webkit.org/attachment.cgi?id=293734&action=review >> Source/WebCore/ChangeLog:11 >> + the call to firePaintRelatedMilestonesIfNeeded until after the commit. > > Was it deferred for a good reason, like coalescing? It was deferred in order to make sure that WebKit client gets notified only after the commit (see bug 115753). That bug was probably reintroduced when <https://trac.webkit.org/r166015> (the fix for bug 130541) made RenderLayerBacking::paintIntoLayer() call FrameView::didPaintContents(), which fires the paint-related milestones synchronously. That is, until <https://trac.webkit.org/r206247> introduced a completely different way for the milestones to be deferred, which happened to defer them too much in some cases. >> Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:428 >> + if (TiledCoreAnimationDrawingArea* drawingArea = static_cast<TiledCoreAnimationDrawingArea*>(retainedPage->drawingArea())) { > > auto foo = downcast<TiledCoreAnimationDrawingArea>() ? > > When is drawingArea != this? Very confusing to fetch it here again. drawingArea is null if in the mean while WebPage::close has been called. >> Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:439 >> + drawingArea->m_pendingNewlyReachedLayoutMilestones = 0; > > ...which you could also call here. I waffled on this. It will be a similar number of lines of code, and once 10.10 support is gone, it will be even more silly for it to be a function.
mitz
Comment 9 2016-11-02 22:30:56 PDT
Created attachment 293747 [details] Have WebKit, not WebCore, defer sending the milestones until after the commit Made a helper function
mitz
Comment 10 2016-11-03 09:23:02 PDT
Note You need to log in before you can comment on or make changes to this bug.