foot/grid.h
Daniel Eklöf 7c7720a3ab
scrolling: optimize row access by assuming number of rows is a power of 2
With this assumption, we can replace 'a % b' with 'a & (b - 1)'. In
terms of instructions, this means a fast 'and' instead of a slow
'div'.

Further optimize scrolling by:

* not double-initializing empty rows. Previously, grid_row_alloc()
  called calloc(), which was then followed by a memset() when
  scrolling. This is of course unnecessary.

* Don't loop the entire set of visible rows (this was done to ensure
  all visible rows had been allocated, and to prefetch the cell
  contents).

  This isn't necessary; only newly pulled in rows can be NULL. For
  now, don't prefetch at all.
2019-08-22 17:33:23 +02:00

49 lines
1.1 KiB
C

#pragma once
#include <stddef.h>
#include "terminal.h"
void grid_swap_row(struct grid *grid, int row_a, int row_b, bool initialize);
struct row *grid_row_alloc(int cols, bool initialize);
void grid_row_free(struct row *row);
static inline struct row *
_grid_row_maybe_alloc(struct grid *grid, int row_no, bool alloc_if_null)
{
assert(grid->offset >= 0);
int real_row = (grid->offset + row_no) & (grid->num_rows - 1);
struct row *row = grid->rows[real_row];
if (row == NULL && alloc_if_null) {
row = grid_row_alloc(grid->num_cols, false);
grid->rows[real_row] = row;
}
assert(row != NULL);
return row;
}
static inline struct row *
grid_row(struct grid *grid, int row_no)
{
return _grid_row_maybe_alloc(grid, row_no, false);
}
static inline struct row *
grid_row_and_alloc(struct grid *grid, int row_no)
{
return _grid_row_maybe_alloc(grid, row_no, true);
}
static inline struct row *
grid_row_in_view(struct grid *grid, int row_no)
{
assert(grid->view >= 0);
int real_row = (grid->view + row_no) & (grid->num_rows - 1);
struct row *row = grid->rows[real_row];
assert(row != NULL);
return row;
}