Image thread safe improvements
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 15 Nov 2012 15:59:58 +0000 (15:59 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 15 Nov 2012 15:59:58 +0000 (15:59 +0000)
This commit makes BKE_image_acquire_ibuf referencing result, which means once
some area requested for image buffer, it'll be guaranteed this buffer wouldn't
be freed by image signal.

To de-reference buffer BKE_image_release_ibuf should now always be used.

To make referencing working correct we can not rely on result of
image_get_ibuf_threadsafe called outside from thread lock. This is so because
we need to guarantee getting image buffer from list of loaded buffers and it's
referencing happens atomic. Without lock here it is possible that between call
of image_get_ibuf_threadsafe and referencing the buffer IMA_SIGNAL_FREE would
be called. Image signal handling too is blocking now to prevent such a
situation.

Threads are locking by spinlock, which are faster than mutexes. There were some
slowdown reports in the past about render slowdown when using OSX on Xeon CPU.
It shouldn't happen with spin locks, but more tests on different hardware would
be really welcome. So far can not see speed regressions on own computers.

This commit also removes BKE_image_get_ibuf, because it was not so intuitive
when get_ibuf and acquire_ibuf should be used.

Thanks to Ton and Brecht for discussion/review :)

52 files changed:
intern/cycles/kernel/kernel_shader.h
source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/image.c
source/blender/blenlib/BLI_threads.h
source/blender/blenlib/intern/threads.c
source/blender/blenloader/intern/readfile.c
source/blender/collada/ImageExporter.cpp
source/blender/compositor/nodes/COM_ImageNode.cpp
source/blender/compositor/operations/COM_ImageOperation.cpp
source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
source/blender/editors/include/ED_image.h
source/blender/editors/object/object_bake.c
source/blender/editors/object/object_edit.c
source/blender/editors/render/render_internal.c
source/blender/editors/render/render_opengl.c
source/blender/editors/render/render_preview.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/space_image/image_buttons.c
source/blender/editors/space_image/image_draw.c
source/blender/editors/space_image/image_edit.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_image/space_image.c
source/blender/editors/space_info/info_ops.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_view.c
source/blender/editors/space_view3d/drawmesh.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/gpu/intern/gpu_draw.c
source/blender/gpu/intern/gpu_material.c
source/blender/makesrna/intern/rna_image.c
source/blender/makesrna/intern/rna_image_api.c
source/blender/makesrna/intern/rna_space.c
source/blender/nodes/composite/nodes/node_composite_image.c
source/blender/nodes/composite/nodes/node_composite_splitViewer.c
source/blender/nodes/composite/nodes/node_composite_viewer.c
source/blender/nodes/shader/nodes/node_shader_tex_environment.c
source/blender/nodes/shader/nodes/node_shader_tex_image.c
source/blender/nodes/shader/nodes/node_shader_texture.c
source/blender/nodes/texture/nodes/node_texture_image.c
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/imagetexture.c
source/blender/render/intern/source/pipeline.c
source/blender/render/intern/source/render_texture.c
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/voxeldata.c
source/blender/windowmanager/intern/wm_playanim.c
source/creator/creator.c
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
source/gameengine/Ketsji/BL_Texture.cpp

index a2a741935a1d4c7ee1b0077a4017f67d1752c973..f935858f8ba88c265b7ee8a01ab2aec7f8bb2bb7 100644 (file)
@@ -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;
index 1875fd666289703c5e9dfd7a5b807c44f44249ea..1f9630d9fce4a8026db631a4f70db3f7a6e4e203 100644 (file)
@@ -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);
index e1e868b234ee23f8f21cd52d10f92430f8f40e0e..40cd5b3d4033ab28892bce8c49e05fcee1a046a3 100644 (file)
@@ -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();
 
