Fix leak when changing background image using remote control

This commit is contained in:
Kovid Goyal
2020-02-02 09:27:58 +05:30
parent 226488717a
commit eddae44d6d

View File

@@ -90,18 +90,18 @@ send_bgimage_to_gpu(BackgroundImageLayout layout, BackgroundImage *bgimage) {
} }
static void static void
free_bgimage(BackgroundImage *bgimage, bool release_texture) { free_bgimage(BackgroundImage **bgimage, bool release_texture) {
if (bgimage && bgimage->refcnt) { if (*bgimage && (*bgimage)->refcnt) {
bgimage->refcnt--; (*bgimage)->refcnt--;
if (bgimage->refcnt == 0) { if ((*bgimage)->refcnt == 0) {
free(bgimage->bitmap); bgimage->bitmap = NULL; free((*bgimage)->bitmap); (*bgimage)->bitmap = NULL;
if (release_texture) free_texture(&bgimage->texture_id); if (release_texture) free_texture(&(*bgimage)->texture_id);
free(*bgimage);
bgimage = NULL;
} }
} }
} }
static BackgroundImage global_bg_image = {0};
OSWindow* OSWindow*
add_os_window() { add_os_window() {
WITH_OS_WINDOW_REFS WITH_OS_WINDOW_REFS
@@ -116,7 +116,8 @@ add_os_window() {
bool wants_bg = OPT(background_image) && OPT(background_image)[0] != 0; bool wants_bg = OPT(background_image) && OPT(background_image)[0] != 0;
if (wants_bg) { if (wants_bg) {
if (!global_state.bgimage) { if (!global_state.bgimage) {
global_state.bgimage = &global_bg_image; global_state.bgimage = calloc(1, sizeof(BackgroundImage));
if (!global_state.bgimage) fatal("Out of memory allocating the global bg image object");
global_state.bgimage->refcnt++; global_state.bgimage->refcnt++;
size_t size; size_t size;
if (png_path_to_bitmap(OPT(background_image), &global_state.bgimage->bitmap, &global_state.bgimage->width, &global_state.bgimage->height, &size)) { if (png_path_to_bitmap(OPT(background_image), &global_state.bgimage->bitmap, &global_state.bgimage->width, &global_state.bgimage->height, &size)) {
@@ -307,7 +308,7 @@ destroy_os_window_item(OSWindow *w) {
remove_vao(w->tab_bar_render_data.vao_idx); remove_vao(w->tab_bar_render_data.vao_idx);
remove_vao(w->gvao_idx); remove_vao(w->gvao_idx);
free(w->tabs); w->tabs = NULL; free(w->tabs); w->tabs = NULL;
free_bgimage(w->bgimage, true); free_bgimage(&w->bgimage, true);
w->bgimage = NULL; w->bgimage = NULL;
} }
@@ -921,7 +922,7 @@ pyset_background_image(PyObject *self UNUSED, PyObject *args) {
send_bgimage_to_gpu(layout, bgimage); send_bgimage_to_gpu(layout, bgimage);
bgimage->refcnt++; bgimage->refcnt++;
if (configured) { if (configured) {
free_bgimage(global_state.bgimage, true); free_bgimage(&global_state.bgimage, true);
global_state.bgimage = bgimage; global_state.bgimage = bgimage;
bgimage->refcnt++; bgimage->refcnt++;
OPT(background_image_layout) = layout; OPT(background_image_layout) = layout;
@@ -930,13 +931,13 @@ pyset_background_image(PyObject *self UNUSED, PyObject *args) {
id_type os_window_id = PyLong_AsUnsignedLongLong(PyTuple_GET_ITEM(os_window_ids, i)); id_type os_window_id = PyLong_AsUnsignedLongLong(PyTuple_GET_ITEM(os_window_ids, i));
WITH_OS_WINDOW(os_window_id) WITH_OS_WINDOW(os_window_id)
make_os_window_context_current(os_window); make_os_window_context_current(os_window);
free_bgimage(os_window->bgimage, true); free_bgimage(&os_window->bgimage, true);
os_window->bgimage = bgimage; os_window->bgimage = bgimage;
os_window->render_calls = 0; os_window->render_calls = 0;
bgimage->refcnt++; bgimage->refcnt++;
END_WITH_OS_WINDOW END_WITH_OS_WINDOW
} }
free_bgimage(bgimage, true); free_bgimage(&bgimage, true);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
@@ -1017,7 +1018,7 @@ finalize(void) {
// that freeing the texture will work during shutdown and // that freeing the texture will work during shutdown and
// the GPU driver should take care of it when the OpenGL context is // the GPU driver should take care of it when the OpenGL context is
// destroyed. // destroyed.
free_bgimage(global_state.bgimage, false); free_bgimage(&global_state.bgimage, false);
global_state.bgimage = NULL; global_state.bgimage = NULL;
} }