Code refactor: move more memory allocation logic into device API.
[blender.git] / intern / cycles / render / image.cpp
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "device/device.h"
18 #include "render/image.h"
19 #include "render/scene.h"
20
21 #include "util/util_foreach.h"
22 #include "util/util_logging.h"
23 #include "util/util_path.h"
24 #include "util/util_progress.h"
25 #include "util/util_texture.h"
26
27 #ifdef WITH_OSL
28 #include <OSL/oslexec.h>
29 #endif
30
31 CCL_NAMESPACE_BEGIN
32
33 /* Some helpers to silence warning in templated function. */
34 static bool isfinite(uchar /*value*/)
35 {
36         return false;
37 }
38 static bool isfinite(half /*value*/)
39 {
40         return false;
41 }
42
43 ImageManager::ImageManager(const DeviceInfo& info)
44 {
45         need_update = true;
46         osl_texture_system = NULL;
47         animation_frame = 0;
48
49         /* In case of multiple devices used we need to know type of an actual
50          * compute device.
51          *
52          * NOTE: We assume that all the devices are same type, otherwise we'll
53          * be screwed on so many levels..
54          */
55         DeviceType device_type = info.type;
56         if(device_type == DEVICE_MULTI) {
57                 device_type = info.multi_devices[0].type;
58         }
59
60         /* Set image limits */
61         max_num_images = TEX_NUM_MAX;
62         has_half_images = true;
63         cuda_fermi_limits = false;
64
65         if(device_type == DEVICE_CUDA) {
66                 if(!info.has_bindless_textures) {
67                         /* CUDA Fermi hardware (SM 2.x) has a hard limit on the number of textures */
68                         cuda_fermi_limits = true;
69                         has_half_images = false;
70                 }
71         }
72         else if(device_type == DEVICE_OPENCL) {
73                 has_half_images = false;
74         }
75
76         for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
77                 tex_num_images[type] = 0;
78         }
79 }
80
81 ImageManager::~ImageManager()
82 {
83         for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
84                 for(size_t slot = 0; slot < images[type].size(); slot++)
85                         assert(!images[type][slot]);
86         }
87 }
88
89 void ImageManager::set_osl_texture_system(void *texture_system)
90 {
91         osl_texture_system = texture_system;
92 }
93
94 bool ImageManager::set_animation_frame_update(int frame)
95 {
96         if(frame != animation_frame) {
97                 animation_frame = frame;
98
99                 for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
100                         for(size_t slot = 0; slot < images[type].size(); slot++) {
101                                 if(images[type][slot] && images[type][slot]->animated)
102                                         return true;
103                         }
104                 }
105         }
106
107         return false;
108 }
109
110 ImageDataType ImageManager::get_image_metadata(const string& filename,
111                                                void *builtin_data,
112                                                bool& is_linear,
113                                                bool& builtin_free_cache)
114 {
115         bool is_float = false, is_half = false;
116         is_linear = false;
117         builtin_free_cache = false;
118         int channels = 4;
119
120         if(builtin_data) {
121                 if(builtin_image_info_cb) {
122                         int width, height, depth;
123                         builtin_image_info_cb(filename, builtin_data, is_float, width, height, depth, channels, builtin_free_cache);
124                 }
125
126                 if(is_float) {
127                         is_linear = true;
128                         return (channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
129                 }
130                 else {
131                         return (channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
132                 }
133         }
134
135         /* Perform preliminary checks, with meaningful logging. */
136         if(!path_exists(filename)) {
137                 VLOG(1) << "File '" << filename << "' does not exist.";
138                 return IMAGE_DATA_TYPE_BYTE4;
139         }
140         if(path_is_directory(filename)) {
141                 VLOG(1) << "File '" << filename << "' is a directory, can't use as image.";
142                 return IMAGE_DATA_TYPE_BYTE4;
143         }
144
145         ImageInput *in = ImageInput::create(filename);
146
147         if(in) {
148                 ImageSpec spec;
149
150                 if(in->open(filename, spec)) {
151                         /* check the main format, and channel formats;
152                          * if any take up more than one byte, we'll need a float texture slot */
153                         if(spec.format.basesize() > 1) {
154                                 is_float = true;
155                                 is_linear = true;
156                         }
157
158                         for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
159                                 if(spec.channelformats[channel].basesize() > 1) {
160                                         is_float = true;
161                                         is_linear = true;
162                                 }
163                         }
164
165                         /* check if it's half float */
166                         if(spec.format == TypeDesc::HALF)
167                                 is_half = true;
168
169                         channels = spec.nchannels;
170
171                         /* basic color space detection, not great but better than nothing
172                          * before we do OpenColorIO integration */
173                         if(is_float) {
174                                 string colorspace = spec.get_string_attribute("oiio:ColorSpace");
175
176                                 is_linear = !(colorspace == "sRGB" ||
177                                               colorspace == "GammaCorrected" ||
178                                               (colorspace == "" &&
179                                                   (strcmp(in->format_name(), "png") == 0 ||
180                                                    strcmp(in->format_name(), "tiff") == 0 ||
181                                                    strcmp(in->format_name(), "dpx") == 0 ||
182                                                    strcmp(in->format_name(), "jpeg2000") == 0)));
183                         }
184                         else {
185                                 is_linear = false;
186                         }
187
188                         in->close();
189                 }
190
191                 delete in;
192         }
193
194         if(is_half) {
195                 return (channels > 1) ? IMAGE_DATA_TYPE_HALF4 : IMAGE_DATA_TYPE_HALF;
196         }
197         else if(is_float) {
198                 return (channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
199         }
200         else {
201                 return (channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
202         }
203 }
204
205 int ImageManager::max_flattened_slot(ImageDataType type)
206 {
207         if(tex_num_images[type] == 0) {
208                 /* No textures for the type, no slots needs allocation. */
209                 return 0;
210         }
211         return type_index_to_flattened_slot(tex_num_images[type], type);
212 }
213
214 /* The lower three bits of a device texture slot number indicate its type.
215  * These functions convert the slot ids from ImageManager "images" ones
216  * to device ones and vice verse.
217  */
218 int ImageManager::type_index_to_flattened_slot(int slot, ImageDataType type)
219 {
220         return (slot << IMAGE_DATA_TYPE_SHIFT) | (type);
221 }
222
223 int ImageManager::flattened_slot_to_type_index(int flat_slot, ImageDataType *type)
224 {
225         *type = (ImageDataType)(flat_slot & IMAGE_DATA_TYPE_MASK);
226         return flat_slot >> IMAGE_DATA_TYPE_SHIFT;
227 }
228
229 string ImageManager::name_from_type(int type)
230 {
231         if(type == IMAGE_DATA_TYPE_FLOAT4)
232                 return "float4";
233         else if(type == IMAGE_DATA_TYPE_FLOAT)
234                 return "float";
235         else if(type == IMAGE_DATA_TYPE_BYTE)
236                 return "byte";
237         else if(type == IMAGE_DATA_TYPE_HALF4)
238                 return "half4";
239         else if(type == IMAGE_DATA_TYPE_HALF)
240                 return "half";
241         else
242                 return "byte4";
243 }
244
245 static bool image_equals(ImageManager::Image *image,
246                          const string& filename,
247                          void *builtin_data,
248                          InterpolationType interpolation,
249                          ExtensionType extension,
250                          bool use_alpha)
251 {
252         return image->filename == filename &&
253                image->builtin_data == builtin_data &&
254                image->interpolation == interpolation &&
255                image->extension == extension &&
256                image->use_alpha == use_alpha;
257 }
258
259 int ImageManager::add_image(const string& filename,
260                             void *builtin_data,
261                             bool animated,
262                             float frame,
263                             bool& is_float,
264                             bool& is_linear,
265                             InterpolationType interpolation,
266                             ExtensionType extension,
267                             bool use_alpha)
268 {
269         Image *img;
270         size_t slot;
271         bool builtin_free_cache;
272
273         ImageDataType type = get_image_metadata(filename, builtin_data, is_linear, builtin_free_cache);
274
275         thread_scoped_lock device_lock(device_mutex);
276
277         /* Check whether it's a float texture. */
278         is_float = (type == IMAGE_DATA_TYPE_FLOAT || type == IMAGE_DATA_TYPE_FLOAT4);
279
280         /* No single channel and half textures on CUDA (Fermi) and no half on OpenCL, use available slots */
281         if(!has_half_images) {
282                 if(type == IMAGE_DATA_TYPE_HALF4) {
283                         type = IMAGE_DATA_TYPE_FLOAT4;
284                 }
285                 else if(type == IMAGE_DATA_TYPE_HALF) {
286                         type = IMAGE_DATA_TYPE_FLOAT;
287                 }
288         }
289
290         if(cuda_fermi_limits) {
291                 if(type == IMAGE_DATA_TYPE_FLOAT) {
292                         type = IMAGE_DATA_TYPE_FLOAT4;
293                 }
294                 else if(type == IMAGE_DATA_TYPE_BYTE) {
295                         type = IMAGE_DATA_TYPE_BYTE4;
296                 }
297         }
298
299         /* Fnd existing image. */
300         for(slot = 0; slot < images[type].size(); slot++) {
301                 img = images[type][slot];
302                 if(img && image_equals(img,
303                                        filename,
304                                        builtin_data,
305                                        interpolation,
306                                        extension,
307                                        use_alpha))
308                 {
309                         if(img->frame != frame) {
310                                 img->frame = frame;
311                                 img->need_load = true;
312                         }
313                         if(img->use_alpha != use_alpha) {
314                                 img->use_alpha = use_alpha;
315                                 img->need_load = true;
316                         }
317                         img->users++;
318                         return type_index_to_flattened_slot(slot, type);
319                 }
320         }
321
322         /* Find free slot. */
323         for(slot = 0; slot < images[type].size(); slot++) {
324                 if(!images[type][slot])
325                         break;
326         }
327
328         /* Count if we're over the limit */
329         if(cuda_fermi_limits) {
330                 if(tex_num_images[IMAGE_DATA_TYPE_BYTE4] == TEX_NUM_BYTE4_CUDA
331                         || tex_num_images[IMAGE_DATA_TYPE_FLOAT4] == TEX_NUM_FLOAT4_CUDA)
332                 {
333                         printf("ImageManager::add_image: Reached %s image limit (%d), skipping '%s'\n",
334                                 name_from_type(type).c_str(), tex_num_images[type], filename.c_str());
335                         return -1;
336                 }
337         }
338         else {
339                 /* Very unlikely, since max_num_images is insanely big. But better safe than sorry. */
340                 int tex_count = 0;
341                 for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
342                         tex_count += tex_num_images[type];
343                 }
344                 if(tex_count > max_num_images) {
345                         printf("ImageManager::add_image: Reached image limit (%d), skipping '%s'\n",
346                                 max_num_images, filename.c_str());
347                         return -1;
348                 }
349         }
350
351         if(slot == images[type].size()) {
352                 images[type].resize(images[type].size() + 1);
353         }
354
355         /* Add new image. */
356         img = new Image();
357         img->filename = filename;
358         img->builtin_data = builtin_data;
359         img->builtin_free_cache = builtin_free_cache;
360         img->need_load = true;
361         img->animated = animated;
362         img->frame = frame;
363         img->interpolation = interpolation;
364         img->extension = extension;
365         img->users = 1;
366         img->use_alpha = use_alpha;
367         img->mem = NULL;
368
369         images[type][slot] = img;
370
371         ++tex_num_images[type];
372
373         need_update = true;
374
375         return type_index_to_flattened_slot(slot, type);
376 }
377
378 void ImageManager::remove_image(int flat_slot)
379 {
380         ImageDataType type;
381         int slot = flattened_slot_to_type_index(flat_slot, &type);
382
383         Image *image = images[type][slot];
384         assert(image && image->users >= 1);
385
386         /* decrement user count */
387         image->users--;
388
389         /* don't remove immediately, rather do it all together later on. one of
390          * the reasons for this is that on shader changes we add and remove nodes
391          * that use them, but we do not want to reload the image all the time. */
392         if(image->users == 0)
393                 need_update = true;
394 }
395
396 void ImageManager::remove_image(const string& filename,
397                                 void *builtin_data,
398                                 InterpolationType interpolation,
399                                 ExtensionType extension,
400                                 bool use_alpha)
401 {
402         size_t slot;
403
404         for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
405                 for(slot = 0; slot < images[type].size(); slot++) {
406                         if(images[type][slot] && image_equals(images[type][slot],
407                                                               filename,
408                                                               builtin_data,
409                                                               interpolation,
410                                                               extension,
411                                                               use_alpha))
412                         {
413                                 remove_image(type_index_to_flattened_slot(slot, (ImageDataType)type));
414                                 return;
415                         }
416                 }
417         }
418 }
419
420 /* TODO(sergey): Deduplicate with the iteration above, but make it pretty,
421  * without bunch of arguments passing around making code readability even
422  * more cluttered.
423  */
424 void ImageManager::tag_reload_image(const string& filename,
425                                     void *builtin_data,
426                                     InterpolationType interpolation,
427                                     ExtensionType extension,
428                                     bool use_alpha)
429 {
430         for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
431                 for(size_t slot = 0; slot < images[type].size(); slot++) {
432                         if(images[type][slot] && image_equals(images[type][slot],
433                                                               filename,
434                                                               builtin_data,
435                                                               interpolation,
436                                                               extension,
437                                                               use_alpha))
438                         {
439                                 images[type][slot]->need_load = true;
440                                 break;
441                         }
442                 }
443         }
444 }
445
446 bool ImageManager::file_load_image_generic(Image *img,
447                                            ImageInput **in,
448                                            int &width,
449                                            int &height,
450                                            int &depth,
451                                            int &components)
452 {
453         if(img->filename == "")
454                 return false;
455
456         if(!img->builtin_data) {
457                 /* NOTE: Error logging is done in meta data acquisition. */
458                 if(!path_exists(img->filename) || path_is_directory(img->filename)) {
459                         return false;
460                 }
461
462                 /* load image from file through OIIO */
463                 *in = ImageInput::create(img->filename);
464
465                 if(!*in)
466                         return false;
467
468                 ImageSpec spec = ImageSpec();
469                 ImageSpec config = ImageSpec();
470
471                 if(img->use_alpha == false)
472                         config.attribute("oiio:UnassociatedAlpha", 1);
473
474                 if(!(*in)->open(img->filename, spec, config)) {
475                         delete *in;
476                         *in = NULL;
477                         return false;
478                 }
479
480                 width = spec.width;
481                 height = spec.height;
482                 depth = spec.depth;
483                 components = spec.nchannels;
484         }
485         else {
486                 /* load image using builtin images callbacks */
487                 if(!builtin_image_info_cb || !builtin_image_pixels_cb)
488                         return false;
489
490                 bool is_float, free_cache;
491                 builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, depth, components, free_cache);
492         }
493
494         /* we only handle certain number of components */
495         if(!(components >= 1 && components <= 4)) {
496                 if(*in) {
497                         (*in)->close();
498                         delete *in;
499                         *in = NULL;
500                 }
501
502                 return false;
503         }
504
505         return true;
506 }
507
508 template<TypeDesc::BASETYPE FileFormat,
509          typename StorageType,
510          typename DeviceType>
511 bool ImageManager::file_load_image(Image *img,
512                                    ImageDataType type,
513                                    int texture_limit,
514                                    device_vector<DeviceType>& tex_img)
515 {
516         const StorageType alpha_one = (FileFormat == TypeDesc::UINT8)? 255 : 1;
517         ImageInput *in = NULL;
518         int width, height, depth, components;
519         if(!file_load_image_generic(img, &in, width, height, depth, components)) {
520                 return false;
521         }
522         /* Read RGBA pixels. */
523         vector<StorageType> pixels_storage;
524         StorageType *pixels;
525         const size_t max_size = max(max(width, height), depth);
526         if(max_size == 0) {
527                 /* Don't bother with invalid images. */
528                 return false;
529         }
530         if(texture_limit > 0 && max_size > texture_limit) {
531                 pixels_storage.resize(((size_t)width)*height*depth*4);
532                 pixels = &pixels_storage[0];
533         }
534         else {
535                 thread_scoped_lock device_lock(device_mutex);
536                 pixels = (StorageType*)tex_img.alloc(width, height, depth);
537         }
538         if(pixels == NULL) {
539                 /* Could be that we've run out of memory. */
540                 return false;
541         }
542         bool cmyk = false;
543         const size_t num_pixels = ((size_t)width) * height * depth;
544         if(in) {
545                 StorageType *readpixels = pixels;
546                 vector<StorageType> tmppixels;
547                 if(components > 4) {
548                         tmppixels.resize(((size_t)width)*height*components);
549                         readpixels = &tmppixels[0];
550                 }
551                 if(depth <= 1) {
552                         size_t scanlinesize = ((size_t)width)*components*sizeof(StorageType);
553                         in->read_image(FileFormat,
554                                        (uchar*)readpixels + (height-1)*scanlinesize,
555                                        AutoStride,
556                                        -scanlinesize,
557                                        AutoStride);
558                 }
559                 else {
560                         in->read_image(FileFormat, (uchar*)readpixels);
561                 }
562                 if(components > 4) {
563                         size_t dimensions = ((size_t)width)*height;
564                         for(size_t i = dimensions-1, pixel = 0; pixel < dimensions; pixel++, i--) {
565                                 pixels[i*4+3] = tmppixels[i*components+3];
566                                 pixels[i*4+2] = tmppixels[i*components+2];
567                                 pixels[i*4+1] = tmppixels[i*components+1];
568                                 pixels[i*4+0] = tmppixels[i*components+0];
569                         }
570                         tmppixels.clear();
571                 }
572                 cmyk = strcmp(in->format_name(), "jpeg") == 0 && components == 4;
573                 in->close();
574                 delete in;
575         }
576         else {
577                 if(FileFormat == TypeDesc::FLOAT) {
578                         builtin_image_float_pixels_cb(img->filename,
579                                                       img->builtin_data,
580                                                       (float*)&pixels[0],
581                                                       num_pixels * components,
582                                                       img->builtin_free_cache);
583                 }
584                 else if(FileFormat == TypeDesc::UINT8) {
585                         builtin_image_pixels_cb(img->filename,
586                                                 img->builtin_data,
587                                                 (uchar*)&pixels[0],
588                                                 num_pixels * components,
589                                                 img->builtin_free_cache);
590                 }
591                 else {
592                         /* TODO(dingto): Support half for ImBuf. */
593                 }
594         }
595         /* Check if we actually have a float4 slot, in case components == 1,
596          * but device doesn't support single channel textures.
597          */
598         bool is_rgba = (type == IMAGE_DATA_TYPE_FLOAT4 ||
599                         type == IMAGE_DATA_TYPE_HALF4 ||
600                         type == IMAGE_DATA_TYPE_BYTE4);
601         if(is_rgba) {
602                 if(cmyk) {
603                         /* CMYK */
604                         for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
605                                 pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255;
606                                 pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255;
607                                 pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255;
608                                 pixels[i*4+3] = alpha_one;
609                         }
610                 }
611                 else if(components == 2) {
612                         /* grayscale + alpha */
613                         for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
614                                 pixels[i*4+3] = pixels[i*2+1];
615                                 pixels[i*4+2] = pixels[i*2+0];
616                                 pixels[i*4+1] = pixels[i*2+0];
617                                 pixels[i*4+0] = pixels[i*2+0];
618                         }
619                 }
620                 else if(components == 3) {
621                         /* RGB */
622                         for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
623                                 pixels[i*4+3] = alpha_one;
624                                 pixels[i*4+2] = pixels[i*3+2];
625                                 pixels[i*4+1] = pixels[i*3+1];
626                                 pixels[i*4+0] = pixels[i*3+0];
627                         }
628                 }
629                 else if(components == 1) {
630                         /* grayscale */
631                         for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
632                                 pixels[i*4+3] = alpha_one;
633                                 pixels[i*4+2] = pixels[i];
634                                 pixels[i*4+1] = pixels[i];
635                                 pixels[i*4+0] = pixels[i];
636                         }
637                 }
638                 if(img->use_alpha == false) {
639                         for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
640                                 pixels[i*4+3] = alpha_one;
641                         }
642                 }
643         }
644         /* Make sure we don't have buggy values. */
645         if(FileFormat == TypeDesc::FLOAT) {
646                 /* For RGBA buffers we put all channels to 0 if either of them is not
647                  * finite. This way we avoid possible artifacts caused by fully changed
648                  * hue.
649                  */
650                 if(is_rgba) {
651                         for(size_t i = 0; i < num_pixels; i += 4) {
652                                 StorageType *pixel = &pixels[i*4];
653                                 if(!isfinite(pixel[0]) ||
654                                    !isfinite(pixel[1]) ||
655                                    !isfinite(pixel[2]) ||
656                                    !isfinite(pixel[3]))
657                                 {
658                                         pixel[0] = 0;
659                                         pixel[1] = 0;
660                                         pixel[2] = 0;
661                                         pixel[3] = 0;
662                                 }
663                         }
664                 }
665                 else {
666                         for(size_t i = 0; i < num_pixels; ++i) {
667                                 StorageType *pixel = &pixels[i];
668                                 if(!isfinite(pixel[0])) {
669                                         pixel[0] = 0;
670                                 }
671                         }
672                 }
673         }
674         /* Scale image down if needed. */
675         if(pixels_storage.size() > 0) {
676                 float scale_factor = 1.0f;
677                 while(max_size * scale_factor > texture_limit) {
678                         scale_factor *= 0.5f;
679                 }
680                 VLOG(1) << "Scaling image " << img->filename
681                         << " by a factor of " << scale_factor << ".";
682                 vector<StorageType> scaled_pixels;
683                 size_t scaled_width, scaled_height, scaled_depth;
684                 util_image_resize_pixels(pixels_storage,
685                                          width, height, depth,
686                                          is_rgba ? 4 : 1,
687                                          scale_factor,
688                                          &scaled_pixels,
689                                          &scaled_width, &scaled_height, &scaled_depth);
690
691                 StorageType *texture_pixels;
692
693                 {
694                         thread_scoped_lock device_lock(device_mutex);
695                         texture_pixels = (StorageType*)tex_img.alloc(scaled_width,
696                                                                      scaled_height,
697                                                                      scaled_depth);
698                 }
699
700                 memcpy(texture_pixels,
701                        &scaled_pixels[0],
702                        scaled_pixels.size() * sizeof(StorageType));
703         }
704         return true;
705 }
706
707 void ImageManager::device_load_image(Device *device,
708                                      Scene *scene,
709                                      ImageDataType type,
710                                      int slot,
711                                      Progress *progress)
712 {
713         if(progress->get_cancel())
714                 return;
715
716         Image *img = images[type][slot];
717
718         if(osl_texture_system && !img->builtin_data)
719                 return;
720
721         string filename = path_filename(images[type][slot]->filename);
722         progress->set_status("Updating Images", "Loading " + filename);
723
724         const int texture_limit = scene->params.texture_limit;
725
726         /* Slot assignment */
727         int flat_slot = type_index_to_flattened_slot(slot, type);
728         string name = string_printf("__tex_image_%s_%03d", name_from_type(type).c_str(), flat_slot);
729
730         /* Free previous texture in slot. */
731         if(img->mem) {
732                 thread_scoped_lock device_lock(device_mutex);
733                 delete img->mem;
734                 img->mem = NULL;
735         }
736
737         /* Create new texture. */
738         if(type == IMAGE_DATA_TYPE_FLOAT4) {
739                 device_vector<float4> *tex_img
740                         = new device_vector<float4>(device, name.c_str(), MEM_TEXTURE);
741
742                 if(!file_load_image<TypeDesc::FLOAT, float>(img,
743                                                             type,
744                                                             texture_limit,
745                                                             *tex_img))
746                 {
747                         /* on failure to load, we set a 1x1 pixels pink image */
748                         float *pixels = (float*)tex_img->alloc(1, 1);
749
750                         pixels[0] = TEX_IMAGE_MISSING_R;
751                         pixels[1] = TEX_IMAGE_MISSING_G;
752                         pixels[2] = TEX_IMAGE_MISSING_B;
753                         pixels[3] = TEX_IMAGE_MISSING_A;
754                 }
755
756                 img->mem = tex_img;
757                 img->mem->interpolation = img->interpolation;
758                 img->mem->extension = img->extension;
759
760                 thread_scoped_lock device_lock(device_mutex);
761                 tex_img->copy_to_device();
762         }
763         else if(type == IMAGE_DATA_TYPE_FLOAT) {
764                 device_vector<float> *tex_img
765                         = new device_vector<float>(device, name.c_str(), MEM_TEXTURE);
766
767                 if(!file_load_image<TypeDesc::FLOAT, float>(img,
768                                                             type,
769                                                             texture_limit,
770                                                             *tex_img))
771                 {
772                         /* on failure to load, we set a 1x1 pixels pink image */
773                         float *pixels = (float*)tex_img->alloc(1, 1);
774
775                         pixels[0] = TEX_IMAGE_MISSING_R;
776                 }
777
778                 img->mem = tex_img;
779                 img->mem->interpolation = img->interpolation;
780                 img->mem->extension = img->extension;
781
782                 thread_scoped_lock device_lock(device_mutex);
783                 tex_img->copy_to_device();
784         }
785         else if(type == IMAGE_DATA_TYPE_BYTE4) {
786                 device_vector<uchar4> *tex_img
787                         = new device_vector<uchar4>(device, name.c_str(), MEM_TEXTURE);
788
789                 if(!file_load_image<TypeDesc::UINT8, uchar>(img,
790                                                             type,
791                                                             texture_limit,
792                                                             *tex_img))
793                 {
794                         /* on failure to load, we set a 1x1 pixels pink image */
795                         uchar *pixels = (uchar*)tex_img->alloc(1, 1);
796
797                         pixels[0] = (TEX_IMAGE_MISSING_R * 255);
798                         pixels[1] = (TEX_IMAGE_MISSING_G * 255);
799                         pixels[2] = (TEX_IMAGE_MISSING_B * 255);
800                         pixels[3] = (TEX_IMAGE_MISSING_A * 255);
801                 }
802
803                 img->mem = tex_img;
804                 img->mem->interpolation = img->interpolation;
805                 img->mem->extension = img->extension;
806
807                 thread_scoped_lock device_lock(device_mutex);
808                 tex_img->copy_to_device();
809         }
810         else if(type == IMAGE_DATA_TYPE_BYTE) {
811                 device_vector<uchar> *tex_img
812                         = new device_vector<uchar>(device, name.c_str(), MEM_TEXTURE);
813
814                 if(!file_load_image<TypeDesc::UINT8, uchar>(img,
815                                                             type,
816                                                             texture_limit,
817                                                             *tex_img)) {
818                         /* on failure to load, we set a 1x1 pixels pink image */
819                         uchar *pixels = (uchar*)tex_img->alloc(1, 1);
820
821                         pixels[0] = (TEX_IMAGE_MISSING_R * 255);
822                 }
823
824                 img->mem = tex_img;
825                 img->mem->interpolation = img->interpolation;
826                 img->mem->extension = img->extension;
827
828                 thread_scoped_lock device_lock(device_mutex);
829                 tex_img->copy_to_device();
830         }
831         else if(type == IMAGE_DATA_TYPE_HALF4) {
832                 device_vector<half4> *tex_img
833                         = new device_vector<half4>(device, name.c_str(), MEM_TEXTURE);
834
835                 if(!file_load_image<TypeDesc::HALF, half>(img,
836                                                           type,
837                                                           texture_limit,
838                                                           *tex_img)) {
839                         /* on failure to load, we set a 1x1 pixels pink image */
840                         half *pixels = (half*)tex_img->alloc(1, 1);
841
842                         pixels[0] = TEX_IMAGE_MISSING_R;
843                         pixels[1] = TEX_IMAGE_MISSING_G;
844                         pixels[2] = TEX_IMAGE_MISSING_B;
845                         pixels[3] = TEX_IMAGE_MISSING_A;
846                 }
847
848                 img->mem = tex_img;
849                 img->mem->interpolation = img->interpolation;
850                 img->mem->extension = img->extension;
851
852                 thread_scoped_lock device_lock(device_mutex);
853                 tex_img->copy_to_device();
854         }
855         else if(type == IMAGE_DATA_TYPE_HALF) {
856                 device_vector<half> *tex_img
857                         = new device_vector<half>(device, name.c_str(), MEM_TEXTURE);
858
859                 if(!file_load_image<TypeDesc::HALF, half>(img,
860                                                           type,
861                                                           texture_limit,
862                                                           *tex_img)) {
863                         /* on failure to load, we set a 1x1 pixels pink image */
864                         half *pixels = (half*)tex_img->alloc(1, 1);
865
866                         pixels[0] = TEX_IMAGE_MISSING_R;
867                 }
868
869                 img->mem = tex_img;
870                 img->mem->interpolation = img->interpolation;
871                 img->mem->extension = img->extension;
872
873                 thread_scoped_lock device_lock(device_mutex);
874                 tex_img->copy_to_device();
875         }
876
877         img->need_load = false;
878 }
879
880 void ImageManager::device_free_image(Device *, ImageDataType type, int slot)
881 {
882         Image *img = images[type][slot];
883
884         if(img) {
885                 if(osl_texture_system && !img->builtin_data) {
886 #ifdef WITH_OSL
887                         ustring filename(images[type][slot]->filename);
888                         ((OSL::TextureSystem*)osl_texture_system)->invalidate(filename);
889 #endif
890                 }
891
892                 if(img->mem) {
893                         thread_scoped_lock device_lock(device_mutex);
894                         delete img->mem;
895                 }
896
897                 delete img;
898                 images[type][slot] = NULL;
899                 --tex_num_images[type];
900         }
901 }
902
903 void ImageManager::device_update(Device *device,
904                                  Scene *scene,
905                                  Progress& progress)
906 {
907         if(!need_update) {
908                 return;
909         }
910
911         TaskPool pool;
912         for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
913                 for(size_t slot = 0; slot < images[type].size(); slot++) {
914                         if(!images[type][slot])
915                                 continue;
916
917                         if(images[type][slot]->users == 0) {
918                                 device_free_image(device, (ImageDataType)type, slot);
919                         }
920                         else if(images[type][slot]->need_load) {
921                                 if(!osl_texture_system || images[type][slot]->builtin_data)
922                                         pool.push(function_bind(&ImageManager::device_load_image,
923                                                                 this,
924                                                                 device,
925                                                                 scene,
926                                                                 (ImageDataType)type,
927                                                                 slot,
928                                                                 &progress));
929                         }
930                 }
931         }
932
933         pool.wait_work();
934
935         need_update = false;
936 }
937
938 void ImageManager::device_update_slot(Device *device,
939                                       Scene *scene,
940                                       int flat_slot,
941                                       Progress *progress)
942 {
943         ImageDataType type;
944         int slot = flattened_slot_to_type_index(flat_slot, &type);
945
946         Image *image = images[type][slot];
947         assert(image != NULL);
948
949         if(image->users == 0) {
950                 device_free_image(device, type, slot);
951         }
952         else if(image->need_load) {
953                 if(!osl_texture_system || image->builtin_data)
954                         device_load_image(device,
955                                           scene,
956                                           type,
957                                           slot,
958                                           progress);
959         }
960 }
961
962 void ImageManager::device_free_builtin(Device *device)
963 {
964         for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
965                 for(size_t slot = 0; slot < images[type].size(); slot++) {
966                         if(images[type][slot] && images[type][slot]->builtin_data)
967                                 device_free_image(device, (ImageDataType)type, slot);
968                 }
969         }
970 }
971
972 void ImageManager::device_free(Device *device)
973 {
974         for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
975                 for(size_t slot = 0; slot < images[type].size(); slot++) {
976                         device_free_image(device, (ImageDataType)type, slot);
977                 }
978                 images[type].clear();
979         }
980 }
981
982 CCL_NAMESPACE_END
983