index 98b206712d63d621b0e30787f9e1f108141bc68d..f310895f590f12b48e569fceca4896bb37f2bc78 100644 (file)
@@ -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) {
index 55d37c918592e70195157417cb3f4657832e30be..993d72ab2e7fa7e17fdcbc5d13715620f57fbd15 100644 (file)
 
 #include "WM_api.h"
 
+static SpinLock image_spin;
+
 /* max int, to indicate we don't store sequences in ibuf */
 #define IMA_NO_INDEX    0x7FEFEFEF
 
 #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])
index 9cd801f819dd54085137a2a159b699322c6312b9..ec8e567c0efd4f20f3745493739947408a5368ba 100644 (file)
@@ -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
index 66527b9b92ae3686cc125c9863cef52d96c30786..146e1d531f1c7bcb630f993ad90ea744c9d9cc04 100644 (file)
@@ -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)
index 3033171346305d658ab66447ae7772fc0a4962d8..03e5a1d2525b85b70139afff5cd104759b640867 100644 (file)
@@ -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;
index 2e0c0f1ea57051fe1dfc769daea12c889090083a..aba290f5ce4aa13a5b5976ab5b767566e436505e 100644 (file)
@@ -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);
        }
 }
 
index 4ebd28d710a54f4bad5c0b4aba55174bf9849f3b..729cb1b70a04be6dc7496ba41685fdb0f2014b9a 100644 (file)
@@ -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) {
index fb3efbb67ed40c172f479529b7b3f8f105ca7782..a7743cd76681418ba6397076aac1a03768e282be 100644 (file)
@@ -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)
index 4d4c1199f3eb778ff7504c7958889d8872c1fc21..cc313512316a2e6a203ca79002c8fb1c9721f1bf 100644 (file)
@@ -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,
index a50b33966c6deb62dfcbdde9b2c4455446677f7d..9b726cea56ce69fc873712494f93aafb899b4974 100644 (file)
@@ -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);
index 032314d06f3ea461da989d48b66b7117da7a8958..e144c38a350e74c723e98489eb790ec855ed8f2c 100644 (file)
@@ -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);
        }
 }
 
index c0c2195592bf376e195539956fbaf7f3bc7da1f4..4d6b9ed10bb1ce6720023762017fc1a01c881fda 100644 (file)
@@ -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;
index 4b177629f7268302fc20ee20b324742cc1c7da93..7b67f63c646af04d490ef1aa48776cca6311261d 100644 (file)
@@ -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)
index e4592a4f77ead512a44cc776b4bf1047d62393c3..effb984c0839e3d3164338da874d348fd22aee91 100644 (file)
@@ -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");
index b119165fbd0802238e8a09cd2cd07a70dd523cd3..a864fe306b39b0930e7410e2f5dedc6d324cf477 100644 (file)
@@ -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;
index 4b4006239209c066399dd2694ce62f31cb0f0369..192ad35109a1648321370cf084247896e1011cc2 100644 (file)
@@ -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");
index ae7a718ab5b6c1db8098f56c2ae3102b5f9557ea..0a3db59096a06f0946a31e0b72dd83aef457b802 100644 (file)
@@ -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);
                                
index 9fc2b981547a45e63e03b71eee69787d6845b8e3..d565e6f9e9aa0bcb90c127fd15704e30e74b4f1d 100644 (file)
@@ -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);
index 4ca2f8888f8458ab5999ea3f25af85c307a1377f..c4e2230e7a72a4de38bb77ff6c4dd13e95fe0acc 100644 (file)
@@ -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])
index ce3c6e1fd26fa3d6505be870a47eb62d33751660..d4f24babff601f961269094e9ab272f6e4a3b48d 100644 (file)
@@ -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);
index 4131cbfdd0d2c462b660bf18df7a04581f075596..ea696772957c632acc788c0e98fd9e7fd885da38 100644 (file)
@@ -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);
 }
index 131908bc9dbb6be9c1f7a02e1e833353a697e41d..48b5eaf7b44514e11d26751d67218bc454d128e7 100644 (file)
@@ -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);
                }
        }
 
index f808a08d5d242ed55cba467d6884b0e57a77257a..e842bb5f262705c2d901baff9d2336f7ad561f22 100644 (file)
@@ -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);
                }
        }
 }
index a4ea2e3e630da0bca76479cbc6b07a6111ac9792..f386657c46049396775120216d2da366ddf478d1 100644 (file)
@@ -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));
 }
