From 436cdf1fc898097a8cbe6226ad32a4055a6ca4d9 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Mon, 8 Mar 2021 21:16:41 +0100 Subject: [PATCH] Fix #8825: [OpenGL] Don't clear cursor cache from the game loop thread. --- src/video/opengl.cpp | 26 ++++++++++++++++++-------- src/video/opengl.h | 1 + 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/video/opengl.cpp b/src/video/opengl.cpp index 64ea02cf2d..26f6f4b4dc 100644 --- a/src/video/opengl.cpp +++ b/src/video/opengl.cpp @@ -1051,6 +1051,19 @@ void OpenGLBackend::DrawMouseCursor() void OpenGLBackend::PopulateCursorCache() { + if (this->clear_cursor_cache) { + /* We have a pending cursor cache clear to do first. */ + this->clear_cursor_cache = false; + this->last_sprite_pal = (PaletteID)-1; + + Sprite *sp; + while ((sp = this->cursor_cache.Pop()) != nullptr) { + OpenGLSprite *sprite = (OpenGLSprite *)sp->data; + sprite->~OpenGLSprite(); + free(sp); + } + } + for (uint i = 0; i < _cursor.sprite_count; ++i) { SpriteID sprite = _cursor.sprite_seq[i].sprite; @@ -1070,14 +1083,11 @@ void OpenGLBackend::PopulateCursorCache() */ void OpenGLBackend::ClearCursorCache() { - this->last_sprite_pal = (PaletteID)-1; - - Sprite *sp; - while ((sp = this->cursor_cache.Pop()) != nullptr) { - OpenGLSprite *sprite = (OpenGLSprite *)sp->data; - sprite->~OpenGLSprite(); - free(sp); - } + /* If the game loop is threaded, this function might be called + * from the game thread. As we can call OpenGL functions only + * on the main thread, just set a flag that is handled the next + * time we prepare the cursor cache for drawing. */ + this->clear_cursor_cache = true; } /** diff --git a/src/video/opengl.h b/src/video/opengl.h index 3919179e40..c17a8536d9 100644 --- a/src/video/opengl.h +++ b/src/video/opengl.h @@ -63,6 +63,7 @@ private: LRUCache cursor_cache; ///< Cache of encoded cursor sprites. PaletteID last_sprite_pal = (PaletteID)-1; ///< Last uploaded remap palette. + bool clear_cursor_cache = false; ///< A clear of the cursor cache is pending. OpenGLBackend(); ~OpenGLBackend();