VSE: Cache rewrite
[blender.git] / source / blender / imbuf / intern / allocimbuf.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup imbuf
22  */
23
24 /* It's become a bit messy... Basically, only the IMB_ prefixed files
25  * should remain. */
26
27 #include <stddef.h>
28
29 #include "IMB_imbuf.h"
30 #include "IMB_imbuf_types.h"
31
32 #include "IMB_allocimbuf.h"
33 #include "IMB_filetype.h"
34 #include "IMB_metadata.h"
35 #include "IMB_colormanagement_intern.h"
36
37 #include "imbuf.h"
38
39 #include "MEM_guardedalloc.h"
40
41 #include "BLI_utildefines.h"
42 #include "BLI_threads.h"
43
44 static SpinLock refcounter_spin;
45
46 void imb_refcounter_lock_init(void)
47 {
48   BLI_spin_init(&refcounter_spin);
49 }
50
51 void imb_refcounter_lock_exit(void)
52 {
53   BLI_spin_end(&refcounter_spin);
54 }
55
56 #ifdef WIN32
57 static SpinLock mmap_spin;
58
59 void imb_mmap_lock_init(void)
60 {
61   BLI_spin_init(&mmap_spin);
62 }
63
64 void imb_mmap_lock_exit(void)
65 {
66   BLI_spin_end(&mmap_spin);
67 }
68
69 void imb_mmap_lock(void)
70 {
71   BLI_spin_lock(&mmap_spin);
72 }
73
74 void imb_mmap_unlock(void)
75 {
76   BLI_spin_unlock(&mmap_spin);
77 }
78 #endif
79
80 void imb_freemipmapImBuf(ImBuf *ibuf)
81 {
82   int a;
83
84   /* Do not trust ibuf->miptot, in some cases IMB_remakemipmap can leave unfreed unused levels,
85    * leading to memory leaks... */
86   for (a = 0; a < IMB_MIPMAP_LEVELS; a++) {
87     if (ibuf->mipmap[a] != NULL) {
88       IMB_freeImBuf(ibuf->mipmap[a]);
89       ibuf->mipmap[a] = NULL;
90     }
91   }
92
93   ibuf->miptot = 0;
94 }
95
96 /* any free rect frees mipmaps to be sure, creation is in render on first request */
97 void imb_freerectfloatImBuf(ImBuf *ibuf)
98 {
99   if (ibuf == NULL) {
100     return;
101   }
102
103   if (ibuf->rect_float && (ibuf->mall & IB_rectfloat)) {
104     MEM_freeN(ibuf->rect_float);
105     ibuf->rect_float = NULL;
106   }
107
108   imb_freemipmapImBuf(ibuf);
109
110   ibuf->rect_float = NULL;
111   ibuf->mall &= ~IB_rectfloat;
112 }
113
114 /* any free rect frees mipmaps to be sure, creation is in render on first request */
115 void imb_freerectImBuf(ImBuf *ibuf)
116 {
117   if (ibuf == NULL) {
118     return;
119   }
120
121   if (ibuf->rect && (ibuf->mall & IB_rect)) {
122     MEM_freeN(ibuf->rect);
123   }
124   ibuf->rect = NULL;
125
126   imb_freemipmapImBuf(ibuf);
127
128   ibuf->mall &= ~IB_rect;
129 }
130
131 void imb_freetilesImBuf(ImBuf *ibuf)
132 {
133   int tx, ty;
134
135   if (ibuf == NULL) {
136     return;
137   }
138
139   if (ibuf->tiles && (ibuf->mall & IB_tiles)) {
140     for (ty = 0; ty < ibuf->ytiles; ty++) {
141       for (tx = 0; tx < ibuf->xtiles; tx++) {
142         if (ibuf->tiles[ibuf->xtiles * ty + tx]) {
143           imb_tile_cache_tile_free(ibuf, tx, ty);
144           MEM_freeN(ibuf->tiles[ibuf->xtiles * ty + tx]);
145         }
146       }
147     }
148
149     MEM_freeN(ibuf->tiles);
150   }
151
152   ibuf->tiles = NULL;
153   ibuf->mall &= ~IB_tiles;
154 }
155
156 static void freeencodedbufferImBuf(ImBuf *ibuf)
157 {
158   if (ibuf == NULL) {
159     return;
160   }
161
162   if (ibuf->encodedbuffer && (ibuf->mall & IB_mem)) {
163     MEM_freeN(ibuf->encodedbuffer);
164   }
165
166   ibuf->encodedbuffer = NULL;
167   ibuf->encodedbuffersize = 0;
168   ibuf->encodedsize = 0;
169   ibuf->mall &= ~IB_mem;
170 }
171
172 void IMB_freezbufImBuf(ImBuf *ibuf)
173 {
174   if (ibuf == NULL) {
175     return;
176   }
177
178   if (ibuf->zbuf && (ibuf->mall & IB_zbuf)) {
179     MEM_freeN(ibuf->zbuf);
180   }
181
182   ibuf->zbuf = NULL;
183   ibuf->mall &= ~IB_zbuf;
184 }
185
186 void IMB_freezbuffloatImBuf(ImBuf *ibuf)
187 {
188   if (ibuf == NULL) {
189     return;
190   }
191
192   if (ibuf->zbuf_float && (ibuf->mall & IB_zbuffloat)) {
193     MEM_freeN(ibuf->zbuf_float);
194   }
195
196   ibuf->zbuf_float = NULL;
197   ibuf->mall &= ~IB_zbuffloat;
198 }
199
200 void IMB_freeImBuf(ImBuf *ibuf)
201 {
202   if (ibuf) {
203     bool needs_free = false;
204
205     BLI_spin_lock(&refcounter_spin);
206     if (ibuf->refcounter > 0) {
207       ibuf->refcounter--;
208     }
209     else {
210       needs_free = true;
211     }
212     BLI_spin_unlock(&refcounter_spin);
213
214     if (needs_free) {
215       imb_freerectImBuf(ibuf);
216       imb_freerectfloatImBuf(ibuf);
217       imb_freetilesImBuf(ibuf);
218       IMB_freezbufImBuf(ibuf);
219       IMB_freezbuffloatImBuf(ibuf);
220       freeencodedbufferImBuf(ibuf);
221       IMB_metadata_free(ibuf->metadata);
222       colormanage_cache_free(ibuf);
223
224       if (ibuf->dds_data.data != NULL) {
225         /* dds_data.data is allocated by DirectDrawSurface::readData(), so don't use MEM_freeN! */
226         free(ibuf->dds_data.data);
227       }
228       MEM_freeN(ibuf);
229     }
230   }
231 }
232
233 void IMB_refImBuf(ImBuf *ibuf)
234 {
235   BLI_spin_lock(&refcounter_spin);
236   ibuf->refcounter++;
237   BLI_spin_unlock(&refcounter_spin);
238 }
239
240 ImBuf *IMB_makeSingleUser(ImBuf *ibuf)
241 {
242   ImBuf *rval;
243
244   if (ibuf) {
245     bool is_single;
246     BLI_spin_lock(&refcounter_spin);
247     is_single = (ibuf->refcounter == 0);
248     BLI_spin_unlock(&refcounter_spin);
249     if (is_single) {
250       return ibuf;
251     }
252   }
253   else {
254     return NULL;
255   }
256
257   rval = IMB_dupImBuf(ibuf);
258
259   IMB_metadata_copy(rval, ibuf);
260
261   IMB_freeImBuf(ibuf);
262
263   return rval;
264 }
265
266 bool addzbufImBuf(ImBuf *ibuf)
267 {
268   if (ibuf == NULL) {
269     return false;
270   }
271
272   IMB_freezbufImBuf(ibuf);
273
274   if ((ibuf->zbuf = imb_alloc_pixels(ibuf->x, ibuf->y, 1, sizeof(unsigned int), __func__))) {
275     ibuf->mall |= IB_zbuf;
276     ibuf->flags |= IB_zbuf;
277     return true;
278   }
279
280   return false;
281 }
282
283 bool addzbuffloatImBuf(ImBuf *ibuf)
284 {
285   if (ibuf == NULL) {
286     return false;
287   }
288
289   IMB_freezbuffloatImBuf(ibuf);
290
291   if ((ibuf->zbuf_float = imb_alloc_pixels(ibuf->x, ibuf->y, 1, sizeof(float), __func__))) {
292     ibuf->mall |= IB_zbuffloat;
293     ibuf->flags |= IB_zbuffloat;
294     return true;
295   }
296
297   return false;
298 }
299
300 bool imb_addencodedbufferImBuf(ImBuf *ibuf)
301 {
302   if (ibuf == NULL) {
303     return false;
304   }
305
306   freeencodedbufferImBuf(ibuf);
307
308   if (ibuf->encodedbuffersize == 0) {
309     ibuf->encodedbuffersize = 10000;
310   }
311
312   ibuf->encodedsize = 0;
313
314   if ((ibuf->encodedbuffer = MEM_mallocN(ibuf->encodedbuffersize, __func__))) {
315     ibuf->mall |= IB_mem;
316     ibuf->flags |= IB_mem;
317     return true;
318   }
319
320   return false;
321 }
322
323 bool imb_enlargeencodedbufferImBuf(ImBuf *ibuf)
324 {
325   unsigned int newsize, encodedsize;
326   void *newbuffer;
327
328   if (ibuf == NULL) {
329     return false;
330   }
331
332   if (ibuf->encodedbuffersize < ibuf->encodedsize) {
333     printf("%s: error in parameters\n", __func__);
334     return false;
335   }
336
337   newsize = 2 * ibuf->encodedbuffersize;
338   if (newsize < 10000) {
339     newsize = 10000;
340   }
341
342   newbuffer = MEM_mallocN(newsize, __func__);
343   if (newbuffer == NULL) {
344     return false;
345   }
346
347   if (ibuf->encodedbuffer) {
348     memcpy(newbuffer, ibuf->encodedbuffer, ibuf->encodedsize);
349   }
350   else {
351     ibuf->encodedsize = 0;
352   }
353
354   encodedsize = ibuf->encodedsize;
355
356   freeencodedbufferImBuf(ibuf);
357
358   ibuf->encodedbuffersize = newsize;
359   ibuf->encodedsize = encodedsize;
360   ibuf->encodedbuffer = newbuffer;
361   ibuf->mall |= IB_mem;
362   ibuf->flags |= IB_mem;
363
364   return true;
365 }
366
367 void *imb_alloc_pixels(
368     unsigned int x, unsigned int y, unsigned int channels, size_t typesize, const char *name)
369 {
370   /* Protect against buffer overflow vulnerabilities from files specifying
371    * a width and height that overflow and alloc too little memory. */
372   if (!((uint64_t)x * (uint64_t)y < (SIZE_MAX / (channels * typesize)))) {
373     return NULL;
374   }
375
376   size_t size = (size_t)x * (size_t)y * (size_t)channels * typesize;
377   return MEM_mapallocN(size, name);
378 }
379
380 bool imb_addrectfloatImBuf(ImBuf *ibuf)
381 {
382   if (ibuf == NULL) {
383     return false;
384   }
385
386   if (ibuf->rect_float) {
387     imb_freerectfloatImBuf(ibuf); /* frees mipmap too, hrm */
388   }
389
390   ibuf->channels = 4;
391   if ((ibuf->rect_float = imb_alloc_pixels(ibuf->x, ibuf->y, 4, sizeof(float), __func__))) {
392     ibuf->mall |= IB_rectfloat;
393     ibuf->flags |= IB_rectfloat;
394     return true;
395   }
396
397   return false;
398 }
399
400 /* question; why also add zbuf? */
401 bool imb_addrectImBuf(ImBuf *ibuf)
402 {
403   if (ibuf == NULL) {
404     return false;
405   }
406
407   /* Don't call imb_freerectImBuf, it frees mipmaps,
408    * this call is used only too give float buffers display. */
409   if (ibuf->rect && (ibuf->mall & IB_rect)) {
410     MEM_freeN(ibuf->rect);
411   }
412   ibuf->rect = NULL;
413
414   if ((ibuf->rect = imb_alloc_pixels(ibuf->x, ibuf->y, 4, sizeof(unsigned char), __func__))) {
415     ibuf->mall |= IB_rect;
416     ibuf->flags |= IB_rect;
417     if (ibuf->planes > 32) {
418       return (addzbufImBuf(ibuf));
419     }
420     else {
421       return true;
422     }
423   }
424
425   return false;
426 }
427
428 struct ImBuf *IMB_allocFromBuffer(const unsigned int *rect,
429                                   const float *rectf,
430                                   unsigned int w,
431                                   unsigned int h)
432 {
433   ImBuf *ibuf = NULL;
434
435   if (!(rect || rectf)) {
436     return NULL;
437   }
438
439   ibuf = IMB_allocImBuf(w, h, 32, 0);
440
441   if (rectf) {
442     ibuf->rect_float = MEM_dupallocN(rectf);
443     ibuf->flags |= IB_rectfloat;
444     ibuf->mall |= IB_rectfloat;
445   }
446   if (rect) {
447     ibuf->rect = MEM_dupallocN(rect);
448     ibuf->flags |= IB_rect;
449     ibuf->mall |= IB_rect;
450   }
451
452   return ibuf;
453 }
454
455 bool imb_addtilesImBuf(ImBuf *ibuf)
456 {
457   if (ibuf == NULL) {
458     return false;
459   }
460
461   if (!ibuf->tiles) {
462     if ((ibuf->tiles = MEM_callocN(sizeof(unsigned int *) * ibuf->xtiles * ibuf->ytiles,
463                                    "imb_tiles"))) {
464       ibuf->mall |= IB_tiles;
465     }
466   }
467
468   return (ibuf->tiles != NULL);
469 }
470
471 ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar planes, unsigned int flags)
472 {
473   ImBuf *ibuf;
474
475   ibuf = MEM_mallocN(sizeof(ImBuf), "ImBuf_struct");
476
477   if (ibuf) {
478     if (!IMB_initImBuf(ibuf, x, y, planes, flags)) {
479       IMB_freeImBuf(ibuf);
480       return NULL;
481     }
482   }
483
484   return (ibuf);
485 }
486
487 bool IMB_initImBuf(
488     struct ImBuf *ibuf, unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
489 {
490   memset(ibuf, 0, sizeof(ImBuf));
491
492   ibuf->x = x;
493   ibuf->y = y;
494   ibuf->planes = planes;
495   ibuf->ftype = IMB_FTYPE_PNG;
496   ibuf->foptions.quality =
497       15;             /* the 15 means, set compression to low ratio but not time consuming */
498   ibuf->channels = 4; /* float option, is set to other values when buffers get assigned */
499   ibuf->ppm[0] = ibuf->ppm[1] = IMB_DPI_DEFAULT /
500                                 0.0254f; /* IMB_DPI_DEFAULT -> pixels-per-meter */
501
502   if (flags & IB_rect) {
503     if (imb_addrectImBuf(ibuf) == false) {
504       return false;
505     }
506   }
507
508   if (flags & IB_rectfloat) {
509     if (imb_addrectfloatImBuf(ibuf) == false) {
510       return false;
511     }
512   }
513
514   if (flags & IB_zbuf) {
515     if (addzbufImBuf(ibuf) == false) {
516       return false;
517     }
518   }
519
520   if (flags & IB_zbuffloat) {
521     if (addzbuffloatImBuf(ibuf) == false) {
522       return false;
523     }
524   }
525
526   /* assign default spaces */
527   colormanage_imbuf_set_default_spaces(ibuf);
528
529   return true;
530 }
531
532 /* does no zbuffers? */
533 ImBuf *IMB_dupImBuf(const ImBuf *ibuf1)
534 {
535   ImBuf *ibuf2, tbuf;
536   int flags = 0;
537   int a, x, y;
538
539   if (ibuf1 == NULL) {
540     return NULL;
541   }
542
543   if (ibuf1->rect) {
544     flags |= IB_rect;
545   }
546   if (ibuf1->rect_float) {
547     flags |= IB_rectfloat;
548   }
549   if (ibuf1->zbuf) {
550     flags |= IB_zbuf;
551   }
552   if (ibuf1->zbuf_float) {
553     flags |= IB_zbuffloat;
554   }
555
556   x = ibuf1->x;
557   y = ibuf1->y;
558
559   ibuf2 = IMB_allocImBuf(x, y, ibuf1->planes, flags);
560   if (ibuf2 == NULL) {
561     return NULL;
562   }
563
564   if (flags & IB_rect) {
565     memcpy(ibuf2->rect, ibuf1->rect, ((size_t)x) * y * sizeof(int));
566   }
567
568   if (flags & IB_rectfloat) {
569     memcpy(
570         ibuf2->rect_float, ibuf1->rect_float, ((size_t)ibuf1->channels) * x * y * sizeof(float));
571   }
572
573   if (flags & IB_zbuf) {
574     memcpy(ibuf2->zbuf, ibuf1->zbuf, ((size_t)x) * y * sizeof(int));
575   }
576
577   if (flags & IB_zbuffloat) {
578     memcpy(ibuf2->zbuf_float, ibuf1->zbuf_float, ((size_t)x) * y * sizeof(float));
579   }
580
581   if (ibuf1->encodedbuffer) {
582     ibuf2->encodedbuffersize = ibuf1->encodedbuffersize;
583     if (imb_addencodedbufferImBuf(ibuf2) == false) {
584       IMB_freeImBuf(ibuf2);
585       return NULL;
586     }
587
588     memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize);
589   }
590
591   /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */
592   tbuf = *ibuf1;
593
594   /* fix pointers */
595   tbuf.rect = ibuf2->rect;
596   tbuf.rect_float = ibuf2->rect_float;
597   tbuf.encodedbuffer = ibuf2->encodedbuffer;
598   tbuf.zbuf = ibuf2->zbuf;
599   tbuf.zbuf_float = ibuf2->zbuf_float;
600   for (a = 0; a < IMB_MIPMAP_LEVELS; a++) {
601     tbuf.mipmap[a] = NULL;
602   }
603   tbuf.dds_data.data = NULL;
604
605   /* set malloc flag */
606   tbuf.mall = ibuf2->mall;
607   tbuf.c_handle = NULL;
608   tbuf.refcounter = 0;
609
610   /* for now don't duplicate metadata */
611   tbuf.metadata = NULL;
612
613   tbuf.display_buffer_flags = NULL;
614   tbuf.colormanage_cache = NULL;
615
616   *ibuf2 = tbuf;
617
618   return (ibuf2);
619 }
620
621 size_t IMB_get_size_in_memory(ImBuf *ibuf)
622 {
623   int a;
624   size_t size = 0, channel_size = 0;
625
626   size += sizeof(ImBuf);
627
628   if (ibuf->rect)
629     channel_size += sizeof(char);
630
631   if (ibuf->rect_float)
632     channel_size += sizeof(float);
633
634   size += channel_size * ibuf->x * ibuf->y * ibuf->channels;
635
636   if (ibuf->miptot) {
637     for (a = 0; a < ibuf->miptot; a++) {
638       if (ibuf->mipmap[a])
639         size += IMB_get_size_in_memory(ibuf->mipmap[a]);
640     }
641   }
642
643   if (ibuf->tiles) {
644     size += sizeof(unsigned int) * ibuf->ytiles * ibuf->xtiles;
645   }
646
647   return size;
648 }
649
650 #if 0 /* remove? - campbell */
651 /* support for cache limiting */
652
653 static void imbuf_cache_destructor(void *data)
654 {
655   ImBuf *ibuf = (ImBuf *)data;
656
657   imb_freerectImBuf(ibuf);
658   imb_freerectfloatImBuf(ibuf);
659   IMB_freezbufImBuf(ibuf);
660   IMB_freezbuffloatImBuf(ibuf);
661   freeencodedbufferImBuf(ibuf);
662
663   ibuf->c_handle = NULL;
664 }
665
666 static MEM_CacheLimiterC **get_imbuf_cache_limiter(void)
667 {
668   static MEM_CacheLimiterC *c = NULL;
669
670   if (!c) {
671     c = new_MEM_CacheLimiter(imbuf_cache_destructor, NULL);
672   }
673
674   return &c;
675 }
676 #endif