index cb5556396dd35d4199ea22f828da95e54510669f..f35a844afc98ab325c09031f3dd6871778d90101 100644 (file)
@@ -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) {
index 729f810eb877210c16c145fd6b0d6acf04d7ab70..08ba4fb59bc090303fe38911ac5f0848b5bccfe0 100644 (file)
@@ -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])
index 24fc6adae6d646e0ab492637ef8ff619366470c0..a9b3823e6a295e2cd02cac18c792edf6da93e677 100644 (file)
@@ -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;
index 7bd72430969311b01df5ed1a1f39d896151fe57c..e3ba4cb1f956da471f5c73dbc6785482b283377a 100644 (file)
@@ -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)
index ef73764753cb55a164ad342983a085a0e0038a6d..497105d94ecac029dd0f7d03b1a576fd638a5bfc 100644 (file)
@@ -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
index f8af2427827e8b81fedcf30362d389576ff42f23..9fedbee41ff3689e006ea47306ba7f3e661e6c9e 100644 (file)
@@ -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
index cb5c515ce1fa90afffea86110f524987c9ed7efa..686e6c80f1d9e065c64cf20899fa99baba987481 100644 (file)
@@ -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;
 }
 
index 962a92223eb6d98a25e8442d7cee059c7b23429d..caa81dafa0e0b19df9410e62981346275e70fac4 100644 (file)
@@ -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 */
index 150382c1f8f7c9b4190f06ca750e0f8a421c5e55..88d78df190f02a0c0b12b036a1338fc6024e3f8f 100644 (file)
@@ -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);
        }
 }
 
index 73cf039c6df468f1c610ce599f8ef96ae2411d54..81f2f9b05a918a6e905b3c67136573382f5cef8e 100644 (file)
@@ -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);
index 938f75cf3f54350ad536e9e0776655e057e5f6d3..b186a9aeaf9c5158cf5e2d83d9cd92a8d76782f0 100644 (file)
@@ -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);
index abe8e0190c83f80521efe17821d7c5a4aab27396..d2d0870e2ed5c7b1dfb35eb4b22a7363ac80160f 100644 (file)
@@ -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;
index 9b17f76bd4760868c42ff6039115440143ba3232..49b3843424647feab77d54efba4d3cb1add30561 100644 (file)
@@ -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;
index 6d1b3ff6dba63dcb55c7c3f8cb36453a1baf6173..b77c7d074075485cce7f4f672d87507b4786b35e 100644 (file)
@@ -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;
index f3fdaf0bb64847579989084a71ddf7e06443c3a9..2ef1669a266446bd09cf69ff2469403f386c02a7 100644 (file)
@@ -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);
                }
        }
 }
index 28f70211a9c379f7509329b21b55e9051fa8a496..c3126e57b53868a04b35d4e511d00c168250ce14 100644 (file)
@@ -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);
                        }
                }
        }
index db1454fd82f6883127e9275e13837aef8d8f230c..cd06839b00423589be36666df7fc4c94b190f9b2 100644 (file)
@@ -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])
index f2549f04659d80ff8fdfc703f322c1365a8f8280..1b237d61e8147aaa33ec50f97ead3029238fde50 100644 (file)
@@ -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"
 
index c507d6595e04584dd340c7f53402fc4e52d285d4..e6daa5f90943122257e9bb39a23160649096a006 100644 (file)
@@ -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 */
index 9fe2620747c97b3a759da86f0978ea0b97a260ee..3431c3ff5de692ab57ddde3f2c3588e51be95687 100644 (file)
@@ -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);
                }
        }
        
index 42849a019716b6c3b9bd5fe31719e120f541b666..77d6644479aa815b843965fc3943da20d80f7ef0 100644 (file)
@@ -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;
 }
index 96bbedfee1b9d5528961cf8182586c3501b47ddd..fba45065fbe8e6c0bda255e77564fc4775cccb8f 100644 (file)
@@ -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);
index ca3deaf70a4f9e0fb55c9539e51cd9b636162e56..fc2f555227f4b6c3f9ebf8284d62b81c04d5f205 100644 (file)
@@ -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();
index 3e8755c41cee0b64f55ebc7444dfec7d1db44bec..4451c78b99c007db20f696aaeb18e916d4ffe0f1 100644 (file)
@@ -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);
index 26523df8db31962e9afc3be4e23213df0c540ee1..66423ed820ed7423d4053f4c03cfa67a1257e576 100644 (file)
@@ -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;