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