102c6107fb74d98c08023a939dcfea0ac5a6dfc1
[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.h"
18 #include "image.h"
19 #include "scene.h"
20
21 #include "util_foreach.h"
22 #include "util_path.h"
23 #include "util_progress.h"
24 #include "util_texture.h"
25
26 #ifdef WITH_OSL
27 #include <OSL/oslexec.h>
28 #endif
29
30 CCL_NAMESPACE_BEGIN
31
32 ImageManager::ImageManager(const DeviceInfo& info)
33 {
34         need_update = true;
35         pack_images = false;
36         osl_texture_system = NULL;
37         animation_frame = 0;
38
39         /* Set image limits */
40
41         /* CPU */
42         if(info.type == DEVICE_CPU) {
43                 tex_num_images[IMAGE_DATA_TYPE_BYTE4] = TEX_NUM_BYTE4_IMAGES_CPU;
44                 tex_num_images[IMAGE_DATA_TYPE_FLOAT4] = TEX_NUM_FLOAT4_IMAGES_CPU;
45                 tex_num_images[IMAGE_DATA_TYPE_FLOAT] = TEX_NUM_FLOAT_IMAGES_CPU;
46                 tex_image_byte4_start = TEX_IMAGE_BYTE4_START_CPU;
47                 tex_image_float_start = TEX_IMAGE_FLOAT_START_CPU;
48         }
49         /* CUDA (Fermi) */
50         else if((info.type == DEVICE_CUDA || info.type == DEVICE_MULTI) && !info.extended_images) {
51                 tex_num_images[IMAGE_DATA_TYPE_BYTE4] = TEX_NUM_BYTE4_IMAGES_CUDA;
52                 tex_num_images[IMAGE_DATA_TYPE_FLOAT4] = TEX_NUM_FLOAT4_IMAGES_CUDA;
53                 tex_num_images[IMAGE_DATA_TYPE_FLOAT] = TEX_NUM_FLOAT_IMAGES_CUDA;
54                 tex_image_byte4_start = TEX_IMAGE_BYTE4_START_CUDA;
55                 tex_image_float_start = TEX_IMAGE_FLOAT_START_CUDA;
56         }
57         /* CUDA (Kepler and above) */
58         else if((info.type == DEVICE_CUDA || info.type == DEVICE_MULTI) && info.extended_images) {
59                 tex_num_images[IMAGE_DATA_TYPE_BYTE4] = TEX_NUM_BYTE4_IMAGES_CUDA_KEPLER;
60                 tex_num_images[IMAGE_DATA_TYPE_FLOAT4] = TEX_NUM_FLOAT4_IMAGES_CUDA_KEPLER;
61                 tex_num_images[IMAGE_DATA_TYPE_FLOAT] = TEX_NUM_FLOAT_IMAGES_CUDA_KEPLER;
62                 tex_image_byte4_start = TEX_IMAGE_BYTE4_START_CUDA_KELPER;
63                 tex_image_float_start = TEX_IMAGE_FLOAT_START_CUDA_KELPER;
64         }
65         /* OpenCL */
66         else if(info.pack_images) {
67                 tex_num_images[IMAGE_DATA_TYPE_BYTE4] = TEX_NUM_BYTE4_IMAGES_OPENCL;
68                 tex_num_images[IMAGE_DATA_TYPE_FLOAT4] = TEX_NUM_FLOAT4_IMAGES_OPENCL;
69                 tex_num_images[IMAGE_DATA_TYPE_FLOAT] = TEX_NUM_FLOAT_IMAGES_OPENCL;
70                 tex_image_byte4_start = TEX_IMAGE_BYTE4_START_OPENCL;
71                 tex_image_float_start = TEX_IMAGE_FLOAT_START_OPENCL;
72         }
73         /* Should never happen */
74         else {
75                 tex_num_images[IMAGE_DATA_TYPE_BYTE4] = 0;
76                 tex_num_images[IMAGE_DATA_TYPE_FLOAT4] = 0;
77                 tex_num_images[IMAGE_DATA_TYPE_FLOAT] = 0;
78                 tex_image_byte4_start = 0;
79                 tex_image_float_start = 0;
80                 assert(0);
81         }
82 }
83
84 ImageManager::~ImageManager()
85 {
86         for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
87                 for(size_t slot = 0; slot < images[type].size(); slot++)
88                         assert(!images[type][slot]);
89         }
90 }
91
92 void ImageManager::set_pack_images(bool pack_images_)
93 {
94         pack_images = pack_images_;
95 }
96
97 void ImageManager::set_osl_texture_system(void *texture_system)
98 {
99         osl_texture_system = texture_system;
100 }
101
102 bool ImageManager::set_animation_frame_update(int frame)
103 {
104         if(frame != animation_frame) {
105                 animation_frame = frame;
106
107                 for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
108                         for(size_t slot = 0; slot < images[type].size(); slot++) {
109                                 if(images[type][slot] && images[type][slot]->animated)
110                                         return true;
111                         }
112                 }
113         }
114
115         return false;
116 }
117
118 ImageManager::ImageDataType ImageManager::get_image_metadata(const string& filename,
119                                                              void *builtin_data,
120                                                              bool& is_linear)
121 {
122         bool is_float = false;
123         is_linear = false;
124         int channels = 4;
125
126         if(builtin_data) {
127                 if(builtin_image_info_cb) {
128                         int width, height, depth;
129                         builtin_image_info_cb(filename, builtin_data, is_float, width, height, depth, channels);
130                 }
131
132                 if(is_float) {
133                         is_linear = true;
134
135                         if(channels > 1)
136                                 return IMAGE_DATA_TYPE_FLOAT4;
137                         else
138                                 return IMAGE_DATA_TYPE_FLOAT;
139                 }
140                 else
141                         return IMAGE_DATA_TYPE_BYTE4;
142         }
143
144         ImageInput *in = ImageInput::create(filename);
145
146         if(in) {
147                 ImageSpec spec;
148
149                 if(in->open(filename, spec)) {
150                         /* check the main format, and channel formats;
151                          * if any take up more than one byte, we'll need a float texture slot */
152                         if(spec.format.basesize() > 1) {
153                                 is_float = true;
154                                 is_linear = true;
155                         }
156
157                         for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
158                                 if(spec.channelformats[channel].basesize() > 1) {
159                                         is_float = true;
160                                         is_linear = true;
161                                 }
162                         }
163
164                         channels = spec.nchannels;
165
166                         /* basic color space detection, not great but better than nothing
167                          * before we do OpenColorIO integration */
168                         if(is_float) {
169                                 string colorspace = spec.get_string_attribute("oiio:ColorSpace");
170
171                                 is_linear = !(colorspace == "sRGB" ||
172                                               colorspace == "GammaCorrected" ||
173                                               (colorspace == "" &&
174                                                   (strcmp(in->format_name(), "png") == 0 ||
175                                                    strcmp(in->format_name(), "tiff") == 0 ||
176                                                    strcmp(in->format_name(), "dpx") == 0 ||
177                                                    strcmp(in->format_name(), "jpeg2000") == 0)));
178                         }
179                         else {
180                                 is_linear = false;
181                         }
182
183                         in->close();
184                 }
185
186                 delete in;
187         }
188
189         if(is_float) {
190                 if(channels > 1)
191                         return IMAGE_DATA_TYPE_FLOAT4;
192                 else
193                         return IMAGE_DATA_TYPE_FLOAT;
194         }
195         else
196                 return IMAGE_DATA_TYPE_BYTE4;
197 }
198
199 int ImageManager::type_index_to_flattened_slot(int slot, ImageDataType type)
200 {
201         if(type == IMAGE_DATA_TYPE_BYTE4)
202                 return slot + tex_image_byte4_start;
203         else if(type == IMAGE_DATA_TYPE_FLOAT)
204                 return slot + tex_image_float_start;
205         else
206                 return slot;
207 }
208
209 int ImageManager::flattened_slot_to_type_index(int flat_slot, ImageDataType *type)
210 {
211         if(flat_slot >= tex_image_float_start)
212         {
213                 *type = IMAGE_DATA_TYPE_FLOAT;
214                 return flat_slot - tex_image_float_start;
215         }
216         else if(flat_slot >= tex_image_byte4_start) {
217                 *type = IMAGE_DATA_TYPE_BYTE4;
218                 return flat_slot - tex_image_byte4_start;
219         }
220         else {
221                 *type = IMAGE_DATA_TYPE_FLOAT4;
222                 return flat_slot;
223         }
224 }
225
226 string ImageManager::name_from_type(int type)
227 {
228         if(type == IMAGE_DATA_TYPE_FLOAT4)
229                 return "float4";
230         else if(type == IMAGE_DATA_TYPE_FLOAT)
231                 return "float";
232         else
233                 return "byte4";
234 }
235
236 static bool image_equals(ImageManager::Image *image,
237                          const string& filename,
238                          void *builtin_data,
239                          InterpolationType interpolation,
240                          ExtensionType extension)
241 {
242         return image->filename == filename &&
243                image->builtin_data == builtin_data &&
244                image->interpolation == interpolation &&
245                image->extension == extension;
246 }
247
248 int ImageManager::add_image(const string& filename,
249                             void *builtin_data,
250                             bool animated,
251                             float frame,
252                             bool& is_float,
253                             bool& is_linear,
254                             InterpolationType interpolation,
255                             ExtensionType extension,
256                             bool use_alpha)
257 {
258         Image *img;
259         size_t slot;
260
261         ImageDataType type = get_image_metadata(filename, builtin_data, is_linear);
262
263         /* Do we have a float? */
264         if(type == IMAGE_DATA_TYPE_FLOAT || type == IMAGE_DATA_TYPE_FLOAT4)
265                 is_float = true;
266
267         /* No float textures on GPU yet */
268         if(type == IMAGE_DATA_TYPE_FLOAT && tex_num_images[type] == 0)
269                 type = IMAGE_DATA_TYPE_FLOAT4;
270
271         /* Fnd existing image. */
272         for(slot = 0; slot < images[type].size(); slot++) {
273                 img = images[type][slot];
274                 if(img && image_equals(img,
275                                            filename,
276                                            builtin_data,
277                                            interpolation,
278                                            extension))
279                 {
280                         if(img->frame != frame) {
281                                 img->frame = frame;
282                                 img->need_load = true;
283                         }
284                         if(img->use_alpha != use_alpha) {
285                                 img->use_alpha = use_alpha;
286                                 img->need_load = true;
287                         }
288                         img->users++;
289                         return type_index_to_flattened_slot(slot, type);
290                 }
291         }
292
293         /* Find free slot. */
294         for(slot = 0; slot < images[type].size(); slot++) {
295                 if(!images[type][slot])
296                         break;
297         }
298
299         if(slot == images[type].size()) {
300                 /* Max images limit reached. */
301                 if(images[type].size() == tex_num_images[type]) {
302                         printf("ImageManager::add_image: Reached %s image limit (%d), skipping '%s'\n",
303                                name_from_type(type).c_str(), tex_num_images[type], filename.c_str());
304                         return -1;
305                 }
306
307                 images[type].resize(images[type].size() + 1);
308         }
309
310         /* Add new image. */
311         img = new Image();
312         img->filename = filename;
313         img->builtin_data = builtin_data;
314         img->need_load = true;
315         img->animated = animated;
316         img->frame = frame;
317         img->interpolation = interpolation;
318         img->extension = extension;
319         img->users = 1;
320         img->use_alpha = use_alpha;
321
322         images[type][slot] = img;
323
324         need_update = true;
325
326         return type_index_to_flattened_slot(slot, type);
327 }
328
329 void ImageManager::remove_image(int flat_slot)
330 {
331         ImageDataType type;
332         int slot = flattened_slot_to_type_index(flat_slot, &type);
333
334         Image *image = images[type][slot];
335         assert(image && image->users >= 1);
336
337         /* decrement user count */
338         image->users--;
339
340         /* don't remove immediately, rather do it all together later on. one of
341          * the reasons for this is that on shader changes we add and remove nodes
342          * that use them, but we do not want to reload the image all the time. */
343         if(image->users == 0)
344                 need_update = true;
345 }
346
347 void ImageManager::remove_image(const string& filename,
348                                 void *builtin_data,
349                                 InterpolationType interpolation,
350                                 ExtensionType extension)
351 {
352         size_t slot;
353
354         for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
355                 for(slot = 0; slot < images[type].size(); slot++) {
356                         if(images[type][slot] && image_equals(images[type][slot],
357                                                           filename,
358                                                           builtin_data,
359                                                           interpolation,
360                                                           extension))
361                         {
362                                 remove_image(type_index_to_flattened_slot(slot, (ImageDataType)type));
363                                 return;
364                         }
365                 }
366         }
367 }
368
369 /* TODO(sergey): Deduplicate with the iteration above, but make it pretty,
370  * without bunch of arguments passing around making code readability even
371  * more cluttered.
372  */
373 void ImageManager::tag_reload_image(const string& filename,
374                                     void *builtin_data,
375                                     InterpolationType interpolation,
376                                     ExtensionType extension)
377 {
378         for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
379                 for(size_t slot = 0; slot < images[type].size(); slot++) {
380                         if(images[type][slot] && image_equals(images[type][slot],
381                                                           filename,
382                                                           builtin_data,
383                                                           interpolation,
384                                                           extension))
385                         {
386                                 images[type][slot]->need_load = true;
387                                 break;
388                         }
389                 }
390         }
391 }
392
393 bool ImageManager::file_load_image_generic(Image *img, ImageInput **in, int &width, int &height, int &depth, int &components)
394 {
395         if(img->filename == "")
396                 return false;
397
398         if(!img->builtin_data) {
399                 /* load image from file through OIIO */
400                 *in = ImageInput::create(img->filename);
401
402                 if(!*in)
403                         return false;
404
405                 ImageSpec spec = ImageSpec();
406                 ImageSpec config = ImageSpec();
407
408                 if(img->use_alpha == false)
409                         config.attribute("oiio:UnassociatedAlpha", 1);
410
411                 if(!(*in)->open(img->filename, spec, config)) {
412                         delete *in;
413                         *in = NULL;
414                         return false;
415                 }
416
417                 width = spec.width;
418                 height = spec.height;
419                 depth = spec.depth;
420                 components = spec.nchannels;
421         }
422         else {
423                 /* load image using builtin images callbacks */
424                 if(!builtin_image_info_cb || !builtin_image_pixels_cb)
425                         return false;
426
427                 bool is_float;
428                 builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, depth, components);
429         }
430
431         /* we only handle certain number of components */
432         if(!(components >= 1 && components <= 4)) {
433                 if(*in) {
434                         (*in)->close();
435                         delete *in;
436                         *in = NULL;
437                 }
438
439                 return false;
440         }
441
442         return true;
443 }
444
445 bool ImageManager::file_load_byte4_image(Image *img, device_vector<uchar4>& tex_img)
446 {
447         ImageInput *in = NULL;
448         int width, height, depth, components;
449
450         if(!file_load_image_generic(img, &in, width, height, depth, components))
451                 return false;
452
453         /* read RGBA pixels */
454         uchar *pixels = (uchar*)tex_img.resize(width, height, depth);
455         if(pixels == NULL) {
456                 return false;
457         }
458         bool cmyk = false;
459
460         if(in) {
461                 if(depth <= 1) {
462                         int scanlinesize = width*components*sizeof(uchar);
463
464                         in->read_image(TypeDesc::UINT8,
465                                 (uchar*)pixels + (((size_t)height)-1)*scanlinesize,
466                                 AutoStride,
467                                 -scanlinesize,
468                                 AutoStride);
469                 }
470                 else {
471                         in->read_image(TypeDesc::UINT8, (uchar*)pixels);
472                 }
473
474                 cmyk = strcmp(in->format_name(), "jpeg") == 0 && components == 4;
475
476                 in->close();
477                 delete in;
478         }
479         else {
480                 builtin_image_pixels_cb(img->filename, img->builtin_data, pixels);
481         }
482
483         size_t num_pixels = ((size_t)width) * height * depth;
484         if(cmyk) {
485                 /* CMYK */
486                 for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
487                         pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255;
488                         pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255;
489                         pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255;
490                         pixels[i*4+3] = 255;
491                 }
492         }
493         else if(components == 2) {
494                 /* grayscale + alpha */
495                 for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
496                         pixels[i*4+3] = pixels[i*2+1];
497                         pixels[i*4+2] = pixels[i*2+0];
498                         pixels[i*4+1] = pixels[i*2+0];
499                         pixels[i*4+0] = pixels[i*2+0];
500                 }
501         }
502         else if(components == 3) {
503                 /* RGB */
504                 for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
505                         pixels[i*4+3] = 255;
506                         pixels[i*4+2] = pixels[i*3+2];
507                         pixels[i*4+1] = pixels[i*3+1];
508                         pixels[i*4+0] = pixels[i*3+0];
509                 }
510         }
511         else if(components == 1) {
512                 /* grayscale */
513                 for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
514                         pixels[i*4+3] = 255;
515                         pixels[i*4+2] = pixels[i];
516                         pixels[i*4+1] = pixels[i];
517                         pixels[i*4+0] = pixels[i];
518                 }
519         }
520
521         if(img->use_alpha == false) {
522                 for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
523                         pixels[i*4+3] = 255;
524                 }
525         }
526
527         return true;
528 }
529
530 bool ImageManager::file_load_float4_image(Image *img, device_vector<float4>& tex_img)
531 {
532         ImageInput *in = NULL;
533         int width, height, depth, components;
534
535         if(!file_load_image_generic(img, &in, width, height, depth, components))
536                 return false;
537
538         /* read RGBA pixels */
539         float *pixels = (float*)tex_img.resize(width, height, depth);
540         if(pixels == NULL) {
541                 return false;
542         }
543         bool cmyk = false;
544
545         if(in) {
546                 float *readpixels = pixels;
547                 vector<float> tmppixels;
548
549                 if(components > 4) {
550                         tmppixels.resize(((size_t)width)*height*components);
551                         readpixels = &tmppixels[0];
552                 }
553
554                 if(depth <= 1) {
555                         int scanlinesize = width*components*sizeof(float);
556
557                         in->read_image(TypeDesc::FLOAT,
558                                 (uchar*)readpixels + (height-1)*scanlinesize,
559                                 AutoStride,
560                                 -scanlinesize,
561                                 AutoStride);
562                 }
563                 else {
564                         in->read_image(TypeDesc::FLOAT, (uchar*)readpixels);
565                 }
566
567                 if(components > 4) {
568                         size_t dimensions = ((size_t)width)*height;
569                         for(size_t i = dimensions-1, pixel = 0; pixel < dimensions; pixel++, i--) {
570                                 pixels[i*4+3] = tmppixels[i*components+3];
571                                 pixels[i*4+2] = tmppixels[i*components+2];
572                                 pixels[i*4+1] = tmppixels[i*components+1];
573                                 pixels[i*4+0] = tmppixels[i*components+0];
574                         }
575
576                         tmppixels.clear();
577                 }
578
579                 cmyk = strcmp(in->format_name(), "jpeg") == 0 && components == 4;
580
581                 in->close();
582                 delete in;
583         }
584         else {
585                 builtin_image_float_pixels_cb(img->filename, img->builtin_data, pixels);
586         }
587
588         size_t num_pixels = ((size_t)width) * height * depth;
589         if(cmyk) {
590                 /* CMYK */
591                 for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
592                         pixels[i*4+3] = 255;
593                         pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255;
594                         pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255;
595                         pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255;
596                 }
597         }
598         else if(components == 2) {
599                 /* grayscale + alpha */
600                 for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
601                         pixels[i*4+3] = pixels[i*2+1];
602                         pixels[i*4+2] = pixels[i*2+0];
603                         pixels[i*4+1] = pixels[i*2+0];
604                         pixels[i*4+0] = pixels[i*2+0];
605                 }
606         }
607         else if(components == 3) {
608                 /* RGB */
609                 for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
610                         pixels[i*4+3] = 1.0f;
611                         pixels[i*4+2] = pixels[i*3+2];
612                         pixels[i*4+1] = pixels[i*3+1];
613                         pixels[i*4+0] = pixels[i*3+0];
614                 }
615         }
616         else if(components == 1) {
617                 /* grayscale */
618                 for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
619                         pixels[i*4+3] = 1.0f;
620                         pixels[i*4+2] = pixels[i];
621                         pixels[i*4+1] = pixels[i];
622                         pixels[i*4+0] = pixels[i];
623                 }
624         }
625
626         if(img->use_alpha == false) {
627                 for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
628                         pixels[i*4+3] = 1.0f;
629                 }
630         }
631
632         return true;
633 }
634
635 bool ImageManager::file_load_float_image(Image *img, device_vector<float>& tex_img)
636 {
637         ImageInput *in = NULL;
638         int width, height, depth, components;
639
640         if(!file_load_image_generic(img, &in, width, height, depth, components))
641                 return false;
642
643         /* read BW pixels */
644         float *pixels = (float*)tex_img.resize(width, height, depth);
645         if(pixels == NULL) {
646                 return false;
647         }
648
649         if(in) {
650                 float *readpixels = pixels;
651
652                 if(depth <= 1) {
653                         int scanlinesize = width*components*sizeof(float);
654
655                         in->read_image(TypeDesc::FLOAT,
656                                        (uchar*)readpixels + (height-1)*scanlinesize,
657                                        AutoStride,
658                                        -scanlinesize,
659                                        AutoStride);
660                 }
661                 else {
662                         in->read_image(TypeDesc::FLOAT, (uchar*)readpixels);
663                 }
664
665                 in->close();
666                 delete in;
667         }
668         else {
669                 builtin_image_float_pixels_cb(img->filename, img->builtin_data, pixels);
670         }
671
672         return true;
673 }
674
675 void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageDataType type, int slot, Progress *progress)
676 {
677         if(progress->get_cancel())
678                 return;
679         
680         Image *img = images[type][slot];
681
682         if(osl_texture_system && !img->builtin_data)
683                 return;
684
685         string filename = path_filename(images[type][slot]->filename);
686         progress->set_status("Updating Images", "Loading " + filename);
687
688         /* Slot assignment */
689         int flat_slot = type_index_to_flattened_slot(slot, type);
690
691         string name;
692         if(flat_slot >= 100)
693                 name = string_printf("__tex_image_%s_%d", name_from_type(type).c_str(), flat_slot);
694         else if(flat_slot >= 10)
695                 name = string_printf("__tex_image_%s_0%d", name_from_type(type).c_str(), flat_slot);
696         else
697                 name = string_printf("__tex_image_%s_00%d", name_from_type(type).c_str(), flat_slot);
698
699         if(type == IMAGE_DATA_TYPE_FLOAT4) {
700                 device_vector<float4>& tex_img = dscene->tex_float4_image[slot];
701
702                 if(tex_img.device_pointer) {
703                         thread_scoped_lock device_lock(device_mutex);
704                         device->tex_free(tex_img);
705                 }
706
707                 if(!file_load_float4_image(img, tex_img)) {
708                         /* on failure to load, we set a 1x1 pixels pink image */
709                         float *pixels = (float*)tex_img.resize(1, 1);
710
711                         pixels[0] = TEX_IMAGE_MISSING_R;
712                         pixels[1] = TEX_IMAGE_MISSING_G;
713                         pixels[2] = TEX_IMAGE_MISSING_B;
714                         pixels[3] = TEX_IMAGE_MISSING_A;
715                 }
716
717                 if(!pack_images) {
718                         thread_scoped_lock device_lock(device_mutex);
719                         device->tex_alloc(name.c_str(),
720                                           tex_img,
721                                           img->interpolation,
722                                           img->extension);
723                 }
724         }
725         else if(type == IMAGE_DATA_TYPE_FLOAT) {
726                 device_vector<float>& tex_img = dscene->tex_float_image[slot];
727
728                 if(tex_img.device_pointer) {
729                         thread_scoped_lock device_lock(device_mutex);
730                         device->tex_free(tex_img);
731                 }
732
733                 if(!file_load_float_image(img, tex_img)) {
734                         /* on failure to load, we set a 1x1 pixels pink image */
735                         float *pixels = (float*)tex_img.resize(1, 1);
736
737                         pixels[0] = TEX_IMAGE_MISSING_R;
738                 }
739
740                 if(!pack_images) {
741                         thread_scoped_lock device_lock(device_mutex);
742                         device->tex_alloc(name.c_str(),
743                                           tex_img,
744                                           img->interpolation,
745                                           img->extension);
746                 }
747         }
748         else {
749                 device_vector<uchar4>& tex_img = dscene->tex_byte4_image[slot];
750
751                 if(tex_img.device_pointer) {
752                         thread_scoped_lock device_lock(device_mutex);
753                         device->tex_free(tex_img);
754                 }
755
756                 if(!file_load_byte4_image(img, tex_img)) {
757                         /* on failure to load, we set a 1x1 pixels pink image */
758                         uchar *pixels = (uchar*)tex_img.resize(1, 1);
759
760                         pixels[0] = (TEX_IMAGE_MISSING_R * 255);
761                         pixels[1] = (TEX_IMAGE_MISSING_G * 255);
762                         pixels[2] = (TEX_IMAGE_MISSING_B * 255);
763                         pixels[3] = (TEX_IMAGE_MISSING_A * 255);
764                 }
765
766                 if(!pack_images) {
767                         thread_scoped_lock device_lock(device_mutex);
768                         device->tex_alloc(name.c_str(),
769                                           tex_img,
770                                           img->interpolation,
771                                           img->extension);
772                 }
773         }
774
775         img->need_load = false;
776 }
777
778 void ImageManager::device_free_image(Device *device, DeviceScene *dscene, ImageDataType type, int slot)
779 {
780         Image *img = images[type][slot];
781
782         if(img) {
783                 if(osl_texture_system && !img->builtin_data) {
784 #ifdef WITH_OSL
785                         ustring filename(images[type][slot]->filename);
786                         ((OSL::TextureSystem*)osl_texture_system)->invalidate(filename);
787 #endif
788                 }
789                 else if(type == IMAGE_DATA_TYPE_FLOAT4) {
790                         device_vector<float4>& tex_img = dscene->tex_float4_image[slot];
791
792                         if(tex_img.device_pointer) {
793                                 thread_scoped_lock device_lock(device_mutex);
794                                 device->tex_free(tex_img);
795                         }
796
797                         tex_img.clear();
798
799                         delete images[type][slot];
800                         images[type][slot] = NULL;
801                 }
802                 else if(type == IMAGE_DATA_TYPE_FLOAT) {
803                         device_vector<float>& tex_img = dscene->tex_float_image[slot];
804
805                         if(tex_img.device_pointer) {
806                                 thread_scoped_lock device_lock(device_mutex);
807                                 device->tex_free(tex_img);
808                         }
809
810                         tex_img.clear();
811
812                         delete images[type][slot];
813                         images[type][slot] = NULL;
814                 }
815                 else {
816                         device_vector<uchar4>& tex_img = dscene->tex_byte4_image[slot];
817
818                         if(tex_img.device_pointer) {
819                                 thread_scoped_lock device_lock(device_mutex);
820                                 device->tex_free(tex_img);
821                         }
822
823                         tex_img.clear();
824
825                         delete images[type][slot];
826                         images[type][slot] = NULL;
827                 }
828         }
829 }
830
831 void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress& progress)
832 {
833         if(!need_update)
834                 return;
835
836         TaskPool pool;
837
838         for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
839                 for(size_t slot = 0; slot < images[type].size(); slot++) {
840                         if(!images[type][slot])
841                                 continue;
842
843                         if(images[type][slot]->users == 0) {
844                                 device_free_image(device, dscene, (ImageDataType)type, slot);
845                         }
846                         else if(images[type][slot]->need_load) {
847                                 if(!osl_texture_system || images[type][slot]->builtin_data)
848                                         pool.push(function_bind(&ImageManager::device_load_image, this, device, dscene, (ImageDataType)type, slot, &progress));
849                         }
850                 }
851         }
852
853         pool.wait_work();
854
855         if(pack_images)
856                 device_pack_images(device, dscene, progress);
857
858         need_update = false;
859 }
860
861 void ImageManager::device_update_slot(Device *device,
862                                       DeviceScene *dscene,
863                                       int flat_slot,
864                                       Progress *progress)
865 {
866         ImageDataType type;
867         int slot = flattened_slot_to_type_index(flat_slot, &type);
868
869         Image *image = images[type][slot];
870         assert(image != NULL);
871
872         if(image->users == 0) {
873                 device_free_image(device, dscene, type, slot);
874         }
875         else if(image->need_load) {
876                 if(!osl_texture_system || image->builtin_data)
877                         device_load_image(device,
878                                           dscene,
879                                           type,
880                                           slot,
881                                           progress);
882         }
883 }
884
885 void ImageManager::device_pack_images(Device *device,
886                                       DeviceScene *dscene,
887                                       Progress& /*progess*/)
888 {
889         /* For OpenCL, we pack all image textures into a single large texture, and
890          * do our own interpolation in the kernel. */
891         size_t size = 0, offset = 0;
892         ImageDataType type;
893
894         int info_size = tex_num_images[IMAGE_DATA_TYPE_FLOAT4] + tex_num_images[IMAGE_DATA_TYPE_BYTE4];
895         uint4 *info = dscene->tex_image_packed_info.resize(info_size);
896
897         /* Byte Textures*/
898         type = IMAGE_DATA_TYPE_BYTE4;
899
900         for(size_t slot = 0; slot < images[type].size(); slot++) {
901                 if(!images[type][slot])
902                         continue;
903
904                 device_vector<uchar4>& tex_img = dscene->tex_byte4_image[slot];
905                 size += tex_img.size();
906         }
907
908         uchar4 *pixels_byte = dscene->tex_image_byte4_packed.resize(size);
909
910         for(size_t slot = 0; slot < images[type].size(); slot++) {
911                 if(!images[type][slot])
912                         continue;
913
914                 device_vector<uchar4>& tex_img = dscene->tex_byte4_image[slot];
915
916                 /* The image options are packed
917                    bit 0 -> periodic
918                    bit 1 + 2 -> interpolation type */
919                 uint8_t interpolation = (images[type][slot]->interpolation << 1) + 1;
920                 info[type_index_to_flattened_slot(slot, type)] = make_uint4(tex_img.data_width, tex_img.data_height, offset, interpolation);
921
922                 memcpy(pixels_byte+offset, (void*)tex_img.data_pointer, tex_img.memory_size());
923                 offset += tex_img.size();
924         }
925
926         /* Float Textures*/
927         type = IMAGE_DATA_TYPE_FLOAT4;
928         size = 0, offset = 0;
929
930         for(size_t slot = 0; slot < images[type].size(); slot++) {
931                 if(!images[type][slot])
932                         continue;
933
934                 device_vector<float4>& tex_img = dscene->tex_float4_image[slot];
935                 size += tex_img.size();
936         }
937
938         float4 *pixels_float = dscene->tex_image_float4_packed.resize(size);
939
940         for(size_t slot = 0; slot < images[type].size(); slot++) {
941                 if(!images[type][slot])
942                         continue;
943
944                 device_vector<float4>& tex_img = dscene->tex_float4_image[slot];
945
946                 /* todo: support 3D textures, only CPU for now */
947
948                 /* The image options are packed
949                    bit 0 -> periodic
950                    bit 1 + 2 -> interpolation type */
951                 uint8_t interpolation = (images[type][slot]->interpolation << 1) + 1;
952                 info[type_index_to_flattened_slot(slot, type)] = make_uint4(tex_img.data_width, tex_img.data_height, offset, interpolation);
953
954                 memcpy(pixels_float+offset, (void*)tex_img.data_pointer, tex_img.memory_size());
955                 offset += tex_img.size();
956         }
957
958         if(dscene->tex_image_byte4_packed.size()) {
959                 if(dscene->tex_image_byte4_packed.device_pointer) {
960                         thread_scoped_lock device_lock(device_mutex);
961                         device->tex_free(dscene->tex_image_byte4_packed);
962                 }
963                 device->tex_alloc("__tex_image_byte4_packed", dscene->tex_image_byte4_packed);
964         }
965         if(dscene->tex_image_float4_packed.size()) {
966                 if(dscene->tex_image_float4_packed.device_pointer) {
967                         thread_scoped_lock device_lock(device_mutex);
968                         device->tex_free(dscene->tex_image_float4_packed);
969                 }
970                 device->tex_alloc("__tex_image_float4_packed", dscene->tex_image_float4_packed);
971         }
972         if(dscene->tex_image_packed_info.size()) {
973                 if(dscene->tex_image_packed_info.device_pointer) {
974                         thread_scoped_lock device_lock(device_mutex);
975                         device->tex_free(dscene->tex_image_packed_info);
976                 }
977                 device->tex_alloc("__tex_image_packed_info", dscene->tex_image_packed_info);
978         }
979 }
980
981 void ImageManager::device_free_builtin(Device *device, DeviceScene *dscene)
982 {
983         for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
984                 for(size_t slot = 0; slot < images[type].size(); slot++) {
985                         if(images[type][slot] && images[type][slot]->builtin_data)
986                                 device_free_image(device, dscene, (ImageDataType)type, slot);
987                 }
988         }
989 }
990
991 void ImageManager::device_free(Device *device, DeviceScene *dscene)
992 {
993         for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
994                 for(size_t slot = 0; slot < images[type].size(); slot++) {
995                         device_free_image(device, dscene, (ImageDataType)type, slot);
996                 }
997                 images[type].clear();
998         }
999
1000         device->tex_free(dscene->tex_image_byte4_packed);
1001         device->tex_free(dscene->tex_image_float4_packed);
1002         device->tex_free(dscene->tex_image_packed_info);
1003
1004         dscene->tex_image_byte4_packed.clear();
1005         dscene->tex_image_float4_packed.clear();
1006         dscene->tex_image_packed_info.clear();
1007 }
1008
1009 CCL_NAMESPACE_END
1010