|
Blender
V2.59
|
00001 /* 00002 * allocimbuf.c 00003 * 00004 * $Id: allocimbuf.c 36715 2011-05-16 13:34:42Z blendix $ 00005 * 00006 * ***** BEGIN GPL LICENSE BLOCK ***** 00007 * 00008 * This program is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU General Public License 00010 * as published by the Free Software Foundation; either version 2 00011 * of the License, or (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software Foundation, 00020 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00021 * 00022 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00023 * All rights reserved. 00024 * 00025 * The Original Code is: all of this file. 00026 * 00027 * Contributor(s): none yet. 00028 * 00029 * ***** END GPL LICENSE BLOCK ***** 00030 */ 00031 00037 /* It's become a bit messy... Basically, only the IMB_ prefixed files 00038 * should remain. */ 00039 00040 #include <stddef.h> 00041 00042 #include "IMB_imbuf.h" 00043 #include "IMB_imbuf_types.h" 00044 00045 #include "IMB_allocimbuf.h" 00046 #include "IMB_filetype.h" 00047 #include "IMB_metadata.h" 00048 00049 #include "imbuf.h" 00050 00051 #include "MEM_CacheLimiterC-Api.h" 00052 #include "MEM_guardedalloc.h" 00053 00054 void imb_freemipmapImBuf(ImBuf *ibuf) 00055 { 00056 int a; 00057 00058 for(a=1; a<ibuf->miptot; a++) { 00059 if(ibuf->mipmap[a-1]) 00060 IMB_freeImBuf(ibuf->mipmap[a-1]); 00061 ibuf->mipmap[a-1]= NULL; 00062 } 00063 00064 ibuf->miptot= 0; 00065 } 00066 00067 /* any free rect frees mipmaps to be sure, creation is in render on first request */ 00068 void imb_freerectfloatImBuf(ImBuf *ibuf) 00069 { 00070 if(ibuf==NULL) return; 00071 00072 if(ibuf->rect_float && (ibuf->mall & IB_rectfloat)) { 00073 MEM_freeN(ibuf->rect_float); 00074 ibuf->rect_float=NULL; 00075 } 00076 00077 imb_freemipmapImBuf(ibuf); 00078 00079 ibuf->rect_float= NULL; 00080 ibuf->mall &= ~IB_rectfloat; 00081 } 00082 00083 /* any free rect frees mipmaps to be sure, creation is in render on first request */ 00084 void imb_freerectImBuf(ImBuf *ibuf) 00085 { 00086 if(ibuf==NULL) return; 00087 00088 if(ibuf->rect && (ibuf->mall & IB_rect)) 00089 MEM_freeN(ibuf->rect); 00090 ibuf->rect= NULL; 00091 00092 imb_freemipmapImBuf(ibuf); 00093 00094 ibuf->mall &= ~IB_rect; 00095 } 00096 00097 void imb_freetilesImBuf(ImBuf *ibuf) 00098 { 00099 int tx, ty; 00100 00101 if(ibuf==NULL) return; 00102 00103 if(ibuf->tiles && (ibuf->mall & IB_tiles)) { 00104 for(ty=0; ty<ibuf->ytiles; ty++) { 00105 for(tx=0; tx<ibuf->xtiles; tx++) { 00106 if(ibuf->tiles[ibuf->xtiles*ty + tx]) { 00107 imb_tile_cache_tile_free(ibuf, tx, ty); 00108 MEM_freeN(ibuf->tiles[ibuf->xtiles*ty + tx]); 00109 } 00110 } 00111 } 00112 00113 MEM_freeN(ibuf->tiles); 00114 } 00115 00116 ibuf->tiles= NULL; 00117 ibuf->mall &= ~IB_tiles; 00118 } 00119 00120 static void freeencodedbufferImBuf(ImBuf *ibuf) 00121 { 00122 if(ibuf==NULL) return; 00123 00124 if(ibuf->encodedbuffer && (ibuf->mall & IB_mem)) 00125 MEM_freeN(ibuf->encodedbuffer); 00126 00127 ibuf->encodedbuffer = NULL; 00128 ibuf->encodedbuffersize = 0; 00129 ibuf->encodedsize = 0; 00130 ibuf->mall &= ~IB_mem; 00131 } 00132 00133 void IMB_freezbufImBuf(ImBuf *ibuf) 00134 { 00135 if(ibuf==NULL) return; 00136 00137 if(ibuf->zbuf && (ibuf->mall & IB_zbuf)) 00138 MEM_freeN(ibuf->zbuf); 00139 00140 ibuf->zbuf= NULL; 00141 ibuf->mall &= ~IB_zbuf; 00142 } 00143 00144 void IMB_freezbuffloatImBuf(ImBuf *ibuf) 00145 { 00146 if(ibuf==NULL) return; 00147 00148 if(ibuf->zbuf_float && (ibuf->mall & IB_zbuffloat)) 00149 MEM_freeN(ibuf->zbuf_float); 00150 00151 ibuf->zbuf_float= NULL; 00152 ibuf->mall &= ~IB_zbuffloat; 00153 } 00154 00155 void IMB_freeImBuf(ImBuf *ibuf) 00156 { 00157 if(ibuf) { 00158 if(ibuf->refcounter > 0) { 00159 ibuf->refcounter--; 00160 } 00161 else { 00162 imb_freerectImBuf(ibuf); 00163 imb_freerectfloatImBuf(ibuf); 00164 imb_freetilesImBuf(ibuf); 00165 IMB_freezbufImBuf(ibuf); 00166 IMB_freezbuffloatImBuf(ibuf); 00167 freeencodedbufferImBuf(ibuf); 00168 IMB_cache_limiter_unmanage(ibuf); 00169 IMB_metadata_free(ibuf); 00170 MEM_freeN(ibuf); 00171 } 00172 } 00173 } 00174 00175 void IMB_refImBuf(ImBuf *ibuf) 00176 { 00177 ibuf->refcounter++; 00178 } 00179 00180 short addzbufImBuf(ImBuf *ibuf) 00181 { 00182 int size; 00183 00184 if(ibuf==NULL) return FALSE; 00185 00186 IMB_freezbufImBuf(ibuf); 00187 00188 size = ibuf->x *ibuf->y *sizeof(unsigned int); 00189 if((ibuf->zbuf = MEM_mapallocN(size, "addzbufImBuf"))) { 00190 ibuf->mall |= IB_zbuf; 00191 ibuf->flags |= IB_zbuf; 00192 return TRUE; 00193 } 00194 00195 return FALSE; 00196 } 00197 00198 short addzbuffloatImBuf(ImBuf *ibuf) 00199 { 00200 int size; 00201 00202 if(ibuf==NULL) return FALSE; 00203 00204 IMB_freezbuffloatImBuf(ibuf); 00205 00206 size = ibuf->x *ibuf->y *sizeof(float); 00207 if((ibuf->zbuf_float = MEM_mapallocN(size, "addzbuffloatImBuf"))) { 00208 ibuf->mall |= IB_zbuffloat; 00209 ibuf->flags |= IB_zbuffloat; 00210 return TRUE; 00211 } 00212 00213 return FALSE; 00214 } 00215 00216 00217 short imb_addencodedbufferImBuf(ImBuf *ibuf) 00218 { 00219 if(ibuf==NULL) return FALSE; 00220 00221 freeencodedbufferImBuf(ibuf); 00222 00223 if(ibuf->encodedbuffersize == 0) 00224 ibuf->encodedbuffersize = 10000; 00225 00226 ibuf->encodedsize = 0; 00227 00228 if((ibuf->encodedbuffer = MEM_mallocN(ibuf->encodedbuffersize, "addencodedbufferImBuf"))) { 00229 ibuf->mall |= IB_mem; 00230 ibuf->flags |= IB_mem; 00231 return TRUE; 00232 } 00233 00234 return FALSE; 00235 } 00236 00237 00238 short imb_enlargeencodedbufferImBuf(ImBuf *ibuf) 00239 { 00240 unsigned int newsize, encodedsize; 00241 void *newbuffer; 00242 00243 if(ibuf==NULL) return FALSE; 00244 00245 if(ibuf->encodedbuffersize < ibuf->encodedsize) { 00246 printf("imb_enlargeencodedbufferImBuf: error in parameters\n"); 00247 return FALSE; 00248 } 00249 00250 newsize = 2 *ibuf->encodedbuffersize; 00251 if(newsize < 10000) newsize = 10000; 00252 00253 newbuffer = MEM_mallocN(newsize, "enlargeencodedbufferImBuf"); 00254 if(newbuffer == NULL) return FALSE; 00255 00256 if(ibuf->encodedbuffer) { 00257 memcpy(newbuffer, ibuf->encodedbuffer, ibuf->encodedsize); 00258 } else { 00259 ibuf->encodedsize = 0; 00260 } 00261 00262 encodedsize = ibuf->encodedsize; 00263 00264 freeencodedbufferImBuf(ibuf); 00265 00266 ibuf->encodedbuffersize = newsize; 00267 ibuf->encodedsize = encodedsize; 00268 ibuf->encodedbuffer = newbuffer; 00269 ibuf->mall |= IB_mem; 00270 ibuf->flags |= IB_mem; 00271 00272 return TRUE; 00273 } 00274 00275 short imb_addrectfloatImBuf(ImBuf *ibuf) 00276 { 00277 int size; 00278 00279 if(ibuf==NULL) return FALSE; 00280 00281 if(ibuf->rect_float) 00282 imb_freerectfloatImBuf(ibuf); /* frees mipmap too, hrm */ 00283 00284 size = ibuf->x *ibuf->y; 00285 size = size *4 *sizeof(float); 00286 ibuf->channels= 4; 00287 00288 if((ibuf->rect_float = MEM_mapallocN(size, "imb_addrectfloatImBuf"))) { 00289 ibuf->mall |= IB_rectfloat; 00290 ibuf->flags |= IB_rectfloat; 00291 return TRUE; 00292 } 00293 00294 return FALSE; 00295 } 00296 00297 /* question; why also add zbuf? */ 00298 short imb_addrectImBuf(ImBuf *ibuf) 00299 { 00300 int size; 00301 00302 if(ibuf==NULL) return FALSE; 00303 00304 /* don't call imb_freerectImBuf, it frees mipmaps, this call is used only too give float buffers display */ 00305 if(ibuf->rect && (ibuf->mall & IB_rect)) 00306 MEM_freeN(ibuf->rect); 00307 ibuf->rect= NULL; 00308 00309 size = ibuf->x*ibuf->y; 00310 size = size*sizeof(unsigned int); 00311 00312 if((ibuf->rect = MEM_mapallocN(size, "imb_addrectImBuf"))) { 00313 ibuf->mall |= IB_rect; 00314 ibuf->flags |= IB_rect; 00315 if(ibuf->depth > 32) return (addzbufImBuf(ibuf)); 00316 else return TRUE; 00317 } 00318 00319 return FALSE; 00320 } 00321 00322 short imb_addtilesImBuf(ImBuf *ibuf) 00323 { 00324 if(ibuf==NULL) return FALSE; 00325 00326 if(!ibuf->tiles) 00327 if((ibuf->tiles = MEM_callocN(sizeof(unsigned int*)*ibuf->xtiles*ibuf->ytiles, "imb_tiles"))) 00328 ibuf->mall |= IB_tiles; 00329 00330 return (ibuf->tiles != NULL); 00331 } 00332 00333 ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar d, unsigned int flags) 00334 { 00335 ImBuf *ibuf; 00336 00337 ibuf = MEM_callocN(sizeof(ImBuf), "ImBuf_struct"); 00338 00339 if(ibuf) { 00340 ibuf->x= x; 00341 ibuf->y= y; 00342 ibuf->depth= d; 00343 ibuf->ftype= TGA; 00344 ibuf->channels= 4; /* float option, is set to other values when buffers get assigned */ 00345 ibuf->ppm[0]= ibuf->ppm[1]= 150.0 / 0.0254; /* 150dpi -> pixels-per-meter */ 00346 00347 if(flags & IB_rect) { 00348 if(imb_addrectImBuf(ibuf)==FALSE) { 00349 IMB_freeImBuf(ibuf); 00350 return NULL; 00351 } 00352 } 00353 00354 if(flags & IB_rectfloat) { 00355 if(imb_addrectfloatImBuf(ibuf)==FALSE) { 00356 IMB_freeImBuf(ibuf); 00357 return NULL; 00358 } 00359 } 00360 00361 if(flags & IB_zbuf) { 00362 if(addzbufImBuf(ibuf)==FALSE) { 00363 IMB_freeImBuf(ibuf); 00364 return NULL; 00365 } 00366 } 00367 00368 if(flags & IB_zbuffloat) { 00369 if(addzbuffloatImBuf(ibuf)==FALSE) { 00370 IMB_freeImBuf(ibuf); 00371 return NULL; 00372 } 00373 } 00374 } 00375 return (ibuf); 00376 } 00377 00378 /* does no zbuffers? */ 00379 ImBuf *IMB_dupImBuf(ImBuf *ibuf1) 00380 { 00381 ImBuf *ibuf2, tbuf; 00382 int flags = 0; 00383 int a, x, y; 00384 00385 if(ibuf1 == NULL) return NULL; 00386 00387 if(ibuf1->rect) flags |= IB_rect; 00388 if(ibuf1->rect_float) flags |= IB_rectfloat; 00389 00390 x = ibuf1->x; 00391 y = ibuf1->y; 00392 if(ibuf1->flags & IB_fields) y *= 2; 00393 00394 ibuf2 = IMB_allocImBuf(x, y, ibuf1->depth, flags); 00395 if(ibuf2 == NULL) return NULL; 00396 00397 if(flags & IB_rect) 00398 memcpy(ibuf2->rect, ibuf1->rect, x *y *sizeof(int)); 00399 00400 if(flags & IB_rectfloat) 00401 memcpy(ibuf2->rect_float, ibuf1->rect_float, ibuf1->channels *x *y *sizeof(float)); 00402 00403 if(ibuf1->encodedbuffer) { 00404 ibuf2->encodedbuffersize = ibuf1->encodedbuffersize; 00405 if(imb_addencodedbufferImBuf(ibuf2) == FALSE) { 00406 IMB_freeImBuf(ibuf2); 00407 return NULL; 00408 } 00409 00410 memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize); 00411 } 00412 00413 /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */ 00414 tbuf = *ibuf1; 00415 00416 // fix pointers 00417 tbuf.rect = ibuf2->rect; 00418 tbuf.rect_float = ibuf2->rect_float; 00419 tbuf.encodedbuffer = ibuf2->encodedbuffer; 00420 tbuf.zbuf= NULL; 00421 tbuf.zbuf_float= NULL; 00422 for(a=0; a<IB_MIPMAP_LEVELS; a++) 00423 tbuf.mipmap[a]= NULL; 00424 00425 // set malloc flag 00426 tbuf.mall = ibuf2->mall; 00427 tbuf.c_handle = NULL; 00428 tbuf.refcounter = 0; 00429 00430 // for now don't duplicate metadata 00431 tbuf.metadata = NULL; 00432 00433 *ibuf2 = tbuf; 00434 00435 return(ibuf2); 00436 } 00437 00438 /* support for cache limiting */ 00439 00440 static void imbuf_cache_destructor(void *data) 00441 { 00442 ImBuf *ibuf = (ImBuf*) data; 00443 00444 imb_freerectImBuf(ibuf); 00445 imb_freerectfloatImBuf(ibuf); 00446 IMB_freezbufImBuf(ibuf); 00447 IMB_freezbuffloatImBuf(ibuf); 00448 freeencodedbufferImBuf(ibuf); 00449 00450 ibuf->c_handle = NULL; 00451 } 00452 00453 static MEM_CacheLimiterC **get_imbuf_cache_limiter(void) 00454 { 00455 static MEM_CacheLimiterC *c = NULL; 00456 00457 if(!c) 00458 c = new_MEM_CacheLimiter(imbuf_cache_destructor); 00459 00460 return &c; 00461 } 00462 00463 void IMB_free_cache_limiter(void) 00464 { 00465 delete_MEM_CacheLimiter(*get_imbuf_cache_limiter()); 00466 *get_imbuf_cache_limiter() = NULL; 00467 } 00468 00469 void IMB_cache_limiter_insert(ImBuf *i) 00470 { 00471 if(!i->c_handle) { 00472 i->c_handle = MEM_CacheLimiter_insert( 00473 *get_imbuf_cache_limiter(), i); 00474 MEM_CacheLimiter_ref(i->c_handle); 00475 MEM_CacheLimiter_enforce_limits( 00476 *get_imbuf_cache_limiter()); 00477 MEM_CacheLimiter_unref(i->c_handle); 00478 } 00479 } 00480 00481 void IMB_cache_limiter_unmanage(ImBuf *i) 00482 { 00483 if(i->c_handle) { 00484 MEM_CacheLimiter_unmanage(i->c_handle); 00485 i->c_handle = NULL; 00486 } 00487 } 00488 00489 void IMB_cache_limiter_touch(ImBuf *i) 00490 { 00491 if(i->c_handle) 00492 MEM_CacheLimiter_touch(i->c_handle); 00493 } 00494 00495 void IMB_cache_limiter_ref(ImBuf *i) 00496 { 00497 if(i->c_handle) 00498 MEM_CacheLimiter_ref(i->c_handle); 00499 } 00500 00501 void IMB_cache_limiter_unref(ImBuf *i) 00502 { 00503 if(i->c_handle) 00504 MEM_CacheLimiter_unref(i->c_handle); 00505 } 00506 00507 int IMB_cache_limiter_get_refcount(ImBuf *i) 00508 { 00509 if(i->c_handle) 00510 return MEM_CacheLimiter_get_refcount(i->c_handle); 00511 00512 return 0; 00513 } 00514