diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2018-08-12 14:52:49 +0300 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2018-08-12 14:52:49 +0300 |
commit | dc2d841b7c50565302af2986d62ddbd29c332acd (patch) | |
tree | 324f234e56fde77fb80dfdef0c7c21f01968f71b /intern/cycles/render/image.cpp | |
parent | 27b28e437d974ebbafa234205941c07aa0ab546c (diff) | |
parent | 4b6fa4d897a0bb3252b16383492b526d2cef3920 (diff) |
Merge branch 'blender2.8' into hair_guideshair_guides
Diffstat (limited to 'intern/cycles/render/image.cpp')
-rw-r--r-- | intern/cycles/render/image.cpp | 177 |
1 files changed, 99 insertions, 78 deletions
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index fa280fec01f..2865b0e5e97 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -17,6 +17,7 @@ #include "device/device.h" #include "render/image.h" #include "render/scene.h" +#include "render/stats.h" #include "util/util_foreach.h" #include "util/util_logging.h" @@ -30,20 +31,58 @@ CCL_NAMESPACE_BEGIN +namespace { + /* Some helpers to silence warning in templated function. */ -static bool isfinite(uchar /*value*/) +bool isfinite(uchar /*value*/) { - return false; + return true; } -static bool isfinite(half /*value*/) +bool isfinite(half /*value*/) { - return false; + return true; } -static bool isfinite(uint16_t /*value*/) +bool isfinite(uint16_t /*value*/) { - return false; + return true; +} + +/* The lower three bits of a device texture slot number indicate its type. + * These functions convert the slot ids from ImageManager "images" ones + * to device ones and vice verse. + */ +int type_index_to_flattened_slot(int slot, ImageDataType type) +{ + return (slot << IMAGE_DATA_TYPE_SHIFT) | (type); } +int flattened_slot_to_type_index(int flat_slot, ImageDataType *type) +{ + *type = (ImageDataType)(flat_slot & IMAGE_DATA_TYPE_MASK); + return flat_slot >> IMAGE_DATA_TYPE_SHIFT; +} + +const char* name_from_type(ImageDataType type) +{ + switch(type) { + case IMAGE_DATA_TYPE_FLOAT4: return "float4"; + case IMAGE_DATA_TYPE_BYTE4: return "byte4"; + case IMAGE_DATA_TYPE_HALF4: return "half4"; + case IMAGE_DATA_TYPE_FLOAT: return "float"; + case IMAGE_DATA_TYPE_BYTE: return "byte"; + case IMAGE_DATA_TYPE_HALF: return "half"; + case IMAGE_DATA_TYPE_USHORT4: return "ushort4"; + case IMAGE_DATA_TYPE_USHORT: return "ushort"; + case IMAGE_DATA_NUM_TYPES: + assert(!"System enumerator type, should never be used"); + return ""; + } + assert(!"Unhandled image data type"); + return ""; +} + +} // namespace + ImageManager::ImageManager(const DeviceInfo& info) { need_update = true; @@ -90,12 +129,12 @@ bool ImageManager::set_animation_frame_update(int frame) device_memory *ImageManager::image_memory(int flat_slot) { - ImageDataType type; - int slot = flattened_slot_to_type_index(flat_slot, &type); + ImageDataType type; + int slot = flattened_slot_to_type_index(flat_slot, &type); - Image *img = images[type][slot]; + Image *img = images[type][slot]; - return img->mem; + return img->mem; } bool ImageManager::get_image_metadata(int flat_slot, @@ -133,10 +172,12 @@ bool ImageManager::get_image_metadata(const string& filename, if(metadata.is_float) { metadata.is_linear = true; - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 + : IMAGE_DATA_TYPE_FLOAT; } else { - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 + : IMAGE_DATA_TYPE_BYTE; } return true; @@ -148,7 +189,8 @@ bool ImageManager::get_image_metadata(const string& filename, return false; } if(path_is_directory(filename)) { - VLOG(1) << "File '" << filename << "' is a directory, can't use as image."; + VLOG(1) << "File '" << filename + << "' is a directory, can't use as image."; return false; } @@ -211,16 +253,20 @@ bool ImageManager::get_image_metadata(const string& filename, metadata.channels = spec.nchannels; if(metadata.is_half) { - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_HALF4 : IMAGE_DATA_TYPE_HALF; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_HALF4 + : IMAGE_DATA_TYPE_HALF; } else if(metadata.is_float) { - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 + : IMAGE_DATA_TYPE_FLOAT; } else if(spec.format == TypeDesc::USHORT) { - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_USHORT4 : IMAGE_DATA_TYPE_USHORT; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_USHORT4 + : IMAGE_DATA_TYPE_USHORT; } else { - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 + : IMAGE_DATA_TYPE_BYTE; } in->close(); @@ -229,50 +275,6 @@ bool ImageManager::get_image_metadata(const string& filename, return true; } -int ImageManager::max_flattened_slot(ImageDataType type) -{ - if(tex_num_images[type] == 0) { - /* No textures for the type, no slots needs allocation. */ - return 0; - } - return type_index_to_flattened_slot(tex_num_images[type], type); -} - -/* The lower three bits of a device texture slot number indicate its type. - * These functions convert the slot ids from ImageManager "images" ones - * to device ones and vice verse. - */ -int ImageManager::type_index_to_flattened_slot(int slot, ImageDataType type) -{ - return (slot << IMAGE_DATA_TYPE_SHIFT) | (type); -} - -int ImageManager::flattened_slot_to_type_index(int flat_slot, ImageDataType *type) -{ - *type = (ImageDataType)(flat_slot & IMAGE_DATA_TYPE_MASK); - return flat_slot >> IMAGE_DATA_TYPE_SHIFT; -} - -string ImageManager::name_from_type(int type) -{ - if(type == IMAGE_DATA_TYPE_FLOAT4) - return "float4"; - else if(type == IMAGE_DATA_TYPE_FLOAT) - return "float"; - else if(type == IMAGE_DATA_TYPE_BYTE) - return "byte"; - else if(type == IMAGE_DATA_TYPE_HALF4) - return "half4"; - else if(type == IMAGE_DATA_TYPE_HALF) - return "half"; - else if(type == IMAGE_DATA_TYPE_USHORT) - return "ushort"; - else if(type == IMAGE_DATA_TYPE_USHORT4) - return "ushort4"; - else - return "byte4"; -} - static bool image_equals(ImageManager::Image *image, const string& filename, void *builtin_data, @@ -344,14 +346,16 @@ int ImageManager::add_image(const string& filename, } /* Count if we're over the limit. - * Very unlikely, since max_num_images is insanely big. But better safe than sorry. */ + * Very unlikely, since max_num_images is insanely big. But better safe + * than sorry. + */ int tex_count = 0; for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) { tex_count += tex_num_images[type]; } if(tex_count > max_num_images) { - printf("ImageManager::add_image: Reached image limit (%d), skipping '%s'\n", - max_num_images, filename.c_str()); + printf("ImageManager::add_image: Reached image limit (%d), " + "skipping '%s'\n", max_num_images, filename.c_str()); return -1; } @@ -508,7 +512,6 @@ bool ImageManager::file_load_image(Image *img, int texture_limit, device_vector<DeviceType>& tex_img) { - const StorageType alpha_one = (FileFormat == TypeDesc::UINT8)? 255 : 1; ImageInput *in = NULL; if(!file_load_image_generic(img, &in)) { return false; @@ -601,13 +604,19 @@ bool ImageManager::file_load_image(Image *img, type == IMAGE_DATA_TYPE_BYTE4 || type == IMAGE_DATA_TYPE_USHORT4); if(is_rgba) { + const StorageType one = util_image_cast_from_float<StorageType>(1.0f); + if(cmyk) { /* CMYK */ for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255; - pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255; - pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255; - pixels[i*4+3] = alpha_one; + float c = util_image_cast_to_float(pixels[i*4+0]); + float m = util_image_cast_to_float(pixels[i*4+1]); + float y = util_image_cast_to_float(pixels[i*4+2]); + float k = util_image_cast_to_float(pixels[i*4+3]); + pixels[i*4+0] = util_image_cast_from_float<StorageType>((1.0f - c) * (1.0f - k)); + pixels[i*4+1] = util_image_cast_from_float<StorageType>((1.0f - m) * (1.0f - k)); + pixels[i*4+2] = util_image_cast_from_float<StorageType>((1.0f - y) * (1.0f - k)); + pixels[i*4+3] = one; } } else if(components == 2) { @@ -622,7 +631,7 @@ bool ImageManager::file_load_image(Image *img, else if(components == 3) { /* RGB */ for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = alpha_one; + pixels[i*4+3] = one; pixels[i*4+2] = pixels[i*3+2]; pixels[i*4+1] = pixels[i*3+1]; pixels[i*4+0] = pixels[i*3+0]; @@ -631,7 +640,7 @@ bool ImageManager::file_load_image(Image *img, else if(components == 1) { /* grayscale */ for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = alpha_one; + pixels[i*4+3] = one; pixels[i*4+2] = pixels[i]; pixels[i*4+1] = pixels[i]; pixels[i*4+0] = pixels[i]; @@ -639,7 +648,7 @@ bool ImageManager::file_load_image(Image *img, } if(img->use_alpha == false) { for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = alpha_one; + pixels[i*4+3] = one; } } } @@ -727,7 +736,8 @@ void ImageManager::device_load_image(Device *device, /* Slot assignment */ int flat_slot = type_index_to_flattened_slot(slot, type); - img->mem_name = string_printf("__tex_image_%s_%03d", name_from_type(type).c_str(), flat_slot); + img->mem_name = string_printf("__tex_image_%s_%03d", + name_from_type(type), flat_slot); /* Free previous texture in slot. */ if(img->mem) { @@ -871,7 +881,7 @@ void ImageManager::device_load_image(Device *device, thread_scoped_lock device_lock(device_mutex); uint16_t *pixels = (uint16_t*)tex_img->alloc(1, 1); - pixels[0] = TEX_IMAGE_MISSING_R; + pixels[0] = (TEX_IMAGE_MISSING_R * 65535); } img->mem = tex_img; @@ -893,10 +903,10 @@ void ImageManager::device_load_image(Device *device, thread_scoped_lock device_lock(device_mutex); uint16_t *pixels = (uint16_t*)tex_img->alloc(1, 1); - pixels[0] = TEX_IMAGE_MISSING_R; - pixels[1] = TEX_IMAGE_MISSING_G; - pixels[2] = TEX_IMAGE_MISSING_B; - pixels[3] = TEX_IMAGE_MISSING_A; + pixels[0] = (TEX_IMAGE_MISSING_R * 65535); + pixels[1] = (TEX_IMAGE_MISSING_G * 65535); + pixels[2] = (TEX_IMAGE_MISSING_B * 65535); + pixels[3] = (TEX_IMAGE_MISSING_A * 65535); } img->mem = tex_img; @@ -1066,4 +1076,15 @@ void ImageManager::device_free(Device *device) } } +void ImageManager::collect_statistics(RenderStats *stats) +{ + for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) { + foreach(const Image *image, images[type]) { + stats->image.textures.add_entry( + NamedSizeEntry(path_filename(image->filename), + image->mem->memory_size())); + } + } +} + CCL_NAMESPACE_END |