Commit graph

1805 commits

Author SHA1 Message Date
Daniel Eklöf
2c7ee09dad
Merge branch 'scroll-damage-performance' 2020-03-29 12:07:53 +02:00
Daniel Eklöf
043ee41c0d
changelog: mention renderer performance improvements with scrolling 2020-03-29 11:32:38 +02:00
Daniel Eklöf
f0e8d146bd
ci: initial sr.ht build manifest 2020-03-28 12:32:40 +01:00
Daniel Eklöf
a2a370acba
conf: rename 'startup-mode' to 'initial-window-mode' 2020-03-28 12:04:00 +01:00
Daniel Eklöf
598ac4bcd0
Merge branch 'master' into scroll-damage-performance 2020-03-27 21:16:42 +01:00
Daniel Eklöf
758fd9fd58
client: add --maximized and --fullscreen
We now create a copy of the config for each client, and updates it
with the values passed from the client.

Since we're not actually cloning it (and e.g. strdup() all strings
etc) we can't call conf_destroy() to free it, but need to free just
the strings we've replaced.
2020-03-27 21:14:49 +01:00
Daniel Eklöf
728e23863c
foot: add --maximized and --fullscreen command line options 2020-03-26 19:47:00 +01:00
Daniel Eklöf
e197368c0f
config: add 'startup-mode' option
This option controls the initial window mode: windowed, maximized or
fullscreen. The default is windowed.
2020-03-26 19:39:12 +01:00
Daniel Eklöf
c4aaba6299
conf: max-shm-pool-size-mb=0 now disables SHM scrolling 2020-03-26 18:04:30 +01:00
Daniel Eklöf
0baa249d8b
shm: make max pool size user configurable (via a 'tweak' setting) 2020-03-25 20:48:02 +01:00
Daniel Eklöf
e9f1638750
shm: handle ftruncate failure 2020-03-25 18:32:41 +01:00
Daniel Eklöf
dc42cc1d19
shm: seal the memfd
This both prevents accidental resizing of the memfd, and allows the
Wayland server to optimze reads from the buffer - it no longer has to
setup SIGBUS handlers.
2020-03-25 18:30:21 +01:00
Daniel Eklöf
03319560f5
shm: scroll: keep shm pool around, and fix its size at max allowed
This lessens the burden on (primarily) the compositor, since we no
longer tear down and re-create the SHM pool when scrolling.

The SHM pool is setup once, and its size is fixed at the maximum
allowed (512MB for now, 2GB would be possible).

This also allows us to mmap() the memfd once. The exposed raw pointer
is simply an offset from the memfd mmapping.

Note that this means e.g. rouge rendering code will be able to write
outside the buffer.

Finally, only do this if the caller explicitly wants to enable
scrolling. The memfd of other buffers are sized to the requested size.
2020-03-25 18:26:58 +01:00
Daniel Eklöf
1891489cd6
app synchronized updates: set is_armed=false when enabling 2020-03-25 18:24:58 +01:00
Daniel Eklöf
9bbbd26c7a
render: pace title updates
Synchronize window title updates with window rendering.
2020-03-25 18:23:55 +01:00
Daniel Eklöf
b46ad6a50a
render: explain _why_ we set a clip region 2020-03-24 21:04:30 +01:00
Daniel Eklöf
5c5f1d096c
shm: scroll: implement offset wrap-around
* Impose a maximum memfd size limit. In theory, this can be
  2GB (wl_shm_create_pool() is the limiting factor - its size argument
  is an int32_t). For now, use 256MB.

  This is mainly to reduce the amount of virtual address space used by
  the compositor, which keeps at least one mmapping (of the entire
  memfd) around. One mmapping *per terminal window* that is.

  Given that we have 128TB with 48-bit virtual addresses, we could
  probably bump this to 2GB without any issues. However, 256MB should
  be enough.

  TODO: check how much we typically move the offset when scrolling in
  a fullscreen window on a 4K monitor. 256MB may turn out to be too
  small.

  On 32-bit shm_scroll() is completely disabled. There simply isn't
  enough address space.

* Wrapping is done by moving the offset to "the other end" of the
  memfd, and copying the buffer contents to the new, wrapped offset.

  The "normal" scrolling code then does the actual scrolling. This
  means we'll re-instantiate all objects twice when wrapping.
