Remove currently unused IMB_cache_limiter_* function.
[blender.git] / source / blender / imbuf / intern / allocimbuf.c
1 /*
2  * allocimbuf.c
3  *
4  *
5  * ***** BEGIN GPL LICENSE BLOCK *****
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
22  * All rights reserved.
23  *
24  * The Original Code is: all of this file.
25  *
26  * Contributor(s): none yet.
27  *
28  * ***** END GPL LICENSE BLOCK *****
29  */
30
31 /** \file blender/imbuf/intern/allocimbuf.c
32  *  \ingroup imbuf
33  */
34
35
36 /* It's become a bit messy... Basically, only the IMB_ prefixed files
37  * should remain. */
38
39 #include <stddef.h>
40
41 #include "IMB_imbuf.h"
42 #include "IMB_imbuf_types.h"
43
44 #include "IMB_allocimbuf.h"
45 #include "IMB_filetype.h"
46 #include "IMB_metadata.h"
47
48 #include "imbuf.h"
49
50 #include "MEM_CacheLimiterC-Api.h"
51 #include "MEM_guardedalloc.h"
52
53 void imb_freemipmapImBuf(ImBuf *ibuf)
54 {
55         int a;
56         
57         for(a=1; a<ibuf->miptot; a++) {
58                 if(ibuf->mipmap[a-1])
59                         IMB_freeImBuf(ibuf->mipmap[a-1]);
60                 ibuf->mipmap[a-1]= NULL;
61         }
62
63         ibuf->miptot= 0;
64 }
65
66 /* any free rect frees mipmaps to be sure, creation is in render on first request */
67 void imb_freerectfloatImBuf(ImBuf *ibuf)
68 {
69         if(ibuf==NULL) return;
70         
71         if(ibuf->rect_float && (ibuf->mall & IB_rectfloat)) {
72                 MEM_freeN(ibuf->rect_float);
73                 ibuf->rect_float=NULL;
74         }
75
76         imb_freemipmapImBuf(ibuf);
77         
78         ibuf->rect_float= NULL;
79         ibuf->mall &= ~IB_rectfloat;
80 }
81
82 /* any free rect frees mipmaps to be sure, creation is in render on first request */
83 void imb_freerectImBuf(ImBuf *ibuf)
84 {
85         if(ibuf==NULL) return;
86
87         if(ibuf->rect && (ibuf->mall & IB_rect))
88                 MEM_freeN(ibuf->rect);
89         ibuf->rect= NULL;
90         
91         imb_freemipmapImBuf(ibuf);
92
93         ibuf->mall &= ~IB_rect;
94 }
95
96 void imb_freetilesImBuf(ImBuf *ibuf)
97 {
98         int tx, ty;
99
100         if(ibuf==NULL) return;
101
102         if(ibuf->tiles && (ibuf->mall & IB_tiles)) {
103                 for(ty=0; ty<ibuf->ytiles; ty++) {
104                         for(tx=0; tx<ibuf->xtiles; tx++) {
105                                 if(ibuf->tiles[ibuf->xtiles*ty + tx]) {
106                                         imb_tile_cache_tile_free(ibuf, tx, ty);
107                                         MEM_freeN(ibuf->tiles[ibuf->xtiles*ty + tx]);
108                                 }
109                         }
110                 }
111
112                 MEM_freeN(ibuf->tiles);
113         }
114
115         ibuf->tiles= NULL;
116         ibuf->mall &= ~IB_tiles;
117 }
118
119 static void freeencodedbufferImBuf(ImBuf *ibuf)
120 {
121         if(ibuf==NULL) return;
122
123         if(ibuf->encodedbuffer && (ibuf->mall & IB_mem))
124                 MEM_freeN(ibuf->encodedbuffer);
125
126         ibuf->encodedbuffer = NULL;
127         ibuf->encodedbuffersize = 0;
128         ibuf->encodedsize = 0;
129         ibuf->mall &= ~IB_mem;
130 }
131
132 void IMB_freezbufImBuf(ImBuf *ibuf)
133 {
134         if(ibuf==NULL) return;
135
136         if(ibuf->zbuf && (ibuf->mall & IB_zbuf))
137                 MEM_freeN(ibuf->zbuf);
138
139         ibuf->zbuf= NULL;
140         ibuf->mall &= ~IB_zbuf;
141 }
142
143 void IMB_freezbuffloatImBuf(ImBuf *ibuf)
144 {
145         if(ibuf==NULL) return;
146
147         if(ibuf->zbuf_float && (ibuf->mall & IB_zbuffloat))
148                 MEM_freeN(ibuf->zbuf_float);
149
150         ibuf->zbuf_float= NULL;
151         ibuf->mall &= ~IB_zbuffloat;
152 }
153
154 void IMB_freeImBuf(ImBuf *ibuf)
155 {
156         if(ibuf) {
157                 if(ibuf->refcounter > 0) {
158                         ibuf->refcounter--;
159                 }
160                 else {
161                         imb_freerectImBuf(ibuf);
162                         imb_freerectfloatImBuf(ibuf);
163                         imb_freetilesImBuf(ibuf);
164                         IMB_freezbufImBuf(ibuf);
165                         IMB_freezbuffloatImBuf(ibuf);
166                         freeencodedbufferImBuf(ibuf);
167                         IMB_metadata_free(ibuf);
168                         MEM_freeN(ibuf);
169                 }
170         }
171 }
172
173 void IMB_refImBuf(ImBuf *ibuf)
174 {
175         ibuf->refcounter++;
176 }
177
178 ImBuf * IMB_makeSingleUser(ImBuf *ibuf)
179 {
180         ImBuf * rval;
181
182         if (!ibuf || ibuf->refcounter == 0) { return ibuf; }
183
184         rval = IMB_dupImBuf(ibuf);
185
186         IMB_freeImBuf(ibuf);
187
188         return rval;
189 }
190
191 short addzbufImBuf(ImBuf *ibuf)
192 {
193         int size;
194         
195         if(ibuf==NULL) return FALSE;
196         
197         IMB_freezbufImBuf(ibuf);
198         
199         size = ibuf->x *ibuf->y *sizeof(unsigned int);
200         if((ibuf->zbuf = MEM_mapallocN(size, "addzbufImBuf"))) {
201                 ibuf->mall |= IB_zbuf;
202                 ibuf->flags |= IB_zbuf;
203                 return TRUE;
204         }
205         
206         return FALSE;
207 }
208
209 short addzbuffloatImBuf(ImBuf *ibuf)
210 {
211         int size;
212         
213         if(ibuf==NULL) return FALSE;
214         
215         IMB_freezbuffloatImBuf(ibuf);
216         
217         size = ibuf->x *ibuf->y *sizeof(float);
218         if((ibuf->zbuf_float = MEM_mapallocN(size, "addzbuffloatImBuf"))) {
219                 ibuf->mall |= IB_zbuffloat;
220                 ibuf->flags |= IB_zbuffloat;
221                 return TRUE;
222         }
223         
224         return FALSE;
225 }
226
227
228 short imb_addencodedbufferImBuf(ImBuf *ibuf)
229 {
230         if(ibuf==NULL) return FALSE;
231
232         freeencodedbufferImBuf(ibuf);
233
234         if(ibuf->encodedbuffersize == 0) 
235                 ibuf->encodedbuffersize = 10000;
236
237         ibuf->encodedsize = 0;
238
239         if((ibuf->encodedbuffer = MEM_mallocN(ibuf->encodedbuffersize, "addencodedbufferImBuf"))) {
240                 ibuf->mall |= IB_mem;
241                 ibuf->flags |= IB_mem;
242                 return TRUE;
243         }
244
245         return FALSE;
246 }
247
248
249 short imb_enlargeencodedbufferImBuf(ImBuf *ibuf)
250 {
251         unsigned int newsize, encodedsize;
252         void *newbuffer;
253
254         if(ibuf==NULL) return FALSE;
255
256         if(ibuf->encodedbuffersize < ibuf->encodedsize) {
257                 printf("imb_enlargeencodedbufferImBuf: error in parameters\n");
258                 return FALSE;
259         }
260
261         newsize = 2 *ibuf->encodedbuffersize;
262         if(newsize < 10000) newsize = 10000;
263
264         newbuffer = MEM_mallocN(newsize, "enlargeencodedbufferImBuf");
265         if(newbuffer == NULL) return FALSE;
266
267         if(ibuf->encodedbuffer) {
268                 memcpy(newbuffer, ibuf->encodedbuffer, ibuf->encodedsize);
269         } else {
270                 ibuf->encodedsize = 0;
271         }
272
273         encodedsize = ibuf->encodedsize;
274
275         freeencodedbufferImBuf(ibuf);
276
277         ibuf->encodedbuffersize = newsize;
278         ibuf->encodedsize = encodedsize;
279         ibuf->encodedbuffer = newbuffer;
280         ibuf->mall |= IB_mem;
281         ibuf->flags |= IB_mem;
282
283         return TRUE;
284 }
285
286 short imb_addrectfloatImBuf(ImBuf *ibuf)
287 {
288         int size;
289         
290         if(ibuf==NULL) return FALSE;
291         
292         if(ibuf->rect_float)
293                 imb_freerectfloatImBuf(ibuf); /* frees mipmap too, hrm */
294         
295         size = ibuf->x *ibuf->y;
296         size = size *4 *sizeof(float);
297         ibuf->channels= 4;
298         
299         if((ibuf->rect_float = MEM_mapallocN(size, "imb_addrectfloatImBuf"))) {
300                 ibuf->mall |= IB_rectfloat;
301                 ibuf->flags |= IB_rectfloat;
302                 return TRUE;
303         }
304         
305         return FALSE;
306 }
307
308 /* question; why also add zbuf? */
309 short imb_addrectImBuf(ImBuf *ibuf)
310 {
311         int size;
312
313         if(ibuf==NULL) return FALSE;
314         
315         /* don't call imb_freerectImBuf, it frees mipmaps, this call is used only too give float buffers display */
316         if(ibuf->rect && (ibuf->mall & IB_rect))
317                 MEM_freeN(ibuf->rect);
318         ibuf->rect= NULL;
319         
320         size = ibuf->x*ibuf->y;
321         size = size*sizeof(unsigned int);
322
323         if((ibuf->rect = MEM_mapallocN(size, "imb_addrectImBuf"))) {
324                 ibuf->mall |= IB_rect;
325                 ibuf->flags |= IB_rect;
326                 if(ibuf->depth > 32) return (addzbufImBuf(ibuf));
327                 else return TRUE;
328         }
329
330         return FALSE;
331 }
332
333 short imb_addtilesImBuf(ImBuf *ibuf)
334 {
335         if(ibuf==NULL) return FALSE;
336
337         if(!ibuf->tiles)
338                 if((ibuf->tiles = MEM_callocN(sizeof(unsigned int*)*ibuf->xtiles*ibuf->ytiles, "imb_tiles")))
339                         ibuf->mall |= IB_tiles;
340
341         return (ibuf->tiles != NULL);
342 }
343
344 ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar d, unsigned int flags)
345 {
346         ImBuf *ibuf;
347
348         ibuf = MEM_callocN(sizeof(ImBuf), "ImBuf_struct");
349
350         if(ibuf) {
351                 ibuf->x= x;
352                 ibuf->y= y;
353                 ibuf->depth= d;
354                 ibuf->ftype= TGA;
355                 ibuf->channels= 4;      /* float option, is set to other values when buffers get assigned */
356                 ibuf->ppm[0]= ibuf->ppm[1]= 150.0 / 0.0254; /* 150dpi -> pixels-per-meter */
357                 
358                 if(flags & IB_rect) {
359                         if(imb_addrectImBuf(ibuf)==FALSE) {
360                                 IMB_freeImBuf(ibuf);
361                                 return NULL;
362                         }
363                 }
364                 
365                 if(flags & IB_rectfloat) {
366                         if(imb_addrectfloatImBuf(ibuf)==FALSE) {
367                                 IMB_freeImBuf(ibuf);
368                                 return NULL;
369                         }
370                 }
371                 
372                 if(flags & IB_zbuf) {
373                         if(addzbufImBuf(ibuf)==FALSE) {
374                                 IMB_freeImBuf(ibuf);
375                                 return NULL;
376                         }
377                 }
378                 
379                 if(flags & IB_zbuffloat) {
380                         if(addzbuffloatImBuf(ibuf)==FALSE) {
381                                 IMB_freeImBuf(ibuf);
382                                 return NULL;
383                         }
384                 }
385         }
386         return (ibuf);
387 }
388
389 /* does no zbuffers? */
390 ImBuf *IMB_dupImBuf(ImBuf *ibuf1)
391 {
392         ImBuf *ibuf2, tbuf;
393         int flags = 0;
394         int a, x, y;
395         
396         if(ibuf1 == NULL) return NULL;
397
398         if(ibuf1->rect) flags |= IB_rect;
399         if(ibuf1->rect_float) flags |= IB_rectfloat;
400
401         x = ibuf1->x;
402         y = ibuf1->y;
403         if(ibuf1->flags & IB_fields) y *= 2;
404         
405         ibuf2 = IMB_allocImBuf(x, y, ibuf1->depth, flags);
406         if(ibuf2 == NULL) return NULL;
407
408         if(flags & IB_rect)
409                 memcpy(ibuf2->rect, ibuf1->rect, x *y *sizeof(int));
410         
411         if(flags & IB_rectfloat)
412                 memcpy(ibuf2->rect_float, ibuf1->rect_float, ibuf1->channels *x *y *sizeof(float));
413
414         if(ibuf1->encodedbuffer) {
415                 ibuf2->encodedbuffersize = ibuf1->encodedbuffersize;
416                 if(imb_addencodedbufferImBuf(ibuf2) == FALSE) {
417                         IMB_freeImBuf(ibuf2);
418                         return NULL;
419                 }
420
421                 memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize);
422         }
423
424         /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */
425         tbuf = *ibuf1;
426         
427         // fix pointers 
428         tbuf.rect               = ibuf2->rect;
429         tbuf.rect_float = ibuf2->rect_float;
430         tbuf.encodedbuffer = ibuf2->encodedbuffer;
431         tbuf.zbuf= NULL;
432         tbuf.zbuf_float= NULL;
433         for(a=0; a<IB_MIPMAP_LEVELS; a++)
434                 tbuf.mipmap[a]= NULL;
435         
436         // set malloc flag
437         tbuf.mall               = ibuf2->mall;
438         tbuf.c_handle           = NULL;
439         tbuf.refcounter         = 0;
440
441         // for now don't duplicate metadata
442         tbuf.metadata = NULL;
443
444         *ibuf2 = tbuf;
445         
446         return(ibuf2);
447 }
448
449 /* support for cache limiting */
450
451 static void imbuf_cache_destructor(void *data)
452 {
453         ImBuf *ibuf = (ImBuf*) data;
454
455         imb_freerectImBuf(ibuf);
456         imb_freerectfloatImBuf(ibuf);
457         IMB_freezbufImBuf(ibuf);
458         IMB_freezbuffloatImBuf(ibuf);
459         freeencodedbufferImBuf(ibuf);
460
461         ibuf->c_handle = NULL;
462 }
463
464 static MEM_CacheLimiterC **get_imbuf_cache_limiter(void)
465 {
466         static MEM_CacheLimiterC *c = NULL;
467
468         if(!c)
469                 c = new_MEM_CacheLimiter(imbuf_cache_destructor, NULL);
470
471         return &c;
472 }