Prepare of alpha blending of cursor

Will allow for cursor blink animation eventually.
This commit is contained in:
Kovid Goyal 2024-07-16 13:25:45 +05:30
parent 10bd0f71d8
commit eb7487d7a2
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
6 changed files with 19 additions and 16 deletions

View file

@ -16,7 +16,7 @@ in vec3 underline_pos;
in vec3 cursor_pos;
in vec3 strike_pos;
in vec3 foreground;
in vec4 cursor_color_vec;
in vec4 cursor_color_premult;
in vec3 decoration_fg;
in float colored_sprite;
#endif
@ -134,7 +134,7 @@ vec4 calculate_premul_foreground_from_sprites(vec4 text_fg) {
float combined_alpha = min(text_fg.a + strike_alpha, 1.0f);
// Underline color might be different, so alpha blend
vec4 ans = alpha_blend(vec4(text_fg.rgb, combined_alpha * effective_text_alpha), vec4(decoration_fg, underline_alpha * effective_text_alpha));
return mix(ans, cursor_color_vec, cursor_alpha);
return mix(ans, cursor_color_premult, cursor_alpha);
}
vec4 adjust_foreground_contrast_with_background(vec4 text_fg, vec3 bg) {

View file

@ -9,7 +9,7 @@ layout(std140) uniform CellRenderData {
uint default_fg, default_bg, highlight_fg, highlight_bg, cursor_fg, cursor_bg, url_color, url_style, inverted;
uint xnum, ynum, cursor_fg_sprite_idx;
float cursor_x, cursor_y, cursor_w;
float cursor_x, cursor_y, cursor_w, cursor_opacity;
uint color_table[NUM_COLORS + MARK_MASK + MARK_MASK + 2];
};
@ -44,7 +44,7 @@ uniform float dim_opacity;
out vec3 sprite_pos;
out vec3 underline_pos;
out vec3 cursor_pos;
out vec4 cursor_color_vec;
out vec4 cursor_color_premult;
out vec3 strike_pos;
out vec3 foreground;
out vec3 decoration_fg;
@ -185,7 +185,7 @@ void main() {
strike_pos = to_sprite_pos(cell_data.pos, ((text_attrs >> STRIKE_SHIFT) & ONE) * STRIKE_SPRITE_INDEX, ZERO, ZERO);
// Cursor
cursor_color_vec = vec4(color_to_vec(cursor_bg), 1.0);
cursor_color_premult = vec4(color_to_vec(cursor_bg) * cursor_opacity, cursor_opacity);
vec3 final_cursor_text_color = color_to_vec(cursor_fg);
foreground = choose_color(cell_data.has_block_cursor, final_cursor_text_color, foreground);
decoration_fg = choose_color(cell_data.has_block_cursor, final_cursor_text_color, decoration_fg);
@ -222,7 +222,7 @@ void main() {
// Selection and cursor
bg = choose_color(float(is_selected & ONE), choose_color(use_cell_for_selection_bg, color_to_vec(fg_as_uint), color_to_vec(highlight_bg)), bg);
background = choose_color(cell_data.has_block_cursor, color_to_vec(cursor_bg), bg);
background = choose_color(cell_data.has_block_cursor, mix(bg, color_to_vec(cursor_bg), cursor_opacity), bg);
#if !defined(TRANSPARENT) && (PHASE == PHASE_SPECIAL)
float is_special_cell = cell_data.has_block_cursor + float(is_selected & ONE);
bg_alpha = step(0.5, is_special_cell);

View file

@ -652,7 +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_visible_at_last_render != cri.is_visible || 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;
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
}
@ -669,7 +669,7 @@ 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->is_visible = false;
ans->opacity = 0;
if (rd->screen->scrolled_by || !screen_is_cursor_visible(rd->screen)) 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));
@ -683,8 +683,8 @@ collect_cursor_info(CursorRenderInfo *ans, Window *w, monotonic_t now, OSWindow
monotonic_t delay = bucket - time_since_start_blink;
set_maximum_wait(delay);
}
if (!do_draw_cursor) { ans->is_visible = false; return cursor_needs_render(w); }
ans->is_visible = true;
if (!do_draw_cursor) { ans->opacity = 0; return cursor_needs_render(w); }
ans->opacity = 1;
ans->shape = cursor->shape ? cursor->shape : OPT(cursor_shape);
ans->is_focused = os_window->is_focused;
return cursor_needs_render(w);
@ -752,7 +752,7 @@ prepare_to_render_os_window(OSWindow *os_window, monotonic_t now, unsigned int *
if (collect_cursor_info(&WD.screen->cursor_render_info, w, now, os_window)) needs_render = true;
WD.screen->cursor_render_info.is_focused = false;
} else {
WD.screen->cursor_render_info.is_visible = false;
WD.screen->cursor_render_info.opacity = 0;
}
}
if (scan_for_animated_images) {
@ -803,7 +803,7 @@ render_prepared_os_window(OSWindow *os_window, unsigned int active_window_id, co
if (WD.screen->start_visual_bell_at != 0) {
set_maximum_wait(OPT(repaint_delay));
}
w->cursor_visible_at_last_render = WD.screen->cursor_render_info.is_visible; w->last_cursor_shape = WD.screen->cursor_render_info.shape;
w->cursor_opacity_at_last_render = WD.screen->cursor_render_info.opacity; w->last_cursor_shape = WD.screen->cursor_render_info.shape;
}
}
if (os_window->live_resize.in_progress) draw_resizing_text(os_window);

View file

@ -300,9 +300,10 @@ typedef struct {
} Cursor;
typedef struct {
bool is_visible, is_focused, render_even_when_unfocused;
bool is_focused, render_even_when_unfocused;
CursorShape shape;
unsigned int x, y;
float opacity;
} CursorRenderInfo;
typedef enum DynamicColorType {

View file

@ -297,7 +297,7 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, c
GLuint default_fg, default_bg, highlight_fg, highlight_bg, cursor_fg, cursor_bg, url_color, url_style, inverted;
GLuint xnum, ynum, cursor_fg_sprite_idx;
GLfloat cursor_x, cursor_y, cursor_w;
GLfloat cursor_x, cursor_y, cursor_w, cursor_opacity;
};
// Send the uniform data
struct GPUCellRenderData *rd = (struct GPUCellRenderData*)map_vao_buffer(vao_idx, uniform_buffer, GL_WRITE_ONLY);
@ -322,8 +322,9 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, c
// Cursor position
enum { BLOCK_IDX = 0, BEAM_IDX = NUM_UNDERLINE_STYLES + 3, UNDERLINE_IDX = NUM_UNDERLINE_STYLES + 4, UNFOCUSED_IDX = NUM_UNDERLINE_STYLES + 5 };
Line *line_for_cursor = NULL;
if (cursor->is_visible) {
if (cursor->opacity > 0) {
rd->cursor_x = cursor->x, rd->cursor_y = cursor->y;
rd->cursor_opacity = cursor->opacity;
if (cursor->is_focused) {
switch(cursor->shape) {
default:

View file

@ -178,7 +178,8 @@ typedef struct WindowBarData {
typedef struct {
id_type id;
bool visible, cursor_visible_at_last_render;
bool visible;
float cursor_opacity_at_last_render;
CursorShape last_cursor_shape;
PyObject *title;
WindowRenderData render_data;