Commit graph

2 commits

Author SHA1 Message Date
greg904 58f5d7c72e
Update _TerminalCursorPositionChanged to use ThrottledFunc (#6492)
* Update _TerminalCursorPositionChanged to use ThrottledFunc.
* Rename previous ThrottledFunc to ThrottledArgFunc because now
  ThrottledFunc is for functions that do not take an argument.
* Update ThrottledFunc and ThrottledArgFunc to accept a CoreDispatcher
  on which the function should be called for convenience.
* Don't use coroutines/winrt::fire_and_forget in
  ThrottledFunc/ThrottledArgFunc because they are too slow (see PR).

_AdjustCursorPosition went from 17% of samples to 3% in performance
testing.
2020-06-23 14:05:40 -07:00
greg904 25df527743
Throttle scrollbar updates in TermControl to ~one per 8ms (#4608)
In addition to the below (original) description, this commit introduces
a ThrottledFunc template that can throttle _any_ function. It applies
that type to muffle updates to the scrollbar.

---

Redo #3531 but without the bug that it caused (#3622) which is why it
was reverted.

I'm sorry if I explain this badly. If you don't understand a part, make
sure to let me know and I will explain it better.

### Explanation

How it worked before: `Terminal` signals that viewport changed ->
`TermControl::_TerminalScrollPositionChanged` gets called on the
terminal thread -> it dispatches work for later to be ran the UI thread
to updates the scrollbar's values

Why it's bad:
* If we have many viewport changes, it will create a long stack of
  operations to run. Instead, we should just update the scroll bar with
  the most recent information that we know.
* Imagine if the rate that the work gets pushed on the UI thread is
  greater than the rate that it can handle: it might freeze?
* No need to be real time, we can wait just a little bit (8ms) to
  accumulate viewport changes before we actually change the scroll bar's
  value because it appears to be expensive (see perf below).

Now: `Terminal` signals that viewport changed ->
`TermControl::_TerminalScrollPositionChanged` gets called on the
terminal thread -> it tells the `ScrollBarUpdater` about a new update ->
the `ScrollBarUpdater` only runs one job (I don't know if that's the
right term) on the UI thread at a time. If a job is already running but
hasn't updated the scroll bar yet, it changes the setting in the already
existing job to update the scroll bar with the new values. A job "waits"
some time before doing the update to throttle updates because we don't
need real time scroll bar updates. -> eventually, it updates the scroll
bar If the user scrolls when a scroll bar update is pending, we keep the
scroll bar's Maximum and Minimum but let the user choose its new Value
with the `CancelPendingValueChange` method.

### Note

Also I changed a little bit the code from the Terminal to notify the
TermControl less often when possible.

I tried to scroll with the scroll bar, with the mouse wheel. I tried to
scroll while content is being outputted.

I tried to reproduce the crash from #2248 without success (good).

Co-authored-by: Leonard Hecker <leonard@hecker.io>

Closes #3622
2020-06-12 12:51:37 -07:00