In the bad trace I see input events arriving after begin frame (see InputEventFilter::ForwardToHandler traces). Most of the begin frames cause a draw immediately and run prepare tiles after drawing. The input events arriving after begin frame's deadline are not picked up in the prepare tiles. Since we limit to one prepare tiles per frame ("funnel" logic) those input events don't affect tile priorities until next frame. If we're missing visible tiles we'll checkerboard until those are rasterized. Therefore those checkerboarded tiles will be drawn at least two frames later.
If the input events arrive at/before begin frame and tile priority changes get picked up in prepare tiles, then we would schedule raster tasks and stop checkerboarding at least one frame later (next draw). I suspect removing the prepare tiles funnel has the effect.
Thank you for the comment! That's really helpful on understanding the scheduling order.I can see how the event was delayed and missed the frame, but I'm still not clear why this would cause checkerboard. IIUC the delayed event should be handled normally next frame as if it just arrived, and it shouldn't affect any status before it was popped from the queue and processed.
The only explanation I could think of is:If 1. is the reality then it would just be a telemetry test issue, otherwise there must be something went out-of-sync from receiving to dispatching input events.
- We always have checkerboard issue if the event arrives at a bad timing (e.g. right after begin frame);
- The telemetry tests used to dispatch events right before begin frame, but my patch delayed events to be always right after begin frame.
On Thursday, April 20, 2017 at 6:24:00 PM UTC-4, Sunny Sachanandani wrote:In the bad trace I see input events arriving after begin frame (see InputEventFilter::ForwardToHandler traces). Most of the begin frames cause a draw immediately and run prepare tiles after drawing. The input events arriving after begin frame's deadline are not picked up in the prepare tiles. Since we limit to one prepare tiles per frame ("funnel" logic) those input events don't affect tile priorities until next frame. If we're missing visible tiles we'll checkerboard until those are rasterized. Therefore those checkerboarded tiles will be drawn at least two frames later.Do you mean the events arriving after begin frame's deadline will affect scrolling offset immediately, but won't get picked up by prepare tiles until next frame, thus tiles and scrolling offset will get out-of-sync by 1 frame and cause checkerboard? Sorry if I misunderstood as I'm not so familiar with the compositing process...
On Fri, Apr 21, 2017 at 2:50 PM Chong <cho...@chromium.org> wrote:Thank you for the comment! That's really helpful on understanding the scheduling order.I can see how the event was delayed and missed the frame, but I'm still not clear why this would cause checkerboard. IIUC the delayed event should be handled normally next frame as if it just arrived, and it shouldn't affect any status before it was popped from the queue and processed.LayerTreeHostImpl::ScrollBegin is in the InputEventFilter::ForwardToHandler stack frame. That means the input event is being processed immediately rather than being queued.
On Fri, Apr 21, 2017 at 9:12 PM, Sunny Sachanandani <sun...@chromium.org> wrote:On Fri, Apr 21, 2017 at 2:50 PM Chong <cho...@chromium.org> wrote:Thank you for the comment! That's really helpful on understanding the scheduling order.I can see how the event was delayed and missed the frame, but I'm still not clear why this would cause checkerboard. IIUC the delayed event should be handled normally next frame as if it just arrived, and it shouldn't affect any status before it was popped from the queue and processed.LayerTreeHostImpl::ScrollBegin is in the InputEventFilter::ForwardToHandler stack frame. That means the input event is being processed immediately rather than being queued.I'm trying to understand the bad trace and I'm seeing Scheduler::BeginImplFrame followed almost immediately by draw, is that surprising to you Sunny? Because that would prevent a PrepareTiles in layerTreeHostImpl::WillBeginImplFrame from being useful.When we are batching input, the goal is that the compositor's state is not changing at all between LayerTreeHostImpl::WillBeginImplFrame.
On Tue, Apr 25, 2017 at 12:01 PM, <dan...@chromium.org> wrote:On Fri, Apr 21, 2017 at 9:12 PM, Sunny Sachanandani <sun...@chromium.org> wrote:On Fri, Apr 21, 2017 at 2:50 PM Chong <cho...@chromium.org> wrote:Thank you for the comment! That's really helpful on understanding the scheduling order.I can see how the event was delayed and missed the frame, but I'm still not clear why this would cause checkerboard. IIUC the delayed event should be handled normally next frame as if it just arrived, and it shouldn't affect any status before it was popped from the queue and processed.LayerTreeHostImpl::ScrollBegin is in the InputEventFilter::ForwardToHandler stack frame. That means the input event is being processed immediately rather than being queued.I'm trying to understand the bad trace and I'm seeing Scheduler::BeginImplFrame followed almost immediately by draw, is that surprising to you Sunny? Because that would prevent a PrepareTiles in layerTreeHostImpl::WillBeginImplFrame from being useful.
When we are batching input, the goal is that the compositor's state is not changing at all between LayerTreeHostImpl::WillBeginImplFrame.Oops! I mean between LayerTreeHostImpl::WillBeginImplFrame and LayerTreeHostImpl::DrawLayers (ie the deadline).Outside of that range, events can be delivered immediately, they only needs be batched during the compositor frame. I'm not sure if that would help in landing this as an incremental step (and make the work done after the commits more accurate since PrepareTiles is happening in there).
Are the commits happening outside of the impl frame because of high latency mode?
On Tue, Apr 25, 2017 at 9:12 AM <dan...@chromium.org> wrote:On Tue, Apr 25, 2017 at 12:01 PM, <dan...@chromium.org> wrote:On Fri, Apr 21, 2017 at 9:12 PM, Sunny Sachanandani <sun...@chromium.org> wrote:On Fri, Apr 21, 2017 at 2:50 PM Chong <cho...@chromium.org> wrote:Thank you for the comment! That's really helpful on understanding the scheduling order.I can see how the event was delayed and missed the frame, but I'm still not clear why this would cause checkerboard. IIUC the delayed event should be handled normally next frame as if it just arrived, and it shouldn't affect any status before it was popped from the queue and processed.LayerTreeHostImpl::ScrollBegin is in the InputEventFilter::ForwardToHandler stack frame. That means the input event is being processed immediately rather than being queued.I'm trying to understand the bad trace and I'm seeing Scheduler::BeginImplFrame followed almost immediately by draw, is that surprising to you Sunny? Because that would prevent a PrepareTiles in layerTreeHostImpl::WillBeginImplFrame from being useful.If we do PrepareTiles in WillBeginImplFrame we have to use a regular deadline and wait for a bit for NotifyReadyToDraw (signals visible active tree tiles done) before drawing. Today we draw immediately if main thread is in high latency mode or if commit isn't needed.When we are batching input, the goal is that the compositor's state is not changing at all between LayerTreeHostImpl::WillBeginImplFrame.Oops! I mean between LayerTreeHostImpl::WillBeginImplFrame and LayerTreeHostImpl::DrawLayers (ie the deadline).Outside of that range, events can be delivered immediately, they only needs be batched during the compositor frame. I'm not sure if that would help in landing this as an incremental step (and make the work done after the commits more accurate since PrepareTiles is happening in there).I think the easiest implementation would be to be batch in WillBeginImplFrame (as chongz@ has implemented). Are you suggesting an alternative?
On Tue, Apr 25, 2017 at 1:29 PM, Sunny Sachanandani <sun...@chromium.org> wrote:On Tue, Apr 25, 2017 at 9:12 AM <dan...@chromium.org> wrote:On Tue, Apr 25, 2017 at 12:01 PM, <dan...@chromium.org> wrote:On Fri, Apr 21, 2017 at 9:12 PM, Sunny Sachanandani <sun...@chromium.org> wrote:On Fri, Apr 21, 2017 at 2:50 PM Chong <cho...@chromium.org> wrote:Thank you for the comment! That's really helpful on understanding the scheduling order.I can see how the event was delayed and missed the frame, but I'm still not clear why this would cause checkerboard. IIUC the delayed event should be handled normally next frame as if it just arrived, and it shouldn't affect any status before it was popped from the queue and processed.LayerTreeHostImpl::ScrollBegin is in the InputEventFilter::ForwardToHandler stack frame. That means the input event is being processed immediately rather than being queued.I'm trying to understand the bad trace and I'm seeing Scheduler::BeginImplFrame followed almost immediately by draw, is that surprising to you Sunny? Because that would prevent a PrepareTiles in layerTreeHostImpl::WillBeginImplFrame from being useful.If we do PrepareTiles in WillBeginImplFrame we have to use a regular deadline and wait for a bit for NotifyReadyToDraw (signals visible active tree tiles done) before drawing. Today we draw immediately if main thread is in high latency mode or if commit isn't needed.When we are batching input, the goal is that the compositor's state is not changing at all between LayerTreeHostImpl::WillBeginImplFrame.Oops! I mean between LayerTreeHostImpl::WillBeginImplFrame and LayerTreeHostImpl::DrawLayers (ie the deadline).Outside of that range, events can be delivered immediately, they only needs be batched during the compositor frame. I'm not sure if that would help in landing this as an incremental step (and make the work done after the commits more accurate since PrepareTiles is happening in there).I think the easiest implementation would be to be batch in WillBeginImplFrame (as chongz@ has implemented). Are you suggesting an alternative?It seems like that is causing problems for high latency mode since we do PrepareTiles outside of WillBeginImplFrame and we don't do one inside. As I see it solutions could be:1) Do PrepareTiles in WillBeginImplFrame. This is what we want but I think it requires removing the one after submitting a frame also, and the change is behind a flag right now. I've been planning to wait on compositor changes until the input batching isn't behind a flag but we can revisit that if we need to.
or2) Get input events sent to the compositor after a commit. What if LayerTreeHostImpl::CommitComplete did a DeliverInputForBeginFrame() before UpdateDrawProps/PrepareTiles if it's not inside an ImplFrame?or3) It seems like the problem is CommitComplete not seeing events, so an alternative could be to batch input during the ImplFrame but not outside, to let CommitComplete get events sooner.
or4) We don't UpdateDrawProps/PrepareTiles in CommitComplete (when batching is on)?
On Tue, Apr 25, 2017 at 10:37 AM <dan...@chromium.org> wrote:On Tue, Apr 25, 2017 at 1:29 PM, Sunny Sachanandani <sun...@chromium.org> wrote:On Tue, Apr 25, 2017 at 9:12 AM <dan...@chromium.org> wrote:On Tue, Apr 25, 2017 at 12:01 PM, <dan...@chromium.org> wrote:On Fri, Apr 21, 2017 at 9:12 PM, Sunny Sachanandani <sun...@chromium.org> wrote:On Fri, Apr 21, 2017 at 2:50 PM Chong <cho...@chromium.org> wrote:Thank you for the comment! That's really helpful on understanding the scheduling order.I can see how the event was delayed and missed the frame, but I'm still not clear why this would cause checkerboard. IIUC the delayed event should be handled normally next frame as if it just arrived, and it shouldn't affect any status before it was popped from the queue and processed.LayerTreeHostImpl::ScrollBegin is in the InputEventFilter::ForwardToHandler stack frame. That means the input event is being processed immediately rather than being queued.I'm trying to understand the bad trace and I'm seeing Scheduler::BeginImplFrame followed almost immediately by draw, is that surprising to you Sunny? Because that would prevent a PrepareTiles in layerTreeHostImpl::WillBeginImplFrame from being useful.If we do PrepareTiles in WillBeginImplFrame we have to use a regular deadline and wait for a bit for NotifyReadyToDraw (signals visible active tree tiles done) before drawing. Today we draw immediately if main thread is in high latency mode or if commit isn't needed.When we are batching input, the goal is that the compositor's state is not changing at all between LayerTreeHostImpl::WillBeginImplFrame.Oops! I mean between LayerTreeHostImpl::WillBeginImplFrame and LayerTreeHostImpl::DrawLayers (ie the deadline).Outside of that range, events can be delivered immediately, they only needs be batched during the compositor frame. I'm not sure if that would help in landing this as an incremental step (and make the work done after the commits more accurate since PrepareTiles is happening in there).I think the easiest implementation would be to be batch in WillBeginImplFrame (as chongz@ has implemented). Are you suggesting an alternative?It seems like that is causing problems for high latency mode since we do PrepareTiles outside of WillBeginImplFrame and we don't do one inside. As I see it solutions could be:1) Do PrepareTiles in WillBeginImplFrame. This is what we want but I think it requires removing the one after submitting a frame also, and the change is behind a flag right now. I've been planning to wait on compositor changes until the input batching isn't behind a flag but we can revisit that if we need to.I'd strongly prefer this. Two concerns though:1. Will we also do a PrepareTiles in commit?
Would doing two PrepareTiles hurt performance?
2. If a commit and activation happens in the same frame, will we waste any time spent rasterizing active tree tiles that aren't there any more?
Maybe we should do PrepareTiles at the beginning of the frame in high latency mode only?
or2) Get input events sent to the compositor after a commit. What if LayerTreeHostImpl::CommitComplete did a DeliverInputForBeginFrame() before UpdateDrawProps/PrepareTiles if it's not inside an ImplFrame?or3) It seems like the problem is CommitComplete not seeing events, so an alternative could be to batch input during the ImplFrame but not outside, to let CommitComplete get events sooner.or4) We don't UpdateDrawProps/PrepareTiles in CommitComplete (when batching is on)?This means no low latency mode, right?
On Tue, Apr 25, 2017 at 4:48 PM, Sunny Sachanandani <sun...@chromium.org> wrote:On Tue, Apr 25, 2017 at 10:37 AM <dan...@chromium.org> wrote:On Tue, Apr 25, 2017 at 1:29 PM, Sunny Sachanandani <sun...@chromium.org> wrote:On Tue, Apr 25, 2017 at 9:12 AM <dan...@chromium.org> wrote:On Tue, Apr 25, 2017 at 12:01 PM, <dan...@chromium.org> wrote:On Fri, Apr 21, 2017 at 9:12 PM, Sunny Sachanandani <sun...@chromium.org> wrote:On Fri, Apr 21, 2017 at 2:50 PM Chong <cho...@chromium.org> wrote:Thank you for the comment! That's really helpful on understanding the scheduling order.I can see how the event was delayed and missed the frame, but I'm still not clear why this would cause checkerboard. IIUC the delayed event should be handled normally next frame as if it just arrived, and it shouldn't affect any status before it was popped from the queue and processed.LayerTreeHostImpl::ScrollBegin is in the InputEventFilter::ForwardToHandler stack frame. That means the input event is being processed immediately rather than being queued.I'm trying to understand the bad trace and I'm seeing Scheduler::BeginImplFrame followed almost immediately by draw, is that surprising to you Sunny? Because that would prevent a PrepareTiles in layerTreeHostImpl::WillBeginImplFrame from being useful.If we do PrepareTiles in WillBeginImplFrame we have to use a regular deadline and wait for a bit for NotifyReadyToDraw (signals visible active tree tiles done) before drawing. Today we draw immediately if main thread is in high latency mode or if commit isn't needed.When we are batching input, the goal is that the compositor's state is not changing at all between LayerTreeHostImpl::WillBeginImplFrame.Oops! I mean between LayerTreeHostImpl::WillBeginImplFrame and LayerTreeHostImpl::DrawLayers (ie the deadline).Outside of that range, events can be delivered immediately, they only needs be batched during the compositor frame. I'm not sure if that would help in landing this as an incremental step (and make the work done after the commits more accurate since PrepareTiles is happening in there).I think the easiest implementation would be to be batch in WillBeginImplFrame (as chongz@ has implemented). Are you suggesting an alternative?It seems like that is causing problems for high latency mode since we do PrepareTiles outside of WillBeginImplFrame and we don't do one inside. As I see it solutions could be:1) Do PrepareTiles in WillBeginImplFrame. This is what we want but I think it requires removing the one after submitting a frame also, and the change is behind a flag right now. I've been planning to wait on compositor changes until the input batching isn't behind a flag but we can revisit that if we need to.I'd strongly prefer this. Two concerns though:1. Will we also do a PrepareTiles in commit?In high latency mode (commit is outside of BeginFrame), we could, it depends I guess. That was roughly my suggestion 3 vs 4. In my mind we should do "Get input events. UpdateDrawProps. PrepareTiles." together always. There's little point in doing part of that sequence without the rest, and at worst you waste work or produce stale results. So I guess my answer is related to if we'd get input events in CommitComplete.
Would doing two PrepareTiles hurt performance?If we receive input in the meantime then we also have to UpdateDrawProps which is the more heavy thing. This is the long term thing but doing 3 per frame would be definitely a power regression.
2. If a commit and activation happens in the same frame, will we waste any time spent rasterizing active tree tiles that aren't there any more?We can prioritize required for activation tiles. Do we do that now? This seems like tile scheduling problem to be solved there, rather than by avoiding doing PrepareTiles at all. We should get the right math data available as early as possible in the frame, and make decisions based on it IMO.
Maybe we should do PrepareTiles at the beginning of the frame in high latency mode only?I think this would produce less optimal results, where you're preparing tiles from the last frame's scroll offset etc, like we have now.
or2) Get input events sent to the compositor after a commit. What if LayerTreeHostImpl::CommitComplete did a DeliverInputForBeginFrame() before UpdateDrawProps/PrepareTiles if it's not inside an ImplFrame?or3) It seems like the problem is CommitComplete not seeing events, so an alternative could be to batch input during the ImplFrame but not outside, to let CommitComplete get events sooner.or4) We don't UpdateDrawProps/PrepareTiles in CommitComplete (when batching is on)?This means no low latency mode, right?I don't think so, we'd just wait until the BeginFrame to prepare the tiles in high latency mode instead of doing it at CommitComplete. But I might be misunderstanding low latency mode.
Would doing two PrepareTiles hurt performance?If we receive input in the meantime then we also have to UpdateDrawProps which is the more heavy thing. This is the long term thing but doing 3 per frame would be definitely a power regression.3 per frame? I don't think we ever need more than 2 per frame?
2. If a commit and activation happens in the same frame, will we waste any time spent rasterizing active tree tiles that aren't there any more?We can prioritize required for activation tiles. Do we do that now? This seems like tile scheduling problem to be solved there, rather than by avoiding doing PrepareTiles at all. We should get the right math data available as early as possible in the frame, and make decisions based on it IMO.In low latency mode, if we do a PrepareTiles in WillBeginImplFrame, we'll schedule some active tree tiles for raster (assuming no pending tree). Some of these raster tasks could run quickly and queue up work in the GPU process. Then on commit we'll get a pending tree and schedule more tiles at a higher priority than active tree tiles (depends on tree priority). Now if we're able to activate in the same frame it's possible the already rasterized active tree tiles aren't needed any more.
Would doing two PrepareTiles hurt performance?If we receive input in the meantime then we also have to UpdateDrawProps which is the more heavy thing. This is the long term thing but doing 3 per frame would be definitely a power regression.3 per frame? I don't think we ever need more than 2 per frame?
2. If a commit and activation happens in the same frame, will we waste any time spent rasterizing active tree tiles that aren't there any more?We can prioritize required for activation tiles. Do we do that now? This seems like tile scheduling problem to be solved there, rather than by avoiding doing PrepareTiles at all. We should get the right math data available as early as possible in the frame, and make decisions based on it IMO.In low latency mode, if we do a PrepareTiles in WillBeginImplFrame, we'll schedule some active tree tiles for raster (assuming no pending tree). Some of these raster tasks could run quickly and queue up work in the GPU process. Then on commit we'll get a pending tree and schedule more tiles at a higher priority than active tree tiles (depends on tree priority). Now if we're able to activate in the same frame it's possible the already rasterized active tree tiles aren't needed any more.
Maybe we should do PrepareTiles at the beginning of the frame in high latency mode only?I think this would produce less optimal results, where you're preparing tiles from the last frame's scroll offset etc, like we have now.You mean the PrepareTiles inside CommitComplete? The scroll offsets should be synced between active and pending tree.
or2) Get input events sent to the compositor after a commit. What if LayerTreeHostImpl::CommitComplete did a DeliverInputForBeginFrame() before UpdateDrawProps/PrepareTiles if it's not inside an ImplFrame?or3) It seems like the problem is CommitComplete not seeing events, so an alternative could be to batch input during the ImplFrame but not outside, to let CommitComplete get events sooner.or4) We don't UpdateDrawProps/PrepareTiles in CommitComplete (when batching is on)?This means no low latency mode, right?I don't think so, we'd just wait until the BeginFrame to prepare the tiles in high latency mode instead of doing it at CommitComplete. But I might be misunderstanding low latency mode.We need PrepareTiles to rasterize pending tree tiles and activate before the deadline. Otherwise, we'll be drawing active tree tiles only.