Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/intern/image.c8
-rw-r--r--source/blender/gpu/GPU_draw.h2
-rw-r--r--source/blender/gpu/intern/gpu_draw.c73
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c2
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c2
5 files changed, 44 insertions, 43 deletions
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 24d175511c7..bb793b58a1d 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -360,13 +360,7 @@ void BKE_image_free_buffers_ex(Image *ima, bool do_lock)
ima->rr = NULL;
}
- if (!G.background) {
- /* Background mode doesn't use OpenGL,
- * so we can avoid freeing GPU images and save some
- * time by skipping mutex lock.
- */
- GPU_free_image(ima);
- }
+ GPU_free_image(ima);
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
tile->ok = IMA_OK;
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index ab507d852e8..1cd5c4d519e 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -86,7 +86,7 @@ void GPU_create_smoke_coba_field(struct FluidModifierData *mmd);
void GPU_create_smoke_velocity(struct FluidModifierData *mmd);
/* Delayed free of OpenGL buffers by main thread */
-void GPU_free_unused_buffers(struct Main *bmain);
+void GPU_free_unused_buffers(void);
#ifdef __cplusplus
}
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index d768ce373b6..f07e3ed70d7 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -60,7 +60,8 @@
#include "PIL_time.h"
-static void gpu_free_image_immediate(Image *ima);
+static void gpu_free_image(Image *ima, const bool immediate);
+static void gpu_free_unused_buffers(void);
//* Checking powers of two for images since OpenGL ES requires it */
#ifdef WITH_DDS
@@ -859,9 +860,13 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, ImBuf *ibuf,
return NULL;
}
+ /* Free any unused GPU textures, since we know we are in a thread with OpenGL
+ * context and might as well ensure we have as much space free as possible. */
+ gpu_free_unused_buffers();
+
/* currently, gpu refresh tagging is used by ima sequences */
if (ima->gpuflag & IMA_GPU_REFRESH) {
- gpu_free_image_immediate(ima);
+ gpu_free_image(ima, true);
ima->gpuflag &= ~IMA_GPU_REFRESH;
}
@@ -1338,47 +1343,47 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i
#endif
}
-static LinkNode *image_free_queue = NULL;
-static ThreadMutex img_queue_mutex = BLI_MUTEX_INITIALIZER;
+/* Delayed GPU texture free. Image datablocks can be deleted by any thread,
+ * but there may not be any active OpenGL context. In that case we push them
+ * into a queue and free the buffers later. */
+static LinkNode *gpu_texture_free_queue = NULL;
+static ThreadMutex gpu_texture_queue_mutex = BLI_MUTEX_INITIALIZER;
-static void gpu_queue_image_for_free(Image *ima)
+static void gpu_free_unused_buffers()
{
- BLI_mutex_lock(&img_queue_mutex);
- BLI_linklist_prepend(&image_free_queue, ima);
- BLI_mutex_unlock(&img_queue_mutex);
-}
-
-void GPU_free_unused_buffers(Main *bmain)
-{
- if (!BLI_thread_is_main()) {
+ if (gpu_texture_free_queue == NULL) {
return;
}
- BLI_mutex_lock(&img_queue_mutex);
-
- /* images */
- for (LinkNode *node = image_free_queue; node; node = node->next) {
- Image *ima = node->link;
+ BLI_mutex_lock(&gpu_texture_queue_mutex);
- /* check in case it was freed in the meantime */
- if (bmain && BLI_findindex(&bmain->images, ima) != -1) {
- GPU_free_image(ima);
+ if (gpu_texture_free_queue != NULL) {
+ for (LinkNode *node = gpu_texture_free_queue; node; node = node->next) {
+ GPUTexture *tex = node->link;
+ GPU_texture_free(tex);
}
- }
- BLI_linklist_free(image_free_queue, NULL);
- image_free_queue = NULL;
+ BLI_linklist_free(gpu_texture_free_queue, NULL);
+ gpu_texture_free_queue = NULL;
+ }
- BLI_mutex_unlock(&img_queue_mutex);
+ BLI_mutex_unlock(&gpu_texture_queue_mutex);
}
-static void gpu_free_image_immediate(Image *ima)
+static void gpu_free_image(Image *ima, const bool immediate)
{
for (int eye = 0; eye < 2; eye++) {
for (int i = 0; i < TEXTARGET_COUNT; i++) {
- /* free glsl image binding */
if (ima->gputexture[i][eye] != NULL) {
- GPU_texture_free(ima->gputexture[i][eye]);
+ if (immediate) {
+ GPU_texture_free(ima->gputexture[i][eye]);
+ }
+ else {
+ BLI_mutex_lock(&gpu_texture_queue_mutex);
+ BLI_linklist_prepend(&gpu_texture_free_queue, ima->gputexture[i][eye]);
+ BLI_mutex_unlock(&gpu_texture_queue_mutex);
+ }
+
ima->gputexture[i][eye] = NULL;
}
}
@@ -1387,14 +1392,16 @@ static void gpu_free_image_immediate(Image *ima)
ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
}
-void GPU_free_image(Image *ima)
+void GPU_free_unused_buffers()
{
- if (!BLI_thread_is_main()) {
- gpu_queue_image_for_free(ima);
- return;
+ if (BLI_thread_is_main()) {
+ gpu_free_unused_buffers();
}
+}
- gpu_free_image_immediate(ima);
+void GPU_free_image(Image *ima)
+{
+ gpu_free_image(ima, BLI_thread_is_main());
}
void GPU_free_images(Main *bmain)
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 6a19ce62f50..3c2bc14837d 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -1012,7 +1012,7 @@ void wm_draw_update(bContext *C)
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win;
- GPU_free_unused_buffers(bmain);
+ GPU_free_unused_buffers();
for (win = wm->windows.first; win; win = win->next) {
#ifdef WIN32
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index e0d2127ba51..cb5a039765a 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -578,7 +578,7 @@ void WM_exit_ex(bContext *C, const bool do_python)
BKE_subdiv_exit();
if (opengl_is_init) {
- GPU_free_unused_buffers(G_MAIN);
+ GPU_free_unused_buffers();
}
BKE_blender_free(); /* blender.c, does entire library and spacetypes */