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--intern/cycles/kernel/kernel_shader.h2
-rw-r--r--source/blender/blenkernel/BKE_image.h10
-rw-r--r--source/blender/blenkernel/intern/blender.c2
-rw-r--r--source/blender/blenkernel/intern/brush.c2
-rw-r--r--source/blender/blenkernel/intern/image.c263
-rw-r--r--source/blender/blenlib/BLI_threads.h17
-rw-r--r--source/blender/blenlib/intern/threads.c36
-rw-r--r--source/blender/blenloader/intern/readfile.c2
-rw-r--r--source/blender/collada/ImageExporter.cpp4
-rw-r--r--source/blender/compositor/nodes/COM_ImageNode.cpp3
-rw-r--r--source/blender/compositor/operations/COM_ImageOperation.cpp5
-rw-r--r--source/blender/compositor/operations/COM_ViewerBaseOperation.cpp10
-rw-r--r--source/blender/editors/include/ED_image.h2
-rw-r--r--source/blender/editors/object/object_bake.c46
-rw-r--r--source/blender/editors/object/object_edit.c4
-rw-r--r--source/blender/editors/render/render_internal.c2
-rw-r--r--source/blender/editors/render/render_opengl.c4
-rw-r--r--source/blender/editors/render/render_preview.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c72
-rw-r--r--source/blender/editors/space_image/image_buttons.c5
-rw-r--r--source/blender/editors/space_image/image_draw.c11
-rw-r--r--source/blender/editors/space_image/image_edit.c16
-rw-r--r--source/blender/editors/space_image/image_ops.c55
-rw-r--r--source/blender/editors/space_image/space_image.c2
-rw-r--r--source/blender/editors/space_info/info_ops.c8
-rw-r--r--source/blender/editors/space_node/drawnode.c6
-rw-r--r--source/blender/editors/space_node/node_view.c8
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c2
-rw-r--r--source/blender/editors/space_view3d/drawobject.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c3
-rw-r--r--source/blender/gpu/intern/gpu_draw.c14
-rw-r--r--source/blender/gpu/intern/gpu_material.c3
-rw-r--r--source/blender/makesrna/intern/rna_image.c27
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c19
-rw-r--r--source/blender/makesrna/intern/rna_space.c4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.c22
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_splitViewer.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_viewer.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c3
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c3
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_texture.c3
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_image.c4
-rw-r--r--source/blender/render/intern/source/envmap.c3
-rw-r--r--source/blender/render/intern/source/imagetexture.c81
-rw-r--r--source/blender/render/intern/source/pipeline.c1
-rw-r--r--source/blender/render/intern/source/render_texture.c30
-rw-r--r--source/blender/render/intern/source/rendercore.c28
-rw-r--r--source/blender/render/intern/source/voxeldata.c11
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c2
-rw-r--r--source/creator/creator.c1
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp3
-rw-r--r--source/gameengine/Ketsji/BL_Texture.cpp20
52 files changed, 604 insertions, 292 deletions
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index a2a741935a1..f935858f8ba 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -625,7 +625,7 @@ __device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_facto
#else
*N = sd->N;
- if(CLOSURE_IS_DIFFUSE(sd->closure.type))
+ if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type))
return sd->closure.weight*ao_factor;
else if(CLOSURE_IS_AMBIENT_OCCLUSION(sd->closure.type))
return sd->closure.weight;
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 1875fd66628..1f9630d9fce 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -48,6 +48,9 @@ struct Main;
#define IMA_MAX_SPACE 64
+void BKE_images_init(void);
+void BKE_images_exit(void);
+
/* call from library */
void BKE_image_free(struct Image *me);
@@ -133,14 +136,13 @@ enum {
#define IMA_CHAN_FLAG_RGB 2
#define IMA_CHAN_FLAG_ALPHA 4
-/* depending Image type, and (optional) ImageUser setting it returns ibuf */
-/* always call to make signals work */
-struct ImBuf *BKE_image_get_ibuf(struct Image *ima, struct ImageUser *iuser);
+/* checks whether there's an image buffer for given image and user */
+int BKE_image_has_ibuf(struct Image *ima, struct ImageUser *iuser);
/* same as above, but can be used to retrieve images being rendered in
* a thread safe way, always call both acquire and release */
struct ImBuf *BKE_image_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, void **lock_r);
-void BKE_image_release_ibuf(struct Image *ima, void *lock);
+void BKE_image_release_ibuf(struct Image *ima, struct ImBuf *ibuf, void *lock);
/* returns a new image or NULL if it can't load */
struct Image *BKE_image_load(const char *filepath);
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index e1e868b234e..40cd5b3d403 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -70,6 +70,7 @@
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
+#include "BKE_image.h"
#include "BKE_ipo.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -113,6 +114,7 @@ void free_blender(void)
BKE_spacetypes_free(); /* after free main, it uses space callbacks */
IMB_exit();
+ BKE_images_exit();
BLI_callback_global_finalize();
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 98b206712d6..f310895f590 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1287,8 +1287,6 @@ unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side)
texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
- BKE_image_get_ibuf(mtex->tex->ima, NULL);
-
/*do normalized cannonical view coords for texture*/
for (y = -1.0, iy = 0; iy < side; iy++, y += step) {
for (x = -1.0, ix = 0; ix < side; ix++, x += step) {
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 55d37c91859..993d72ab2e7 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -100,6 +100,8 @@
#include "WM_api.h"
+static SpinLock image_spin;
+
/* max int, to indicate we don't store sequences in ibuf */
#define IMA_NO_INDEX 0x7FEFEFEF
@@ -108,6 +110,16 @@
#define IMA_INDEX_FRAME(index) (index >> 10)
#define IMA_INDEX_PASS(index) (index & ~1023)
+void BKE_images_init(void)
+{
+ BLI_spin_init(&image_spin);
+}
+
+void BKE_images_exit(void)
+{
+ BLI_spin_end(&image_spin);
+}
+
/* ******** IMAGE PROCESSING ************* */
static void de_interlace_ng(struct ImBuf *ibuf) /* neogeo fields */
@@ -168,13 +180,14 @@ static void de_interlace_st(struct ImBuf *ibuf) /* standard fields */
void BKE_image_de_interlace(Image *ima, int odd)
{
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ibuf) {
if (odd)
de_interlace_st(ibuf);
else
de_interlace_ng(ibuf);
}
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
/* ***************** ALLOC & FREE, DATA MANAGING *************** */
@@ -260,8 +273,9 @@ static ImBuf *image_get_ibuf(Image *ima, int index, int frame)
/* this function is intended to be thread safe. with IMA_NO_INDEX this
* should be OK, but when iterating over the list this is more tricky
* */
- if (index == IMA_NO_INDEX)
+ if (index == IMA_NO_INDEX) {
return ima->ibufs.first;
+ }
else {
ImBuf *ibuf;
@@ -269,9 +283,9 @@ static ImBuf *image_get_ibuf(Image *ima, int index, int frame)
for (ibuf = ima->ibufs.first; ibuf; ibuf = ibuf->next)
if (ibuf->index == index)
return ibuf;
-
- return NULL;
}
+
+ return NULL;
}
/* no ima->ibuf anymore, but listbase */
@@ -534,7 +548,7 @@ int BKE_image_scale(Image *image, int width, int height)
ibuf->userflags |= IB_BITMAPDIRTY;
}
- BKE_image_release_ibuf(image, lock);
+ BKE_image_release_ibuf(image, ibuf, lock);
return (ibuf != NULL);
}
@@ -2081,6 +2095,8 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
if (ima == NULL)
return;
+ BLI_spin_lock(&image_spin);
+
switch (signal) {
case IMA_SIGNAL_FREE:
image_free_buffers(ima);
@@ -2167,6 +2183,8 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
}
}
}
+
+ BLI_spin_unlock(&image_spin);
}
/* if layer or pass changes, we need an index for the imbufs list */
@@ -2320,7 +2338,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
if (ibuf) {
#ifdef WITH_OPENEXR
- /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */
+ /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */
if (ibuf->ftype == OPENEXR && ibuf->userdata) {
image_create_multilayer(ima, ibuf, frame);
ima->type = IMA_TYPE_MULTILAYER;
@@ -2482,7 +2500,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
}
if (ibuf) {
- /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */
+ /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */
if (ibuf->ftype == OPENEXR && ibuf->userdata) {
image_create_multilayer(ima, ibuf, cfra);
ima->type = IMA_TYPE_MULTILAYER;
@@ -2751,38 +2769,32 @@ static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame
* a big bottleneck */
}
- *frame_r = frame;
- *index_r = index;
+ if (frame_r)
+ *frame_r = frame;
+
+ if (index_r)
+ *index_r = index;
return ibuf;
}
-/* Checks optional ImageUser and verifies/creates ImBuf. */
-/* use this one if you want to get a render result in progress,
- * if not, use BKE_image_get_ibuf which doesn't require a release */
-ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
+/* Checks optional ImageUser and verifies/creates ImBuf.
+ *
+ * not thread-safe, so callee should worry about thread locks
+ */
+static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
{
ImBuf *ibuf = NULL;
float color[] = {0, 0, 0, 1};
int frame = 0, index = 0;
- /* This function is intended to be thread-safe. It postpones the mutex lock
- * until it needs to load the image, if the image is already there it
- * should just get the pointer and return. The reason is that a lot of mutex
- * locks appears to be very slow on certain multicore macs, causing a render
- * with image textures to actually slow down as more threads are used.
- *
- * Note that all the image loading functions should also make sure they do
- * things in a threadsafe way for image_get_ibuf_threadsafe to work correct.
- * That means, the last two steps must be, 1) add the ibuf to the list and
- * 2) set ima/iuser->ok to 0 to IMA_OK_LOADED */
-
if (lock_r)
*lock_r = NULL;
/* quick reject tests */
if (ima == NULL)
return NULL;
+
if (iuser) {
if (iuser->ok == 0)
return NULL;
@@ -2790,95 +2802,71 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
else if (ima->ok == 0)
return NULL;
- /* try to get the ibuf without locking */
ibuf = image_get_ibuf_threadsafe(ima, iuser, &frame, &index);
if (ibuf == NULL) {
- /* couldn't get ibuf and image is not ok, so let's lock and try to
- * load the image */
- BLI_lock_thread(LOCK_IMAGE);
-
- /* need to check ok flag and loading ibuf again, because the situation
- * might have changed in the meantime */
- if (iuser) {
- if (iuser->ok == 0) {
- BLI_unlock_thread(LOCK_IMAGE);
- return NULL;
+ /* we are sure we have to load the ibuf, using source and type */
+ if (ima->source == IMA_SRC_MOVIE) {
+ /* source is from single file, use flipbook to store ibuf */
+ ibuf = image_load_movie_file(ima, iuser, frame);
+ }
+ else if (ima->source == IMA_SRC_SEQUENCE) {
+ if (ima->type == IMA_TYPE_IMAGE) {
+ /* regular files, ibufs in flipbook, allows saving */
+ ibuf = image_load_sequence_file(ima, iuser, frame);
}
- }
- else if (ima->ok == 0) {
- BLI_unlock_thread(LOCK_IMAGE);
- return NULL;
- }
-
- ibuf = image_get_ibuf_threadsafe(ima, iuser, &frame, &index);
-
- if (ibuf == NULL) {
- /* we are sure we have to load the ibuf, using source and type */
- if (ima->source == IMA_SRC_MOVIE) {
- /* source is from single file, use flipbook to store ibuf */
- ibuf = image_load_movie_file(ima, iuser, frame);
- }
- else if (ima->source == IMA_SRC_SEQUENCE) {
- if (ima->type == IMA_TYPE_IMAGE) {
- /* regular files, ibufs in flipbook, allows saving */
- ibuf = image_load_sequence_file(ima, iuser, frame);
- }
- /* no else; on load the ima type can change */
- if (ima->type == IMA_TYPE_MULTILAYER) {
- /* only 1 layer/pass stored in imbufs, no exrhandle anim storage, no saving */
- ibuf = image_load_sequence_multilayer(ima, iuser, frame);
- }
- }
- else if (ima->source == IMA_SRC_FILE) {
-
- if (ima->type == IMA_TYPE_IMAGE)
- ibuf = image_load_image_file(ima, iuser, frame); /* cfra only for '#', this global is OK */
- /* no else; on load the ima type can change */
- if (ima->type == IMA_TYPE_MULTILAYER)
- /* keeps render result, stores ibufs in listbase, allows saving */
- ibuf = image_get_ibuf_multilayer(ima, iuser);
-
+ /* no else; on load the ima type can change */
+ if (ima->type == IMA_TYPE_MULTILAYER) {
+ /* only 1 layer/pass stored in imbufs, no exrhandle anim storage, no saving */
+ ibuf = image_load_sequence_multilayer(ima, iuser, frame);
}
- else if (ima->source == IMA_SRC_GENERATED) {
- /* generated is: ibuf is allocated dynamically */
- /* UV testgrid or black or solid etc */
- if (ima->gen_x == 0) ima->gen_x = 1024;
- if (ima->gen_y == 0) ima->gen_y = 1024;
- ibuf = add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 24, (ima->gen_flag & IMA_GEN_FLOAT) != 0, ima->gen_type,
- color, &ima->colorspace_settings);
- image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
- ima->ok = IMA_OK_LOADED;
+ }
+ else if (ima->source == IMA_SRC_FILE) {
+
+ if (ima->type == IMA_TYPE_IMAGE)
+ ibuf = image_load_image_file(ima, iuser, frame); /* cfra only for '#', this global is OK */
+ /* no else; on load the ima type can change */
+ if (ima->type == IMA_TYPE_MULTILAYER)
+ /* keeps render result, stores ibufs in listbase, allows saving */
+ ibuf = image_get_ibuf_multilayer(ima, iuser);
+
+ }
+ else if (ima->source == IMA_SRC_GENERATED) {
+ /* generated is: ibuf is allocated dynamically */
+ /* UV testgrid or black or solid etc */
+ if (ima->gen_x == 0) ima->gen_x = 1024;
+ if (ima->gen_y == 0) ima->gen_y = 1024;
+ ibuf = add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 24, (ima->gen_flag & IMA_GEN_FLOAT) != 0, ima->gen_type,
+ color, &ima->colorspace_settings);
+ image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+ ima->ok = IMA_OK_LOADED;
+ }
+ else if (ima->source == IMA_SRC_VIEWER) {
+ if (ima->type == IMA_TYPE_R_RESULT) {
+ /* always verify entirely, and potentially
+ * returns pointer to release later */
+ ibuf = image_get_render_result(ima, iuser, lock_r);
}
- else if (ima->source == IMA_SRC_VIEWER) {
- if (ima->type == IMA_TYPE_R_RESULT) {
- /* always verify entirely, and potentially
- * returns pointer to release later */
- ibuf = image_get_render_result(ima, iuser, lock_r);
- }
- else if (ima->type == IMA_TYPE_COMPOSITE) {
- /* requires lock/unlock, otherwise don't return image */
- if (lock_r) {
- /* unlock in BKE_image_release_ibuf */
- BLI_lock_thread(LOCK_VIEWER);
- *lock_r = ima;
-
- /* XXX anim play for viewer nodes not yet supported */
- frame = 0; // XXX iuser?iuser->framenr:0;
- ibuf = image_get_ibuf(ima, 0, frame);
-
- if (!ibuf) {
- /* Composite Viewer, all handled in compositor */
- /* fake ibuf, will be filled in compositor */
- ibuf = IMB_allocImBuf(256, 256, 32, IB_rect);
- image_assign_ibuf(ima, ibuf, 0, frame);
- }
+ else if (ima->type == IMA_TYPE_COMPOSITE) {
+ /* requires lock/unlock, otherwise don't return image */
+ if (lock_r) {
+ /* unlock in BKE_image_release_ibuf */
+ BLI_lock_thread(LOCK_VIEWER);
+ *lock_r = ima;
+
+ /* XXX anim play for viewer nodes not yet supported */
+ frame = 0; // XXX iuser?iuser->framenr:0;
+ ibuf = image_get_ibuf(ima, 0, frame);
+
+ if (!ibuf) {
+ /* Composite Viewer, all handled in compositor */
+ /* fake ibuf, will be filled in compositor */
+ ibuf = IMB_allocImBuf(256, 256, 32, IB_rect);
+ image_assign_ibuf(ima, ibuf, 0, frame);
}
}
}
}
-
- BLI_unlock_thread(LOCK_IMAGE);
}
BKE_image_tag_time(ima);
@@ -2886,23 +2874,66 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
return ibuf;
}
-void BKE_image_release_ibuf(Image *ima, void *lock)
+/* return image buffer for given image and user
+ *
+ * - will lock render result if image type is render result and lock is not NULL
+ * - will return NULL if image type if render or composite result and lock is NULL
+ *
+ * references the result, BKE_image_release_ibuf should be used to de-reference
+ */
+ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
{
- /* for getting image during threaded render / compositing, need to release */
- if (lock == ima) {
- BLI_unlock_thread(LOCK_VIEWER); /* viewer image */
+ ImBuf *ibuf;
+
+ BLI_spin_lock(&image_spin);
+
+ ibuf = image_acquire_ibuf(ima, iuser, lock_r);
+
+ if (ibuf)
+ IMB_refImBuf(ibuf);
+
+ BLI_spin_unlock(&image_spin);
+
+ return ibuf;
+}
+
+void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
+{
+ if (lock) {
+ /* for getting image during threaded render / compositing, need to release */
+ if (lock == ima) {
+ BLI_unlock_thread(LOCK_VIEWER); /* viewer image */
+ }
+ else if (lock) {
+ RE_ReleaseResultImage(lock); /* render result */
+ BLI_unlock_thread(LOCK_VIEWER); /* view image imbuf */
+ }
}
- else if (lock) {
- RE_ReleaseResultImage(lock); /* render result */
- BLI_unlock_thread(LOCK_VIEWER); /* view image imbuf */
+
+ if (ibuf) {
+ BLI_spin_lock(&image_spin);
+ IMB_freeImBuf(ibuf);
+ BLI_spin_unlock(&image_spin);
}
}
-/* warning, this can allocate generated images */
-ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
+/* checks whether there's an image buffer for given image and user */
+int BKE_image_has_ibuf(Image *ima, ImageUser *iuser)
{
- /* here (+fie_ima/2-1) makes sure that division happens correctly */
- return BKE_image_acquire_ibuf(ima, iuser, NULL);
+ ImBuf *ibuf = image_get_ibuf_threadsafe(ima, iuser, NULL, NULL);
+
+ if (!ibuf) {
+ BLI_spin_lock(&image_spin);
+
+ ibuf = image_get_ibuf_threadsafe(ima, iuser, NULL, NULL);
+
+ if (!ibuf)
+ ibuf = image_acquire_ibuf(ima, iuser, NULL);
+
+ BLI_spin_unlock(&image_spin);
+ }
+
+ return ibuf != NULL;
}
int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, int fieldnr, short *r_is_in_range)
@@ -3020,7 +3051,7 @@ int BKE_image_has_alpha(struct Image *image)
ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
planes = (ibuf ? ibuf->planes : 0);
- BKE_image_release_ibuf(image, lock);
+ BKE_image_release_ibuf(image, ibuf, lock);
if (planes == 32)
return 1;
@@ -3044,7 +3075,7 @@ void BKE_image_get_size(Image *image, ImageUser *iuser, int *width, int *height)
*height = IMG_SIZE_FALLBACK;
}
- BKE_image_release_ibuf(image, lock);
+ BKE_image_release_ibuf(image, ibuf, lock);
}
void BKE_image_get_size_fl(Image *image, ImageUser *iuser, float size[2])
diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h
index 9cd801f819d..ec8e567c0ef 100644
--- a/source/blender/blenlib/BLI_threads.h
+++ b/source/blender/blenlib/BLI_threads.h
@@ -37,6 +37,10 @@ extern "C" {
#include <pthread.h>
+#ifdef __APPLE__
+#include <libkern/OSAtomic.h>
+#endif
+
/* for tables, button in UI, etc */
#define BLENDER_MAX_THREADS 64
@@ -92,6 +96,19 @@ void BLI_mutex_lock(ThreadMutex *mutex);
void BLI_mutex_unlock(ThreadMutex *mutex);
void BLI_mutex_end(ThreadMutex *mutex);
+/* Spin Lock */
+
+#ifdef __APPLE__
+typedef OSSpinLock SpinLock;
+#else
+typedef pthread_spinlock_t SpinLock;
+#endif
+
+void BLI_spin_init(SpinLock *spin);
+void BLI_spin_lock(SpinLock *spin);
+void BLI_spin_unlock(SpinLock *spin);
+void BLI_spin_end(SpinLock *spin);
+
/* Read/Write Mutex Lock */
#define THREAD_LOCK_READ 1
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index 66527b9b92a..146e1d531f1 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -400,6 +400,42 @@ void BLI_mutex_end(ThreadMutex *mutex)
pthread_mutex_destroy(mutex);
}
+/* Spin Locks */
+
+void BLI_spin_init(SpinLock *spin)
+{
+#ifdef __APPLE__
+ *spin = OS_SPINLOCK_INIT;
+#else
+ pthread_spin_init(spin, 0);
+#endif
+}
+
+void BLI_spin_lock(SpinLock *spin)
+{
+#ifdef __APPLE__
+ OSSpinLockLock(spin);
+#else
+ pthread_spin_lock(spin);
+#endif
+}
+
+void BLI_spin_unlock(SpinLock *spin)
+{
+#ifdef __APPLE__
+ OSSpinLockUnlock(spin);
+#else
+ pthread_spin_unlock(spin);
+#endif
+}
+
+void BLI_spin_end(SpinLock *spin)
+{
+#ifndef __APPLE__
+ pthread_spin_destroy(spin);
+#endif
+}
+
/* Read/Write Mutex Lock */
void BLI_rw_mutex_init(ThreadRWMutex *mutex)
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 30331713463..03e5a1d2525 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3043,7 +3043,7 @@ static void direct_link_image(FileData *fd, Image *ima)
link_ibuf_list(fd, &ima->ibufs);
else
ima->ibufs.first = ima->ibufs.last = NULL;
-
+
/* if not restored, we keep the binded opengl index */
if (ima->ibufs.first == NULL) {
ima->bindcode = 0;
diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp
index 2e0c0f1ea57..aba290f5ce4 100644
--- a/source/blender/collada/ImageExporter.cpp
+++ b/source/blender/collada/ImageExporter.cpp
@@ -61,7 +61,7 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
if (not_yet_exported) {
- ImBuf *imbuf = BKE_image_get_ibuf(image, NULL);
+ ImBuf *imbuf = BKE_image_acquire_ibuf(image, NULL, NULL);
if (!imbuf) {
fprintf(stderr, "Collada export: image does not exist:\n%s\n", image->name);
return;
@@ -147,6 +147,8 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
img.add(mSW);
fprintf(stdout, "Collada export: Added image: %s\n", export_file);
mImages.push_back(translated_name);
+
+ BKE_image_release_ibuf(image, imbuf, NULL);
}
}
diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp
index 4ebd28d710a..729cb1b70a0 100644
--- a/source/blender/compositor/nodes/COM_ImageNode.cpp
+++ b/source/blender/compositor/nodes/COM_ImageNode.cpp
@@ -73,7 +73,7 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
/* force a load, we assume iuser index will be set OK anyway */
if (image && image->type == IMA_TYPE_MULTILAYER) {
bool is_multilayer_ok = false;
- BKE_image_get_ibuf(image, imageuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, imageuser, NULL);
if (image->rr) {
RenderLayer *rl = (RenderLayer *)BLI_findlink(&image->rr->layers, imageuser->layer);
if (rl) {
@@ -118,6 +118,7 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c
}
}
}
+ BKE_image_release_ibuf(image, ibuf, NULL);
/* without this, multilayer that fail to load will crash blender [#32490] */
if (is_multilayer_ok == false) {
diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp
index fb3efbb67ed..a7743cd7668 100644
--- a/source/blender/compositor/operations/COM_ImageOperation.cpp
+++ b/source/blender/compositor/operations/COM_ImageOperation.cpp
@@ -65,7 +65,7 @@ ImBuf *BaseImageOperation::getImBuf()
{
ImBuf *ibuf;
- ibuf = BKE_image_get_ibuf(this->m_image, this->m_imageUser);
+ ibuf = BKE_image_acquire_ibuf(this->m_image, this->m_imageUser, NULL);
if (ibuf == NULL || (ibuf->rect == NULL && ibuf->rect_float == NULL)) {
return NULL;
}
@@ -93,6 +93,7 @@ void BaseImageOperation::initExecution()
void BaseImageOperation::deinitExecution()
{
this->m_imageBuffer = NULL;
+ IMB_freeImBuf(this->m_buffer);
}
void BaseImageOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
@@ -106,6 +107,8 @@ void BaseImageOperation::determineResolution(unsigned int resolution[2], unsigne
resolution[0] = stackbuf->x;
resolution[1] = stackbuf->y;
}
+
+ IMB_freeImBuf(stackbuf);
}
void ImageOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
index 4d4c1199f3e..cc313512316 100644
--- a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
@@ -87,20 +87,16 @@ void ViewerBaseOperation::initImage()
/* now we combine the input with ibuf */
this->m_outputBuffer = ibuf->rect_float;
- /* needed for display buffer update
- *
- * no need to lock / reference the image buffer because it's seems
- * to be the single place which changes buffers of viewer image
- * which is this node
- */
+ /* needed for display buffer update */
this->m_ibuf = ibuf;
if (m_doDepthBuffer) {
this->m_depthBuffer = ibuf->zbuf_float;
}
- BKE_image_release_ibuf(this->m_image, this->m_lock);
+ BKE_image_release_ibuf(this->m_image, this->m_ibuf, this->m_lock);
}
+
void ViewerBaseOperation:: updateImage(rcti *rect)
{
IMB_partial_display_buffer_update(this->m_ibuf, this->m_outputBuffer, NULL, getWidth(), 0, 0,
diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h
index a50b33966c6..9b726cea56c 100644
--- a/source/blender/editors/include/ED_image.h
+++ b/source/blender/editors/include/ED_image.h
@@ -49,7 +49,7 @@ void ED_space_image_set_mask(struct bContext *C, struct SpaceImage *sim
int ED_space_image_color_sample(struct SpaceImage *sima, struct ARegion *ar, int mval[2], float r_col[3]);
struct ImBuf *ED_space_image_acquire_buffer(struct SpaceImage *sima, void **lock_r);
-void ED_space_image_release_buffer(struct SpaceImage *sima, void *lock);
+void ED_space_image_release_buffer(struct SpaceImage *sima, struct ImBuf *ibuf, void *lock);
int ED_space_image_has_buffer(struct SpaceImage *sima);
void ED_space_image_get_size(struct SpaceImage *sima, int *width, int *height);
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index 032314d06f3..e144c38a350 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -114,7 +114,7 @@ typedef struct {
} MultiresBakeRender;
typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
- const int face_index, const int lvl, const float st[2],
+ ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
float tangmat[3][3], const int x, const int y);
typedef void * (*MInitBakeData)(MultiresBakeRender *bkr, Image *ima);
@@ -133,6 +133,7 @@ typedef struct {
DerivedMesh *lores_dm, *hires_dm;
int lvl;
void *bake_data;
+ ImBuf *ibuf;
MPassKnownData pass_data;
} MResolvePixelData;
@@ -257,7 +258,7 @@ static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
/* sequence end */
data->pass_data(data->lores_dm, data->hires_dm, data->bake_data,
- data->face_index, data->lvl, st, to_tang, x, y);
+ data->ibuf, data->face_index, data->lvl, st, to_tang, x, y);
}
static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y)
@@ -368,7 +369,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, MPassKnownData
MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData)
{
DerivedMesh *dm = bkr->lores_dm;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
const int lvl = bkr->lvl;
const int tot_face = dm->getNumTessFaces(dm);
MVert *mvert = dm->getVertArray(dm);
@@ -414,6 +415,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, MPassKnownData
continue;
data.face_index = f;
+ data.ibuf = ibuf;
/* might support other forms of diagonal splits later on such as
* split by shortest diagonal.*/
@@ -449,6 +451,8 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, MPassKnownData
if (freeBakeData)
freeBakeData(data.bake_data);
}
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
/* mode = 0: interpolate normals,
@@ -579,7 +583,7 @@ static void interp_barycentric_mface(DerivedMesh *dm, MFace *mface, const float
static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
{
MHeightBakeData *height_data;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
DerivedMesh *lodm = bkr->lores_dm;
height_data = MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData");
@@ -609,6 +613,8 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
height_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
height_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX);
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
return (void *)height_data;
}
@@ -635,7 +641,7 @@ static void free_normal_data(void *bake_data)
static void apply_heights_data(void *bake_data)
{
MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
- ImBuf *ibuf = BKE_image_get_ibuf(height_data->ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(height_data->ima, NULL, NULL);
int x, y, i;
float height, *heights = height_data->heights;
float min = height_data->height_min, max = height_data->height_max;
@@ -667,6 +673,8 @@ static void apply_heights_data(void *bake_data)
}
ibuf->userflags = IB_RECT_INVALID | IB_DISPLAY_BUFFER_INVALID;
+
+ BKE_image_release_ibuf(height_data->ima, ibuf, NULL);
}
static void free_heights_data(void *bake_data)
@@ -687,13 +695,11 @@ static void free_heights_data(void *bake_data)
* mesh to make texture smoother) let's call this point p0 and n.
* - height wound be dot(n, p1-p0) */
static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
- const int face_index, const int lvl, const float st[2],
+ ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
float UNUSED(tangmat[3][3]), const int x, const int y)
{
MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
MFace mface;
- Image *ima = mtface[face_index].tpage;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
float uv[2], *st0, *st1, *st2, *st3;
int pixel = ibuf->x * y + x;
@@ -764,13 +770,11 @@ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm,
* - multiply it by tangmat
* - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */
static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
- const int face_index, const int lvl, const float st[2],
+ ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
float tangmat[3][3], const int x, const int y)
{
MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
MFace mface;
- Image *ima = mtface[face_index].tpage;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
float uv[2], *st0, *st1, *st2, *st3;
int pixel = ibuf->x * y + x;
@@ -853,7 +857,7 @@ static void bake_images(MultiresBakeRender *bkr)
for (link = bkr->image.first; link; link = link->next) {
Image *ima = (Image *)link->data;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ibuf->x > 0 && ibuf->y > 0) {
ibuf->userdata = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask");
@@ -869,6 +873,8 @@ static void bake_images(MultiresBakeRender *bkr)
}
}
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
ima->id.flag |= LIB_DOIT;
}
}
@@ -879,7 +885,7 @@ static void finish_images(MultiresBakeRender *bkr)
for (link = bkr->image.first; link; link = link->next) {
Image *ima = (Image *)link->data;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ibuf->x <= 0 || ibuf->y <= 0)
continue;
@@ -900,6 +906,8 @@ static void finish_images(MultiresBakeRender *bkr)
MEM_freeN(ibuf->userdata);
ibuf->userdata = NULL;
}
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
@@ -974,7 +982,7 @@ static int multiresbake_check(bContext *C, wmOperator *op)
ok = 0;
}
else {
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (!ibuf) {
BKE_report(op->reports, RPT_ERROR, "Baking should happen to image with image buffer");
@@ -991,6 +999,8 @@ static int multiresbake_check(bContext *C, wmOperator *op)
if (!ok)
BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type");
}
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
}
@@ -1061,10 +1071,12 @@ static void clear_images(MTFace *mtface, int totface)
Image *ima = mtface[a].tpage;
if ((ima->id.flag & LIB_DOIT) == 0) {
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
ima->id.flag |= LIB_DOIT;
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
@@ -1358,7 +1370,7 @@ static void finish_bake_internal(BakeRender *bkr)
/* force OpenGL reload and mipmap recalc */
for (ima = G.main->image.first; ima; ima = ima->id.next) {
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
/* some of the images could have been changed during bake,
* so recreate mipmaps regardless bake result status
@@ -1383,6 +1395,8 @@ static void finish_bake_internal(BakeRender *bkr)
ibuf->userdata = NULL;
}
}
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index c0c2195592b..4d6b9ed10bb 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -1380,7 +1380,7 @@ static void UNUSED_FUNCTION(image_aspect) (Scene * scene, View3D * v3d)
if (ma->mtex[b] && ma->mtex[b]->tex) {
tex = ma->mtex[b]->tex;
if (tex->type == TEX_IMAGE && tex->ima) {
- ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, NULL, NULL);
/* texturespace */
space = 1.0;
@@ -1402,6 +1402,8 @@ static void UNUSED_FUNCTION(image_aspect) (Scene * scene, View3D * v3d)
done = TRUE;
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
+
+ BKE_image_release_ibuf(tex->ima, ibuf, NULL);
}
}
if (done) break;
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 4b177629f72..7b67f63c646 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -375,7 +375,7 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
/* make jobs timer to send notifier */
*(rj->do_update) = TRUE;
}
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
}
static void render_startjob(void *rjv, short *stop, short *do_update, float *progress)
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index e4592a4f77e..effb984c083 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -288,7 +288,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
}
}
- BKE_image_release_ibuf(oglrender->ima, lock);
+ BKE_image_release_ibuf(oglrender->ima, ibuf, lock);
}
static int screen_opengl_render_init(bContext *C, wmOperator *op)
@@ -613,7 +613,7 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op)
IMB_freeImBuf(ibuf);
}
- BKE_image_release_ibuf(oglrender->ima, lock);
+ BKE_image_release_ibuf(oglrender->ima, ibuf, lock);
/* movie stats prints have no line break */
printf("\n");
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index b119165fbd0..a864fe306b3 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -934,13 +934,15 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat
/* elubie: this needs to be changed: here image is always loaded if not
* already there. Very expensive for large images. Need to find a way to
* only get existing ibuf */
- ibuf = BKE_image_get_ibuf(ima, &iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
if (ibuf == NULL || ibuf->rect == NULL)
return;
icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect);
*do_update = TRUE;
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
else if (idtype == ID_BR) {
Brush *br = (Brush *)id;
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 4b400623920..192ad35109a 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -500,7 +500,7 @@ static void image_undo_restore(bContext *C, ListBase *lb)
ima = BLI_findstring(&bmain->image, tile->idname, offsetof(ID, name));
}
- ibuf = BKE_image_get_ibuf(ima, NULL);
+ ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ima && ibuf && strcmp(tile->ibufname, ibuf->name) != 0) {
/* current ImBuf filename was changed, probably current frame
@@ -508,19 +508,27 @@ static void image_undo_restore(bContext *C, ListBase *lb)
* full image user (which isn't so obvious, btw) try to find ImBuf with
* matched file name in list of already loaded images */
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
ibuf = BLI_findstring(&ima->ibufs, tile->ibufname, offsetof(ImBuf, name));
}
- if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float))
+ if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
continue;
+ }
- if (ima->gen_type != tile->gen_type || ima->source != tile->source)
+ if (ima->gen_type != tile->gen_type || ima->source != tile->source) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
continue;
+ }
use_float = ibuf->rect_float ? 1 : 0;
- if (use_float != tile->use_float)
+ if (use_float != tile->use_float) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
continue;
+ }
undo_copy_tile(tile, tmpibuf, ibuf, 1);
@@ -530,6 +538,8 @@ static void image_undo_restore(bContext *C, ListBase *lb)
if (ibuf->mipmap[0])
ibuf->userflags |= IB_MIPMAP_INVALID; /* force mipmap recreatiom */
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
IMB_freeImBuf(tmpibuf);
@@ -1398,8 +1408,8 @@ static float project_paint_uvpixel_mask(
Image *other_tpage = project_paint_face_image(ps, ps->dm_mtface_stencil, face_index);
const MTFace *tf_other = ps->dm_mtface_stencil + face_index;
- if (other_tpage && (ibuf_other = BKE_image_get_ibuf(other_tpage, NULL))) {
- /* BKE_image_get_ibuf - TODO - this may be slow */
+ if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) {
+ /* BKE_image_acquire_ibuf - TODO - this may be slow */
unsigned char rgba_ub[4];
float rgba_f[4];
@@ -1411,7 +1421,9 @@ static float project_paint_uvpixel_mask(
else { /* from char to float */
mask = ((rgba_ub[0] + rgba_ub[1] + rgba_ub[2]) / (256 * 3.0f)) * (rgba_ub[3] / 256.0f);
}
-
+
+ BKE_image_release_ibuf(other_tpage, ibuf_other, NULL);
+
if (!ps->do_layer_stencil_inv) /* matching the gimps layer mask black/white rules, white==full opacity */
mask = (1.0f - mask);
@@ -1579,8 +1591,8 @@ static ProjPixel *project_paint_uvpixel_init(
Image *other_tpage = project_paint_face_image(ps, ps->dm_mtface_clone, face_index);
const MTFace *tf_other = ps->dm_mtface_clone + face_index;
- if (other_tpage && (ibuf_other = BKE_image_get_ibuf(other_tpage, NULL))) {
- /* BKE_image_get_ibuf - TODO - this may be slow */
+ if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) {
+ /* BKE_image_acquire_ibuf - TODO - this may be slow */
if (ibuf->rect_float) {
if (ibuf_other->rect_float) { /* from float to float */
@@ -1602,6 +1614,8 @@ static ProjPixel *project_paint_uvpixel_init(
project_face_pixel(tf_other, ibuf_other, w, side, ((ProjPixelClone *)projPixel)->clonepx.ch, NULL);
}
}
+
+ BKE_image_release_ibuf(other_tpage, ibuf_other, NULL);
}
else {
if (ibuf->rect_float) {
@@ -3408,7 +3422,7 @@ static void project_paint_begin(ProjPaintState *ps)
image_index = BLI_linklist_index(image_LinkList, tpage);
- if (image_index == -1 && BKE_image_get_ibuf(tpage, NULL)) { /* MemArena dosnt have an append func */
+ if (image_index == -1 && BKE_image_has_ibuf(tpage, NULL)) { /* MemArena dosnt have an append func */
BLI_linklist_append(&image_LinkList, tpage);
image_index = ps->image_tot;
ps->image_tot++;
@@ -3431,7 +3445,7 @@ static void project_paint_begin(ProjPaintState *ps)
for (node = image_LinkList, i = 0; node; node = node->next, i++, projIma++) {
projIma->ima = node->link;
projIma->touch = 0;
- projIma->ibuf = BKE_image_get_ibuf(projIma->ima, NULL);
+ projIma->ibuf = BKE_image_acquire_ibuf(projIma->ima, NULL, NULL);
projIma->partRedrawRect = BLI_memarena_alloc(arena, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
memset(projIma->partRedrawRect, 0, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
}
@@ -3458,6 +3472,7 @@ static void project_paint_begin_clone(ProjPaintState *ps, int mouse[2])
static void project_paint_end(ProjPaintState *ps)
{
int a;
+ ProjPaintImage *projIma;
/* build undo data from original pixel colors */
if (U.uiflag & USER_GLOBALUNDO) {
@@ -3545,7 +3560,14 @@ static void project_paint_end(ProjPaintState *ps)
if (tmpibuf_float) IMB_freeImBuf(tmpibuf_float);
}
/* done calculating undo data */
-
+
+ /* dereference used image buffers */
+ for (a = 0, projIma = ps->projImages; a < ps->image_tot; a++, projIma++) {
+ BKE_image_release_ibuf(projIma->ima, projIma->ibuf, NULL);
+ }
+
+ BKE_image_release_ibuf(ps->reproject_image, ps->reproject_ibuf, NULL);
+
MEM_freeN(ps->screenCoords);
MEM_freeN(ps->bucketRect);
MEM_freeN(ps->bucketFaces);
@@ -4672,7 +4694,7 @@ static int texpaint_break_stroke(float *prevuv, float *fwuv, float *bkuv, float
static int imapaint_canvas_set(ImagePaintState *s, Image *ima)
{
- ImBuf *ibuf = BKE_image_get_ibuf(ima, s->sima ? &s->sima->iuser : NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
/* verify that we can paint and set canvas */
if (ima == NULL) {
@@ -4695,10 +4717,12 @@ static int imapaint_canvas_set(ImagePaintState *s, Image *ima)
/* set clone canvas */
if (s->tool == PAINT_TOOL_CLONE) {
ima = s->brush->clone.image;
- ibuf = BKE_image_get_ibuf(ima, s->sima ? &s->sima->iuser : NULL);
+ ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
- if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float))
+ if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return 0;
+ }
s->clonecanvas = ibuf;
@@ -4713,13 +4737,15 @@ static int imapaint_canvas_set(ImagePaintState *s, Image *ima)
return 1;
}
-static void imapaint_canvas_free(ImagePaintState *UNUSED(s))
+static void imapaint_canvas_free(ImagePaintState *s)
{
+ BKE_image_release_ibuf(s->image, s->canvas, NULL);
+ BKE_image_release_ibuf(s->brush->clone.image, s->clonecanvas, NULL);
}
static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter, Image *image, short texpaint, float *uv, double time, int update, float pressure)
{
- ImBuf *ibuf = BKE_image_get_ibuf(image, s->sima ? &s->sima->iuser : NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, s->sima ? &s->sima->iuser : NULL, NULL);
float pos[2];
int is_data;
@@ -4739,9 +4765,13 @@ static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter,
if (BKE_brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s, is_data == FALSE)) {
if (update)
imapaint_image_update(s->scene, s->sima, image, ibuf, texpaint);
+ BKE_image_release_ibuf(image, ibuf, NULL);
return 1;
}
- else return 0;
+ else {
+ BKE_image_release_ibuf(image, ibuf, NULL);
+ return 0;
+ }
}
static int imapaint_paint_stroke(ViewContext *vc, ImagePaintState *s, BrushPainter *painter, short texpaint, const int prevmval[2], const int mval[2], double time, float pressure)
@@ -4759,7 +4789,7 @@ static int imapaint_paint_stroke(ViewContext *vc, ImagePaintState *s, BrushPaint
ImBuf *ibuf;
newimage = imapaint_face_image(s, newfaceindex);
- ibuf = BKE_image_get_ibuf(newimage, s->sima ? &s->sima->iuser : NULL);
+ ibuf = BKE_image_acquire_ibuf(newimage, s->sima ? &s->sima->iuser : NULL, NULL);
if (ibuf && ibuf->rect)
imapaint_pick_uv(s->scene, s->ob, newfaceindex, mval, newuv);
@@ -4767,6 +4797,8 @@ static int imapaint_paint_stroke(ViewContext *vc, ImagePaintState *s, BrushPaint
newimage = NULL;
newuv[0] = newuv[1] = 0.0f;
}
+
+ BKE_image_release_ibuf(newimage, ibuf, NULL);
}
else
newuv[0] = newuv[1] = 0.0f;
@@ -5890,7 +5922,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
}
ps.reproject_image = image;
- ps.reproject_ibuf = BKE_image_get_ibuf(image, NULL);
+ ps.reproject_ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
if (ps.reproject_ibuf == NULL || ps.reproject_ibuf->rect == NULL) {
BKE_report(op->reports, RPT_ERROR, "Image data could not be found");
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index ae7a718ab5b..0a3db59096a 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -593,7 +593,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
if (ima->source == IMA_SRC_VIEWER) {
ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
image_info(scene, iuser, ima, ibuf, str);
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
uiItemL(layout, ima->id.name + 2, ICON_NONE);
uiItemL(layout, str, ICON_NONE);
@@ -663,7 +663,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
if (compact == 0) {
ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
image_info(scene, iuser, ima, ibuf, str);
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
uiItemL(layout, str, ICON_NONE);
}
}
@@ -722,7 +722,6 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
split = uiLayoutSplit(layout, 0.0f, FALSE);
col = uiLayoutColumn(split, TRUE);
- uiLayoutSetEnabled(col, 0);
uiItemR(col, &imaptr, "generated_width", 0, "X", ICON_NONE);
uiItemR(col, &imaptr, "generated_height", 0, "Y", ICON_NONE);
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 9fc2b981547..d565e6f9e9a 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -652,7 +652,7 @@ static unsigned char *get_alpha_clone_image(const bContext *C, Scene *scene, int
if (!brush || !brush->clone.image)
return NULL;
- ibuf = BKE_image_get_ibuf(brush->clone.image, NULL);
+ ibuf = BKE_image_acquire_ibuf(brush->clone.image, NULL, NULL);
if (!ibuf)
return NULL;
@@ -660,6 +660,7 @@ static unsigned char *get_alpha_clone_image(const bContext *C, Scene *scene, int
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
if (!display_buffer) {
+ BKE_image_release_ibuf(brush->clone.image, ibuf, NULL);
IMB_display_buffer_release(cache_handle);
return NULL;
@@ -669,8 +670,10 @@ static unsigned char *get_alpha_clone_image(const bContext *C, Scene *scene, int
IMB_display_buffer_release(cache_handle);
- if (!rect)
+ if (!rect) {
+ BKE_image_release_ibuf(brush->clone.image, ibuf, NULL);
return NULL;
+ }
*width = ibuf->x;
*height = ibuf->y;
@@ -684,6 +687,8 @@ static unsigned char *get_alpha_clone_image(const bContext *C, Scene *scene, int
cp += 4;
}
+ BKE_image_release_ibuf(brush->clone.image, ibuf, NULL);
+
return rect;
}
@@ -799,7 +804,7 @@ void draw_image_main(const bContext *C, ARegion *ar)
}
#endif
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
if (show_viewer) {
BLI_unlock_thread(LOCK_DRAW_IMAGE);
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index 4ca2f8888f8..c4e2230e7a7 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -117,8 +117,12 @@ ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **lock_r)
#endif
ibuf = BKE_image_acquire_ibuf(sima->image, &sima->iuser, lock_r);
- if (ibuf && (ibuf->rect || ibuf->rect_float))
- return ibuf;
+ if (ibuf) {
+ if (ibuf->rect || ibuf->rect_float)
+ return ibuf;
+
+ BKE_image_release_ibuf(sima->image, ibuf, NULL);
+ }
}
else
*lock_r = NULL;
@@ -126,10 +130,10 @@ ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **lock_r)
return NULL;
}
-void ED_space_image_release_buffer(SpaceImage *sima, void *lock)
+void ED_space_image_release_buffer(SpaceImage *sima, ImBuf *ibuf, void *lock)
{
if (sima && sima->image)
- BKE_image_release_ibuf(sima->image, lock);
+ BKE_image_release_ibuf(sima->image, ibuf, lock);
}
int ED_space_image_has_buffer(SpaceImage *sima)
@@ -140,7 +144,7 @@ int ED_space_image_has_buffer(SpaceImage *sima)
ibuf = ED_space_image_acquire_buffer(sima, &lock);
has_buffer = (ibuf != NULL);
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
return has_buffer;
}
@@ -175,7 +179,7 @@ void ED_space_image_get_size(SpaceImage *sima, int *width, int *height)
*height = IMG_SIZE_FALLBACK;
}
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
}
void ED_space_image_get_size_fl(SpaceImage *sima, float size[2])
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index ce3c6e1fd26..d4f24babff6 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -167,7 +167,7 @@ static int space_image_file_exists_poll(bContext *C)
ret = TRUE;
}
}
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
return ret;
}
@@ -1188,7 +1188,7 @@ static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima,
BKE_color_managed_view_settings_copy(&simopts->im_format.view_settings, &scene->view_settings);
}
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
return (ibuf != NULL);
}
@@ -1328,7 +1328,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
IMB_freeImBuf(colormanaged_ibuf);
}
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
}
static void image_save_as_free(wmOperator *op)
@@ -1743,17 +1743,14 @@ void IMAGE_OT_new(wmOperatorType *ot)
static int image_invert_poll(bContext *C)
{
Image *ima = CTX_data_edit_image(C);
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
-
- if (ibuf != NULL)
- return 1;
- return 0;
+
+ return BKE_image_has_ibuf(ima, NULL);
}
static int image_invert_exec(bContext *C, wmOperator *op)
{
Image *ima = CTX_data_edit_image(C);
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
/* flags indicate if this channel should be inverted */
const short r = RNA_boolean_get(op->ptr, "invert_r");
@@ -1792,6 +1789,7 @@ static int image_invert_exec(bContext *C, wmOperator *op)
}
}
else {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return OPERATOR_CANCELLED;
}
@@ -1800,6 +1798,9 @@ static int image_invert_exec(bContext *C, wmOperator *op)
ibuf->userflags |= IB_MIPMAP_INVALID;
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
return OPERATOR_FINISHED;
}
@@ -1848,7 +1849,7 @@ static int image_pack_exec(bContext *C, wmOperator *op)
{
struct Main *bmain = CTX_data_main(C);
Image *ima = CTX_data_edit_image(C);
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
int as_png = RNA_boolean_get(op->ptr, "as_png");
if (!image_pack_test(C, op))
@@ -1865,30 +1866,38 @@ static int image_pack_exec(bContext *C, wmOperator *op)
ima->packedfile = newPackedFile(op->reports, ima->name, ID_BLEND_PATH(bmain, &ima->id));
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
-
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
return OPERATOR_FINISHED;
}
static int image_pack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
{
Image *ima = CTX_data_edit_image(C);
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf;
uiPopupMenu *pup;
uiLayout *layout;
int as_png = RNA_boolean_get(op->ptr, "as_png");
if (!image_pack_test(C, op))
return OPERATOR_CANCELLED;
-
+
+ ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+
if (!as_png && (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))) {
pup = uiPupMenuBegin(C, "OK", ICON_QUESTION);
layout = uiPupMenuLayout(pup);
uiItemBooleanO(layout, "Can't pack edited image from disk. Pack as internal PNG?", ICON_NONE, op->idname, "as_png", 1);
uiPupMenuEnd(C, pup);
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
return OPERATOR_CANCELLED;
}
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
return image_pack_exec(C, op);
}
@@ -2032,7 +2041,7 @@ int ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], floa
int ret = FALSE;
if (ibuf == NULL) {
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
return FALSE;
}
@@ -2058,7 +2067,7 @@ int ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], floa
}
}
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
return ret;
}
@@ -2074,7 +2083,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, wmEvent *event)
CurveMapping *curve_mapping = scene->view_settings.curve_mapping;
if (ibuf == NULL) {
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
info->draw = 0;
return;
}
@@ -2175,7 +2184,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, wmEvent *event)
info->draw = 0;
}
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
ED_area_tag_redraw(CTX_wm_area(C));
}
@@ -2266,12 +2275,12 @@ static int image_sample_line_exec(bContext *C, wmOperator *op)
float x1f, y1f, x2f, y2f;
if (ibuf == NULL) {
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
return OPERATOR_CANCELLED;
}
/* hmmmm */
if (ibuf->channels < 3) {
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
return OPERATOR_CANCELLED;
}
@@ -2288,7 +2297,7 @@ static int image_sample_line_exec(bContext *C, wmOperator *op)
/* reset y zoom */
hist->ymax = 1.0f;
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
ED_area_tag_redraw(CTX_wm_area(C));
@@ -2383,11 +2392,13 @@ static int image_record_composite_apply(bContext *C, wmOperator *op)
ED_area_tag_redraw(CTX_wm_area(C));
- ibuf = BKE_image_get_ibuf(sima->image, &sima->iuser);
+ ibuf = BKE_image_acquire_ibuf(sima->image, &sima->iuser, NULL);
/* save memory in flipbooks */
if (ibuf)
imb_freerectfloatImBuf(ibuf);
-
+
+ BKE_image_release_ibuf(sima->image, ibuf, NULL);
+
scene->r.cfra++;
return (scene->r.cfra <= rcd->efra);
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 4131cbfdd0d..ea696772957 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -780,7 +780,7 @@ static void image_scope_area_draw(const bContext *C, ARegion *ar)
}
scopes_update(&sima->scopes, ibuf, &scene->view_settings, &scene->display_settings);
}
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
ED_region_panels(C, ar, 1, NULL, -1);
}
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 131908bc9db..48b5eaf7b44 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -87,10 +87,14 @@ static int pack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
// first check for dirty images
for (ima = bmain->image.first; ima; ima = ima->id.next) {
if (ima->ibufs.first) { /* XXX FIX */
- ibuf = BKE_image_get_ibuf(ima, NULL);
+ ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
- if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
+ if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
break;
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index f808a08d5d2..e842bb5f262 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -3313,7 +3313,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
glPopMatrix();
}
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
}
}
@@ -3326,7 +3326,7 @@ static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode)
if (snode->flag & SNODE_BACKDRAW) {
Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ibuf) {
int x, y;
float zoom = 1.0;
@@ -3362,6 +3362,8 @@ static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode)
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
}
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c
index a4ea2e3e630..f386657c460 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.c
@@ -241,7 +241,7 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
if (ibuf == NULL) {
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
return OPERATOR_CANCELLED;
}
@@ -255,7 +255,7 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
nvm->ymin = -(ar->winy / 2) - (ibuf->y * (0.5f * snode->zoom)) + pad;
nvm->ymax = (ar->winy / 2) + (ibuf->y * (0.5f * snode->zoom)) - pad;
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
/* add modal handler */
WM_event_add_modal_handler(C, op);
@@ -403,7 +403,7 @@ int ED_space_node_color_sample(SpaceNode *snode, ARegion *ar, int mval[2], float
}
}
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
return ret;
}
@@ -493,7 +493,7 @@ static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
ED_node_sample_set(NULL);
}
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
ED_area_tag_redraw(CTX_wm_area(C));
}
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index cb5556396dd..f35a844afc9 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -728,7 +728,7 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
BKE_bproperty_set_valstr(prop, string);
characters = strlen(string);
- if (!BKE_image_get_ibuf(mtpoly->tpage, NULL))
+ if (!BKE_image_has_ibuf(mtpoly->tpage, NULL))
characters = 0;
if (!mf_smooth) {
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 729f810eb87..08ba4fb59bc 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -530,7 +530,7 @@ void drawaxes(float size, char drawtype)
static void draw_empty_image(Object *ob, const short dflag, const unsigned char ob_wire_col[4])
{
Image *ima = (Image *)ob->data;
- ImBuf *ibuf = ima ? BKE_image_get_ibuf(ima, NULL) : NULL;
+ ImBuf *ibuf = ima ? BKE_image_acquire_ibuf(ima, NULL, NULL) : NULL;
float scale, ofs_x, ofs_y, sca_x, sca_y;
int ima_x, ima_y;
@@ -615,6 +615,8 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char
/* Reset GL settings */
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, float tmat[][4])
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 24fc6adae6d..a9b3823e6a2 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1561,7 +1561,8 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
ibuf = NULL; /* frame is out of range, dont show */
}
else {
- ibuf = BKE_image_get_ibuf(ima, &bgpic->iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, &bgpic->iuser, NULL);
+ freeibuf = ibuf;
}
image_aspect[0] = ima->aspx;
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 7bd72430969..e3ba4cb1f95 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -318,7 +318,7 @@ static void gpu_make_repbind(Image *ima)
{
ImBuf *ibuf;
- ibuf = BKE_image_get_ibuf(ima, NULL);
+ ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ibuf==NULL)
return;
@@ -333,6 +333,8 @@ static void gpu_make_repbind(Image *ima)
if (ima->totbind>1)
ima->repbind= MEM_callocN(sizeof(int)*ima->totbind, "repbind");
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
static void gpu_clear_tpage(void)
@@ -479,7 +481,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
return 0;
/* check if we have a valid image buffer */
- ibuf= BKE_image_get_ibuf(ima, iuser);
+ ibuf= BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ibuf==NULL)
return 0;
@@ -574,6 +576,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
if (*bind != 0) {
/* enable opengl drawing with textures */
glBindTexture(GL_TEXTURE_2D, *bind);
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return *bind;
}
@@ -635,6 +638,8 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
if (srgb_frect)
MEM_freeN(srgb_frect);
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
return *bind;
}
@@ -896,7 +901,7 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
{
ImBuf *ibuf;
- ibuf = BKE_image_get_ibuf(ima, NULL);
+ ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ima->repbind || (GPU_get_mipmap() && !GTS.gpu_mipmap) || !ima->bindcode || !ibuf ||
(!is_power_of_2_i(ibuf->x) || !is_power_of_2_i(ibuf->y)) ||
@@ -935,6 +940,7 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
}
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return;
}
@@ -959,6 +965,8 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
}
}
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
void GPU_update_images_framechange(void)
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index ef73764753c..497105d94ec 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -1165,13 +1165,14 @@ static void do_material_tex(GPUShadeInput *shi)
// resolve texture resolution
if ( (mtex->texflag & MTEX_BUMP_TEXTURESPACE) || found_deriv_map ) {
- ImBuf *ibuf= BKE_image_get_ibuf(tex->ima, &tex->iuser);
+ ImBuf *ibuf= BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
ima_x= 512.0f; ima_y= 512.f; // prevent calling textureSize, glsl 1.3 only
if (ibuf) {
ima_x= ibuf->x;
ima_y= ibuf->y;
aspect = ((float) ima_y) / ima_x;
}
+ BKE_image_release_ibuf(tex->ima, ibuf, NULL);
}
// The negate on norfac is done because the
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index f8af2427827..9fedbee41ff 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -113,7 +113,7 @@ static void rna_Image_fields_update(Main *UNUSED(bmain), Scene *UNUSED(scene), P
BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
}
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
}
static void rna_Image_free_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
@@ -187,8 +187,12 @@ static EnumPropertyItem *rna_Image_source_itemf(bContext *UNUSED(C), PointerRNA
static int rna_Image_file_format_get(PointerRNA *ptr)
{
Image *image = (Image *)ptr->data;
- ImBuf *ibuf = BKE_image_get_ibuf(image, NULL);
- return BKE_ftype_to_imtype(ibuf ? ibuf->ftype : 0);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
+ int imtype = BKE_ftype_to_imtype(ibuf ? ibuf->ftype : 0);
+
+ BKE_image_release_ibuf(image, ibuf, NULL);
+
+ return imtype;
}
static void rna_Image_file_format_set(PointerRNA *ptr, int value)
@@ -199,12 +203,13 @@ static void rna_Image_file_format_set(PointerRNA *ptr, int value)
int ftype = BKE_imtype_to_ftype(value);
#if 0
- ibuf = BKE_image_get_ibuf(image, NULL);
+ ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
if (ibuf)
ibuf->ftype = ftype;
#endif
/* to be safe change all buffer file types */
+ /* TODO: this is never threadsafe */
for (ibuf = image->ibufs.first; ibuf; ibuf = ibuf->next) {
ibuf->ftype = ftype;
}
@@ -237,7 +242,7 @@ static void rna_Image_size_get(PointerRNA *ptr, int *values)
values[1] = 0;
}
- BKE_image_release_ibuf(im, lock);
+ BKE_image_release_ibuf(im, ibuf, lock);
}
static void rna_Image_resolution_get(PointerRNA *ptr, float *values)
@@ -256,7 +261,7 @@ static void rna_Image_resolution_get(PointerRNA *ptr, float *values)
values[1] = 0;
}
- BKE_image_release_ibuf(im, lock);
+ BKE_image_release_ibuf(im, ibuf, lock);
}
static void rna_Image_resolution_set(PointerRNA *ptr, const float *values)
@@ -271,7 +276,7 @@ static void rna_Image_resolution_set(PointerRNA *ptr, const float *values)
ibuf->ppm[1] = values[1];
}
- BKE_image_release_ibuf(im, lock);
+ BKE_image_release_ibuf(im, ibuf, lock);
}
static int rna_Image_depth_get(PointerRNA *ptr)
@@ -290,7 +295,7 @@ static int rna_Image_depth_get(PointerRNA *ptr)
else
planes = ibuf->planes;
- BKE_image_release_ibuf(im, lock);
+ BKE_image_release_ibuf(im, ibuf, lock);
return planes;
}
@@ -317,7 +322,7 @@ static int rna_Image_pixels_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY
else
length[0] = 0;
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
return length[0];
}
@@ -343,7 +348,7 @@ static void rna_Image_pixels_get(PointerRNA *ptr, float *values)
}
}
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
}
static void rna_Image_pixels_set(PointerRNA *ptr, const float *values)
@@ -369,7 +374,7 @@ static void rna_Image_pixels_set(PointerRNA *ptr, const float *values)
ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;
}
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
}
#else
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index cb5c515ce1f..686e6c80f1d 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -99,7 +99,7 @@ static void rna_Image_save_render(Image *image, bContext *C, ReportList *reports
IMB_freeImBuf(write_ibuf);
}
- BKE_image_release_ibuf(image, lock);
+ BKE_image_release_ibuf(image, ibuf, lock);
}
else {
BKE_report(reports, RPT_ERROR, "Scene not in context, could not get save parameters");
@@ -108,7 +108,7 @@ static void rna_Image_save_render(Image *image, bContext *C, ReportList *reports
static void rna_Image_save(Image *image, ReportList *reports)
{
- ImBuf *ibuf = BKE_image_get_ibuf(image, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
if (ibuf) {
char filename[FILE_MAX];
BLI_strncpy(filename, image->name, sizeof(filename));
@@ -136,11 +136,13 @@ static void rna_Image_save(Image *image, ReportList *reports)
else {
BKE_reportf(reports, RPT_ERROR, "Image '%s' does not have any image data", image->id.name + 2);
}
+
+ BKE_image_release_ibuf(image, ibuf, NULL);
}
static void rna_Image_pack(Image *image, ReportList *reports, int as_png)
{
- ImBuf *ibuf = BKE_image_get_ibuf(image, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
if (!as_png && (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))) {
BKE_report(reports, RPT_ERROR, "Cannot pack edited image from disk, only as internal PNG");
@@ -153,6 +155,8 @@ static void rna_Image_pack(Image *image, ReportList *reports, int as_png)
image->packedfile = newPackedFile(reports, image->name, ID_BLEND_PATH(G.main, &image->id));
}
}
+
+ BKE_image_release_ibuf(image, ibuf, NULL);
}
static void rna_Image_unpack(Image *image, ReportList *reports, int method)
@@ -177,7 +181,7 @@ static void rna_Image_reload(Image *image)
static void rna_Image_update(Image *image, ReportList *reports)
{
- ImBuf *ibuf = BKE_image_get_ibuf(image, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
if (ibuf == NULL) {
BKE_reportf(reports, RPT_ERROR, "Image '%s' does not have any image data", image->id.name + 2);
@@ -188,6 +192,8 @@ static void rna_Image_update(Image *image, ReportList *reports)
IMB_rect_from_float(ibuf);
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+
+ BKE_image_release_ibuf(image, ibuf, NULL);
}
static void rna_Image_scale(Image *image, ReportList *reports, int width, int height)
@@ -206,10 +212,11 @@ static int rna_Image_gl_load(Image *image, ReportList *reports, int filter, int
if (*bind)
return error;
- ibuf = BKE_image_get_ibuf(image, NULL);
+ ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
if (ibuf == NULL || ibuf->rect == NULL) {
BKE_reportf(reports, RPT_ERROR, "Image '%s' does not have any image data", image->id.name + 2);
+ BKE_image_release_ibuf(image, ibuf, NULL);
return (int)GL_INVALID_OPERATION;
}
@@ -238,6 +245,8 @@ static int rna_Image_gl_load(Image *image, ReportList *reports, int filter, int
image->bindcode = 0;
}
+ BKE_image_release_ibuf(image, ibuf, NULL);
+
return error;
}
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 962a92223eb..caa81dafa0e 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -598,7 +598,7 @@ static EnumPropertyItem *rna_SpaceImageEditor_draw_channels_itemf(bContext *UNUS
alpha = ibuf && (ibuf->channels == 4);
zbuf = ibuf && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1));
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
if (alpha && zbuf)
return draw_channels_items;
@@ -678,7 +678,7 @@ static void rna_SpaceImageEditor_scopes_update(Main *UNUSED(bmain), Scene *scene
scopes_update(&sima->scopes, ibuf, &scene->view_settings, &scene->display_settings);
WM_main_add_notifier(NC_IMAGE, sima->image);
}
- ED_space_image_release_buffer(sima, lock);
+ ED_space_image_release_buffer(sima, ibuf, lock);
}
/* Space Text Editor */
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index 150382c1f8f..88d78df190f 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -173,9 +173,10 @@ static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node)
Image *ima= (Image *)node->id;
if (ima) {
ImageUser *iuser= node->storage;
+ ImBuf *ibuf;
/* make sure ima->type is correct */
- BKE_image_get_ibuf(ima, iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ima->rr) {
RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
@@ -191,6 +192,8 @@ static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node)
}
else
cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE|RRES_OUT_ALPHA|RRES_OUT_Z);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
else
cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE|RRES_OUT_ALPHA);
@@ -312,7 +315,7 @@ float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc)
}
/* note: this function is used for multilayer too, to ensure uniform
- * handling with BKE_image_get_ibuf() */
+ * handling with BKE_image_acquire_ibuf() */
static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *iuser)
{
ImBuf *ibuf;
@@ -322,7 +325,7 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i
float *rect;
int alloc= FALSE;
- ibuf= BKE_image_get_ibuf(ima, iuser);
+ ibuf= BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
return NULL;
}
@@ -374,12 +377,15 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i
}
}
#endif
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
return stackbuf;
}
static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd)
{
- ImBuf *ibuf= BKE_image_get_ibuf((Image *)node->id, node->storage);
+ ImBuf *ibuf= BKE_image_acquire_ibuf((Image *)node->id, node->storage, NULL);
CompBuf *zbuf= NULL;
if (ibuf && ibuf->zbuf_float) {
@@ -391,6 +397,9 @@ static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd)
zbuf->rect= ibuf->zbuf_float;
}
}
+
+ BKE_image_release_ibuf((Image *)node->id, ibuf, NULL);
+
return zbuf;
}
@@ -418,13 +427,14 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSE
RenderData *rd= data;
Image *ima= (Image *)node->id;
ImageUser *iuser= (ImageUser *)node->storage;
+ ImBuf *ibuf = NULL;
/* first set the right frame number in iuser */
BKE_image_user_frame_calc(iuser, rd->cfra, 0);
/* force a load, we assume iuser index will be set OK anyway */
if (ima->type==IMA_TYPE_MULTILAYER)
- BKE_image_get_ibuf(ima, iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ima->type==IMA_TYPE_MULTILAYER && ima->rr) {
RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
@@ -505,6 +515,8 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **UNUSE
generate_preview(data, node, stackbuf);
}
}
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c
index 73cf039c6df..81f2f9b05a9 100644
--- a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c
+++ b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c
@@ -128,7 +128,7 @@ static void node_composit_exec_splitviewer(void *data, bNode *node, bNodeStack *
composit3_pixel_processor(node, cbuf, buf1, in[0]->vec, buf2, in[1]->vec, mask, NULL, do_copy_split_rgba, CB_RGBA, CB_RGBA, CB_VAL);
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
generate_preview(data, node, cbuf);
free_compbuf(cbuf);
diff --git a/source/blender/nodes/composite/nodes/node_composite_viewer.c b/source/blender/nodes/composite/nodes/node_composite_viewer.c
index 938f75cf3f5..b186a9aeaf9 100644
--- a/source/blender/nodes/composite/nodes/node_composite_viewer.c
+++ b/source/blender/nodes/composite/nodes/node_composite_viewer.c
@@ -112,7 +112,7 @@ static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in,
free_compbuf(zbuf);
}
- BKE_image_release_ibuf(ima, lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
generate_preview(data, node, cbuf);
free_compbuf(cbuf);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
index abe8e0190c8..d2d0870e2ed 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -75,12 +75,13 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node, GPUNod
ret = GPU_stack_link(mat, "node_tex_environment", in, out, GPU_image(ima, iuser, isdata));
if (ret) {
- ImBuf *ibuf = BKE_image_get_ibuf(ima, iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
GPU_material_do_color_management(mat))
{
GPU_link(mat, "srgb_to_linearrgb", out[0].link, &out[0].link);
}
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
return ret;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
index 9b17f76bd47..49b38434246 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
@@ -75,12 +75,13 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, GPUNodeStack
ret = GPU_stack_link(mat, "node_tex_image", in, out, GPU_image(ima, iuser, isdata));
if (ret) {
- ImBuf *ibuf = BKE_image_get_ibuf(ima, iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
GPU_material_do_color_management(mat))
{
GPU_link(mat, "srgb_to_linearrgb", out[0].link, &out[0].link);
}
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
return ret;
diff --git a/source/blender/nodes/shader/nodes/node_shader_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c
index 6d1b3ff6dba..b77c7d07407 100644
--- a/source/blender/nodes/shader/nodes/node_shader_texture.c
+++ b/source/blender/nodes/shader/nodes/node_shader_texture.c
@@ -128,12 +128,13 @@ static int gpu_shader_texture(GPUMaterial *mat, bNode *node, GPUNodeStack *in, G
int ret = GPU_stack_link(mat, "texture_image", in, out, texlink);
if (ret) {
- ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) ==0 &&
GPU_material_do_color_management(mat))
{
GPU_link(mat, "srgb_to_linearrgb", out[1].link, &out[1].link);
}
+ BKE_image_release_ibuf(tex->ima, ibuf, NULL);
}
return ret;
diff --git a/source/blender/nodes/texture/nodes/node_texture_image.c b/source/blender/nodes/texture/nodes/node_texture_image.c
index f3fdaf0bb64..2ef1669a266 100644
--- a/source/blender/nodes/texture/nodes/node_texture_image.c
+++ b/source/blender/nodes/texture/nodes/node_texture_image.c
@@ -46,7 +46,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(i
ImageUser *iuser= (ImageUser *)node->storage;
if ( ima ) {
- ImBuf *ibuf = BKE_image_get_ibuf(ima, iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if ( ibuf ) {
float xsize, ysize;
float xoff, yoff;
@@ -77,6 +77,8 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(i
result = ibuf->rect_float + py*ibuf->x*4 + px*4;
copy_v4_v4(out, result);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
}
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index 28f70211a9c..c3126e57b53 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -687,11 +687,12 @@ int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int o
env->ima = tex->ima;
if (env->ima && env->ima->ok) {
if (env->cube[1] == NULL) {
- ImBuf *ibuf_ima = BKE_image_get_ibuf(env->ima, NULL);
+ ImBuf *ibuf_ima = BKE_image_acquire_ibuf(env->ima, NULL, NULL);
if (ibuf_ima)
envmap_split_ima(env, ibuf_ima);
else
env->ok = 0;
+ BKE_image_release_ibuf(env->ima, ibuf_ima, NULL);
}
}
}
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index db1454fd82f..cd06839b004 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -124,13 +124,16 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
/* hack for icon render */
if (ima->ibufs.first==NULL && (R.r.scemode & R_NO_IMAGE_LOAD))
return retval;
-
- ibuf= BKE_image_get_ibuf(ima, &tex->iuser);
+
+ ibuf= BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
ima->flag|= IMA_USED_FOR_RENDER;
}
- if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL))
+ if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
+ }
/* setup mapping */
if (tex->imaflag & TEX_IMAROT) {
@@ -155,11 +158,17 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
/* pass */
}
else {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
}
}
if ( (tex->flag & TEX_CHECKER_EVEN)==0) {
- if ((xs+ys) & 1) return retval;
+ if ((xs+ys) & 1) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return retval;
+ }
}
/* scale around center, (0.5, 0.5) */
if (tex->checkerdist<1.0f) {
@@ -173,11 +182,15 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
if (tex->extend == TEX_CLIPCUBE) {
if (x<0 || y<0 || x>=ibuf->x || y>=ibuf->y || texvec[2]<-1.0f || texvec[2]>1.0f) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
}
}
else if ( tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
if (x<0 || y<0 || x>=ibuf->x || y>=ibuf->y) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
}
}
@@ -287,6 +300,9 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
texres->tb*= fx;
}
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
BRICONTRGB;
return retval;
@@ -1056,10 +1072,14 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
if (ima) { /* hack for icon render */
if ((ima->ibufs.first == NULL) && (R.r.scemode & R_NO_IMAGE_LOAD)) return retval;
- ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
}
- if ((ibuf == NULL) || ((ibuf->rect == NULL) && (ibuf->rect_float == NULL))) return retval;
+ if ((ibuf == NULL) || ((ibuf->rect == NULL) && (ibuf->rect_float == NULL))) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return retval;
+ }
if (ima) {
ima->flag |= IMA_USED_FOR_RENDER;
@@ -1172,8 +1192,16 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
}
}
else {
- if ((tex->flag & TEX_CHECKER_ODD) == 0 && ((xs + ys) & 1) == 0) return retval;
- if ((tex->flag & TEX_CHECKER_EVEN) == 0 && (xs + ys) & 1) return retval;
+ if ((tex->flag & TEX_CHECKER_ODD) == 0 && ((xs + ys) & 1) == 0) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return retval;
+ }
+ if ((tex->flag & TEX_CHECKER_EVEN) == 0 && (xs + ys) & 1) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return retval;
+ }
fx -= xs;
fy -= ys;
}
@@ -1189,10 +1217,18 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
}
if (tex->extend == TEX_CLIPCUBE) {
- if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f || texvec[2] < -1.f || texvec[2] > 1.f) return retval;
+ if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f || texvec[2] < -1.f || texvec[2] > 1.f) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return retval;
+ }
}
else if (tex->extend == TEX_CLIP || tex->extend == TEX_CHECKER) {
- if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f) return retval;
+ if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return retval;
+ }
}
else {
if (tex->extend == TEX_EXTEND) {
@@ -1413,6 +1449,9 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
texres->tb *= fx;
}
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
BRICONTRGB;
return retval;
@@ -1449,12 +1488,15 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
if (ima->ibufs.first==NULL && (R.r.scemode & R_NO_IMAGE_LOAD))
return retval;
- ibuf= BKE_image_get_ibuf(ima, &tex->iuser);
+ ibuf= BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
ima->flag|= IMA_USED_FOR_RENDER;
}
- if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL))
+ if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
+ }
/* mipmap test */
image_mipmap_test(tex, ibuf);
@@ -1565,11 +1607,15 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
/* pass */
}
else {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
}
}
if ( (tex->flag & TEX_CHECKER_EVEN)==0) {
if ((xs + ys) & 1) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
}
}
@@ -1605,11 +1651,15 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
if (tex->extend == TEX_CLIPCUBE) {
if (fx+minx<0.0f || fy+miny<0.0f || fx-minx>1.0f || fy-miny>1.0f || texvec[2]<-1.0f || texvec[2]>1.0f) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
}
}
else if (tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
if (fx+minx<0.0f || fy+miny<0.0f || fx-minx>1.0f || fy-miny>1.0f) {
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
return retval;
}
}
@@ -1804,6 +1854,9 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
mul_v3_fl(&texres->tr, 1.0f / texres->ta);
}
+ if (ima)
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
BRICONTRGB;
return retval;
@@ -1812,7 +1865,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
void image_sample(Image *ima, float fx, float fy, float dx, float dy, float result[4])
{
TexResult texres;
- ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
if (UNLIKELY(ibuf == NULL)) {
zero_v4(result);
@@ -1830,6 +1883,8 @@ void image_sample(Image *ima, float fx, float fy, float dx, float dy, float resu
ibuf->rect-= (ibuf->x*ibuf->y);
ima->flag|= IMA_USED_FOR_RENDER;
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float result[4])
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index f2549f04659..1b237d61e81 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -63,6 +63,7 @@
#include "BLI_string.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
+#include "BLI_threads.h"
#include "BLI_rand.h"
#include "BLI_callbacks.h"
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index c507d6595e0..e6daa5f9094 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -1233,11 +1233,13 @@ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int os
rgbnor = multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output);
if (mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) {
- ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(&texres->tr, ibuf->rect_colorspace);
+
+ BKE_image_release_ibuf(tex->ima, ibuf, NULL);
}
}
else {
@@ -1264,11 +1266,13 @@ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int os
rgbnor= multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres, thread, which_output);
{
- ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(&texres->tr, ibuf->rect_colorspace);
+
+ BKE_image_release_ibuf(tex->ima, ibuf, NULL);
}
}
@@ -1723,11 +1727,12 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi,
if (!shi->osatex && (tex->type == TEX_IMAGE) && tex->ima) {
/* in case we have no proper derivatives, fall back to
* computing du/dv it based on image size */
- ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
if (ibuf) {
du = 1.f/(float)ibuf->x;
dv = 1.f/(float)ibuf->y;
}
+ BKE_image_release_ibuf(tex->ima, ibuf, NULL);
}
else if (shi->osatex) {
/* we have derivatives, can compute proper du/dv */
@@ -1900,12 +1905,13 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
/* resolve image dimensions */
if (found_deriv_map || (mtex->texflag&MTEX_BUMP_TEXTURESPACE)!=0) {
- ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL);
if (ibuf) {
dimx = ibuf->x;
dimy = ibuf->y;
aspect = ((float) dimy) / dimx;
}
+ BKE_image_release_ibuf(tex->ima, ibuf, NULL);
}
if (found_deriv_map) {
@@ -2396,11 +2402,13 @@ void do_material_tex(ShadeInput *shi, Render *re)
/* inverse gamma correction */
if (tex->type==TEX_IMAGE) {
Image *ima = tex->ima;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
if (mtex->mapto & MAP_COL) {
@@ -2928,11 +2936,13 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4])
/* inverse gamma correction */
if (mtex->tex->type==TEX_IMAGE) {
Image *ima = mtex->tex->ima;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, &mtex->tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &mtex->tex->iuser, NULL);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
fact= texres.tin*mtex->colfac;
@@ -3147,11 +3157,13 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h
/* inverse gamma correction */
if (tex->type==TEX_IMAGE) {
Image *ima = tex->ima;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
if (mtex->mapto & WOMAP_HORIZ) {
@@ -3361,11 +3373,13 @@ void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r
/* inverse gamma correction */
if (tex->type==TEX_IMAGE) {
Image *ima = tex->ima;
- ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &tex->iuser, NULL);
/* don't linearize float buffers, assumed to be linear */
if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
/* lamp colors were premultiplied with this */
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 9fe2620747c..3431c3ff5de 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -2506,21 +2506,26 @@ static int get_next_bake_face(BakeShade *bs)
if (tface && tface->tpage) {
Image *ima= tface->tpage;
- ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
const float vec_alpha[4]= {0.0f, 0.0f, 0.0f, 0.0f};
const float vec_solid[4]= {0.0f, 0.0f, 0.0f, 1.0f};
if (ibuf==NULL)
continue;
- if (ibuf->rect==NULL && ibuf->rect_float==NULL)
+ if (ibuf->rect==NULL && ibuf->rect_float==NULL) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
continue;
+ }
- if (ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
+ if (ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4)) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
continue;
+ }
if (ima->flag & IMA_USED_FOR_RENDER) {
ima->id.flag &= ~LIB_DOIT;
+ BKE_image_release_ibuf(ima, ibuf, NULL);
continue;
}
@@ -2548,6 +2553,9 @@ static int get_next_bake_face(BakeShade *bs)
v++;
BLI_unlock_thread(LOCK_CUSTOM1);
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
return 1;
}
}
@@ -2571,8 +2579,10 @@ static void shade_tface(BakeShade *bs)
/* check valid zspan */
if (ima!=bs->ima) {
+ BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL);
+
bs->ima= ima;
- bs->ibuf= BKE_image_get_ibuf(ima, NULL);
+ bs->ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
/* note, these calls only free/fill contents of zspan struct, not zspan itself */
zbuf_free_span(bs->zspan);
zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop);
@@ -2638,7 +2648,9 @@ static void *do_bake_thread(void *bs_v)
*bs->do_update= TRUE;
}
bs->ready= 1;
-
+
+ BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL);
+
return NULL;
}
@@ -2689,12 +2701,13 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
/* baker uses this flag to detect if image was initialized */
for (ima= G.main->image.first; ima; ima= ima->id.next) {
- ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
ima->id.flag |= LIB_DOIT;
ima->flag&= ~IMA_USED_FOR_RENDER;
if (ibuf) {
ibuf->userdata = NULL; /* use for masking if needed */
}
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
BLI_init_threads(&threads, do_bake_thread, re->r.threads);
@@ -2747,7 +2760,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
/* filter and refresh images */
for (ima= G.main->image.first; ima; ima= ima->id.next) {
if ((ima->id.flag & LIB_DOIT)==0) {
- ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ima->flag & IMA_USED_FOR_RENDER)
result= BAKE_RESULT_FEEDBACK_LOOP;
@@ -2758,6 +2771,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, re->r.bake_filter);
ibuf->userflags |= IB_BITMAPDIRTY;
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c
index 42849a01971..77d6644479a 100644
--- a/source/blender/render/intern/source/voxeldata.c
+++ b/source/blender/render/intern/source/voxeldata.c
@@ -157,10 +157,10 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex)
/* find the first valid ibuf and use it to initialize the resolution of the data set */
/* need to do this in advance so we know how much memory to allocate */
- ibuf = BKE_image_get_ibuf(ima, &iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
while (!ibuf && (iuser.framenr < iuser.frames)) {
iuser.framenr++;
- ibuf = BKE_image_get_ibuf(ima, &iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
}
if (!ibuf) return;
if (!ibuf->rect_float) IMB_float_from_rect(ibuf);
@@ -175,7 +175,8 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex)
/* get a new ibuf for each frame */
if (z > 0) {
iuser.framenr++;
- ibuf = BKE_image_get_ibuf(ima, &iuser);
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
if (!ibuf) break;
if (!ibuf->rect_float) IMB_float_from_rect(ibuf);
}
@@ -191,7 +192,9 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex)
BKE_image_free_anim_ibufs(ima, iuser.framenr);
}
-
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
vd->ok = 1;
return;
}
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index 96bbedfee1b..fba45065fbe 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -61,6 +61,7 @@
#include "BKE_blender.h"
#include "BKE_global.h"
+#include "BKE_image.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -1082,6 +1083,7 @@ void WM_main_playanim(int argc, const char **argv)
/* we still miss freeing a lot!,
* but many areas could skip initialization too for anim play */
IMB_exit();
+ BKE_images_exit();
BLF_exit();
#endif
GHOST_DisposeWindow(g_WS.ghost_system, g_WS.ghost_window);
diff --git a/source/creator/creator.c b/source/creator/creator.c
index ca3deaf70a4..fc2f555227f 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -1270,6 +1270,7 @@ int main(int argc, const char **argv)
initglobals(); /* blender.c */
IMB_init();
+ BKE_images_init();
#ifdef WITH_FFMPEG
IMB_ffmpeg_init();
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index 3e8755c41ce..4451c78b99c 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -60,6 +60,7 @@ extern "C"
#include "BKE_blender.h"
#include "BKE_global.h"
#include "BKE_icons.h"
+#include "BKE_image.h"
#include "BKE_node.h"
#include "BKE_report.h"
#include "BKE_library.h"
@@ -446,6 +447,7 @@ int main(int argc, char** argv)
G.main = NULL;
IMB_init();
+ BKE_images_init();
// Setup builtin font for BLF (mostly copied from creator.c, wm_init_exit.c and interface_style.c)
BLF_init(11, U.dpi);
@@ -1067,6 +1069,7 @@ int main(int argc, char** argv)
#endif
IMB_exit();
+ BKE_images_exit();
free_nodesystem();
SYS_DeleteSystem(syshandle);
diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp
index 26523df8db3..66423ed820e 100644
--- a/source/gameengine/Ketsji/BL_Texture.cpp
+++ b/source/gameengine/Ketsji/BL_Texture.cpp
@@ -109,7 +109,7 @@ bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap)
return mOk;
}
- ibuf= BKE_image_get_ibuf(img, NULL);
+ ibuf= BKE_image_acquire_ibuf(img, NULL, NULL);
if (ibuf==NULL)
{
img->ok = 0;
@@ -128,6 +128,7 @@ bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap)
if (mTexture != 0) {
glBindTexture(GL_TEXTURE_2D, mTexture );
Validate();
+ BKE_image_release_ibuf(img, ibuf, NULL);
return mOk;
}
@@ -140,6 +141,7 @@ bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap)
mTexture = mapLook->second.gl_texture;
glBindTexture(GL_TEXTURE_2D, mTexture);
mOk = IsValid();
+ BKE_image_release_ibuf(img, ibuf, NULL);
return mOk;
}
}
@@ -166,6 +168,9 @@ bool BL_Texture::InitFromImage(int unit, Image *img, bool mipmap)
glDisable(GL_TEXTURE_2D);
ActivateUnit(0);
Validate();
+
+ BKE_image_release_ibuf(img, ibuf, NULL);
+
return mOk;
}
@@ -251,7 +256,7 @@ bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap)
return mOk;
}
- ImBuf *ibuf= BKE_image_get_ibuf(cubemap->ima, NULL);
+ ImBuf *ibuf= BKE_image_acquire_ibuf(cubemap->ima, NULL, NULL);
if (ibuf==0)
{
cubemap->ima->ok = 0;
@@ -274,6 +279,7 @@ bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap)
mTexture = mapLook->second.gl_texture;
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mTexture);
mOk = IsValid();
+ BKE_image_release_ibuf(cubemap->ima, ibuf, NULL);
return mOk;
}
}
@@ -307,6 +313,7 @@ bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap)
my_free_envmapdata(cubemap);
mOk = false;
+ BKE_image_release_ibuf(cubemap->ima, ibuf, NULL);
return mOk;
}
@@ -341,6 +348,9 @@ bool BL_Texture::InitCubeMap(int unit, EnvMap *cubemap)
ActivateUnit(0);
mOk = IsValid();
+
+ BKE_image_release_ibuf(cubemap->ima, ibuf, NULL);
+
return mOk;
}
@@ -646,9 +656,11 @@ int BL_Texture::GetPow2(int n)
void BL_Texture::SplitEnvMap(EnvMap *map)
{
if (!map || !map->ima || (map->ima && !map->ima->ok)) return;
- ImBuf *ibuf= BKE_image_get_ibuf(map->ima, NULL);
- if (ibuf)
+ ImBuf *ibuf= BKE_image_acquire_ibuf(map->ima, NULL, NULL);
+ if (ibuf) {
my_envmap_split_ima(map, ibuf);
+ BKE_image_release_ibuf(map->ima, ibuf, NULL);
+ }
}
unsigned int BL_Texture::mDisableState = 0;