diff options
30 files changed, 324 insertions, 124 deletions
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 597f2f25575..bfee5e820c3 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -44,6 +44,7 @@ struct anim; struct Scene; struct Object; struct ImageFormatData; +struct ImagePool; struct Main; #define IMA_MAX_SPACE 64 @@ -146,6 +147,11 @@ int BKE_image_has_ibuf(struct Image *ima, struct ImageUser *iuser); struct ImBuf *BKE_image_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, void **lock_r); void BKE_image_release_ibuf(struct Image *ima, struct ImBuf *ibuf, void *lock); +struct ImagePool *BKE_image_pool_new(void); +void BKE_image_pool_free(struct ImagePool *pool); +struct ImBuf *BKE_image_pool_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, struct ImagePool *pool); +void BKE_image_pool_release_ibuf(struct Image *ima, struct ImBuf *ibuf, struct ImagePool *pool); + /* returns a new image or NULL if it can't load */ struct Image *BKE_image_load(const char *filepath); /* returns existing Image when filename/type is same (frame optional) */ diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 078923ee5f9..211b6189fa8 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -47,6 +47,7 @@ struct Paint; struct PBVH; struct Scene; struct StrokeCache; +struct ImagePool; extern const char PAINT_CURSOR_SCULPT[3]; extern const char PAINT_CURSOR_VERTEX_PAINT[3]; @@ -116,6 +117,7 @@ typedef struct SculptSession { /* Used to cache the render of the active texture */ unsigned int texcache_side, *texcache, texcache_actual; + struct ImagePool *tex_pool; /* Layer brush persistence between strokes */ float (*layer_co)[3]; /* Copy of the mesh vertices' locations */ diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index fff51ab2a59..c92c52a7651 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -1483,7 +1483,9 @@ static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface) /* for vertex surface loop through tfaces and find uv color * that provides highest alpha */ if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { - #pragma omp parallel for schedule(static) + struct ImagePool *pool = BKE_image_pool_new(); + + #pragma omp parallel for schedule(static) shared(pool) for (i = 0; i < numOfFaces; i++) { int numOfVert = (mface[i].v4) ? 4 : 3; float uv[3] = {0.0f}; @@ -1496,7 +1498,7 @@ static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface) uv[0] = tface[i].uv[j][0] * 2.0f - 1.0f; uv[1] = tface[i].uv[j][1] * 2.0f - 1.0f; - multitex_ext_safe(tex, uv, &texres); + multitex_ext_safe(tex, uv, &texres, pool); if (texres.tin > pPoint[*vert].alpha) { copy_v3_v3(pPoint[*vert].color, &texres.tr); @@ -1504,6 +1506,7 @@ static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface) } } } + BKE_image_pool_free(pool); } else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { ImgSeqFormatData *f_data = (ImgSeqFormatData *)sData->format_data; @@ -1529,7 +1532,7 @@ static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface) uv_final[0] = uv_final[0] * 2.0f - 1.0f; uv_final[1] = uv_final[1] * 2.0f - 1.0f; - multitex_ext_safe(tex, uv_final, &texres); + multitex_ext_safe(tex, uv_final, &texres, NULL); /* apply color */ copy_v3_v3(pPoint[i].color, &texres.tr); diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 1f6db19ac27..1880cb42f4d 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -769,7 +769,7 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP mul_m4_v3(eff->ob->imat, tex_co); } - hasrgb = multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result); + hasrgb = multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result, NULL); if (hasrgb && mode==PFIELD_TEX_RGB) { force[0] = (0.5f - result->tr) * strength; @@ -780,15 +780,15 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP strength/=nabla; tex_co[0] += nabla; - multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+1); + multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+1, NULL); tex_co[0] -= nabla; tex_co[1] += nabla; - multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+2); + multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+2, NULL); tex_co[1] -= nabla; tex_co[2] += nabla; - multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+3); + multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+3, NULL); if (mode == PFIELD_TEX_GRAD || !hasrgb) { /* if we don't have rgb fall back to grad */ /* generate intensity if texture only has rgb value */ diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 5124406b641..90158f8cc70 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2811,6 +2811,28 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ return ibuf; } +static void image_get_fame_and_index(Image *ima, ImageUser *iuser, int *frame_r, int *index_r) +{ + int frame = 0, index = 0; + + /* see if we already have an appropriate ibuf, with image source and type */ + if (ima->source == IMA_SRC_MOVIE) { + frame = iuser ? iuser->framenr : ima->lastframe; + } + else if (ima->source == IMA_SRC_SEQUENCE) { + if (ima->type == IMA_TYPE_IMAGE) { + frame = iuser ? iuser->framenr : ima->lastframe; + } + else if (ima->type == IMA_TYPE_MULTILAYER) { + frame = iuser ? iuser->framenr : ima->lastframe; + index = iuser ? iuser->multi_index : IMA_NO_INDEX; + } + } + + *frame_r = frame; + *index_r = index; +} + static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame_r, int *index_r) { ImBuf *ibuf = NULL; @@ -3037,6 +3059,119 @@ int BKE_image_has_ibuf(Image *ima, ImageUser *iuser) return ibuf != NULL; } +/* ******** Pool for image buffers ******** */ + +typedef struct ImagePoolEntry { + struct ImagePoolEntry *next, *prev; + Image *image; + ImBuf *ibuf; + int index; + int frame; +} ImagePoolEntry; + +typedef struct ImagePool { + ListBase image_buffers; +} ImagePool; + +ImagePool *BKE_image_pool_new(void) +{ + ImagePool *pool = MEM_callocN(sizeof(ImagePool), "Image Pool"); + + return pool; +} + +void BKE_image_pool_free(ImagePool *pool) +{ + ImagePoolEntry *entry, *next_entry; + + /* use single lock to dereference all the image buffers */ + BLI_spin_lock(&image_spin); + + for (entry = pool->image_buffers.first; entry; entry = next_entry) { + next_entry = entry->next; + + if (entry->ibuf) + IMB_freeImBuf(entry->ibuf); + + MEM_freeN(entry); + } + + BLI_spin_unlock(&image_spin); + + MEM_freeN(pool); +} + +BLI_INLINE ImBuf *image_pool_find_entry(ImagePool *pool, Image *image, int frame, int index, int *found) +{ + ImagePoolEntry *entry; + + *found = FALSE; + + for (entry = pool->image_buffers.first; entry; entry = entry->next) { + if (entry->image == image && entry->frame == frame && entry->index == index) { + *found = TRUE; + return entry->ibuf; + } + } + + return NULL; +} + +ImBuf *BKE_image_pool_acquire_ibuf(Image *ima, ImageUser *iuser, ImagePool *pool) +{ + ImBuf *ibuf; + int index, frame, found; + + if (pool == NULL) { + /* pool could be NULL, in this case use general acquire function */ + return BKE_image_acquire_ibuf(ima, iuser, NULL); + } + + image_get_fame_and_index(ima, iuser, &frame, &index); + + ibuf = image_pool_find_entry(pool, ima, frame, index, &found); + if (found) + return ibuf; + + BLI_spin_lock(&image_spin); + + ibuf = image_pool_find_entry(pool, ima, frame, index, &found); + + /* will also create entry even in cases image buffer failed to load, + * prevents trying to load the same buggy file multiple times + */ + if (!found) { + ImagePoolEntry *entry; + + ibuf = image_acquire_ibuf(ima, iuser, NULL); + + if (ibuf) + IMB_refImBuf(ibuf); + + entry = MEM_callocN(sizeof(ImagePoolEntry), "Image Pool Entry"); + entry->image = ima; + entry->frame = frame; + entry->index = index; + entry->ibuf = ibuf; + + BLI_addtail(&pool->image_buffers, entry); + } + + BLI_spin_unlock(&image_spin); + + return ibuf; +} + +void BKE_image_pool_release_ibuf(Image *ima, ImBuf *ibuf, ImagePool *pool) +{ + /* if pool wasn't actually used, use general release stuff, + * for pools image buffers will be dereferenced on pool free + */ + if (pool == NULL) { + BKE_image_release_ibuf(ima, ibuf, NULL); + } +} + int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, int fieldnr, short *r_is_in_range) { const int len = (iuser->fie_ima * iuser->frames) / 2; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index b2371da0c3c..05031ddc142 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -83,6 +83,7 @@ #include "BKE_fcurve.h" #include "BKE_group.h" #include "BKE_icons.h" +#include "BKE_image.h" #include "BKE_key.h" #include "BKE_lamp.h" #include "BKE_lattice.h" @@ -308,6 +309,9 @@ void free_sculptsession(Object *ob) if (ss->texcache) MEM_freeN(ss->texcache); + if (ss->tex_pool) + BKE_image_pool_free(ss->tex_pool); + if (ss->layer_co) MEM_freeN(ss->layer_co); diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 2563fc268b1..be36e30808d 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -1060,7 +1060,7 @@ static void get_texture_value(Tex *texture, float tex_co[3], TexResult *texres) int result_type; /* no node textures for now */ - result_type = multitex_ext_safe(texture, tex_co, texres); + result_type = multitex_ext_safe(texture, tex_co, texres, NULL); /* if the texture gave an RGB value, we assume it didn't give a valid * intensity, since this is in the context of modifiers don't use perceptual color conversion. diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp index f8d6c0cfc01..23a3abe61ee 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.cpp +++ b/source/blender/compositor/operations/COM_TextureOperation.cpp @@ -23,6 +23,7 @@ #include "COM_TextureOperation.h" #include "BLI_listbase.h" +#include "BKE_image.h" TextureBaseOperation::TextureBaseOperation() : NodeOperation() { @@ -46,11 +47,14 @@ void TextureBaseOperation::initExecution() { this->m_inputOffset = getInputSocketReader(0); this->m_inputSize = getInputSocketReader(1); + this->m_pool = BKE_image_pool_new(); } void TextureBaseOperation::deinitExecution() { this->m_inputSize = NULL; this->m_inputOffset = NULL; + BKE_image_pool_free(this->m_pool); + this->m_pool = NULL; } void TextureBaseOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) @@ -95,7 +99,7 @@ void TextureBaseOperation::executePixel(float output[4], float x, float y, Pixel vec[1] = textureSize[1] * (v + textureOffset[1]); vec[2] = textureSize[2] * textureOffset[2]; - retval = multitex_ext(this->m_texture, vec, NULL, NULL, 0, &texres); + retval = multitex_ext(this->m_texture, vec, NULL, NULL, 0, &texres, m_pool); if (texres.talpha) output[3] = texres.ta; diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h index f8435ecdaa2..227ad37579a 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.h +++ b/source/blender/compositor/operations/COM_TextureOperation.h @@ -45,6 +45,7 @@ private: const RenderData *m_rd; SocketReader *m_inputSize; SocketReader *m_inputOffset; + struct ImagePool *m_pool; protected: diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 280e967f4d5..ffea5af74a3 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -43,6 +43,7 @@ #include "BKE_brush.h" #include "BKE_context.h" +#include "BKE_image.h" #include "BKE_paint.h" #include "WM_api.h" @@ -143,6 +144,8 @@ static int load_tex(Brush *br, ViewContext *vc) !same_snap(&snap, br, vc); if (refresh) { + struct ImagePool *pool = NULL; + if (br->mtex.tex && br->mtex.tex->preview) tex_changed_timestamp = br->mtex.tex->preview->changed_timestamp[0]; @@ -182,6 +185,9 @@ static int load_tex(Brush *br, ViewContext *vc) buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex"); + if (br->mtex.tex) + pool = BKE_image_pool_new(); + #pragma omp parallel for schedule(static) for (j = 0; j < size; j++) { int i; @@ -232,7 +238,7 @@ static int load_tex(Brush *br, ViewContext *vc) x += br->mtex.ofs[0]; y += br->mtex.ofs[1]; - avg = br->mtex.tex ? paint_get_tex_pixel(br, x, y) : 1; + avg = br->mtex.tex ? paint_get_tex_pixel(br, x, y, pool) : 1; avg += br->texture_sample_bias; @@ -247,6 +253,9 @@ static int load_tex(Brush *br, ViewContext *vc) } } + if (pool) + BKE_image_pool_free(pool); + if (!overlay_texture) glGenTextures(1, &overlay_texture); } diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c index c8cd38045bd..0b76c88df66 100644 --- a/source/blender/editors/sculpt_paint/paint_image_2d.c +++ b/source/blender/editors/sculpt_paint/paint_image_2d.c @@ -540,7 +540,7 @@ unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side) co[2] = 0.0f; /* This is copied from displace modifier code */ - hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres); + hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres, NULL); /* if the texture gave an RGB value, we assume it didn't give a valid * intensity, so calculate one (formula from do_material_tex). diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 75a95d4d6fd..faa9ce00da8 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -36,6 +36,7 @@ struct ARegion; struct bContext; struct bglMats; struct Brush; +struct ImagePool; struct ListBase; struct Mesh; struct Object; @@ -140,7 +141,7 @@ void paint_calc_redraw_planes(float planes[4][4], void projectf(struct bglMats *mats, const float v[3], float p[2]); float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius); -float paint_get_tex_pixel(struct Brush *br, float u, float v); +float paint_get_tex_pixel(struct Brush *br, float u, float v, struct ImagePool *pool); int imapaint_pick_face(struct ViewContext *vc, const int mval[2], unsigned int *index, unsigned int totface); void imapaint_pick_uv(struct Scene *scene, struct Object *ob, unsigned int faceindex, const int xy[2], float uv[2]); diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index e7d13bd080d..4f156276aac 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -173,13 +173,13 @@ float paint_calc_object_space_radius(ViewContext *vc, const float center[3], return len_v3(delta) / scale; } -float paint_get_tex_pixel(Brush *br, float u, float v) +float paint_get_tex_pixel(Brush *br, float u, float v, struct ImagePool *pool) { TexResult texres = {0}; float co[3] = {u, v, 0.0f}; int hasrgb; - hasrgb = multitex_ext(br->mtex.tex, co, NULL, NULL, 0, &texres); + hasrgb = multitex_ext(br->mtex.tex, co, NULL, NULL, 0, &texres, pool); if (hasrgb & TEX_RGB) texres.tin = rgb_to_grayscale(&texres.tr) * texres.ta; diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index d60d683e0f6..f49d8006ab8 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -56,6 +56,7 @@ #include "BKE_cdderivedmesh.h" #include "BKE_context.h" #include "BKE_depsgraph.h" +#include "BKE_image.h" #include "BKE_key.h" #include "BKE_library.h" #include "BKE_mesh.h" @@ -983,7 +984,7 @@ static float tex_strength(SculptSession *ss, Brush *br, x += br->mtex.ofs[0]; y += br->mtex.ofs[1]; - avg = paint_get_tex_pixel(br, x, y); + avg = paint_get_tex_pixel(br, x, y, ss->tex_pool); } avg += br->texture_sample_bias; @@ -3376,11 +3377,17 @@ static void sculpt_update_tex(const Scene *scene, Sculpt *sd, SculptSession *ss) ss->texcache = NULL; } + if (ss->tex_pool) { + BKE_image_pool_free(ss->tex_pool); + ss->tex_pool = NULL; + } + /* Need to allocate a bigger buffer for bigger brush size */ ss->texcache_side = 2 * radius; if (!ss->texcache || ss->texcache_side > ss->texcache_actual) { ss->texcache = BKE_brush_gen_texture_cache(brush, radius); ss->texcache_actual = ss->texcache_side; + ss->tex_pool = BKE_image_pool_new(); } } diff --git a/source/blender/makesrna/intern/rna_texture_api.c b/source/blender/makesrna/intern/rna_texture_api.c index 5be9d3a0dec..218fda361fa 100644 --- a/source/blender/makesrna/intern/rna_texture_api.c +++ b/source/blender/makesrna/intern/rna_texture_api.c @@ -71,7 +71,7 @@ static void clear_envmap(struct EnvMap *env, bContext *C) static void texture_evaluate(struct Tex *tex, float value[3], float color_r[4]) { TexResult texres = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; - multitex_ext(tex, value, NULL, NULL, 1, &texres); + multitex_ext(tex, value, NULL, NULL, 1, &texres, NULL); color_r[0] = texres.tr; color_r[1] = texres.tg; diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index 6c2f68891af..a94c51aa6b4 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -74,7 +74,7 @@ void get_texture_value(Tex *texture, float *tex_co, TexResult *texres) int result_type; /* no node textures for now */ - result_type = multitex_ext_safe(texture, tex_co, texres); + result_type = multitex_ext_safe(texture, tex_co, texres, NULL); /* if the texture gave an RGB value, we assume it didn't give a valid * intensity, since this is in the context of modifiers don't use perceptual color conversion. diff --git a/source/blender/nodes/shader/nodes/node_shader_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c index b77c7d07407..ec238b62408 100644 --- a/source/blender/nodes/shader/nodes/node_shader_texture.c +++ b/source/blender/nodes/shader/nodes/node_shader_texture.c @@ -72,7 +72,7 @@ static void node_shader_exec_texture(void *data, bNode *node, bNodeStack **in, b if (in[0]->datatype==NS_OSA_VECTORS) { float *fp= in[0]->data; - retval= multitex_nodes((Tex *)node->id, vec, fp, fp+3, shi->osatex, &texres, thread, which_output, NULL, NULL); + retval = multitex_nodes((Tex *)node->id, vec, fp, fp+3, shi->osatex, &texres, thread, which_output, NULL, NULL, NULL); } else if (in[0]->datatype==NS_OSA_VALUES) { float *fp= in[0]->data; @@ -80,14 +80,14 @@ static void node_shader_exec_texture(void *data, bNode *node, bNodeStack **in, b dxt[0] = fp[0]; dxt[1] = dxt[2] = 0.0f; dyt[0] = fp[1]; dyt[1] = dyt[2] = 0.0f; - retval= multitex_nodes((Tex *)node->id, vec, dxt, dyt, shi->osatex, &texres, thread, which_output, NULL, NULL); + retval = multitex_nodes((Tex *)node->id, vec, dxt, dyt, shi->osatex, &texres, thread, which_output, NULL, NULL, NULL); } else - retval= multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL); + retval = multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL, NULL); } else { copy_v3_v3(vec, shi->lo); - retval= multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL); + retval = multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL, NULL); } /* stupid exception */ diff --git a/source/blender/nodes/texture/nodes/node_texture_proc.c b/source/blender/nodes/texture/nodes/node_texture_proc.c index 8876d98b9b2..de2dac22d81 100644 --- a/source/blender/nodes/texture/nodes/node_texture_proc.c +++ b/source/blender/nodes/texture/nodes/node_texture_proc.c @@ -69,7 +69,7 @@ static void do_proc(float *result, TexParams *p, const float col1[4], const floa texres.nor = NULL; textype = multitex_nodes(tex, p->co, p->dxt, p->dyt, p->osatex, - &texres, thread, 0, p->shi, p->mtex); + &texres, thread, 0, p->shi, p->mtex, NULL); if (is_normal) return; diff --git a/source/blender/nodes/texture/nodes/node_texture_texture.c b/source/blender/nodes/texture/nodes/node_texture_texture.c index cc7367a7632..f839f485976 100644 --- a/source/blender/nodes/texture/nodes/node_texture_texture.c +++ b/source/blender/nodes/texture/nodes/node_texture_texture.c @@ -78,7 +78,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor texres.nor = nor; textype = multitex_nodes(nodetex, co, dxt, dyt, p->osatex, - &texres, thread, 0, p->shi, p->mtex); + &texres, thread, 0, p->shi, p->mtex, NULL); if (textype & TEX_RGB) { copy_v4_v4(out, &texres.tr); diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index 10045a8f7e1..4b3e7c2bc42 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -189,14 +189,15 @@ typedef struct ShadeInput { struct Tex; struct MTex; struct ImBuf; +struct ImagePool; /* this one uses nodes */ -int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres); +int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool); /* nodes disabled */ -int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres); +int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres, struct ImagePool *pool); /* only for internal node usage */ int multitex_nodes(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, - const short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex); + const short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex, struct ImagePool *pool); /* shaded view and bake */ struct Render; diff --git a/source/blender/render/intern/include/envmap.h b/source/blender/render/intern/include/envmap.h index d0f346f7402..a6c6d46e2e9 100644 --- a/source/blender/render/intern/include/envmap.h +++ b/source/blender/render/intern/include/envmap.h @@ -44,9 +44,10 @@ struct Render; struct TexResult; +struct ImagePool; void make_envmaps(struct Render *re); -int envmaptex(struct Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres); +int envmaptex(struct Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool); #endif /* __ENVMAP_H__ */ diff --git a/source/blender/render/intern/include/pixelshading.h b/source/blender/render/intern/include/pixelshading.h index 30d574694b2..faf8c5f54f5 100644 --- a/source/blender/render/intern/include/pixelshading.h +++ b/source/blender/render/intern/include/pixelshading.h @@ -32,6 +32,8 @@ #ifndef __PIXELSHADING_H__ #define __PIXELSHADING_H__ +struct ImagePool; + /** * Render the pixel at (x,y) for object ap. Apply the jitter mask. * Output is given in float collector[4]. The type vector: diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 905b4b4f4a8..d65da586b9a 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -62,6 +62,7 @@ struct RayFace; struct RenderEngine; struct ReportList; struct Main; +struct ImagePool; #define TABLEINITSIZE 1024 @@ -260,6 +261,8 @@ struct Render RenderStats i; struct ReportList *reports; + + struct ImagePool *pool; }; /* ------------------------------------------------------------------------- */ @@ -373,6 +376,7 @@ struct halosort { /* ------------------------------------------------------------------------- */ struct Material; struct MTFace; +struct ImagePool; typedef struct RadFace { float unshot[3], totrad[3]; @@ -402,6 +406,7 @@ typedef struct HaloRen { int pixels; unsigned int lay; struct Material *mat; + struct ImagePool *pool; } HaloRen; /* ------------------------------------------------------------------------- */ diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h index 4b9fa2d2042..2dc12f39db7 100644 --- a/source/blender/render/intern/include/texture.h +++ b/source/blender/render/intern/include/texture.h @@ -60,6 +60,7 @@ struct TexResult; struct Tex; struct Image; struct ImBuf; +struct ImagePool; /* texture.h */ @@ -76,9 +77,9 @@ void render_realtime_texture(struct ShadeInput *shi, struct Image *ima); /* imagetexture.h */ -int imagewraposa(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], const float dxt[2], const float dyt[2], struct TexResult *texres); -int imagewrap(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], struct TexResult *texres); -void image_sample(struct Image *ima, float fx, float fy, float dx, float dy, float result[4]); +int imagewraposa(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], const float dxt[2], const float dyt[2], struct TexResult *texres, struct ImagePool *pool); +int imagewrap(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], struct TexResult *texres, struct ImagePool *pool); +void image_sample(struct Image *ima, float fx, float fy, float dx, float dy, float result[4], struct ImagePool *pool); #endif /* __TEXTURE_H__ */ diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 05f5f248944..73304a033b8 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -150,6 +150,7 @@ static HaloRen *initstar(Render *re, ObjectRen *obr, const float vec[3], float h har->hasize= hasize; har->zd= 0.0; + har->pool = re->pool; return har; } diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index be8b7f6c357..9adae6f49ba 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -668,7 +668,7 @@ static void set_dxtdyt(float r_dxt[3], float r_dyt[3], const float dxt[3], const /* ------------------------------------------------------------------------- */ -int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres) +int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, struct ImagePool *pool) { extern Render R; /* only in this call */ /* texvec should be the already reflected normal */ @@ -687,12 +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_acquire_ibuf(env->ima, NULL, NULL); + ImBuf *ibuf_ima = BKE_image_pool_acquire_ibuf(env->ima, NULL, pool); if (ibuf_ima) envmap_split_ima(env, ibuf_ima); else env->ok = 0; - BKE_image_release_ibuf(env->ima, ibuf_ima, NULL); + BKE_image_pool_release_ibuf(env->ima, ibuf_ima, pool); } } } @@ -720,7 +720,7 @@ int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int o mul_mat3_m4_v3(R.viewinv, dyt); } set_dxtdyt(dxts, dyts, dxt, dyt, face); - imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, texres); + imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, texres, pool); /* edges? */ @@ -737,7 +737,7 @@ int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int o if (face != face1) { ibuf = env->cube[face1]; set_dxtdyt(dxts, dyts, dxt, dyt, face1); - imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr1); + imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr1, pool); } else texr1.tr = texr1.tg = texr1.tb = texr1.ta = 0.0; @@ -750,7 +750,7 @@ int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int o if (face != face1) { ibuf = env->cube[face1]; set_dxtdyt(dxts, dyts, dxt, dyt, face1); - imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr2); + imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr2, pool); } else texr2.tr = texr2.tg = texr2.tb = texr2.ta = 0.0; @@ -766,7 +766,7 @@ int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int o } } else { - imagewrap(tex, NULL, ibuf, sco, texres); + imagewrap(tex, NULL, ibuf, sco, texres, pool); } return 1; diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 4aaa6247478..0a427d57ebc 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -110,7 +110,7 @@ static void ibuf_get_color(float col[4], struct ImBuf *ibuf, int x, int y) } } -int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResult *texres) +int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResult *texres, struct ImagePool *pool) { float fx, fy, val1, val2, val3; int x, y, retval; @@ -130,13 +130,13 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul if (ima->ibufs.first==NULL && (R.r.scemode & R_NO_IMAGE_LOAD)) return retval; - ibuf= BKE_image_acquire_ibuf(ima, &tex->iuser, NULL); + ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, pool); ima->flag|= IMA_USED_FOR_RENDER; } if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) { if (ima) - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_pool_release_ibuf(ima, ibuf, pool); return retval; } @@ -164,14 +164,14 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul } else { if (ima) - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_pool_release_ibuf(ima, ibuf, pool); return retval; } } if ( (tex->flag & TEX_CHECKER_EVEN)==0) { if ((xs+ys) & 1) { if (ima) - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_pool_release_ibuf(ima, ibuf, pool); return retval; } } @@ -188,14 +188,14 @@ 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); + BKE_image_pool_release_ibuf(ima, ibuf, pool); 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); + BKE_image_pool_release_ibuf(ima, ibuf, pool); return retval; } } @@ -302,10 +302,10 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul texres->tg*= fx; texres->tb*= fx; } - + if (ima) - BKE_image_release_ibuf(ima, ibuf, NULL); - + BKE_image_pool_release_ibuf(ima, ibuf, pool); + BRICONTRGB; return retval; @@ -1045,7 +1045,7 @@ static void image_mipmap_test(Tex *tex, ImBuf *ibuf) } -static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], float dxt[2], float dyt[2], TexResult *texres) +static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], float dxt[2], float dyt[2], TexResult *texres, struct ImagePool *pool) { TexResult texr; float fx, fy, minx, maxx, miny, maxy; @@ -1076,12 +1076,12 @@ 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_acquire_ibuf(ima, &tex->iuser, NULL); + ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, pool); } if ((ibuf == NULL) || ((ibuf->rect == NULL) && (ibuf->rect_float == NULL))) { if (ima) - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_pool_release_ibuf(ima, ibuf, pool); return retval; } @@ -1199,12 +1199,12 @@ 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) { if (ima) - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_pool_release_ibuf(ima, ibuf, pool); return retval; } if ((tex->flag & TEX_CHECKER_EVEN) == 0 && (xs + ys) & 1) { if (ima) - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_pool_release_ibuf(ima, ibuf, pool); return retval; } fx -= xs; @@ -1224,14 +1224,14 @@ 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) { if (ima) - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_pool_release_ibuf(ima, ibuf, pool); 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) { if (ima) - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_pool_release_ibuf(ima, ibuf, pool); return retval; } } @@ -1455,7 +1455,7 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex } if (ima) - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_pool_release_ibuf(ima, ibuf, pool); BRICONTRGB; @@ -1463,7 +1463,7 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex } -int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const float DXT[2], const float DYT[2], TexResult *texres) +int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const float DXT[2], const float DYT[2], TexResult *texres, struct ImagePool *pool) { TexResult texr; float fx, fy, minx, maxx, miny, maxy, dx, dy, dxt[2], dyt[2]; @@ -1477,7 +1477,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const /* anisotropic filtering */ if (tex->texfilter != TXF_BOX) - return imagewraposa_aniso(tex, ima, ibuf, texvec, dxt, dyt, texres); + return imagewraposa_aniso(tex, ima, ibuf, texvec, dxt, dyt, texres, pool); texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f; @@ -1493,13 +1493,13 @@ 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_acquire_ibuf(ima, &tex->iuser, NULL); + ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, pool); ima->flag|= IMA_USED_FOR_RENDER; } if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) { if (ima) - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_pool_release_ibuf(ima, ibuf, pool); return retval; } @@ -1608,14 +1608,14 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const } else { if (ima) - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_pool_release_ibuf(ima, ibuf, pool); return retval; } } if ( (tex->flag & TEX_CHECKER_EVEN)==0) { if ((xs + ys) & 1) { if (ima) - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_pool_release_ibuf(ima, ibuf, pool); return retval; } } @@ -1652,14 +1652,14 @@ 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); + BKE_image_pool_release_ibuf(ima, ibuf, pool); 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); + BKE_image_pool_release_ibuf(ima, ibuf, pool); return retval; } } @@ -1855,17 +1855,17 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const } if (ima) - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_pool_release_ibuf(ima, ibuf, pool); BRICONTRGB; return retval; } -void image_sample(Image *ima, float fx, float fy, float dx, float dy, float result[4]) +void image_sample(Image *ima, float fx, float fy, float dx, float dy, float result[4], struct ImagePool *pool) { TexResult texres; - ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL); + ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, NULL, pool); if (UNLIKELY(ibuf == NULL)) { zero_v4(result); @@ -1884,7 +1884,7 @@ void image_sample(Image *ima, float fx, float fy, float dx, float dy, float resu ima->flag|= IMA_USED_FOR_RENDER; - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_pool_release_ibuf(ima, ibuf, pool); } void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float result[4]) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 5210803b708..3e9f5996ddc 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1787,6 +1787,8 @@ static void do_render_all_options(Render *re) /* ensure no images are in memory from previous animated sequences */ BKE_image_all_free_anim_ibufs(re->r.cfra); + re->pool = BKE_image_pool_new(); + if (RE_engine_render(re, 1)) { /* in this case external render overrides all */ } @@ -1811,6 +1813,9 @@ static void do_render_all_options(Render *re) renderresult_stampinfo(re); re->display_draw(re->ddh, re->result, NULL); } + + BKE_image_pool_free(re->pool); + re->pool = NULL; } static int check_valid_camera(Scene *scene, Object *camera_override) @@ -2385,6 +2390,8 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce) RE_InitState(re, NULL, &sce->r, NULL, winx, winy, NULL); + re->pool = BKE_image_pool_new(); + re->main = bmain; re->scene = sce; re->scene_color_manage = BKE_scene_check_color_management_enabled(sce); @@ -2394,6 +2401,9 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce) RE_SetCamera(re, camera); do_render_3d(re); + + BKE_image_pool_free(re->pool); + re->pool = NULL; } /* note; repeated win/disprect calc... solve that nicer, also in compo */ diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index e3bfd535f11..01eee4686af 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -1099,7 +1099,7 @@ static void do_2d_mapping(MTex *mtex, float texvec[3], VlakRen *vlr, const float /* ************************************** */ -static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, const short thread, short which_output) +static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, const short thread, short which_output, struct ImagePool *pool) { float tmpvec[3]; int retval = 0; /* return value, int:0, col:1, nor:2, everything:3 */ @@ -1137,12 +1137,12 @@ static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int o retval = texnoise(tex, texres); break; case TEX_IMAGE: - if (osatex) retval = imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres); - else retval = imagewrap(tex, tex->ima, NULL, texvec, texres); + if (osatex) retval = imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres, pool); + else retval = imagewrap(tex, tex->ima, NULL, texvec, texres, pool); BKE_image_tag_time(tex->ima); /* tag image as having being used */ break; case TEX_ENVMAP: - retval = envmaptex(tex, texvec, dxt, dyt, osatex, texres); + retval = envmaptex(tex, texvec, dxt, dyt, osatex, texres, pool); break; case TEX_MUSGRAVE: /* newnoise: musgrave types */ @@ -1214,7 +1214,7 @@ static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int o /* this is called from the shader and texture nodes */ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, - const short thread, short which_output, ShadeInput *shi, MTex *mtex) + const short thread, short which_output, ShadeInput *shi, MTex *mtex, struct ImagePool *pool) { if (tex==NULL) { memset(texres, 0, sizeof(TexResult)); @@ -1230,16 +1230,16 @@ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int os if (mtex) { /* we have mtex, use it for 2d mapping images only */ do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt); - rgbnor = multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output); + rgbnor = multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output, pool); if (mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) { - ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL); + ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool); /* 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); + BKE_image_pool_release_ibuf(tex->ima, ibuf, pool); } } else { @@ -1263,28 +1263,28 @@ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int os } do_2d_mapping(&localmtex, texvec_l, NULL, NULL, dxt_l, dyt_l); - rgbnor= multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres, thread, which_output); + rgbnor = multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres, thread, which_output, pool); { - ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, &tex->iuser, NULL); + ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool); /* 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); + BKE_image_pool_release_ibuf(tex->ima, ibuf, pool); } } return rgbnor; } else { - return multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output); + return multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output, pool); } } /* this is called for surface shading */ -static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt[3], float dyt[3], TexResult *texres) +static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt[3], float dyt[3], TexResult *texres, struct ImagePool *pool) { Tex *tex = mtex->tex; @@ -1295,24 +1295,24 @@ static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt tex, mtex->which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, shi, mtex); } else { - return multitex(mtex->tex, texvec, dxt, dyt, shi->osatex, texres, shi->thread, mtex->which_output); + return multitex(mtex->tex, texvec, dxt, dyt, shi->osatex, texres, shi->thread, mtex->which_output, pool); } } /* Warning, if the texres's values are not declared zero, check the return value to be sure * the color values are set before using the r/g/b values, otherwise you may use uninitialized values - Campbell */ -int multitex_ext(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres) +int multitex_ext(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, struct ImagePool *pool) { - return multitex_nodes(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL); + return multitex_nodes(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL, pool); } /* extern-tex doesn't support nodes (ntreeBeginExec() can't be called when rendering is going on) */ -int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres) +int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres, struct ImagePool *pool) { int use_nodes= tex->use_nodes, retval; tex->use_nodes = FALSE; - retval= multitex_nodes(tex, texvec, NULL, NULL, 0, texres, 0, 0, NULL, NULL); + retval= multitex_nodes(tex, texvec, NULL, NULL, 0, texres, 0, 0, NULL, NULL, pool); tex->use_nodes= use_nodes; return retval; @@ -1699,7 +1699,8 @@ static void compatible_bump_uv_derivs(CompatibleBump *compat_bump, ShadeInput *s } static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, - float Tnor, const float co[3], const float dx[3], const float dy[3], float texvec[3], float dxt[3], float dyt[3]) + float Tnor, const float co[3], const float dx[3], const float dy[3], float texvec[3], float dxt[3], float dyt[3], + struct ImagePool *pool) { TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */ float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv; @@ -1727,12 +1728,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_acquire_ibuf(tex->ima, &tex->iuser, NULL); + ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool); if (ibuf) { du = 1.f/(float)ibuf->x; dv = 1.f/(float)ibuf->y; } - BKE_image_release_ibuf(tex->ima, ibuf, NULL); + BKE_image_pool_release_ibuf(tex->ima, ibuf, pool); } else if (shi->osatex) { /* we have derivatives, can compute proper du/dv */ @@ -1752,7 +1753,7 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, /* center, main return value */ texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); - rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres); + rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres, pool); cd = fromrgb ? (texres->tr + texres->tg + texres->tb)*0.33333333f : texres->tin; if (mtex->texco == TEXCO_UV) { @@ -1766,7 +1767,7 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, tco[1] = co[1] + compat_bump->dvdnu*du; tco[2] = 0.f; texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt); - multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr); + multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool); ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin)); /* +v val */ @@ -1774,7 +1775,7 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, tco[1] = co[1] + compat_bump->dvdnv*du; tco[2] = 0.f; texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt); - multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr); + multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool); vd = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin)); } else { @@ -1808,7 +1809,7 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, tco[1] = co[1] + tu[1]*du; tco[2] = co[2] + tu[2]*du; texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt); - multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr); + multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool); ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin)); /* +v val */ @@ -1816,7 +1817,7 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, tco[1] = co[1] + tv[1]*dv; tco[2] = co[2] + tv[2]*dv; texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt); - multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr); + multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool); vd = idv*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin)); } @@ -1858,7 +1859,7 @@ static void ntap_bump_init(NTapBump *ntap_bump) static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, float Tnor, const float co[3], const float dx[3], const float dy[3], - float texvec[3], float dxt[3], float dyt[3]) + float texvec[3], float dxt[3], float dyt[3], struct ImagePool *pool) { TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */ @@ -1905,20 +1906,20 @@ 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_acquire_ibuf(tex->ima, &tex->iuser, NULL); + ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool); if (ibuf) { dimx = ibuf->x; dimy = ibuf->y; aspect = ((float) dimy) / dimx; } - BKE_image_release_ibuf(tex->ima, ibuf, NULL); + BKE_image_pool_release_ibuf(tex->ima, ibuf, pool); } if (found_deriv_map) { float dBdu, dBdv, auto_bump = 1.0f; float s = 1; /* negate this if flipped texture coordinate */ texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); - rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres); + rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres, pool); if (shi->obr->ob->derivedFinal) { auto_bump = shi->obr->ob->derivedFinal->auto_bump_scale; @@ -1960,14 +1961,14 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T } /* use texres for the center sample, set rgbnor */ - rgbnor = multitex_mtex(shi, mtex, STll, dxt, dyt, texres); + rgbnor = multitex_mtex(shi, mtex, STll, dxt, dyt, texres, pool); Hll = (fromrgb) ? rgb_to_grayscale(&texres->tr) : texres->tin; /* use ttexr for the other 2 taps */ - multitex_mtex(shi, mtex, STlr, dxt, dyt, &ttexr); + multitex_mtex(shi, mtex, STlr, dxt, dyt, &ttexr, pool); Hlr = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin; - multitex_mtex(shi, mtex, STul, dxt, dyt, &ttexr); + multitex_mtex(shi, mtex, STul, dxt, dyt, &ttexr, pool); Hul = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin; dHdx = Hscale*(Hlr - Hll); @@ -1998,17 +1999,17 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T } /* use texres for the center sample, set rgbnor */ - rgbnor = multitex_mtex(shi, mtex, STc, dxt, dyt, texres); + rgbnor = multitex_mtex(shi, mtex, STc, dxt, dyt, texres, pool); /* Hc = (fromrgb) ? rgb_to_grayscale(&texres->tr) : texres->tin; */ /* UNUSED */ /* use ttexr for the other taps */ - multitex_mtex(shi, mtex, STl, dxt, dyt, &ttexr); + multitex_mtex(shi, mtex, STl, dxt, dyt, &ttexr, pool); Hl = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin; - multitex_mtex(shi, mtex, STr, dxt, dyt, &ttexr); + multitex_mtex(shi, mtex, STr, dxt, dyt, &ttexr, pool); Hr = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin; - multitex_mtex(shi, mtex, STd, dxt, dyt, &ttexr); + multitex_mtex(shi, mtex, STd, dxt, dyt, &ttexr, pool); Hd = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin; - multitex_mtex(shi, mtex, STu, dxt, dyt, &ttexr); + multitex_mtex(shi, mtex, STu, dxt, dyt, &ttexr, pool); Hu = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin; dHdx = Hscale*(Hr - Hl); @@ -2285,20 +2286,22 @@ void do_material_tex(ShadeInput *shi, Render *re) if (texres.nor && !((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP))) { if (use_compat_bump) { rgbnor = compatible_bump_compute(&compat_bump, shi, mtex, tex, - &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt); + &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt, + re->pool); } else if (use_ntap_bump) { rgbnor = ntap_bump_compute(&ntap_bump, shi, mtex, tex, - &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt); + &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt, + re->pool); } else { texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); - rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres); + rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres, re->pool); } } else { texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); - rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres); + rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres, re->pool); } /* texture output */ @@ -2402,13 +2405,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_acquire_ibuf(ima, &tex->iuser, NULL); + ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, re->pool); /* 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); + BKE_image_pool_release_ibuf(ima, ibuf, re->pool); } if (mtex->mapto & MAP_COL) { @@ -2737,7 +2740,7 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_ else texvec[2]= mtex->size[2]*(mtex->ofs[2]); } - rgbnor= multitex(tex, texvec, NULL, NULL, 0, &texres, 0, mtex->which_output); /* NULL = dxt/dyt, 0 = shi->osatex - not supported */ + rgbnor = multitex(tex, texvec, NULL, NULL, 0, &texres, 0, mtex->which_output, re->pool); /* NULL = dxt/dyt, 0 = shi->osatex - not supported */ /* texture output */ @@ -2904,7 +2907,7 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4]) if (mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); - rgb= multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres, 0, mtex->which_output); + rgb = multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres, 0, mtex->which_output, har->pool); /* texture output */ if (rgb && (mtex->texflag & MTEX_RGBTOINT)) { @@ -2936,13 +2939,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_acquire_ibuf(ima, &mtex->tex->iuser, NULL); + ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, &mtex->tex->iuser, har->pool); /* 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); + BKE_image_pool_release_ibuf(ima, ibuf, har->pool); } fact= texres.tin*mtex->colfac; @@ -3109,7 +3112,7 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h /* texture */ if (tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); - rgb= multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres, thread, mtex->which_output); + rgb = multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres, thread, mtex->which_output, R.pool); /* texture output */ if (rgb && (mtex->texflag & MTEX_RGBTOINT)) { @@ -3157,13 +3160,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_acquire_ibuf(ima, &tex->iuser, NULL); + ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, R.pool); /* 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); + BKE_image_pool_release_ibuf(ima, ibuf, R.pool); } if (mtex->mapto & WOMAP_HORIZ) { @@ -3324,7 +3327,7 @@ void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); } - rgb= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output); + rgb = multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output, R.pool); /* texture output */ if (rgb && (mtex->texflag & MTEX_RGBTOINT)) { @@ -3373,13 +3376,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_acquire_ibuf(ima, &tex->iuser, NULL); + ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, R.pool); /* 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); + BKE_image_pool_release_ibuf(ima, ibuf, R.pool); } /* lamp colors were premultiplied with this */ @@ -3421,7 +3424,7 @@ int externtex(MTex *mtex, const float vec[3], float *tin, float *tr, float *tg, do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); } - rgb= multitex(tex, texvec, dxt, dyt, 0, &texr, thread, mtex->which_output); + rgb = multitex(tex, texvec, dxt, dyt, 0, &texr, thread, mtex->which_output, R.pool); if (rgb) { texr.tin = rgb_to_bw(&texr.tr); @@ -3485,8 +3488,8 @@ void render_realtime_texture(ShadeInput *shi, Image *ima) texr.nor= NULL; - if (shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr); - else imagewrap(tex, ima, NULL, texvec, &texr); + if (shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr, R.pool); + else imagewrap(tex, ima, NULL, texvec, &texr, R.pool); shi->vcol[0]*= texr.tr; shi->vcol[1]*= texr.tg; diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 7ca4f01ae47..31424b900c7 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -1070,6 +1070,8 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, } } + har->pool = re->pool; + return har; } @@ -1223,6 +1225,8 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater //} } + har->pool = re->pool; + return har; } |