Properly release resources used by bgimage
Also allow per OS Window bg images in the future
This commit is contained in:
parent
8e7b8b70dc
commit
fdd7fe1948
@ -689,7 +689,7 @@ render(monotonic_t now, bool input_read) {
|
||||
if (!w->fonts_data) { log_error("No fonts data found for window id: %llu", w->id); continue; }
|
||||
if (prepare_to_render_os_window(w, now, &active_window_id, &active_window_bg, &num_visible_windows, &all_windows_have_same_bg)) needs_render = true;
|
||||
if (w->last_active_window_id != active_window_id || w->last_active_tab != w->active_tab || w->focused_at_last_render != w->is_focused) needs_render = true;
|
||||
if (w->render_calls < 3 && w->bgimage != NULL) needs_render = true;
|
||||
if (w->render_calls < 3 && w->bgimage.texture_id) needs_render = true;
|
||||
if (needs_render) render_os_window(w, now, active_window_id, active_window_bg, num_visible_windows, all_windows_have_same_bg);
|
||||
}
|
||||
last_render_at = now;
|
||||
|
||||
@ -59,6 +59,7 @@ typedef struct {
|
||||
uint32_t texture_id;
|
||||
unsigned int height, width;
|
||||
uint8_t* bitmap;
|
||||
bool load_failed, needs_free;
|
||||
} BackgroundImage;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@ -349,7 +349,7 @@ draw_bg(int program, OSWindow *w) {
|
||||
glUniform1f(glGetUniformLocation(program_id(program), "width"), (float)(w->window_width));
|
||||
glActiveTexture(GL_TEXTURE0 + BGIMAGE_UNIT);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, w->bgimage->texture_id);
|
||||
glBindTexture(GL_TEXTURE_2D, w->bgimage.texture_id);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
unbind_vertex_array();
|
||||
@ -433,7 +433,7 @@ draw_cells_interleaved(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen, OSWind
|
||||
if (OPT(background_opacity) != 0.0)
|
||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
|
||||
|
||||
if (screen->grman->num_of_below_refs || w->bgimage != NULL) {
|
||||
if (screen->grman->num_of_below_refs || w->bgimage.texture_id) {
|
||||
draw_graphics(GRAPHICS_PROGRAM, vao_idx, gvao_idx, screen->grman->render_data, 0, screen->grman->num_of_below_refs);
|
||||
bind_program(CELL_BG_PROGRAM);
|
||||
// draw background for non-default bg cells
|
||||
@ -595,10 +595,10 @@ draw_cells(ssize_t vao_idx, ssize_t gvao_idx, GLfloat xstart, GLfloat ystart, GL
|
||||
);
|
||||
#undef SCALE
|
||||
if (os_window->is_semi_transparent) {
|
||||
if (screen->grman->count || os_window->bgimage != NULL) draw_cells_interleaved_premult(vao_idx, gvao_idx, screen, os_window);
|
||||
if (screen->grman->count || os_window->bgimage.texture_id) draw_cells_interleaved_premult(vao_idx, gvao_idx, screen, os_window);
|
||||
else draw_cells_simple(vao_idx, gvao_idx, screen);
|
||||
} else {
|
||||
if (screen->grman->num_of_negative_refs || screen->grman->num_of_below_refs || os_window->bgimage != NULL) draw_cells_interleaved(vao_idx, gvao_idx, screen, os_window);
|
||||
if (screen->grman->num_of_negative_refs || screen->grman->num_of_below_refs || os_window->bgimage.texture_id) draw_cells_interleaved(vao_idx, gvao_idx, screen, os_window);
|
||||
else draw_cells_simple(vao_idx, gvao_idx, screen);
|
||||
}
|
||||
}
|
||||
@ -642,7 +642,7 @@ create_border_vao(void) {
|
||||
void
|
||||
draw_borders(ssize_t vao_idx, unsigned int num_border_rects, BorderRect *rect_buf, bool rect_data_is_dirty, uint32_t viewport_width, uint32_t viewport_height, color_type active_window_bg, unsigned int num_visible_windows, bool all_windows_have_same_bg, OSWindow *w) {
|
||||
|
||||
if (w->bgimage != NULL) {
|
||||
if (w->bgimage.texture_id) {
|
||||
glEnable(GL_BLEND);
|
||||
BLEND_ONTO_OPAQUE;
|
||||
draw_bg((OPT(background_image_layout) == TILING || OPT(background_image_layout) == MIRRORED) ? BGIMAGE_TILED_PROGRAM : BGIMAGE_PROGRAM, w);
|
||||
@ -670,7 +670,7 @@ draw_borders(ssize_t vao_idx, unsigned int num_border_rects, BorderRect *rect_bu
|
||||
unbind_vertex_array();
|
||||
unbind_program();
|
||||
}
|
||||
if (w->bgimage != NULL) glDisable(GL_BLEND);
|
||||
if (w->bgimage.texture_id) glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
@ -84,16 +84,9 @@ add_os_window() {
|
||||
|
||||
bool wants_bg = OPT(background_image) && OPT(background_image)[0] != 0;
|
||||
if (wants_bg) {
|
||||
bool has_bg;
|
||||
has_bg = global_state.bgimage != NULL;
|
||||
|
||||
if (!has_bg) {
|
||||
BackgroundImage* bgimage = calloc(1, sizeof(BackgroundImage));
|
||||
if (!global_state.bgimage.texture_id && !global_state.bgimage.load_failed) {
|
||||
size_t size;
|
||||
|
||||
has_bg = png_path_to_bitmap(OPT(background_image), &bgimage->bitmap, &bgimage->width, &bgimage->height, &size);
|
||||
if (has_bg) {
|
||||
bgimage->texture_id = 0;
|
||||
if (png_path_to_bitmap(OPT(background_image), &global_state.bgimage.bitmap, &global_state.bgimage.width, &global_state.bgimage.height, &size)) {
|
||||
RepeatStrategy r;
|
||||
switch (OPT(background_image_layout)) {
|
||||
case SCALED:
|
||||
@ -104,14 +97,16 @@ add_os_window() {
|
||||
default:
|
||||
r = REPEAT_DEFAULT; break;
|
||||
}
|
||||
send_image_to_gpu(&bgimage->texture_id, bgimage->bitmap, bgimage->width,
|
||||
bgimage->height, false, true, OPT(background_image_linear), r);
|
||||
ans->bgimage = bgimage;
|
||||
global_state.bgimage = bgimage;
|
||||
}
|
||||
} else {
|
||||
// Reusing already loaded bgimage
|
||||
ans->bgimage = global_state.bgimage;
|
||||
global_state.bgimage.texture_id = 0;
|
||||
send_image_to_gpu(&global_state.bgimage.texture_id, global_state.bgimage.bitmap, global_state.bgimage.width,
|
||||
global_state.bgimage.height, false, true, OPT(background_image_linear), r);
|
||||
global_state.bgimage.needs_free = true;
|
||||
free(global_state.bgimage.bitmap); global_state.bgimage.bitmap = NULL;
|
||||
} else global_state.bgimage.load_failed = true;
|
||||
}
|
||||
if (global_state.bgimage.texture_id) {
|
||||
memcpy(&ans->bgimage, &global_state.bgimage, sizeof(global_state.bgimage));
|
||||
ans->bgimage.needs_free = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,6 +288,9 @@ destroy_os_window_item(OSWindow *w) {
|
||||
remove_vao(w->tab_bar_render_data.vao_idx);
|
||||
remove_vao(w->gvao_idx);
|
||||
free(w->tabs); w->tabs = NULL;
|
||||
if (w->bgimage.needs_free) {
|
||||
free(w->bgimage.bitmap); free_texture(&w->bgimage.texture_id);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@ -960,6 +958,13 @@ finalize(void) {
|
||||
if (detached_windows.windows) free(detached_windows.windows);
|
||||
detached_windows.capacity = 0;
|
||||
if (OPT(background_image)) free(OPT(background_image));
|
||||
if (global_state.bgimage.needs_free) {
|
||||
free(global_state.bgimage.bitmap);
|
||||
// we leak the texture here since it is not guaranteed
|
||||
// that freeing the texture will work during shutdown and
|
||||
// the GPU driver should take care of it when the OpenGL context is
|
||||
// destroyed.
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@ -144,7 +144,7 @@ typedef struct {
|
||||
int viewport_width, viewport_height, window_width, window_height;
|
||||
double viewport_x_ratio, viewport_y_ratio;
|
||||
Tab *tabs;
|
||||
BackgroundImage *bgimage;
|
||||
BackgroundImage bgimage;
|
||||
unsigned int active_tab, num_tabs, capacity, last_active_tab, last_num_tabs, last_active_window_id;
|
||||
bool focused_at_last_render, needs_render;
|
||||
ScreenRenderData tab_bar_render_data;
|
||||
@ -178,7 +178,7 @@ typedef struct {
|
||||
|
||||
id_type os_window_id_counter, tab_id_counter, window_id_counter;
|
||||
PyObject *boss;
|
||||
BackgroundImage *bgimage;
|
||||
BackgroundImage bgimage;
|
||||
OSWindow *os_windows;
|
||||
size_t num_os_windows, capacity;
|
||||
OSWindow *callback_os_window;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user