2020-03-24 17:46:48 +01:00
Daniel Eklöf
dc393bd5d7
render: bug: clear clip region before tinting the window 2020-03-24 17:45:45 +01:00
Daniel Eklöf
b08238a1a1
render: attach buffer just before commit 2020-03-24 17:45:38 +01:00
Daniel Eklöf
9a3e97afa7
render: clear scroll damage list when we force-refresh the entire window 2020-03-24 17:45:16 +01:00
Daniel Eklöf
b42709525c
quirks: add KDE quirk: surface must be damaged *after* being attached
KDE resets all surface damage when a buffer is attached. Add a quirk
that adds a full-buffer damage to the surface. This quirk is intended
to be called after attaching a buffer to a surface.
2020-03-24 17:44:17 +01:00
Daniel Eklöf
3a04061847
Merge branch 'master' into scroll-damage-performance 2020-03-24 17:44:05 +01:00
Daniel Eklöf
be8b6e8c75
render: fdm refresh handler: don't clear pending flags
The pending flags may already be set (from a previous call to the FDM
hook). In this case, they should not be cleared.
2020-03-24 17:42:29 +01:00
Daniel Eklöf
b79ed6f3e4
term: delayed rendering: failure to read timers is always an error 2020-03-24 17:41:33 +01:00
Daniel Eklöf
759fd572e9
shm: shm_scroll(): initial implementation of reverse scrolling
Implemented by truncating the file size and moving the offset
backwards. This means we can only reverse scroll when we've previously
scrolled forward.

TODO: figure out if we can somehow do fast reverse scrolling even
though offset is 0 (or well, less than required for scrolling).
2020-03-23 21:14:51 +01:00
Daniel Eklöf
0de3701984
shm: scroll: move top/bottom region handling from renderer into shm
This allows us to restore the regions without copying the contents to
temporary memory.
2020-03-23 20:45:27 +01:00
Daniel Eklöf
00129b1935
render: scroll: use shm scrolling even though we have a top region 2020-03-23 20:16:19 +01:00
Daniel Eklöf
75180cea37
render: scroll: take margins into account when restoring bottom scroll region 2020-03-23 20:15:53 +01:00
Daniel Eklöf
7958f8b5ef
render: scroll: move comment to where it belongs 2020-03-23 20:15:04 +01:00
Daniel Eklöf
9166be8aed
render: margins: caller explicitly asks for top/bottom margins 2020-03-23 20:14:30 +01:00
Daniel Eklöf
7fd6916446
render: margins: regression: fix incorrect margins 2020-03-23 20:12:19 +01:00
Daniel Eklöf
5ffee08748
shm: add shm_can_scroll() 2020-03-23 19:31:05 +01:00
Daniel Eklöf
6bc9fd4ba1
Merge branch 'master' into scroll-damage-performance 2020-03-23 19:30:20 +01:00
Daniel Eklöf
5a972cb98e
delayed rendering: ignore frame callback if delayed rendering is active
Before, we applied delayed rendering (that is, we gave the client a
chance to do more writes before we scheduled a render refresh) only
when the renderer were idle.

However, with e.g. a high keyboard repeat rate, it is very much
possible to start the render loop and then never break out of it while
receiving keyboard input.

This causes screen flickering, as we're no longer even trying to
detect the clients transaction boundaries.

So, let's rewrite how this is done.

First, we give the user the ability to disable delayed rendering
altogether, by setting either the lower or upper timeout to 0.

Second, when delayed rendering is enabled, we ignore the frame
callback. That is, when receiving input, we *always* reschedule the
lower timeout timer, regardless of whether the render is idle or not.

The render's frame callback handler will *not* render the grid if the
delayed render timers are armed.

This means for longer client data bursts, we may now skip frames. That
is, we're trading screen flicker for the occasional frame hickup.

For short client data bursts we should behave roughly as before.

This greatly improves the behavior of fullscreen, or near fullscreen,
updates of large grids (example, scrolling in emacs in fullscreen,
with a vertical buffer split).
2020-03-23 19:21:41 +01:00
Daniel Eklöf
ba0d0e8bbb
term: delayed rendering: read timers even though is_armed = false
There's a race/chance that we'll have disarmed the delayed rendering
timers and still get the call.

While it _shouldn't_ be anything to read from the timers, it doesn't
hurt to try. And, if the timers *are* readable, not reading them means
we'll end up in an infinite FDM loop.
2020-03-23 19:16:53 +01:00
Daniel Eklöf
795b0e7ea1
shm: print performance warning when FALLOC_FL_PUNCH_HOLE isn't supported 2020-03-22 21:05:05 +01:00
Daniel Eklöf
7404ace40c
shm: verify the system supports FALLOC_FL_PUNCH_HOLE 2020-03-22 21:05:00 +01:00
Daniel Eklöf
3b9be09b06
shm: scroll: no need to instantiate a new buffer when ftruncate() fails 2020-03-22 20:34:58 +01:00
Daniel Eklöf
ed987b2de7
render: use shm_scroll() when we believe it will be faster
shm_scroll() is fast when memmove() is slow. That is, when scrolling
a *small* amount of lines, shm_scroll() is fast.

