Bug 216726

Summary: Redundant rendering updates can be scheduled from inside Page::updateRendering()
Product: WebKit Reporter: Simon Fraser (smfr) <simon.fraser>
Component: WebCore Misc.Assignee: Simon Fraser (smfr) <simon.fraser>
Status: RESOLVED FIXED    
Severity: Normal CC: benjamin, cdumez, changseok, cmarcelo, darin, esprehn+autocc, ews-watchlist, fred.wang, glenn, gyuyoung.kim, Hironori.Fujii, jamesr, japhet, kangil.han, kondapallykalyan, luiz, nham, noam, pdr, rniwa, ryuan.choi, sabouhallawa, sergio, simon.fraser, thorton, tonikitoo, webkit-bug-importer, zeno
Priority: P2 Keywords: InRadar
Version: Safari Technology Preview   
Hardware: Unspecified   
OS: Unspecified   
See Also: https://bugs.webkit.org/show_bug.cgi?id=219447
Bug Depends on: 216958    
Bug Blocks: 202843    
Attachments:
Description Flags
EWSing
none
Patch
ews-feeder: commit-queue-
Patch
none
Patch
none
Patch
none
WK1 Testing
none
Patch
none
Patch none

Description Simon Fraser (smfr) 2020-09-18 20:57:30 PDT
Repaints schedule rendering updates, but if the repaint is issued inside of Page::updateRendering(), we'll handle that repaint in this rendering update, so there's no need to schedule another one.

This might lead to way too many rendering updates.
Comment 1 Radar WebKit Bug Importer 2020-09-18 20:58:04 PDT
<rdar://problem/69193204>
Comment 2 Ryosuke Niwa 2020-09-18 23:46:08 PDT
!!
Comment 3 Simon Fraser (smfr) 2020-09-20 14:53:07 PDT
To fix this we'll need to have some state that tracks the current phase of the rendering update:

enum RenderingUpdatePhase {
  Outside,
  UpdateRendering,
  Flushing,
  Painting
};

A notifyFlushRequired during UpdateRendering just needs to ensure the flush happens. A paint invalidation during UpdateRendering or Flushing doesn't need to schedule another update.
Comment 4 Simon Fraser (smfr) 2020-09-27 17:29:08 PDT
Created attachment 409863 [details]
EWSing
Comment 5 Simon Fraser (smfr) 2020-09-27 17:30:19 PDT
Comments on the approach welcome. It feels a little messy.
Comment 6 Darin Adler 2020-09-28 10:15:16 PDT
Comment on attachment 409863 [details]
EWSing

View in context: https://bugs.webkit.org/attachment.cgi?id=409863&action=review

I think this is a *fantastic* idea. I wish it could be understood in terms of "dirty bits" or "invalidation" rather than "phases", but regardless of the framework it’s something we really need.

> Source/WebCore/dom/Document.cpp:8184
> +    if (!domWindow())
> +        return;
> +
> +    if (auto* timelinesController = this->timelinesController())

Why not put both into local variables?
Comment 7 Simon Fraser (smfr) 2020-09-28 10:33:54 PDT
(In reply to Darin Adler from comment #6)
> Comment on attachment 409863 [details]
> EWSing
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=409863&action=review
> 
> I think this is a *fantastic* idea. I wish it could be understood in terms
> of "dirty bits" or "invalidation" rather than "phases", but regardless of
> the framework it’s something we really need.

I think it's phases, not dirty bits, because it's order-dependent and dirty bits don't communicate that.

> > Source/WebCore/dom/Document.cpp:8184
> > +    if (!domWindow())
> > +        return;
> > +
> > +    if (auto* timelinesController = this->timelinesController())
> 
> Why not put both into local variables?

Can do.
Comment 8 Simon Fraser (smfr) 2020-10-03 15:11:41 PDT
Created attachment 410441 [details]
Patch
Comment 9 Simon Fraser (smfr) 2020-10-03 15:12:10 PDT
This patch uses bits for each step; I think I prefer it.
Comment 10 Simon Fraser (smfr) 2020-10-03 15:21:49 PDT
Created attachment 410442 [details]
Patch
Comment 11 Simon Fraser (smfr) 2020-10-03 21:12:00 PDT
Created attachment 410453 [details]
Patch
Comment 12 Simon Fraser (smfr) 2020-10-04 12:05:18 PDT
Created attachment 410478 [details]
Patch
Comment 13 Darin Adler 2020-10-04 14:11:16 PDT
Comment on attachment 410478 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=410478&action=review

> Source/WTF/wtf/text/TextStream.h:215
> +template<typename ItemType, size_t inlineCapacity = 0>

No need for the "= 0" here.

> Source/WebCore/dom/Document.cpp:8159
> +    if (!domWindow())
> +        return;
> +
> +    if (auto* timelinesController = this->timelinesController())
> +        timelinesController->updateAnimationsAndSendEvents(domWindow()->frozenNowTimestamp());

Same thought as before about putting both into local variables.

> Source/WebCore/page/Page.cpp:1448
> +    // FIXME: flags?

I don’t understand this comment.
Comment 14 Simon Fraser (smfr) 2020-10-04 16:14:31 PDT
Created attachment 410487 [details]
WK1 Testing
Comment 15 Simon Fraser (smfr) 2020-10-06 11:17:56 PDT
Created attachment 410665 [details]
Patch
Comment 16 Simon Fraser (smfr) 2020-10-06 11:32:53 PDT
Created attachment 410669 [details]
Patch
Comment 17 Tim Horton 2020-10-06 12:09:39 PDT
Comment on attachment 410669 [details]
Patch

This is wild.
Comment 18 EWS 2020-10-06 14:33:47 PDT
Committed r268075: <https://trac.webkit.org/changeset/268075>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 410669 [details].
Comment 19 Fujii Hironori 2020-10-08 13:03:26 PDT
Filed: Bug 217490 – [WinCairo] ASSERTION FAILED: m_renderingUpdateRemainingSteps.last().isEmpty() in WebCore::Page::finalizeRenderingUpdate since r268075