|
|
Created:
4 years, 8 months ago by no sievers Modified:
4 years, 8 months ago CC:
chromium-reviews, darin-cc_chromium.org, jam Base URL:
https://chromium.googlesource.com/chromium/src.git@master Target Ref:
refs/pending/heads/master Project:
chromium Visibility:
Public. |
DescriptionAndroid: Browser-side scheduling latency tweaks
- Emit an immediate 'missed' BeginFrame when an
BFObserver is added instead of waiting for next vsync
- Remove unneeded requestRender() (=SetNeedsAnimate()) call
The former helps both the browser compositor and display
scheduler (now that it uses the same BeginFrameSource).
Regarding the browser compositor:
When the omnibox is hiding (or selection handles are showing)
we need to browser composite with the correct scroll offset
for a given renderer frame.
Without this patch we run:
ScrollBegin VSync SwapCompositorFrame VSync BrowserComposite
Now we do:
ScrollBegin VSync SwapCF MissedBF BrowserComposite VSync
In the next interval, this works because if nothing changed yet,
the scheduler will defer the BeginMainFrame until there is
another change in the browser compositor tree (MODE_LATE).
Calling SetNeedsAnimate()) from CompositorViewHolder when the
top control offset changes is unnecessary, since this is a
renderer-driven animation (causes an invalidation in the browser
compositor tree), so will already cause the necessary
UpdateLayerTreeHost(). Requesting SetNeedsAnimate()
causes an extra BeginMainFrame() (SingleThreadProxy+scheduler
are not particularly good at tracking these between needs_commit
and needs_animate) and puts us into high latency mode otherwise.
Fileed bug crbug.com/602489 to make this more robust in
SingleThreadProxy and scheduler.
TBR=dtrainor@chromium.org
BUG=591725, 602489, 602485, 604007
Committed: https://crrev.com/6414a4526b77dd087581d8a9c1cec50affc66333
Cr-Commit-Position: refs/heads/master@{#389248}
Patch Set 1 #
Total comments: 1
Patch Set 2 : #
Total comments: 7
Patch Set 3 : address comments #
Total comments: 2
Patch Set 4 : rebase #
Messages
Total messages: 24 (10 generated)
Description was changed from ========== Android: Low latency when omnibox is hiding. When the omnibox is hiding we need to browser composite with the correct scroll offset for a given renderer frame. Put the browser compositor scheduler in low latency mode by immediately posting a BeginFrame() when the BeginFrameSource becomes active. Do this instead of waiting until the next vsync which adds a whole frame of latency. This works because after the immediate frame, the scheduler will set a deadline on the next vsync if nothing changed yet. When the frame from the renderer arrives which changes the SurfaceLayer (if the scroll offset changed), this will override the deadline and cause an immediate BeginMainFrame. That way we can keep rendering in low latency mode. Also, remove the requestRender() (=SetNeedsAnimate()) from CompositorViewHolder when the top control offset changes. This is a renderer-driven animation (causes an invalidation in the browser compositor tree), so will already cause the necessary UpdateLayerTreeHost(). Requesting SetNeedsAnimate() causes an extra BeginMainFrame() (SingleThreadProxy+scheduler are not particularly good at tracking these between needs_commit and needs_animate).a nd puts us into high latency mode otherwise. Fileed bug crbug.com/602489 to make this more robust in SingleThreadProxy and scheduler. BUG=591725 ========== to ========== Android: Low latency when omnibox is hiding. When the omnibox is hiding we need to browser composite with the correct scroll offset for a given renderer frame. Put the browser compositor scheduler in low latency mode by immediately posting a BeginFrame() when the BeginFrameSource becomes active. Do this instead of waiting until the next vsync which adds a whole frame of latency. This works because after the immediate frame, the scheduler will set a deadline on the next vsync if nothing changed yet. When the frame from the renderer arrives which changes the SurfaceLayer (if the scroll offset changed), this will override the deadline and cause an immediate BeginMainFrame. That way we can keep rendering in low latency mode. Also, remove the requestRender() (=SetNeedsAnimate()) from CompositorViewHolder when the top control offset changes. This is a renderer-driven animation (causes an invalidation in the browser compositor tree), so will already cause the necessary UpdateLayerTreeHost(). Requesting SetNeedsAnimate() causes an extra BeginMainFrame() (SingleThreadProxy+scheduler are not particularly good at tracking these between needs_commit and needs_animate).a nd puts us into high latency mode otherwise. Fileed bug crbug.com/602489 to make this more robust in SingleThreadProxy and scheduler. BUG=591725,602489,602485 ==========
sievers@chromium.org changed reviewers: + sunnyps@chromium.org
Sunny, ptal.
https://codereview.chromium.org/1879833002/diff/1/content/browser/renderer_ho... File content/browser/renderer_host/compositor_impl_android.cc (right): https://codereview.chromium.org/1879833002/diff/1/content/browser/renderer_ho... content/browser/renderer_host/compositor_impl_android.cc:177: if (needs_begin_frames) { Oh I was going to ask: Should I also remember the last vsync to make sure that we didn't already send a BeginFrame() this interval, or can this not happen (or rather does not matter) because the scheduler would have not drawn for a frame if it previously turned off BeginFrames?
The renderer avoids a frame of latency by having RWHVA send it begin frames on input even if not asked for. Can we do something similar for the browser too? See https://code.google.com/p/chromium/codesearch#chromium/src/content/browser/re...
hows this?
https://codereview.chromium.org/1879833002/diff/20001/content/browser/rendere... File content/browser/renderer_host/compositor_impl_android.cc (right): https://codereview.chromium.org/1879833002/diff/20001/content/browser/rendere... content/browser/renderer_host/compositor_impl_android.cc:180: last_begin_frame_args_.type = cc::BeginFrameArgs::MISSED; Btw not using MISSED here breaks the world and I'm wondering if it's because of the reentrency into OnBeginFrame() from AddObserver().
sievers@chromium.org changed reviewers: + enne@chromium.org
This definitely also fixes the performance issue from https://chromeperf.appspot.com/group_report?bug_id=604007. I'll add that to the list of bugs, although I wonder if the title of this cl should be more general, as I don't think the omnibox is related in that bug. https://codereview.chromium.org/1879833002/diff/20001/content/browser/rendere... File content/browser/renderer_host/compositor_impl_android.cc (right): https://codereview.chromium.org/1879833002/diff/20001/content/browser/rendere... content/browser/renderer_host/compositor_impl_android.cc:176: if (last_begin_frame_args_.IsValid()) { style nit: I'd early out here instead of nesting all these conditions. https://codereview.chromium.org/1879833002/diff/20001/content/browser/rendere... content/browser/renderer_host/compositor_impl_android.cc:186: base::TimeDelta::FromMilliseconds(16); With https://codereview.chromium.org/1887243002, is this still needed? If it is, maybe use the BeginFrameArgs::interval instead of a hardcoded number? https://codereview.chromium.org/1879833002/diff/20001/content/browser/rendere... content/browser/renderer_host/compositor_impl_android.cc:201: base::TimeTicks deadline = frame_time + 2 * vsync_period / 3; Where does this come from?
Description was changed from ========== Android: Low latency when omnibox is hiding. When the omnibox is hiding we need to browser composite with the correct scroll offset for a given renderer frame. Put the browser compositor scheduler in low latency mode by immediately posting a BeginFrame() when the BeginFrameSource becomes active. Do this instead of waiting until the next vsync which adds a whole frame of latency. This works because after the immediate frame, the scheduler will set a deadline on the next vsync if nothing changed yet. When the frame from the renderer arrives which changes the SurfaceLayer (if the scroll offset changed), this will override the deadline and cause an immediate BeginMainFrame. That way we can keep rendering in low latency mode. Also, remove the requestRender() (=SetNeedsAnimate()) from CompositorViewHolder when the top control offset changes. This is a renderer-driven animation (causes an invalidation in the browser compositor tree), so will already cause the necessary UpdateLayerTreeHost(). Requesting SetNeedsAnimate() causes an extra BeginMainFrame() (SingleThreadProxy+scheduler are not particularly good at tracking these between needs_commit and needs_animate).a nd puts us into high latency mode otherwise. Fileed bug crbug.com/602489 to make this more robust in SingleThreadProxy and scheduler. BUG=591725,602489,602485 ========== to ========== Android: Low latency when omnibox is hiding. When the omnibox is hiding we need to browser composite with the correct scroll offset for a given renderer frame. Put the browser compositor scheduler in low latency mode by immediately posting a BeginFrame() when the BeginFrameSource becomes active. Do this instead of waiting until the next vsync which adds a whole frame of latency. This works because after the immediate frame, the scheduler will set a deadline on the next vsync if nothing changed yet. When the frame from the renderer arrives which changes the SurfaceLayer (if the scroll offset changed), this will override the deadline and cause an immediate BeginMainFrame. That way we can keep rendering in low latency mode. Also, remove the requestRender() (=SetNeedsAnimate()) from CompositorViewHolder when the top control offset changes. This is a renderer-driven animation (causes an invalidation in the browser compositor tree), so will already cause the necessary UpdateLayerTreeHost(). Requesting SetNeedsAnimate() causes an extra BeginMainFrame() (SingleThreadProxy+scheduler are not particularly good at tracking these between needs_commit and needs_animate).a nd puts us into high latency mode otherwise. Fileed bug crbug.com/602489 to make this more robust in SingleThreadProxy and scheduler. BUG=591725,602489,602485,604007 ==========
On 2016/04/11 at 23:58:31, sunnyps wrote: > The renderer avoids a frame of latency by having RWHVA send it begin frames on input even if not asked for. Can we do something similar for the browser too? > > See https://code.google.com/p/chromium/codesearch#chromium/src/content/browser/re... I wonder if this is something we should just do for all begin frame sources, and just move it into BeginFrameSourceBase?
Description was changed from ========== Android: Low latency when omnibox is hiding. When the omnibox is hiding we need to browser composite with the correct scroll offset for a given renderer frame. Put the browser compositor scheduler in low latency mode by immediately posting a BeginFrame() when the BeginFrameSource becomes active. Do this instead of waiting until the next vsync which adds a whole frame of latency. This works because after the immediate frame, the scheduler will set a deadline on the next vsync if nothing changed yet. When the frame from the renderer arrives which changes the SurfaceLayer (if the scroll offset changed), this will override the deadline and cause an immediate BeginMainFrame. That way we can keep rendering in low latency mode. Also, remove the requestRender() (=SetNeedsAnimate()) from CompositorViewHolder when the top control offset changes. This is a renderer-driven animation (causes an invalidation in the browser compositor tree), so will already cause the necessary UpdateLayerTreeHost(). Requesting SetNeedsAnimate() causes an extra BeginMainFrame() (SingleThreadProxy+scheduler are not particularly good at tracking these between needs_commit and needs_animate).a nd puts us into high latency mode otherwise. Fileed bug crbug.com/602489 to make this more robust in SingleThreadProxy and scheduler. BUG=591725,602489,602485,604007 ========== to ========== Android: Browser-side scheduling latency tweaks - Emit an immediate 'missed' BeginFrame when an BFObserver is added instead of waiting for next vsync - Remove unneeded requestRender() (=SetNeedsAnimate()) call The former helps both the browser compositor and display scheduler (now that it uses the same BeginFrameSource). Regarding the browser compositor: When the omnibox is hiding (or selection handles are showing) we need to browser composite with the correct scroll offset for a given renderer frame. Without this patch we run: ScrollBegin VSync SwapCompositorFrame VSync BrowserComposite Now we do: ScrollBegin VSync SwapCF MissedBF BrowserComposite VSync In the next interval, this works because if nothing changed yet, the scheduler will defer the BeginMainFrame until there is another change in the browser compositor tree (MODE_LATE). Calling SetNeedsAnimate()) from CompositorViewHolder when the top control offset changes is unnecessary, since this is a renderer-driven animation (causes an invalidation in the browser compositor tree), so will already cause the necessary UpdateLayerTreeHost(). Requesting SetNeedsAnimate() causes an extra BeginMainFrame() (SingleThreadProxy+scheduler are not particularly good at tracking these between needs_commit and needs_animate) and puts us into high latency mode otherwise. Fileed bug crbug.com/602489 to make this more robust in SingleThreadProxy and scheduler. BUG=591725,602489,602485,604007 ==========
Title+description updated. Per chat with enne@ going to land this for now. https://codereview.chromium.org/1879833002/diff/20001/content/browser/rendere... File content/browser/renderer_host/compositor_impl_android.cc (right): https://codereview.chromium.org/1879833002/diff/20001/content/browser/rendere... content/browser/renderer_host/compositor_impl_android.cc:176: if (last_begin_frame_args_.IsValid()) { On 2016/04/18 21:36:01, enne wrote: > style nit: I'd early out here instead of nesting all these conditions. Done. https://codereview.chromium.org/1879833002/diff/20001/content/browser/rendere... content/browser/renderer_host/compositor_impl_android.cc:186: base::TimeDelta::FromMilliseconds(16); On 2016/04/18 21:36:01, enne wrote: > With https://codereview.chromium.org/1887243002, is this still needed? > I made it a TODO and reworded the comment, since I think Sunny will be able to remove the (a bit nonsensical) deadline here it when consolidating the missed frame logic in BFSBase. > If it is, maybe use the BeginFrameArgs::interval instead of a hardcoded number? Done. https://codereview.chromium.org/1879833002/diff/20001/content/browser/rendere... content/browser/renderer_host/compositor_impl_android.cc:201: base::TimeTicks deadline = frame_time + 2 * vsync_period / 3; On 2016/04/18 21:36:01, enne wrote: > Where does this come from? Removed. It's not needed as long as the scheduler doesn't somehow immediately send a BeginMainFrame as long as nothing changed, which seems reasonable behavior. see https://bugs.chromium.org/p/chromium/issues/detail?id=603331#c1
https://codereview.chromium.org/1879833002/diff/40001/content/browser/rendere... File content/browser/renderer_host/compositor_impl_android.cc (right): https://codereview.chromium.org/1879833002/diff/40001/content/browser/rendere... content/browser/renderer_host/compositor_impl_android.cc:172: void AddObserver(cc::BeginFrameObserver* obs) override { I do think that maybe we should just put this in the base class, but lgtm to land this for Android now. :)
https://codereview.chromium.org/1879833002/diff/40001/content/browser/rendere... File content/browser/renderer_host/compositor_impl_android.cc (right): https://codereview.chromium.org/1879833002/diff/40001/content/browser/rendere... content/browser/renderer_host/compositor_impl_android.cc:172: void AddObserver(cc::BeginFrameObserver* obs) override { On 2016/04/22 19:58:14, enne wrote: > I do think that maybe we should just put this in the base class, but lgtm to > land this for Android now. :) Yea, I'll let Sunny consolidate this in his patch (since he'd be removing it also from a bunch of other subclasses). Because I don't want to put the deadline workaround in the base class for this, which should become obsolete with his same patch.
LGTM
Description was changed from ========== Android: Browser-side scheduling latency tweaks - Emit an immediate 'missed' BeginFrame when an BFObserver is added instead of waiting for next vsync - Remove unneeded requestRender() (=SetNeedsAnimate()) call The former helps both the browser compositor and display scheduler (now that it uses the same BeginFrameSource). Regarding the browser compositor: When the omnibox is hiding (or selection handles are showing) we need to browser composite with the correct scroll offset for a given renderer frame. Without this patch we run: ScrollBegin VSync SwapCompositorFrame VSync BrowserComposite Now we do: ScrollBegin VSync SwapCF MissedBF BrowserComposite VSync In the next interval, this works because if nothing changed yet, the scheduler will defer the BeginMainFrame until there is another change in the browser compositor tree (MODE_LATE). Calling SetNeedsAnimate()) from CompositorViewHolder when the top control offset changes is unnecessary, since this is a renderer-driven animation (causes an invalidation in the browser compositor tree), so will already cause the necessary UpdateLayerTreeHost(). Requesting SetNeedsAnimate() causes an extra BeginMainFrame() (SingleThreadProxy+scheduler are not particularly good at tracking these between needs_commit and needs_animate) and puts us into high latency mode otherwise. Fileed bug crbug.com/602489 to make this more robust in SingleThreadProxy and scheduler. BUG=591725,602489,602485,604007 ========== to ========== Android: Browser-side scheduling latency tweaks - Emit an immediate 'missed' BeginFrame when an BFObserver is added instead of waiting for next vsync - Remove unneeded requestRender() (=SetNeedsAnimate()) call The former helps both the browser compositor and display scheduler (now that it uses the same BeginFrameSource). Regarding the browser compositor: When the omnibox is hiding (or selection handles are showing) we need to browser composite with the correct scroll offset for a given renderer frame. Without this patch we run: ScrollBegin VSync SwapCompositorFrame VSync BrowserComposite Now we do: ScrollBegin VSync SwapCF MissedBF BrowserComposite VSync In the next interval, this works because if nothing changed yet, the scheduler will defer the BeginMainFrame until there is another change in the browser compositor tree (MODE_LATE). Calling SetNeedsAnimate()) from CompositorViewHolder when the top control offset changes is unnecessary, since this is a renderer-driven animation (causes an invalidation in the browser compositor tree), so will already cause the necessary UpdateLayerTreeHost(). Requesting SetNeedsAnimate() causes an extra BeginMainFrame() (SingleThreadProxy+scheduler are not particularly good at tracking these between needs_commit and needs_animate) and puts us into high latency mode otherwise. Fileed bug crbug.com/602489 to make this more robust in SingleThreadProxy and scheduler. TBR=dtrainor@chromium.org BUG=591725,602489,602485,604007 ==========
The CQ bit was checked by sievers@chromium.org
The patchset sent to the CQ was uploaded after l-g-t-m from sunnyps@chromium.org, enne@chromium.org Link to the patchset: https://codereview.chromium.org/1879833002/#ps60001 (title: "rebase")
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1879833002/60001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1879833002/60001
Message was sent while issue was closed.
Description was changed from ========== Android: Browser-side scheduling latency tweaks - Emit an immediate 'missed' BeginFrame when an BFObserver is added instead of waiting for next vsync - Remove unneeded requestRender() (=SetNeedsAnimate()) call The former helps both the browser compositor and display scheduler (now that it uses the same BeginFrameSource). Regarding the browser compositor: When the omnibox is hiding (or selection handles are showing) we need to browser composite with the correct scroll offset for a given renderer frame. Without this patch we run: ScrollBegin VSync SwapCompositorFrame VSync BrowserComposite Now we do: ScrollBegin VSync SwapCF MissedBF BrowserComposite VSync In the next interval, this works because if nothing changed yet, the scheduler will defer the BeginMainFrame until there is another change in the browser compositor tree (MODE_LATE). Calling SetNeedsAnimate()) from CompositorViewHolder when the top control offset changes is unnecessary, since this is a renderer-driven animation (causes an invalidation in the browser compositor tree), so will already cause the necessary UpdateLayerTreeHost(). Requesting SetNeedsAnimate() causes an extra BeginMainFrame() (SingleThreadProxy+scheduler are not particularly good at tracking these between needs_commit and needs_animate) and puts us into high latency mode otherwise. Fileed bug crbug.com/602489 to make this more robust in SingleThreadProxy and scheduler. TBR=dtrainor@chromium.org BUG=591725,602489,602485,604007 ========== to ========== Android: Browser-side scheduling latency tweaks - Emit an immediate 'missed' BeginFrame when an BFObserver is added instead of waiting for next vsync - Remove unneeded requestRender() (=SetNeedsAnimate()) call The former helps both the browser compositor and display scheduler (now that it uses the same BeginFrameSource). Regarding the browser compositor: When the omnibox is hiding (or selection handles are showing) we need to browser composite with the correct scroll offset for a given renderer frame. Without this patch we run: ScrollBegin VSync SwapCompositorFrame VSync BrowserComposite Now we do: ScrollBegin VSync SwapCF MissedBF BrowserComposite VSync In the next interval, this works because if nothing changed yet, the scheduler will defer the BeginMainFrame until there is another change in the browser compositor tree (MODE_LATE). Calling SetNeedsAnimate()) from CompositorViewHolder when the top control offset changes is unnecessary, since this is a renderer-driven animation (causes an invalidation in the browser compositor tree), so will already cause the necessary UpdateLayerTreeHost(). Requesting SetNeedsAnimate() causes an extra BeginMainFrame() (SingleThreadProxy+scheduler are not particularly good at tracking these between needs_commit and needs_animate) and puts us into high latency mode otherwise. Fileed bug crbug.com/602489 to make this more robust in SingleThreadProxy and scheduler. TBR=dtrainor@chromium.org BUG=591725,602489,602485,604007 ==========
Message was sent while issue was closed.
Committed patchset #4 (id:60001)
Message was sent while issue was closed.
Description was changed from ========== Android: Browser-side scheduling latency tweaks - Emit an immediate 'missed' BeginFrame when an BFObserver is added instead of waiting for next vsync - Remove unneeded requestRender() (=SetNeedsAnimate()) call The former helps both the browser compositor and display scheduler (now that it uses the same BeginFrameSource). Regarding the browser compositor: When the omnibox is hiding (or selection handles are showing) we need to browser composite with the correct scroll offset for a given renderer frame. Without this patch we run: ScrollBegin VSync SwapCompositorFrame VSync BrowserComposite Now we do: ScrollBegin VSync SwapCF MissedBF BrowserComposite VSync In the next interval, this works because if nothing changed yet, the scheduler will defer the BeginMainFrame until there is another change in the browser compositor tree (MODE_LATE). Calling SetNeedsAnimate()) from CompositorViewHolder when the top control offset changes is unnecessary, since this is a renderer-driven animation (causes an invalidation in the browser compositor tree), so will already cause the necessary UpdateLayerTreeHost(). Requesting SetNeedsAnimate() causes an extra BeginMainFrame() (SingleThreadProxy+scheduler are not particularly good at tracking these between needs_commit and needs_animate) and puts us into high latency mode otherwise. Fileed bug crbug.com/602489 to make this more robust in SingleThreadProxy and scheduler. TBR=dtrainor@chromium.org BUG=591725,602489,602485,604007 ========== to ========== Android: Browser-side scheduling latency tweaks - Emit an immediate 'missed' BeginFrame when an BFObserver is added instead of waiting for next vsync - Remove unneeded requestRender() (=SetNeedsAnimate()) call The former helps both the browser compositor and display scheduler (now that it uses the same BeginFrameSource). Regarding the browser compositor: When the omnibox is hiding (or selection handles are showing) we need to browser composite with the correct scroll offset for a given renderer frame. Without this patch we run: ScrollBegin VSync SwapCompositorFrame VSync BrowserComposite Now we do: ScrollBegin VSync SwapCF MissedBF BrowserComposite VSync In the next interval, this works because if nothing changed yet, the scheduler will defer the BeginMainFrame until there is another change in the browser compositor tree (MODE_LATE). Calling SetNeedsAnimate()) from CompositorViewHolder when the top control offset changes is unnecessary, since this is a renderer-driven animation (causes an invalidation in the browser compositor tree), so will already cause the necessary UpdateLayerTreeHost(). Requesting SetNeedsAnimate() causes an extra BeginMainFrame() (SingleThreadProxy+scheduler are not particularly good at tracking these between needs_commit and needs_animate) and puts us into high latency mode otherwise. Fileed bug crbug.com/602489 to make this more robust in SingleThreadProxy and scheduler. TBR=dtrainor@chromium.org BUG=591725,602489,602485,604007 Committed: https://crrev.com/6414a4526b77dd087581d8a9c1cec50affc66333 Cr-Commit-Position: refs/heads/master@{#389248} ==========
Message was sent while issue was closed.
Patchset 4 (id:??) landed as https://crrev.com/6414a4526b77dd087581d8a9c1cec50affc66333 Cr-Commit-Position: refs/heads/master@{#389248} |