e7f5ff002b7bb80df08457d6ca414b84fe9351f3
[blender-staging.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                 pixels = (StorageType*)tex_img.resize(width, height, depth);
536         }
537         if(pixels == NULL) {
538                 /* Could be that we've run out of memory. */
539                 return false;
540         }
541         bool cmyk = false;
542         const size_t num_pixels = ((size_t)width) * height * depth;
543         if(in) {
544                 StorageType *readpixels = pixels;
545                 vector<StorageType> tmppixels;
546                 if(components > 4) {
547                         tmppixels.resize(((size_t)width)*height*components);
548                         readpixels = &tmppixels[0];
549                 }
550                 if(depth <= 1) {
551                         size_t scanlinesize = ((size_t)width)*components*sizeof(StorageType);
552                         in->read_image(FileFormat,
553                                        (uchar*)readpixels + (height-1)*scanlinesize,
554                                        AutoStride,
555                                        -scanlinesize,
556                                        AutoStride);
557                 }
558                 else {
559                         in->read_image(FileFormat, (uchar*)readpixels);
560                 }
561                 if(components > 4) {
562                         size_t dimensions = ((size_t)width)*height;
563                         for(size_t i = dimensions-1, pixel = 0; pixel < dimensions; pixel++, i--) {
564                                 pixels[i*4+3] = tmppixels[i*components+3];
565                                 pixels[i*4+2] = tmppixels[i*components+2];
566                                 pixels[i*4+1] = tmppixels[i*components+1];
567                                 pixels[i*4+0] = tmppixels[i*components+0];
568                         }
569                         tmppixels.clear();
570                 }
571                 cmyk = strcmp(in->format_name(), "jpeg") == 0 && components == 4;
572                 in->close();
573                 delete in;
574         }
575         else {
576                 if(FileFormat == TypeDesc::FLOAT) {
577                         builtin_image_float_pixels_cb(img->filename,
578                                                       img->builtin_data,
579                                                       (float*)&pixels[0],
580                                                       num_pixels * components,
581                                                       img->builtin_free_cache);
582                 }
583                 else if(FileFormat == TypeDesc::UINT8) {
584                         builtin_image_pixels_cb(img->filename,
585                                                 img->builtin_data,
586                                                 (uchar*)&pixels[0],
587                                                 num_pixels * components,
588                                                 img->builtin_free_cache);
589                 }
590                 else {
591                         /* TODO(dingto): Support half for ImBuf. */
592                 }
593         }
594         /* Check if we actually have a float4 slot, in case components == 1,
595          * but device doesn't support single channel textures.
596          */
597         bool is_rgba = (type == IMAGE_DATA_TYPE_FLOAT4 ||
598                         type == IMAGE_DATA_TYPE_HALF4 ||
599                         type == IMAGE_DATA_TYPE_BYTE4);
600         if(is_rgba) {
601                 if(cmyk) {
602                         /* CMYK */
603                         for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
604                                 pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255;
605                                 pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255;
606                                 pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255;
607                                 pixels[i*4+3] = alpha_one;
608                         }
609                 }
610                 else if(components == 2) {
611                         /* grayscale + alpha */
612                         for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
613                                 pixels[i*4+3] = pixels[i*2+1];
614                                 pixels[i*4+2] = pixels[i*2+0];
615                                 pixels[i*4+1] = pixels[i*2+0];
616                                 pixels[i*4+0] = pixels[i*2+0];
617                         }
618                 }
619                 else if(components == 3) {
620                         /* RGB */
621                         for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
622                                 pixels[i*4+3] = alpha_one;
623                                 pixels[i*4+2] = pixels[i*3+2];
624                                 pixels[i*4+1] = pixels[i*3+1];
625                                 pixels[i*4+0] = pixels[i*3+0];
626                         }
627                 }
628                 else if(components == 1) {
629                         /* grayscale */
630                         for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
631                                 pixels[i*4+3] = alpha_one;
632                                 pixels[i*4+2] = pixels[i];
633                                 pixels[i*4+1] = pixels[i];
634                                 pixels[i*4+0] = pixels[i];
635                         }
636                 }
637                 if(img->use_alpha == false) {
638                         for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
639                                 pixels[i*4+3] = alpha_one;
640                         }
641                 }
642         }
643         /* Make sure we don't have buggy values. */
644         if(FileFormat == TypeDesc::FLOAT) {
645                 /* For RGBA buffers we put all channels to 0 if either of them is not
646                  * finite. This way we avoid possible artifacts caused by fully changed
647                  * hue.
648                  */
649                 if(is_rgba) {
650                         for(size_t i = 0; i < num_pixels; i += 4) {
651                                 StorageType *pixel = &pixels[i*4];
652                                 if(!isfinite(pixel[0]) ||
653                                    !isfinite(pixel[1]) ||
654                                    !isfinite(pixel[2]) ||
655                                    !isfinite(pixel[3]))
656                                 {
657                                         pixel[0] = 0;
658                                         pixel[1] = 0;
659                                         pixel[2] = 0;
660                                         pixel[3] = 0;
661                                 }
662                         }
663                 }
664                 else {
665                         for(size_t i = 0; i < num_pixels; ++i) {
666                                 StorageType *pixel = &pixels[i];
667                                 if(!isfinite(pixel[0])) {
668                                         pixel[0] = 0;
669                                 }
670                         }
671                 }
672         }
673         /* Scale image down if needed. */
674         if(pixels_storage.size() > 0) {
675                 float scale_factor = 1.0f;
676                 while(max_size * scale_factor > texture_limit) {
677                         scale_factor *= 0.5f;
678                 }
679                 VLOG(1) << "Scaling image " << img->filename
680                         << " by a factor of " << scale_factor << ".";
681                 vector<StorageType> scaled_pixels;
682                 size_t scaled_width, scaled_height, scaled_depth;
683                 util_image_resize_pixels(pixels_storage,
684                                          width, height, depth,
685                                          is_rgba ? 4 : 1,
686                                          scale_factor,
687                                          &scaled_pixels,
688                                          &scaled_width, &scaled_height, &scaled_depth);
689                 StorageType *texture_pixels = (StorageType*)tex_img.resize(scaled_width,
690                                                                            scaled_height,
691                                                                            scaled_depth);
692                 memcpy(texture_pixels,
693                        &scaled_pixels[0],
694                        scaled_pixels.size() * sizeof(StorageType));
695         }
696         return true;
697 }
698
699 void ImageManager::device_load_image(Device *device,
700                                      Scene *scene,
701                                      ImageDataType type,
702                                      int slot,
703                                      Progress *progress)
704 {
705         if(progress->get_cancel())
706                 return;
707
708         Image *img = images[type][slot];
709
710         if(osl_texture_system && !img->builtin_data)
711                 return;
712
713         string filename = path_filename(images[type][slot]->filename);
714         progress->set_status("Updating Images", "Loading " + filename);
715
716         const int texture_limit = scene->params.texture_limit;
717
718         /* Slot assignment */
719         int flat_slot = type_index_to_flattened_slot(slot, type);
720         string name = string_printf("__tex_image_%s_%03d", name_from_type(type).c_str(), flat_slot);
721
722         /* Free previous texture in slot. */
723         if(img->mem) {
724                 thread_scoped_lock device_lock(device_mutex);
725                 device->tex_free(*img->mem);
726                 delete img->mem;
727                 img->mem = NULL;
728         }
729
730         /* Create new texture. */
731         if(type == IMAGE_DATA_TYPE_FLOAT4) {
732                 device_vector<float4> *tex_img = new device_vector<float4>(device, name.c_str());
733
734                 if(!file_load_image<TypeDesc::FLOAT, float>(img,
735                                                             type,
736                                                             texture_limit,
737                                                             *tex_img))
738                 {
739                         /* on failure to load, we set a 1x1 pixels pink image */
740                         float *pixels = (float*)tex_img->resize(1, 1);
741
742                         pixels[0] = TEX_IMAGE_MISSING_R;
743                         pixels[1] = TEX_IMAGE_MISSING_G;
744                         pixels[2] = TEX_IMAGE_MISSING_B;
745                         pixels[3] = TEX_IMAGE_MISSING_A;
746                 }
747
748                 img->mem = tex_img;
749         }
750         else if(type == IMAGE_DATA_TYPE_FLOAT) {
751                 device_vector<float> *tex_img = new device_vector<float>(device, name.c_str());
752
753                 if(!file_load_image<TypeDesc::FLOAT, float>(img,
754                                                             type,
755                                                             texture_limit,
756                                                             *tex_img))
757                 {
758                         /* on failure to load, we set a 1x1 pixels pink image */
759                         float *pixels = (float*)tex_img->resize(1, 1);
760
761                         pixels[0] = TEX_IMAGE_MISSING_R;
762                 }
763
764                 img->mem = tex_img;
765         }
766         else if(type == IMAGE_DATA_TYPE_BYTE4) {
767                 device_vector<uchar4> *tex_img = new device_vector<uchar4>(device, name.c_str());
768
769                 if(!file_load_image<TypeDesc::UINT8, uchar>(img,
770                                                             type,
771                                                             texture_limit,
772                                                             *tex_img))
773                 {
774                         /* on failure to load, we set a 1x1 pixels pink image */
775                         uchar *pixels = (uchar*)tex_img->resize(1, 1);
776
777                         pixels[0] = (TEX_IMAGE_MISSING_R * 255);
778                         pixels[1] = (TEX_IMAGE_MISSING_G * 255);
779                         pixels[2] = (TEX_IMAGE_MISSING_B * 255);
780                         pixels[3] = (TEX_IMAGE_MISSING_A * 255);
781                 }
782
783                 img->mem = tex_img;
784         }
785         else if(type == IMAGE_DATA_TYPE_BYTE) {
786                 device_vector<uchar> *tex_img = new device_vector<uchar>(device, name.c_str());
787
788                 if(!file_load_image<TypeDesc::UINT8, uchar>(img,
789                                                             type,
790                                                             texture_limit,
791                                                             *tex_img)) {
792                         /* on failure to load, we set a 1x1 pixels pink image */
793                         uchar *pixels = (uchar*)tex_img->resize(1, 1);
794
795                         pixels[0] = (TEX_IMAGE_MISSING_R * 255);
796                 }
797
798                 img->mem = tex_img;
799         }
800         else if(type == IMAGE_DATA_TYPE_HALF4) {
801                 device_vector<half4> *tex_img = new device_vector<half4>(device, name.c_str());
802
803                 if(!file_load_image<TypeDesc::HALF, half>(img,
804                                                           type,
805                                                           texture_limit,
806                                                           *tex_img)) {
807                         /* on failure to load, we set a 1x1 pixels pink image */
808                         half *pixels = (half*)tex_img->resize(1, 1);
809
810                         pixels[0] = TEX_IMAGE_MISSING_R;
811                         pixels[1] = TEX_IMAGE_MISSING_G;
812                         pixels[2] = TEX_IMAGE_MISSING_B;
813                         pixels[3] = TEX_IMAGE_MISSING_A;
814                 }
815
816                 img->mem = tex_img;
817         }
818         else if(type == IMAGE_DATA_TYPE_HALF) {
819                 device_vector<half> *tex_img = new device_vector<half>(device, name.c_str());
820
821                 if(!file_load_image<TypeDesc::HALF, half>(img,
822                                                           type,
823                                                           texture_limit,
824                                                           *tex_img)) {
825                         /* on failure to load, we set a 1x1 pixels pink image */
826                         half *pixels = (half*)tex_img->resize(1, 1);
827
828                         pixels[0] = TEX_IMAGE_MISSING_R;
829                 }
830
831                 img->mem = tex_img;
832         }
833
834         /* Copy to device. */
835         if(img->mem) {
836                 img->mem->interpolation = img->interpolation;
837                 img->mem->extension = img->extension;
838
839                 thread_scoped_lock device_lock(device_mutex);
840                 device->tex_alloc(*img->mem);
841         }
842
843
844         img->need_load = false;
845 }
846
847 void ImageManager::device_free_image(Device *device, ImageDataType type, int slot)
848 {
849         Image *img = images[type][slot];
850
851         if(img) {
852                 if(osl_texture_system && !img->builtin_data) {
853 #ifdef WITH_OSL
854                         ustring filename(images[type][slot]->filename);
855                         ((OSL::TextureSystem*)osl_texture_system)->invalidate(filename);
856 #endif
857                 }
858
859                 if(img->mem) {
860                         thread_scoped_lock device_lock(device_mutex);
861                         device->tex_free(*img->mem);
862                         delete img->mem;
863                 }
864
865                 delete img;
866                 images[type][slot] = NULL;
867                 --tex_num_images[type];
868         }
869 }
870
871 void ImageManager::device_update(Device *device,
872                                  Scene *scene,
873                                  Progress& progress)
874 {
875         if(!need_update) {
876                 return;
877         }
878
879         TaskPool pool;
880         for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
881                 for(size_t slot = 0; slot < images[type].size(); slot++) {
882                         if(!images[type][slot])
883                                 continue;
884
885                         if(images[type][slot]->users == 0) {
886                                 device_free_image(device, (ImageDataType)type, slot);
887                         }
888                         else if(images[type][slot]->need_load) {
889                                 if(!osl_texture_system || images[type][slot]->builtin_data)
890                                         pool.push(function_bind(&ImageManager::device_load_image,
891                                                                 this,
892                                                                 device,
893                                                                 scene,
894                                                                 (ImageDataType)type,
895                                                                 slot,
896                                                                 &progress));
897                         }
898                 }
899         }
900
901         pool.wait_work();
902
903         need_update = false;
904 }
905
906 void ImageManager::device_update_slot(Device *device,
907                                       Scene *scene,
908                                       int flat_slot,
909                                       Progress *progress)
910 {
911         ImageDataType type;
912         int slot = flattened_slot_to_type_index(flat_slot, &type);
913
914         Image *image = images[type][slot];
915         assert(image != NULL);
916
917         if(image->users == 0) {
918                 device_free_image(device, type, slot);
919         }
920         else if(image->need_load) {
921                 if(!osl_texture_system || image->builtin_data)
922                         device_load_image(device,
923                                           scene,
924                                           type,
925                                           slot,
926                                           progress);
927         }
928 }
929
930 void ImageManager::device_free_builtin(Device *device)
931 {
932         for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
933                 for(size_t slot = 0; slot < images[type].size(); slot++) {
934                         if(images[type][slot] && images[type][slot]->builtin_data)
935                                 device_free_image(device, (ImageDataType)type, slot);
936                 }
937         }
938 }
939
940 void ImageManager::device_free(Device *device)
941 {
942         for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
943                 for(size_t slot = 0; slot < images[type].size(); slot++) {
944                         device_free_image(device, (ImageDataType)type, slot);
945                 }
946                 images[type].clear();
947         }
948 }
949
950 CCL_NAMESPACE_END
951