Conversely, when scrolling a *large* number of lines, memmove() is
fast.

For now, assume the two methods perform _roughly_ the same given a
certain number of bytes they have to touch.

This means we should use shm_scroll() when number of scroll lines is
less than half the screen. Otherwise we use memmove.

Since we need to repair the bottom scroll region after a shm_scroll,
those lines are added to the count when determining which method to
use.

TODO:

* Check if it's worth to do shm scrolling when we have a top scroll
  region.
* Do more performance testing with a) various amount of scrolling
  lines, and b) larger bottom scroll regions.
2020-03-22 20:22:17 +01:00
Daniel Eklöf
1224807f50
shm: new function, shm_scroll()
This function "scrolls" the buffer by the specified number of (pixel)
rows.

The idea is move the image offset by re-sizing the underlying memfd
object. I.e. to scroll forward, increase the size of the memfd file,
and move the pixman image offset forward (and the Wayland SHM buffer
as well).

Only increasing the file size would, obviously, cause the memfd file
to grow indefinitely. To deal with this, we "punch" a whole from the
beginning of the file to the new offset. This frees the associated
memory.

Thus, while we have a memfd file whose size is (as seen by
e.g. fstat()) is ever growing, the actual file size is always the
original buffer size.

Some notes:

* FALLOC_FL_PUNCH_HOLE can be quite slow when the number of used pages
  to drop is large.

* all normal fallocate() usages have been replaced with ftruncate(),
  as this is *much* faster. fallocate() guarantees subsequent writes
  wont fail. I.e. it actually reserves (disk) space. While it doesn't
  allocate on-disk blocks for on-disk files, it *does* zero-initialize
  the in-memory blocks. And this is slow. ftruncate() doesn't do this.

TODO: implement reverse scrolling (i.e. a negative row count).
2020-03-22 20:06:44 +01:00
Daniel Eklöf
48091966cb
render: resize: update saved 'normal' cursor if we're in alt screen
When resizing in alt mode, we never updated the saved 'normal'
cursor. This meant that when we exited alt mode, the cursor would be
positioned where it was in the old pre-resize/reflow grid.

Now, we update the saved cursor in the same way we update visible
cursor. The result is that when we exit the alt screen, the cursor
is restored to the same coordinates it would have been updated to had
the resize been done in the 'normal' screen.
2020-03-22 11:14:56 +01:00
Daniel Eklöf
f7572d4ab1
server: purge *all* buffers when a terminal shuts down
Previously we only purged the main grid buffers. Now we also purge the
search buffers and the CSD buffers.
2020-03-18 16:53:12 +01:00
Daniel Eklöf
6a35abb6ca
shm: new functions: shm_cookie_*()
These functions return a SHM cookie given a terminal instance.
2020-03-18 16:52:33 +01:00
Daniel Eklöf
7b610e018b
shm: log size of purged buffer 2020-03-18 16:41:38 +01:00
Daniel Eklöf
0419156494
search: replace hard-coded key bindings with "user configurable" ones
They aren't really user configurable. At least not yet.

However, with this, we now handle raw key codes just like the normal
key bindings. Meaning, e.g. ctrl+g, ctrl+a, ctrl+e etc now works while
searching with e.g. a russian layout.
2020-03-18 15:30:14 +01:00
Daniel Eklöf
a69b818a62
input: bindings: don't match raw key code alone - mods must also match 2020-03-18 14:52:39 +01:00
Daniel Eklöf
c87cec8c1e
conf: bindings: case insensitive matching against 'none' 2020-03-18 14:52:04 +01:00
Daniel Eklöf
6d30e7d15d
input: bind key bindings to raw key codes too
Before, when looking for a matching user key binding, we only
matched *symbols*.

This means that the physical keys that generate a specific key binding
is layout dependent. What's worse, it may not even be possible to
generate the key binding at all.

Russian is one such layout, where all the "normal" (us) symbols are
replaced.

By using raw key codes, we can get around this - the key code has a
direct mapping to the physical key.

However, matching raw key codes **only** doesn't always make sense
either. For now, match **both** symbols _and_ key codes. Symbols take
precedence.

TODO: we might have to make this configurable _per binding_.

Note: 'search' mode still uses mostly hardcoded shortcuts that still
have this problem (i.e. ctrl+g doesn't work with a russian layout).
2020-03-18 14:29:34 +01:00
Daniel Eklöf
fb5ab022de
input: key-binding: log error when we fail to translate to XKB symbol 2020-03-18 10:48:42 +01:00
Daniel Eklöf
ff3d4f89e9
doc: foot.5: spawn-terminal: mention OSC 7 2020-03-17 21:53:26 +01:00