Implement rendering of multi cursors in the shaders
This commit is contained in:
parent
b2f543f9bd
commit
c393c1679e
7 changed files with 32 additions and 29 deletions
|
|
@ -64,10 +64,8 @@ out float effective_text_alpha;
|
|||
const uint BYTE_MASK = uint(0xFF);
|
||||
const uint SPRITE_INDEX_MASK = uint(0x7fffffff);
|
||||
const uint SPRITE_COLORED_MASK = uint(0x80000000);
|
||||
const uint SPRITE_COLORED_SHIFT = uint(31);
|
||||
const uint ZERO = uint(0);
|
||||
const uint ONE = uint(1);
|
||||
const uint TWO = uint(2);
|
||||
const uint SPRITE_COLORED_SHIFT = 31u;
|
||||
const uint ONE = 1u;
|
||||
const uint DECORATION_MASK = uint({DECORATION_MASK});
|
||||
|
||||
vec3 color_to_vec(uint c) {
|
||||
|
|
@ -168,9 +166,14 @@ CellData set_vertex_position() {
|
|||
sprite_pos = to_sprite_pos(pos, sprite_idx[0] & SPRITE_INDEX_MASK);
|
||||
colored_sprite = float((sprite_idx[0] & SPRITE_COLORED_MASK) >> SPRITE_COLORED_SHIFT);
|
||||
#endif
|
||||
float is_block_cursor = one_if_equal_zero_otherwise(cursor_shape, 1u);
|
||||
float has_cursor = is_cursor(column, row);
|
||||
return CellData(has_cursor, has_cursor * is_block_cursor, pos, cursor_shape_map[cursor_shape]);
|
||||
float has_main_cursor = is_cursor(column, row);
|
||||
float multicursor_shape = float((is_selected >> 2) & 3u);
|
||||
float multicursor_uses_main_cursor_shape = float((is_selected >> 4) & ONE);
|
||||
multicursor_shape = if_one_then(multicursor_uses_main_cursor_shape, cursor_shape, multicursor_shape);
|
||||
float final_cursor_shape = if_one_then(has_main_cursor, cursor_shape, multicursor_shape);
|
||||
float has_cursor = zero_or_one(final_cursor_shape);
|
||||
float is_block_cursor = has_cursor * one_if_equal_zero_otherwise(final_cursor_shape, 1.0);
|
||||
return CellData(has_cursor, is_block_cursor, pos, cursor_shape_map[int(final_cursor_shape)]);
|
||||
}
|
||||
|
||||
float background_opacity_for(uint bg, uint colorval, float opacity_if_matched) { // opacity_if_matched if bg == colorval else 1
|
||||
|
|
@ -261,7 +264,7 @@ void main() {
|
|||
foreground = color_to_vec(fg_as_uint);
|
||||
float has_dim = float((text_attrs >> DIM_SHIFT) & ONE);
|
||||
effective_text_alpha = inactive_text_alpha * mix(1.0, dim_opacity, has_dim);
|
||||
float in_url = float((is_selected & TWO) >> 1);
|
||||
float in_url = float((is_selected >> 1) & ONE);
|
||||
decoration_fg = if_one_then(in_url, color_to_vec(url_color), to_color(colors[2], fg_as_uint));
|
||||
// Selection
|
||||
vec3 selection_color = if_one_then(use_cell_bg_for_selection_fg, bg, color_to_vec(highlight_fg));
|
||||
|
|
|
|||
|
|
@ -652,9 +652,7 @@ pyset_iutf8(ChildMonitor *self, PyObject *args) {
|
|||
|
||||
static bool
|
||||
cursor_needs_render(Window *w) {
|
||||
#define cri w->render_data.screen->cursor_render_info
|
||||
return w->cursor_opacity_at_last_render != cri.opacity || w->render_data.screen->last_rendered.cursor_x != cri.x || w->render_data.screen->last_rendered.cursor_y != cri.y || w->last_cursor_shape != cri.shape;
|
||||
#undef cri
|
||||
return memcmp(&w->render_data.screen->last_rendered.cursor, &w->render_data.screen->cursor_render_info, sizeof(CursorRenderInfo)) != 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -670,11 +668,13 @@ collect_cursor_info(CursorRenderInfo *ans, Window *w, monotonic_t now, OSWindow
|
|||
cursor = rd->screen->paused_rendering.expires_at ? &rd->screen->paused_rendering.cursor : rd->screen->cursor;
|
||||
ans->x = cursor->x; ans->y = cursor->y;
|
||||
}
|
||||
ans->opacity = 0;
|
||||
if (rd->screen->scrolled_by || !screen_is_cursor_visible(rd->screen)) return cursor_needs_render(w);
|
||||
ans->is_visible = false; ans->multicursor_count = 0; ans->opacity = 1;
|
||||
if (rd->screen->scrolled_by) return cursor_needs_render(w);
|
||||
ans->multicursor_count = screen_multi_cursor_count(rd->screen);
|
||||
ans->is_visible = screen_is_cursor_visible(rd->screen);
|
||||
if (!ans->is_visible && ans->multicursor_count == 0) return cursor_needs_render(w);
|
||||
monotonic_t time_since_start_blink = now - os_window->cursor_blink_zero_time;
|
||||
bool cursor_blinking = OPT(cursor_blink_interval) > 0 && !cursor->non_blinking && os_window->is_focused && (OPT(cursor_stop_blinking_after) == 0 || time_since_start_blink <= OPT(cursor_stop_blinking_after));
|
||||
ans->opacity = 1;
|
||||
if (cursor_blinking) {
|
||||
if (animation_is_valid(OPT(animation.cursor))) {
|
||||
monotonic_t duration = OPT(cursor_blink_interval) * 2;
|
||||
|
|
@ -812,7 +812,6 @@ render_prepared_os_window(OSWindow *os_window, unsigned int active_window_id, co
|
|||
if (is_active_window) active_window = w;
|
||||
draw_cells(&WD, os_window, is_active_window, false, num_of_visible_windows == 1, w);
|
||||
if (WD.screen->start_visual_bell_at != 0) set_maximum_wait(ANIMATION_SAMPLE_WAIT);
|
||||
w->cursor_opacity_at_last_render = WD.screen->cursor_render_info.opacity; w->last_cursor_shape = WD.screen->cursor_render_info.shape;
|
||||
}
|
||||
}
|
||||
setup_os_window_for_rendering(os_window, tab, active_window, false);
|
||||
|
|
|
|||
|
|
@ -221,9 +221,9 @@ typedef struct {
|
|||
} Cursor;
|
||||
|
||||
typedef struct {
|
||||
bool is_focused, render_even_when_unfocused;
|
||||
bool is_focused, render_even_when_unfocused, is_visible;
|
||||
CursorShape shape;
|
||||
unsigned int x, y;
|
||||
unsigned x, y, multicursor_count;
|
||||
float opacity;
|
||||
} CursorRenderInfo;
|
||||
|
||||
|
|
|
|||
|
|
@ -1900,6 +1900,11 @@ screen_is_cursor_visible(const Screen *self) {
|
|||
return self->paused_rendering.expires_at ? self->paused_rendering.cursor_visible : self->modes.mDECTCEM;
|
||||
}
|
||||
|
||||
unsigned
|
||||
screen_multi_cursor_count(const Screen *self) {
|
||||
return self->paused_rendering.expires_at ? self->paused_rendering.extra_cursors.count : self->extra_cursors.count;
|
||||
}
|
||||
|
||||
void
|
||||
screen_backspace(Screen *self) {
|
||||
screen_cursor_move(self, 1, -1, true);
|
||||
|
|
@ -3470,7 +3475,7 @@ screen_update_cell_data(Screen *self, void *address, FONTS_DATA_HANDLE fonts_dat
|
|||
lnum = y - self->scrolled_by;
|
||||
linebuf_init_line(self->linebuf, lnum);
|
||||
if (self->linebuf->line->attrs.has_dirty_text ||
|
||||
(cursor_has_moved && (self->cursor->y == lnum || self->last_rendered.cursor_y == lnum))) {
|
||||
(cursor_has_moved && (self->cursor->y == lnum || self->last_rendered.cursor.y == lnum))) {
|
||||
render_line(fonts_data, self->linebuf->line, lnum, self->cursor, self->disable_ligatures, self->lc);
|
||||
screen_render_line_graphics(self, self->linebuf->line, y - self->scrolled_by);
|
||||
if (self->linebuf->line->attrs.has_dirty_text && screen_has_marker(self)) mark_text_in_line(
|
||||
|
|
|
|||
|
|
@ -109,9 +109,10 @@ typedef struct {
|
|||
id_type window_id;
|
||||
Selections selections, url_ranges;
|
||||
struct {
|
||||
unsigned int cursor_x, cursor_y, scrolled_by;
|
||||
unsigned int scrolled_by;
|
||||
index_type lines, columns;
|
||||
color_type cursor_bg;
|
||||
CursorRenderInfo cursor;
|
||||
} last_rendered;
|
||||
bool is_dirty, scroll_changed, reload_all_gpu_data;
|
||||
Cursor *cursor;
|
||||
|
|
@ -265,6 +266,7 @@ bool screen_has_selection(Screen*);
|
|||
bool screen_invert_colors(Screen *self);
|
||||
void screen_update_cell_data(Screen *self, void *address, FONTS_DATA_HANDLE, bool cursor_has_moved);
|
||||
bool screen_is_cursor_visible(const Screen *self);
|
||||
unsigned screen_multi_cursor_count(const Screen *self);
|
||||
bool screen_selection_range_for_line(Screen *self, index_type y, index_type *start, index_type *end);
|
||||
bool screen_selection_range_for_word(Screen *self, const index_type x, const index_type y, index_type *, index_type *, index_type *start, index_type *end, bool);
|
||||
void screen_start_selection(Screen *self, index_type x, index_type y, bool, bool, SelectionExtendMode);
|
||||
|
|
|
|||
|
|
@ -476,7 +476,7 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, C
|
|||
// Cursor position
|
||||
Line *line_for_cursor = NULL;
|
||||
rd->cursor_opacity = MAX(0, MIN(cursor->opacity, 1));
|
||||
if (rd->cursor_opacity != 0) {
|
||||
if (rd->cursor_opacity != 0 && cursor->is_visible) {
|
||||
rd->cursor_x1 = cursor->x, rd->cursor_y1 = cursor->y;
|
||||
rd->cursor_x2 = cursor->x, rd->cursor_y2 = cursor->y;
|
||||
CursorShape cs = (cursor->is_focused || OPT(cursor_shape_unfocused) == NO_CURSOR_SHAPE) ? cursor->shape : OPT(cursor_shape_unfocused);
|
||||
|
|
@ -559,8 +559,8 @@ cell_prepare_to_render(ssize_t vao_idx, Screen *screen, FONTS_DATA_HANDLE fonts_
|
|||
ensure_sprite_map(fonts_data);
|
||||
const Cursor *cursor = screen->paused_rendering.expires_at ? &screen->paused_rendering.cursor : screen->cursor;
|
||||
|
||||
bool cursor_pos_changed = cursor->x != screen->last_rendered.cursor_x
|
||||
|| cursor->y != screen->last_rendered.cursor_y;
|
||||
bool cursor_pos_changed = cursor->x != screen->last_rendered.cursor.x \
|
||||
|| cursor->y != screen->last_rendered.cursor.y;
|
||||
bool disable_ligatures = screen->disable_ligatures == DISABLE_LIGATURES_CURSOR;
|
||||
bool screen_resized = screen->last_rendered.columns != screen->columns || screen->last_rendered.lines != screen->lines;
|
||||
|
||||
|
|
@ -576,11 +576,6 @@ cell_prepare_to_render(ssize_t vao_idx, Screen *screen, FONTS_DATA_HANDLE fonts_
|
|||
if (!screen->paused_rendering.cell_data_updated) update_cell_data;
|
||||
} else if (screen->reload_all_gpu_data || screen->scroll_changed || screen->is_dirty || screen_resized || (disable_ligatures && cursor_pos_changed)) update_cell_data;
|
||||
|
||||
if (cursor_pos_changed) {
|
||||
screen->last_rendered.cursor_x = cursor->x;
|
||||
screen->last_rendered.cursor_y = cursor->y;
|
||||
}
|
||||
|
||||
#define update_selection_data { \
|
||||
sz = (size_t)screen->lines * screen->columns; \
|
||||
address = alloc_and_map_vao_buffer(vao_idx, sz, selection_buffer, GL_STREAM_DRAW, GL_WRITE_ONLY); \
|
||||
|
|
@ -607,6 +602,7 @@ cell_prepare_to_render(ssize_t vao_idx, Screen *screen, FONTS_DATA_HANDLE fonts_
|
|||
#undef update_cell_data
|
||||
screen->last_rendered.columns = screen->columns;
|
||||
screen->last_rendered.lines = screen->lines;
|
||||
screen->last_rendered.cursor = screen->cursor_render_info;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -193,8 +193,6 @@ typedef struct WindowBarData {
|
|||
typedef struct Window {
|
||||
id_type id;
|
||||
bool visible;
|
||||
float cursor_opacity_at_last_render;
|
||||
CursorShape last_cursor_shape;
|
||||
PyObject *title;
|
||||
WindowRenderData render_data;
|
||||
WindowLogoRenderData window_logo;
|
||||
|
|
|
|||
Loading…
Reference in a new issue