foot/shm.h
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

46 lines
1.4 KiB
C

#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <sys/types.h>
#include <pixman.h>
#include <wayland-client.h>
struct buffer {
unsigned long cookie;
int width;
int height;
int stride;
bool busy;
size_t size; /* Buffer size */
void *mmapped; /* Raw data */
struct wl_buffer *wl_buf;
pixman_image_t *pix;
/* Internal */
int fd; /* memfd */
void *real_mmapped; /* Address returned from mmap */
size_t mmap_size; /* Size of mmap (>= size) */
off_t offset; /* Offset into memfd where data begins */
bool purge; /* True if this buffer should be destroyed */
};
struct buffer *shm_get_buffer(
struct wl_shm *shm, int width, int height, unsigned long cookie);
void shm_fini(void);
bool shm_can_scroll(void);
bool shm_scroll(struct wl_shm *shm, struct buffer *buf, int rows,
int top_margin, int top_keep_rows,
int bottom_margin, int bottom_keep_rows);
void shm_purge(struct wl_shm *shm, unsigned long cookie);
struct terminal;
static inline unsigned long shm_cookie_grid(const struct terminal *term) { return (unsigned long)((uintptr_t)term + 0); }
static inline unsigned long shm_cookie_search(const struct terminal *term) { return (unsigned long)((uintptr_t)term + 1); }
static inline unsigned long shm_cookie_csd(const struct terminal *term, int n) { return (unsigned long)((uintptr_t)term + 2 + (n)); }