mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-19 15:04:50 +02:00
Implement paused rendering for graphics
This commit is contained in:
@@ -68,7 +68,7 @@ next_id(id_type *counter) {
|
|||||||
static const unsigned PARENT_DEPTH_LIMIT = 8;
|
static const unsigned PARENT_DEPTH_LIMIT = 8;
|
||||||
|
|
||||||
GraphicsManager*
|
GraphicsManager*
|
||||||
grman_alloc(void) {
|
grman_alloc(bool for_paused_rendering) {
|
||||||
GraphicsManager *self = (GraphicsManager *)GraphicsManager_Type.tp_alloc(&GraphicsManager_Type, 0);
|
GraphicsManager *self = (GraphicsManager *)GraphicsManager_Type.tp_alloc(&GraphicsManager_Type, 0);
|
||||||
self->render_data.capacity = 64;
|
self->render_data.capacity = 64;
|
||||||
self->render_data.item = calloc(self->render_data.capacity, sizeof(self->render_data.item[0]));
|
self->render_data.item = calloc(self->render_data.capacity, sizeof(self->render_data.item[0]));
|
||||||
@@ -77,8 +77,10 @@ grman_alloc(void) {
|
|||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
Py_CLEAR(self); return NULL;
|
Py_CLEAR(self); return NULL;
|
||||||
}
|
}
|
||||||
self->disk_cache = create_disk_cache();
|
if (!for_paused_rendering) {
|
||||||
if (!self->disk_cache) { Py_CLEAR(self); return NULL; }
|
self->disk_cache = create_disk_cache();
|
||||||
|
if (!self->disk_cache) { Py_CLEAR(self); return NULL; }
|
||||||
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,6 +115,12 @@ clear_texture_ref(TextureRef **x) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TextureRef*
|
||||||
|
incref_texture_ref(TextureRef *ref) {
|
||||||
|
if (ref) ref->refcnt++;
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
static TextureRef*
|
static TextureRef*
|
||||||
new_texture_ref(void) {
|
new_texture_ref(void) {
|
||||||
TextureRef *ans = malloc(sizeof(TextureRef));
|
TextureRef *ans = malloc(sizeof(TextureRef));
|
||||||
@@ -128,18 +136,20 @@ texture_id_for_img(Image *img) {
|
|||||||
static void
|
static void
|
||||||
free_image_resources(GraphicsManager *self, Image *img) {
|
free_image_resources(GraphicsManager *self, Image *img) {
|
||||||
clear_texture_ref(&img->texture);
|
clear_texture_ref(&img->texture);
|
||||||
ImageAndFrame key = { .image_id=img->internal_id, .frame_id = img->root_frame.id };
|
if (self->disk_cache) {
|
||||||
if (!remove_from_cache(self, key) && PyErr_Occurred()) PyErr_Print();
|
ImageAndFrame key = { .image_id=img->internal_id, .frame_id = img->root_frame.id };
|
||||||
for (unsigned i = 0; i < img->extra_framecnt; i++) {
|
|
||||||
key.frame_id = img->extra_frames[i].id;
|
|
||||||
if (!remove_from_cache(self, key) && PyErr_Occurred()) PyErr_Print();
|
if (!remove_from_cache(self, key) && PyErr_Occurred()) PyErr_Print();
|
||||||
|
for (unsigned i = 0; i < img->extra_framecnt; i++) {
|
||||||
|
key.frame_id = img->extra_frames[i].id;
|
||||||
|
if (!remove_from_cache(self, key) && PyErr_Occurred()) PyErr_Print();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (img->extra_frames) {
|
if (img->extra_frames) {
|
||||||
free(img->extra_frames);
|
free(img->extra_frames);
|
||||||
img->extra_frames = NULL;
|
img->extra_frames = NULL;
|
||||||
}
|
}
|
||||||
free_refs_data(img);
|
free_refs_data(img);
|
||||||
self->used_storage -= img->used_storage;
|
self->used_storage = img->used_storage <= self->used_storage ? self->used_storage - img->used_storage : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -150,7 +160,7 @@ free_image(GraphicsManager *self, Image *img) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dealloc(GraphicsManager* self) {
|
free_all_images(GraphicsManager *self) {
|
||||||
if (self->images) {
|
if (self->images) {
|
||||||
Image *img, *tmp;
|
Image *img, *tmp;
|
||||||
HASH_ITER(hh, self->images, img, tmp) {
|
HASH_ITER(hh, self->images, img, tmp) {
|
||||||
@@ -158,6 +168,11 @@ dealloc(GraphicsManager* self) {
|
|||||||
}
|
}
|
||||||
self->images = NULL;
|
self->images = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dealloc(GraphicsManager* self) {
|
||||||
|
free_all_images(self);
|
||||||
free(self->render_data.item);
|
free(self->render_data.item);
|
||||||
Py_CLEAR(self->disk_cache);
|
Py_CLEAR(self->disk_cache);
|
||||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||||
@@ -222,6 +237,38 @@ remove_images(GraphicsManager *self, bool(*predicate)(Image*), id_type skip_imag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grman_pause_rendering(GraphicsManager *self, GraphicsManager *dest) {
|
||||||
|
make_window_context_current(dest->window_id);
|
||||||
|
free_all_images(dest); dest->images = NULL;
|
||||||
|
dest->render_data.count = 0;
|
||||||
|
if (self == NULL) return;
|
||||||
|
dest->window_id = self->window_id;
|
||||||
|
dest->layers_dirty = true;
|
||||||
|
dest->last_scrolled_by = 0;
|
||||||
|
|
||||||
|
Image *img, *tmpimg;
|
||||||
|
|
||||||
|
HASH_ITER(hh, self->images, img, tmpimg) {
|
||||||
|
Image *clone = calloc(1, sizeof(Image));
|
||||||
|
if (!clone) continue;
|
||||||
|
memcpy(clone, img, sizeof(*clone));
|
||||||
|
clone->extra_frames = NULL;
|
||||||
|
if (img->refs) {
|
||||||
|
clone->refs = NULL;
|
||||||
|
ImageRef *ref, *tmpref;
|
||||||
|
HASH_ITER(hh, img->refs, ref, tmpref) {
|
||||||
|
ImageRef *cr = malloc(sizeof(ImageRef));
|
||||||
|
if (cr) {
|
||||||
|
memcpy(cr, ref, sizeof(*cr));
|
||||||
|
HASH_ADD(hh, clone->refs, internal_id, sizeof(cr->internal_id), cr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HASH_ADD(hh, dest->images, internal_id, sizeof(clone->internal_id), clone);
|
||||||
|
clone->texture = incref_texture_ref(img->texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Loading image data {{{
|
// Loading image data {{{
|
||||||
|
|
||||||
@@ -2164,7 +2211,7 @@ grman_handle_command(GraphicsManager *self, const GraphicsCommand *g, const uint
|
|||||||
// Boilerplate {{{
|
// Boilerplate {{{
|
||||||
static PyObject *
|
static PyObject *
|
||||||
new(PyTypeObject UNUSED *type, PyObject UNUSED *args, PyObject UNUSED *kwds) {
|
new(PyTypeObject UNUSED *type, PyObject UNUSED *args, PyObject UNUSED *kwds) {
|
||||||
PyObject *ans = (PyObject*)grman_alloc();
|
PyObject *ans = (PyObject*)grman_alloc(false);
|
||||||
if (ans == NULL) PyErr_NoMemory();
|
if (ans == NULL) PyErr_NoMemory();
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ gl_pos_y(const unsigned int px_from_top_margin, const unsigned int viewport_size
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GraphicsManager* grman_alloc(void);
|
GraphicsManager* grman_alloc(bool for_paused_rendering);
|
||||||
void grman_clear(GraphicsManager*, bool, CellPixelSize fg);
|
void grman_clear(GraphicsManager*, bool, CellPixelSize fg);
|
||||||
const char* grman_handle_command(GraphicsManager *self, const GraphicsCommand *g, const uint8_t *payload, Cursor *c, bool *is_dirty, CellPixelSize fg);
|
const char* grman_handle_command(GraphicsManager *self, const GraphicsCommand *g, const uint8_t *payload, Cursor *c, bool *is_dirty, CellPixelSize fg);
|
||||||
Image* grman_put_cell_image(GraphicsManager *self, uint32_t row, uint32_t col, uint32_t image_id, uint32_t placement_id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, CellPixelSize cell);
|
Image* grman_put_cell_image(GraphicsManager *self, uint32_t row, uint32_t col, uint32_t image_id, uint32_t placement_id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, CellPixelSize cell);
|
||||||
@@ -196,3 +196,4 @@ bool png_path_to_bitmap(const char *path, uint8_t** data, unsigned int* width, u
|
|||||||
bool png_from_data(void *png_data, size_t png_data_sz, const char *path_for_error_messages, uint8_t** data, unsigned int* width, unsigned int* height, size_t* sz);
|
bool png_from_data(void *png_data, size_t png_data_sz, const char *path_for_error_messages, uint8_t** data, unsigned int* width, unsigned int* height, size_t* sz);
|
||||||
bool scan_active_animations(GraphicsManager *self, const monotonic_t now, monotonic_t *minimum_gap, bool os_window_context_set);
|
bool scan_active_animations(GraphicsManager *self, const monotonic_t now, monotonic_t *minimum_gap, bool os_window_context_set);
|
||||||
void scale_rendered_graphic(ImageRenderData*, float xstart, float ystart, float x_scale, float y_scale);
|
void scale_rendered_graphic(ImageRenderData*, float xstart, float ystart, float x_scale, float y_scale);
|
||||||
|
void grman_pause_rendering(GraphicsManager *self, GraphicsManager *dest);
|
||||||
|
|||||||
@@ -127,8 +127,8 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
|
|||||||
self->main_linebuf = alloc_linebuf(lines, columns); self->alt_linebuf = alloc_linebuf(lines, columns);
|
self->main_linebuf = alloc_linebuf(lines, columns); self->alt_linebuf = alloc_linebuf(lines, columns);
|
||||||
self->linebuf = self->main_linebuf;
|
self->linebuf = self->main_linebuf;
|
||||||
self->historybuf = alloc_historybuf(MAX(scrollback, lines), columns, OPT(scrollback_pager_history_size));
|
self->historybuf = alloc_historybuf(MAX(scrollback, lines), columns, OPT(scrollback_pager_history_size));
|
||||||
self->main_grman = grman_alloc();
|
self->main_grman = grman_alloc(false);
|
||||||
self->alt_grman = grman_alloc();
|
self->alt_grman = grman_alloc(false);
|
||||||
self->active_hyperlink_id = 0;
|
self->active_hyperlink_id = 0;
|
||||||
|
|
||||||
self->grman = self->main_grman;
|
self->grman = self->main_grman;
|
||||||
@@ -474,6 +474,7 @@ dealloc(Screen* self) {
|
|||||||
Py_CLEAR(self->overlay_line.overlay_text);
|
Py_CLEAR(self->overlay_line.overlay_text);
|
||||||
PyMem_Free(self->main_tabstops);
|
PyMem_Free(self->main_tabstops);
|
||||||
Py_CLEAR(self->paused_rendering.linebuf);
|
Py_CLEAR(self->paused_rendering.linebuf);
|
||||||
|
Py_CLEAR(self->paused_rendering.grman);
|
||||||
free(self->selections.items);
|
free(self->selections.items);
|
||||||
free(self->url_ranges.items);
|
free(self->url_ranges.items);
|
||||||
free(self->paused_rendering.url_ranges.items);
|
free(self->paused_rendering.url_ranges.items);
|
||||||
@@ -2391,9 +2392,13 @@ screen_pause_rendering(Screen *self, bool pause, int for_in_ms) {
|
|||||||
self->is_dirty = true;
|
self->is_dirty = true;
|
||||||
// ensure selection data is updated on GPU
|
// ensure selection data is updated on GPU
|
||||||
self->selections.last_rendered_count = SIZE_MAX; self->url_ranges.last_rendered_count = SIZE_MAX;
|
self->selections.last_rendered_count = SIZE_MAX; self->url_ranges.last_rendered_count = SIZE_MAX;
|
||||||
|
// free grman data
|
||||||
|
grman_pause_rendering(NULL, self->paused_rendering.grman);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (self->paused_rendering.expires_at) return false;
|
if (self->paused_rendering.expires_at) return false;
|
||||||
|
if (!self->paused_rendering.grman) self->paused_rendering.grman = grman_alloc(true);
|
||||||
|
if (!self->paused_rendering.grman) return false;
|
||||||
if (for_in_ms <= 0) for_in_ms = 2000;
|
if (for_in_ms <= 0) for_in_ms = 2000;
|
||||||
self->paused_rendering.expires_at = monotonic() + ms_to_monotonic_t(for_in_ms);
|
self->paused_rendering.expires_at = monotonic() + ms_to_monotonic_t(for_in_ms);
|
||||||
self->paused_rendering.inverted = self->modes.mDECSCNM;
|
self->paused_rendering.inverted = self->modes.mDECSCNM;
|
||||||
@@ -2415,6 +2420,7 @@ screen_pause_rendering(Screen *self, bool pause, int for_in_ms) {
|
|||||||
}
|
}
|
||||||
copy_selections(&self->paused_rendering.selections, &self->selections);
|
copy_selections(&self->paused_rendering.selections, &self->selections);
|
||||||
copy_selections(&self->paused_rendering.url_ranges, &self->url_ranges);
|
copy_selections(&self->paused_rendering.url_ranges, &self->url_ranges);
|
||||||
|
grman_pause_rendering(self->grman, self->paused_rendering.grman);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ typedef struct {
|
|||||||
bool inverted, cell_data_updated, cursor_visible;
|
bool inverted, cell_data_updated, cursor_visible;
|
||||||
unsigned int scrolled_by;
|
unsigned int scrolled_by;
|
||||||
LineBuf *linebuf;
|
LineBuf *linebuf;
|
||||||
|
GraphicsManager *grman;
|
||||||
Selections selections, url_ranges;
|
Selections selections, url_ranges;
|
||||||
} paused_rendering;
|
} paused_rendering;
|
||||||
} Screen;
|
} Screen;
|
||||||
|
|||||||
@@ -419,15 +419,18 @@ cell_prepare_to_render(ssize_t vao_idx, Screen *screen, GLfloat xstart, GLfloat
|
|||||||
changed = true; \
|
changed = true; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define update_graphics_data(grman) \
|
||||||
|
grman_update_layers(grman, screen->scrolled_by, xstart, ystart, dx, dy, screen->columns, screen->lines, screen->cell_size)
|
||||||
|
|
||||||
if (screen->paused_rendering.expires_at) {
|
if (screen->paused_rendering.expires_at) {
|
||||||
if (!screen->paused_rendering.cell_data_updated) update_selection_data;
|
if (!screen->paused_rendering.cell_data_updated) {
|
||||||
|
update_selection_data; update_graphics_data(screen->paused_rendering.grman);
|
||||||
|
}
|
||||||
screen->paused_rendering.cell_data_updated = true;
|
screen->paused_rendering.cell_data_updated = true;
|
||||||
screen->last_rendered.scrolled_by = screen->paused_rendering.scrolled_by;
|
screen->last_rendered.scrolled_by = screen->paused_rendering.scrolled_by;
|
||||||
} else {
|
} else {
|
||||||
if (screen->reload_all_gpu_data || screen_resized || screen_is_selection_dirty(screen)) update_selection_data;
|
if (screen->reload_all_gpu_data || screen_resized || screen_is_selection_dirty(screen)) update_selection_data;
|
||||||
if (grman_update_layers(screen->grman, screen->scrolled_by, xstart, ystart, dx, dy, screen->columns, screen->lines, screen->cell_size)) {
|
if (update_graphics_data(screen->grman)) changed = true;
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
screen->last_rendered.scrolled_by = screen->scrolled_by;
|
screen->last_rendered.scrolled_by = screen->scrolled_by;
|
||||||
}
|
}
|
||||||
#undef update_selection_data
|
#undef update_selection_data
|
||||||
@@ -563,11 +566,12 @@ static void
|
|||||||
draw_cells_simple(ssize_t vao_idx, Screen *screen, const CellRenderData *crd, bool is_semi_transparent) {
|
draw_cells_simple(ssize_t vao_idx, Screen *screen, const CellRenderData *crd, bool is_semi_transparent) {
|
||||||
bind_program(CELL_PROGRAM);
|
bind_program(CELL_PROGRAM);
|
||||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
||||||
if (screen->grman->render_data.count) {
|
GraphicsManager *grman = screen->paused_rendering.expires_at && screen->paused_rendering.grman ? screen->paused_rendering.grman : screen->grman;
|
||||||
|
if (grman->render_data.count) {
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
int program = GRAPHICS_PROGRAM;
|
int program = GRAPHICS_PROGRAM;
|
||||||
if (is_semi_transparent) { BLEND_PREMULT; program = GRAPHICS_PREMULT_PROGRAM; } else { BLEND_ONTO_OPAQUE; }
|
if (is_semi_transparent) { BLEND_PREMULT; program = GRAPHICS_PREMULT_PROGRAM; } else { BLEND_ONTO_OPAQUE; }
|
||||||
draw_graphics(program, vao_idx, screen->grman->render_data.item, 0, screen->grman->render_data.count, viewport_for_cells(crd));
|
draw_graphics(program, vao_idx, grman->render_data.item, 0, grman->render_data.count, viewport_for_cells(crd));
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -804,20 +808,21 @@ draw_cells_interleaved(ssize_t vao_idx, Screen *screen, OSWindow *w, const CellR
|
|||||||
BLEND_ONTO_OPAQUE;
|
BLEND_ONTO_OPAQUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (screen->grman->num_of_below_refs || has_bgimage(w) || wl) {
|
GraphicsManager *grman = screen->paused_rendering.expires_at && screen->paused_rendering.grman ? screen->paused_rendering.grman : screen->grman;
|
||||||
|
if (grman->num_of_below_refs || has_bgimage(w) || wl) {
|
||||||
if (wl) {
|
if (wl) {
|
||||||
draw_window_logo(vao_idx, w, wl, crd);
|
draw_window_logo(vao_idx, w, wl, crd);
|
||||||
BLEND_ONTO_OPAQUE;
|
BLEND_ONTO_OPAQUE;
|
||||||
}
|
}
|
||||||
if (screen->grman->num_of_below_refs) draw_graphics(
|
if (grman->num_of_below_refs) draw_graphics(
|
||||||
GRAPHICS_PROGRAM, vao_idx, screen->grman->render_data.item, 0, screen->grman->num_of_below_refs, viewport_for_cells(crd));
|
GRAPHICS_PROGRAM, vao_idx, grman->render_data.item, 0, grman->num_of_below_refs, viewport_for_cells(crd));
|
||||||
bind_program(CELL_BG_PROGRAM);
|
bind_program(CELL_BG_PROGRAM);
|
||||||
// draw background for non-default bg cells
|
// draw background for non-default bg cells
|
||||||
glUniform1ui(cell_program_layouts[CELL_BG_PROGRAM].uniforms.draw_bg_bitfield, 2);
|
glUniform1ui(cell_program_layouts[CELL_BG_PROGRAM].uniforms.draw_bg_bitfield, 2);
|
||||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (screen->grman->num_of_negative_refs) draw_graphics(GRAPHICS_PROGRAM, vao_idx, screen->grman->render_data.item, screen->grman->num_of_below_refs, screen->grman->num_of_negative_refs, viewport_for_cells(crd));
|
if (grman->num_of_negative_refs) draw_graphics(GRAPHICS_PROGRAM, vao_idx, grman->render_data.item, grman->num_of_below_refs, grman->num_of_negative_refs, viewport_for_cells(crd));
|
||||||
|
|
||||||
bind_program(CELL_SPECIAL_PROGRAM);
|
bind_program(CELL_SPECIAL_PROGRAM);
|
||||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
||||||
@@ -827,7 +832,7 @@ draw_cells_interleaved(ssize_t vao_idx, Screen *screen, OSWindow *w, const CellR
|
|||||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
||||||
BLEND_ONTO_OPAQUE;
|
BLEND_ONTO_OPAQUE;
|
||||||
|
|
||||||
if (screen->grman->num_of_positive_refs) draw_graphics(GRAPHICS_PROGRAM, vao_idx, screen->grman->render_data.item, screen->grman->num_of_negative_refs + screen->grman->num_of_below_refs, screen->grman->num_of_positive_refs, viewport_for_cells(crd));
|
if (grman->num_of_positive_refs) draw_graphics(GRAPHICS_PROGRAM, vao_idx, grman->render_data.item, grman->num_of_negative_refs + grman->num_of_below_refs, grman->num_of_positive_refs, viewport_for_cells(crd));
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
@@ -848,13 +853,14 @@ draw_cells_interleaved_premult(ssize_t vao_idx, Screen *screen, OSWindow *os_win
|
|||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
BLEND_PREMULT;
|
BLEND_PREMULT;
|
||||||
|
|
||||||
if (screen->grman->num_of_below_refs || has_bgimage(os_window) || wl) {
|
GraphicsManager *grman = screen->paused_rendering.expires_at && screen->paused_rendering.grman ? screen->paused_rendering.grman : screen->grman;
|
||||||
|
if (grman->num_of_below_refs || has_bgimage(os_window) || wl) {
|
||||||
if (wl) {
|
if (wl) {
|
||||||
draw_window_logo(vao_idx, os_window, wl, crd);
|
draw_window_logo(vao_idx, os_window, wl, crd);
|
||||||
BLEND_PREMULT;
|
BLEND_PREMULT;
|
||||||
}
|
}
|
||||||
if (screen->grman->num_of_below_refs) draw_graphics(
|
if (grman->num_of_below_refs) draw_graphics(
|
||||||
GRAPHICS_PREMULT_PROGRAM, vao_idx, screen->grman->render_data.item, 0, screen->grman->num_of_below_refs, viewport_for_cells(crd));
|
GRAPHICS_PREMULT_PROGRAM, vao_idx, grman->render_data.item, 0, grman->num_of_below_refs, viewport_for_cells(crd));
|
||||||
bind_program(CELL_BG_PROGRAM);
|
bind_program(CELL_BG_PROGRAM);
|
||||||
// Draw background for non-default bg cells
|
// Draw background for non-default bg cells
|
||||||
glUniform1ui(cell_program_layouts[CELL_BG_PROGRAM].uniforms.draw_bg_bitfield, 2);
|
glUniform1ui(cell_program_layouts[CELL_BG_PROGRAM].uniforms.draw_bg_bitfield, 2);
|
||||||
@@ -865,8 +871,8 @@ draw_cells_interleaved_premult(ssize_t vao_idx, Screen *screen, OSWindow *os_win
|
|||||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (screen->grman->num_of_negative_refs) {
|
if (grman->num_of_negative_refs) {
|
||||||
draw_graphics(GRAPHICS_PREMULT_PROGRAM, vao_idx, screen->grman->render_data.item, screen->grman->num_of_below_refs, screen->grman->num_of_negative_refs, viewport_for_cells(crd));
|
draw_graphics(GRAPHICS_PREMULT_PROGRAM, vao_idx, grman->render_data.item, grman->num_of_below_refs, grman->num_of_negative_refs, viewport_for_cells(crd));
|
||||||
}
|
}
|
||||||
|
|
||||||
bind_program(CELL_SPECIAL_PROGRAM);
|
bind_program(CELL_SPECIAL_PROGRAM);
|
||||||
@@ -875,7 +881,7 @@ draw_cells_interleaved_premult(ssize_t vao_idx, Screen *screen, OSWindow *os_win
|
|||||||
bind_program(CELL_FG_PROGRAM);
|
bind_program(CELL_FG_PROGRAM);
|
||||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
||||||
|
|
||||||
if (screen->grman->num_of_positive_refs) draw_graphics(GRAPHICS_PREMULT_PROGRAM, vao_idx, screen->grman->render_data.item, screen->grman->num_of_negative_refs + screen->grman->num_of_below_refs, screen->grman->num_of_positive_refs, viewport_for_cells(crd));
|
if (grman->num_of_positive_refs) draw_graphics(GRAPHICS_PREMULT_PROGRAM, vao_idx, grman->render_data.item, grman->num_of_negative_refs + grman->num_of_below_refs, grman->num_of_positive_refs, viewport_for_cells(crd));
|
||||||
|
|
||||||
if (!has_bgimage(os_window)) glDisable(GL_BLEND);
|
if (!has_bgimage(os_window)) glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
@@ -957,15 +963,16 @@ draw_cells(ssize_t vao_idx, const WindowRenderData *srd, OSWindow *os_window, bo
|
|||||||
set_on_gpu_state(window->window_logo.instance, true);
|
set_on_gpu_state(window->window_logo.instance, true);
|
||||||
} else wl = NULL;
|
} else wl = NULL;
|
||||||
ImageRenderData *previous_graphics_render_data = NULL;
|
ImageRenderData *previous_graphics_render_data = NULL;
|
||||||
if (os_window->live_resize.in_progress && screen->grman->render_data.count && (crd.x_ratio != 1 || crd.y_ratio != 1)) {
|
GraphicsManager *grman = screen->paused_rendering.expires_at && screen->paused_rendering.grman ? screen->paused_rendering.grman : screen->grman;
|
||||||
previous_graphics_render_data = malloc(sizeof(previous_graphics_render_data[0]) * screen->grman->render_data.capacity);
|
if (os_window->live_resize.in_progress && grman->render_data.count && (crd.x_ratio != 1 || crd.y_ratio != 1)) {
|
||||||
|
previous_graphics_render_data = malloc(sizeof(previous_graphics_render_data[0]) * grman->render_data.capacity);
|
||||||
if (previous_graphics_render_data) {
|
if (previous_graphics_render_data) {
|
||||||
memcpy(previous_graphics_render_data, screen->grman->render_data.item, sizeof(previous_graphics_render_data[0]) * screen->grman->render_data.count);
|
memcpy(previous_graphics_render_data, grman->render_data.item, sizeof(previous_graphics_render_data[0]) * grman->render_data.count);
|
||||||
for (size_t i = 0; i < screen->grman->render_data.count; i++)
|
for (size_t i = 0; i < grman->render_data.count; i++)
|
||||||
scale_rendered_graphic(screen->grman->render_data.item + i, srd->xstart, srd->ystart, crd.x_ratio, crd.y_ratio);
|
scale_rendered_graphic(grman->render_data.item + i, srd->xstart, srd->ystart, crd.x_ratio, crd.y_ratio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
has_underlying_image |= screen->grman->num_of_below_refs > 0 || screen->grman->num_of_negative_refs > 0;
|
has_underlying_image |= grman->num_of_below_refs > 0 || grman->num_of_negative_refs > 0;
|
||||||
if (os_window->is_semi_transparent) {
|
if (os_window->is_semi_transparent) {
|
||||||
if (has_underlying_image) draw_cells_interleaved_premult(vao_idx, screen, os_window, &crd, wl);
|
if (has_underlying_image) draw_cells_interleaved_premult(vao_idx, screen, os_window, &crd, wl);
|
||||||
else draw_cells_simple(vao_idx, screen, &crd, os_window->is_semi_transparent);
|
else draw_cells_simple(vao_idx, screen, &crd, os_window->is_semi_transparent);
|
||||||
@@ -982,8 +989,8 @@ draw_cells(ssize_t vao_idx, const WindowRenderData *srd, OSWindow *os_window, bo
|
|||||||
if (window && screen->display_window_char) draw_window_number(os_window, screen, &crd, window);
|
if (window && screen->display_window_char) draw_window_number(os_window, screen, &crd, window);
|
||||||
if (OPT(show_hyperlink_targets) && window && screen->current_hyperlink_under_mouse.id && !is_mouse_hidden(os_window)) draw_hyperlink_target(os_window, screen, &crd, window);
|
if (OPT(show_hyperlink_targets) && window && screen->current_hyperlink_under_mouse.id && !is_mouse_hidden(os_window)) draw_hyperlink_target(os_window, screen, &crd, window);
|
||||||
if (previous_graphics_render_data) {
|
if (previous_graphics_render_data) {
|
||||||
free(screen->grman->render_data.item);
|
free(grman->render_data.item);
|
||||||
screen->grman->render_data.item = previous_graphics_render_data;
|
grman->render_data.item = previous_graphics_render_data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
|
|||||||
Reference in New Issue
Block a user