Image thread safe improvements

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 :)
This commit is contained in:
Sergey Sharybin 2012-11-15 15:59:58 +00:00
parent 613cf7ae37
commit 5c6f6301b0
52 changed files with 601 additions and 289 deletions

View 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;

View 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);

View 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();

View 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) {

View File

@ -100,6 +100,8 @@
#include "WM_api.h"
static SpinLock image_spin;
/* max int, to indicate we don't store sequences in ibuf */
#define IMA_NO_INDEX 0x7FEFEFEF
@ -108,6 +110,16 @@
#define IMA_INDEX_FRAME(index) (index >> 10)
#define IMA_INDEX_PASS(index) (index & ~1023)
void BKE_images_init(void)
{
BLI_spin_init(&image_spin);
}
void BKE_images_exit(void)
{
BLI_spin_end(&image_spin);
}
/* ******** IMAGE PROCESSING ************* */
static void de_interlace_ng(struct ImBuf *ibuf) /* neogeo fields */
@ -168,13 +180,14 @@ static void de_interlace_st(struct ImBuf *ibuf) /* standard fields */
void BKE_image_de_interlace(Image *ima, int odd)
{
ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ibuf) {
if (odd)
de_interlace_st(ibuf);
else
de_interlace_ng(ibuf);
}
BKE_image_release_ibuf(ima, ibuf, NULL);
}
/* ***************** ALLOC & FREE, DATA MANAGING *************** */
@ -260,8 +273,9 @@ static ImBuf *image_get_ibuf(Image *ima, int index, int frame)
/* this function is intended to be thread safe. with IMA_NO_INDEX this
* should be OK, but when iterating over the list this is more tricky
* */
if (index == IMA_NO_INDEX)
if (index == IMA_NO_INDEX) {
return ima->ibufs.first;
}
else {
ImBuf *ibuf;
@ -269,9 +283,9 @@ static ImBuf *image_get_ibuf(Image *ima, int index, int frame)
for (ibuf = ima->ibufs.first; ibuf; ibuf = ibuf->next)
if (ibuf->index == index)
return ibuf;
return NULL;
}
return NULL;
}
/* no ima->ibuf anymore, but listbase */
@ -534,7 +548,7 @@ int BKE_image_scale(Image *image, int width, int height)
ibuf->userflags |= IB_BITMAPDIRTY;
}
BKE_image_release_ibuf(image, lock);
BKE_image_release_ibuf(image, ibuf, lock);
return (ibuf != NULL);
}
@ -2081,6 +2095,8 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
if (ima == NULL)
return;
BLI_spin_lock(&image_spin);
switch (signal) {
case IMA_SIGNAL_FREE:
image_free_buffers(ima);
@ -2167,6 +2183,8 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
}
}
}
BLI_spin_unlock(&image_spin);
}
/* if layer or pass changes, we need an index for the imbufs list */
@ -2320,7 +2338,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
if (ibuf) {
#ifdef WITH_OPENEXR
/* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */
/* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */
if (ibuf->ftype == OPENEXR && ibuf->userdata) {
image_create_multilayer(ima, ibuf, frame);
ima->type = IMA_TYPE_MULTILAYER;
@ -2482,7 +2500,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
}
if (ibuf) {
/* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */
/* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */
if (ibuf->ftype == OPENEXR && ibuf->userdata) {
image_create_multilayer(ima, ibuf, cfra);
ima->type = IMA_TYPE_MULTILAYER;
@ -2751,38 +2769,32 @@ static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame
* a big bottleneck */
}
*frame_r = frame;
*index_r = index;
if (frame_r)
*frame_r = frame;
if (index_r)
*index_r = index;
return ibuf;
}
/* Checks optional ImageUser and verifies/creates ImBuf. */
/* use this one if you want to get a render result in progress,
* if not, use BKE_image_get_ibuf which doesn't require a release */
ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
/* Checks optional ImageUser and verifies/creates ImBuf.
*
* not thread-safe, so callee should worry about thread locks
*/
static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
{
ImBuf *ibuf = NULL;
float color[] = {0, 0, 0, 1};
int frame = 0, index = 0;
/* This function is intended to be thread-safe. It postpones the mutex lock
* until it needs to load the image, if the image is already there it
* should just get the pointer and return. The reason is that a lot of mutex
* locks appears to be very slow on certain multicore macs, causing a render
* with image textures to actually slow down as more threads are used.
*
* Note that all the image loading functions should also make sure they do
* things in a threadsafe way for image_get_ibuf_threadsafe to work correct.
* That means, the last two steps must be, 1) add the ibuf to the list and
* 2) set ima/iuser->ok to 0 to IMA_OK_LOADED */
if (lock_r)
*lock_r = NULL;
/* quick reject tests */
if (ima == NULL)
return NULL;
if (iuser) {
if (iuser->ok == 0)
return NULL;
@ -2790,95 +2802,71 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
else if (ima->ok == 0)
return NULL;
/* try to get the ibuf without locking */
ibuf = image_get_ibuf_threadsafe(ima, iuser, &frame, &index);
if (ibuf == NULL) {
/* couldn't get ibuf and image is not ok, so let's lock and try to
* load the image */
BLI_lock_thread(LOCK_IMAGE);
/* need to check ok flag and loading ibuf again, because the situation
* might have changed in the meantime */
if (iuser) {
if (iuser->ok == 0) {
BLI_unlock_thread(LOCK_IMAGE);
return NULL;
/* we are sure we have to load the ibuf, using source and type */
if (ima->source == IMA_SRC_MOVIE) {
/* source is from single file, use flipbook to store ibuf */
ibuf = image_load_movie_file(ima, iuser, frame);
}
else if (ima->source == IMA_SRC_SEQUENCE) {
if (ima->type == IMA_TYPE_IMAGE) {
/* regular files, ibufs in flipbook, allows saving */
ibuf = image_load_sequence_file(ima, iuser, frame);
}
/* 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->ok == 0) {
BLI_unlock_thread(LOCK_IMAGE);
return NULL;
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);
}
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_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_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) {
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;
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);
/* XXX anim play for viewer nodes not yet supported */
frame = 0; // XXX iuser?iuser->framenr:0;
ibuf = image_get_ibuf(ima, 0, 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_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);
}
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])

View 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

View 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)

View 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;

View 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);
}
}

View 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) {

View 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)

View 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,

View 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);

View 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);
}
}

View 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;

View 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)

View 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");

View 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;

View 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");

View 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);

View 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);

View 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])

View 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);

View 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);
}

View 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);
}
}

View 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);
}
}
}

View 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));
}

View 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) {

View 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])

View 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;

View 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)

View 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

View 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

View 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;
}

View 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 */

View 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);
}
}

View 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);

View 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);

View 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;

View 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;

View 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;

View 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);
}
}
}

View 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);
}
}
}

View 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])

View 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"

View 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 */

View 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);
}
}

View 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;
}

View 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);

View 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();

View 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);

View 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;