Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2020-03-08 16:21:29 +0300
committerBrecht Van Lommel <brecht@blender.org>2020-03-11 22:45:39 +0300
commit6cf4861c3ac09fd65a765e8f8e3584713cc5303b (patch)
treeb2b104fbda65b67c56dd2a39ad812c89bc5b1ee2 /intern/cycles/render/image.cpp
parentd8aa613d94caf6a3d82a8f4e9e90b9b8f5c61a7d (diff)
Cleanup: refactor image loading to use abstract ImageLoader base class
Rather than passing around void pointers, various Blender image sources now subclass this. OIIO is also just another type of image loader. Also fixes T67718: Cycles viewport render crash editing point density settings
Diffstat (limited to 'intern/cycles/render/image.cpp')
-rw-r--r--intern/cycles/render/image.cpp538
1 files changed, 204 insertions, 334 deletions
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 123bb129466..b4539b5ce3c 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -15,12 +15,14 @@
*/
#include "render/image.h"
+#include "render/image_oiio.h"
#include "device/device.h"
#include "render/colorspace.h"
#include "render/scene.h"
#include "render/stats.h"
#include "util/util_foreach.h"
+#include "util/util_image.h"
#include "util/util_image_impl.h"
#include "util/util_logging.h"
#include "util/util_path.h"
@@ -85,10 +87,11 @@ ImageHandle::ImageHandle() : manager(NULL)
{
}
-ImageHandle::ImageHandle(const ImageHandle &other) : slots(other.slots), manager(other.manager)
+ImageHandle::ImageHandle(const ImageHandle &other)
+ : tile_slots(other.tile_slots), manager(other.manager)
{
/* Increase image user count. */
- foreach (const int slot, slots) {
+ foreach (const int slot, tile_slots) {
manager->add_image_user(slot);
}
}
@@ -97,9 +100,9 @@ ImageHandle &ImageHandle::operator=(const ImageHandle &other)
{
clear();
manager = other.manager;
- slots = other.slots;
+ tile_slots = other.tile_slots;
- foreach (const int slot, slots) {
+ foreach (const int slot, tile_slots) {
manager->add_image_user(slot);
}
@@ -113,275 +116,265 @@ ImageHandle::~ImageHandle()
void ImageHandle::clear()
{
- foreach (const int slot, slots) {
+ foreach (const int slot, tile_slots) {
manager->remove_image_user(slot);
}
}
bool ImageHandle::empty()
{
- return slots.empty();
+ return tile_slots.empty();
}
int ImageHandle::num_tiles()
{
- return slots.size();
+ return tile_slots.size();
}
ImageMetaData ImageHandle::metadata()
{
- if (slots.empty()) {
+ if (tile_slots.empty()) {
return ImageMetaData();
}
- return manager->images[slots.front()]->metadata;
+ ImageManager::Image *img = manager->images[tile_slots.front()];
+ manager->load_image_metadata(img);
+ return img->metadata;
}
-int ImageHandle::svm_slot(const int tile_index)
+int ImageHandle::svm_slot(const int tile_index) const
{
- if (tile_index >= slots.size()) {
+ if (tile_index >= tile_slots.size()) {
return -1;
}
if (manager->osl_texture_system) {
- ImageManager::Image *img = manager->images[slots[tile_index]];
- if (!img->key.builtin_data) {
+ ImageManager::Image *img = manager->images[tile_slots[tile_index]];
+ if (img->loader->osl_filepath()) {
return -1;
}
}
- return slots[tile_index];
+ return tile_slots[tile_index];
}
-device_memory *ImageHandle::image_memory(const int tile_index)
+device_memory *ImageHandle::image_memory(const int tile_index) const
{
- if (tile_index >= slots.size()) {
+ if (tile_index >= tile_slots.size()) {
return NULL;
}
- ImageManager::Image *img = manager->images[slots[tile_index]];
+ ImageManager::Image *img = manager->images[tile_slots[tile_index]];
return img ? img->mem : NULL;
}
-/* Image Manager */
-
-ImageManager::ImageManager(const DeviceInfo &info)
+bool ImageHandle::operator==(const ImageHandle &other) const
{
- need_update = true;
- osl_texture_system = NULL;
- animation_frame = 0;
-
- /* Set image limits */
- has_half_images = info.has_half_images;
+ return manager == other.manager && tile_slots == other.tile_slots;
}
-ImageManager::~ImageManager()
+/* Image MetaData */
+
+ImageMetaData::ImageMetaData()
+ : channels(0),
+ width(0),
+ height(0),
+ depth(0),
+ type(IMAGE_DATA_NUM_TYPES),
+ colorspace(u_colorspace_raw),
+ colorspace_file_format(""),
+ compress_as_srgb(false)
{
- for (size_t slot = 0; slot < images.size(); slot++)
- assert(!images[slot]);
}
-void ImageManager::set_osl_texture_system(void *texture_system)
+bool ImageMetaData::operator==(const ImageMetaData &other) const
{
- osl_texture_system = texture_system;
+ return channels == other.channels && width == other.width && height == other.height &&
+ depth == other.depth && type == other.type && colorspace == other.colorspace &&
+ compress_as_srgb == other.compress_as_srgb;
}
-bool ImageManager::set_animation_frame_update(int frame)
+bool ImageMetaData::is_float() const
{
- if (frame != animation_frame) {
- animation_frame = frame;
-
- for (size_t slot = 0; slot < images.size(); slot++) {
- if (images[slot] && images[slot]->key.animated)
- return true;
- }
- }
-
- return false;
+ return (type == IMAGE_DATA_TYPE_FLOAT || type == IMAGE_DATA_TYPE_FLOAT4 ||
+ type == IMAGE_DATA_TYPE_HALF || type == IMAGE_DATA_TYPE_HALF4);
}
-void ImageManager::metadata_detect_colorspace(ImageMetaData &metadata, const char *file_format)
+void ImageMetaData::detect_colorspace()
{
/* Convert used specified color spaces to one we know how to handle. */
- metadata.colorspace = ColorSpaceManager::detect_known_colorspace(
- metadata.colorspace, file_format, metadata.is_float || metadata.is_half);
+ colorspace = ColorSpaceManager::detect_known_colorspace(
+ colorspace, colorspace_file_format, is_float());
- if (metadata.colorspace == u_colorspace_raw) {
+ if (colorspace == u_colorspace_raw) {
/* Nothing to do. */
}
- else if (metadata.colorspace == u_colorspace_srgb) {
+ else if (colorspace == u_colorspace_srgb) {
/* Keep sRGB colorspace stored as sRGB, to save memory and/or loading time
* for the common case of 8bit sRGB images like PNG. */
- metadata.compress_as_srgb = true;
+ compress_as_srgb = true;
}
else {
/* Always compress non-raw 8bit images as scene linear + sRGB, as a
* heuristic to keep memory usage the same without too much data loss
* due to quantization in common cases. */
- metadata.compress_as_srgb = (metadata.type == IMAGE_DATA_TYPE_BYTE ||
- metadata.type == IMAGE_DATA_TYPE_BYTE4);
+ compress_as_srgb = (type == IMAGE_DATA_TYPE_BYTE || type == IMAGE_DATA_TYPE_BYTE4);
/* If colorspace conversion needed, use half instead of short so we can
* represent HDR values that might result from conversion. */
- if (metadata.type == IMAGE_DATA_TYPE_USHORT) {
- metadata.type = IMAGE_DATA_TYPE_HALF;
+ if (type == IMAGE_DATA_TYPE_USHORT) {
+ type = IMAGE_DATA_TYPE_HALF;
}
- else if (metadata.type == IMAGE_DATA_TYPE_USHORT4) {
- metadata.type = IMAGE_DATA_TYPE_HALF4;
+ else if (type == IMAGE_DATA_TYPE_USHORT4) {
+ type = IMAGE_DATA_TYPE_HALF4;
}
}
}
-bool ImageManager::load_image_metadata(const ImageKey &key, ImageMetaData &metadata)
-{
- metadata = ImageMetaData();
- metadata.colorspace = key.colorspace;
-
- if (key.builtin_data) {
- if (builtin_image_info_cb) {
- builtin_image_info_cb(key.filename, key.builtin_data, metadata);
- }
- else {
- return false;
- }
+/* Image Loader */
- if (metadata.is_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;
- }
+ImageLoader::ImageLoader()
+{
+}
- metadata_detect_colorspace(metadata, "");
+ustring ImageLoader::osl_filepath() const
+{
+ return ustring();
+}
+bool ImageLoader::equals(const ImageLoader *a, const ImageLoader *b)
+{
+ if (a == NULL && b == NULL) {
return true;
}
-
- /* Perform preliminary checks, with meaningful logging. */
- if (!path_exists(key.filename)) {
- VLOG(1) << "File '" << key.filename << "' does not exist.";
- return false;
- }
- if (path_is_directory(key.filename)) {
- VLOG(1) << "File '" << key.filename << "' is a directory, can't use as image.";
- return false;
+ else {
+ return (a && b && typeid(*a) == typeid(*b) && a->equals(*b));
}
+}
- unique_ptr<ImageInput> in(ImageInput::create(key.filename));
+/* Image Manager */
- if (!in) {
- return false;
- }
+ImageManager::ImageManager(const DeviceInfo &info)
+{
+ need_update = true;
+ osl_texture_system = NULL;
+ animation_frame = 0;
- ImageSpec spec;
- if (!in->open(key.filename, spec)) {
- return false;
- }
+ /* Set image limits */
+ has_half_images = info.has_half_images;
+}
- metadata.width = spec.width;
- metadata.height = spec.height;
- metadata.depth = spec.depth;
- metadata.compress_as_srgb = false;
+ImageManager::~ImageManager()
+{
+ for (size_t slot = 0; slot < images.size(); slot++)
+ assert(!images[slot]);
+}
- /* Check the main format, and channel formats. */
- size_t channel_size = spec.format.basesize();
+void ImageManager::set_osl_texture_system(void *texture_system)
+{
+ osl_texture_system = texture_system;
+}
- if (spec.format.is_floating_point()) {
- metadata.is_float = true;
- }
+bool ImageManager::set_animation_frame_update(int frame)
+{
+ if (frame != animation_frame) {
+ animation_frame = frame;
- for (size_t channel = 0; channel < spec.channelformats.size(); channel++) {
- channel_size = max(channel_size, spec.channelformats[channel].basesize());
- if (spec.channelformats[channel].is_floating_point()) {
- metadata.is_float = true;
+ for (size_t slot = 0; slot < images.size(); slot++) {
+ if (images[slot] && images[slot]->params.animated)
+ return true;
}
}
- /* check if it's half float */
- if (spec.format == TypeDesc::HALF) {
- metadata.is_half = true;
- }
-
- /* set type and channels */
- metadata.channels = spec.nchannels;
+ return false;
+}
- if (metadata.is_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;
- }
- else if (spec.format == TypeDesc::USHORT) {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_USHORT4 : IMAGE_DATA_TYPE_USHORT;
+void ImageManager::load_image_metadata(Image *img)
+{
+ if (!img->need_metadata) {
+ return;
}
- else {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
+
+ thread_scoped_lock image_lock(img->mutex);
+ if (!img->need_metadata) {
+ return;
}
- metadata_detect_colorspace(metadata, in->format_name());
+ ImageMetaData &metadata = img->metadata;
+ metadata = ImageMetaData();
+ metadata.colorspace = img->params.colorspace;
- in->close();
+ img->loader->load_metadata(metadata);
- return true;
+ metadata.detect_colorspace();
+
+ /* No half textures on OpenCL, use full float instead. */
+ if (!has_half_images) {
+ if (metadata.type == IMAGE_DATA_TYPE_HALF4) {
+ metadata.type = IMAGE_DATA_TYPE_FLOAT4;
+ }
+ else if (metadata.type == IMAGE_DATA_TYPE_HALF) {
+ metadata.type = IMAGE_DATA_TYPE_FLOAT;
+ }
+ }
+
+ img->need_metadata = false;
}
-ImageHandle ImageManager::add_image(const ImageKey &key, float frame)
+ImageHandle ImageManager::add_image(const string &filename, const ImageParams &params)
{
+ const int slot = add_image_slot(new OIIOImageLoader(filename), params, false);
+
ImageHandle handle;
- handle.slots.push_back(add_image_slot(key, frame));
+ handle.tile_slots.push_back(slot);
handle.manager = this;
return handle;
}
-ImageHandle ImageManager::add_image(const ImageKey &key, float frame, const vector<int> &tiles)
+ImageHandle ImageManager::add_image(const string &filename,
+ const ImageParams &params,
+ const vector<int> &tiles)
{
ImageHandle handle;
handle.manager = this;
foreach (int tile, tiles) {
- ImageKey tile_key = key;
+ string tile_filename = filename;
if (tile != 0) {
- string_replace(tile_key.filename, "<UDIM>", string_printf("%04d", tile));
+ string_replace(tile_filename, "<UDIM>", string_printf("%04d", tile));
}
- handle.slots.push_back(add_image_slot(tile_key, frame));
+ const int slot = add_image_slot(new OIIOImageLoader(tile_filename), params, false);
+ handle.tile_slots.push_back(slot);
}
return handle;
}
-int ImageManager::add_image_slot(const ImageKey &key, float frame)
+ImageHandle ImageManager::add_image(ImageLoader *loader, const ImageParams &params)
+{
+ const int slot = add_image_slot(loader, params, true);
+
+ ImageHandle handle;
+ handle.tile_slots.push_back(slot);
+ handle.manager = this;
+ return handle;
+}
+
+int ImageManager::add_image_slot(ImageLoader *loader,
+ const ImageParams &params,
+ const bool builtin)
{
Image *img;
size_t slot;
- ImageMetaData metadata;
- load_image_metadata(key, metadata);
-
thread_scoped_lock device_lock(device_mutex);
- /* No half textures on OpenCL, use full float instead. */
- if (!has_half_images) {
- if (metadata.type == IMAGE_DATA_TYPE_HALF4) {
- metadata.type = IMAGE_DATA_TYPE_FLOAT4;
- }
- else if (metadata.type == IMAGE_DATA_TYPE_HALF) {
- metadata.type = IMAGE_DATA_TYPE_FLOAT;
- }
- }
-
/* Fnd existing image. */
for (slot = 0; slot < images.size(); slot++) {
img = images[slot];
- if (img && img->key == key) {
- if (img->frame != frame) {
- img->frame = frame;
- img->need_load = true;
- }
- if (!(img->metadata == metadata)) {
- img->metadata = metadata;
- img->need_load = true;
- }
+ if (img && ImageLoader::equals(img->loader, loader) && img->params == params) {
img->users++;
+ delete loader;
return slot;
}
}
@@ -398,10 +391,11 @@ int ImageManager::add_image_slot(const ImageKey &key, float frame)
/* Add new image. */
img = new Image();
- img->key = key;
- img->frame = frame;
- img->metadata = metadata;
- img->need_load = true;
+ img->params = params;
+ img->loader = loader;
+ img->need_metadata = true;
+ img->need_load = !(osl_texture_system && img->loader->osl_filepath());
+ img->builtin = builtin;
img->users = 1;
img->mem = NULL;
@@ -439,54 +433,9 @@ static bool image_associate_alpha(ImageManager::Image *img)
{
/* For typical RGBA images we let OIIO convert to associated alpha,
* but some types we want to leave the RGB channels untouched. */
- return !(ColorSpaceManager::colorspace_is_data(img->key.colorspace) ||
- img->key.alpha_type == IMAGE_ALPHA_IGNORE ||
- img->key.alpha_type == IMAGE_ALPHA_CHANNEL_PACKED);
-}
-
-bool ImageManager::file_load_image_generic(Image *img, unique_ptr<ImageInput> *in)
-{
- if (img->key.filename == "")
- return false;
-
- if (!img->key.builtin_data) {
- /* NOTE: Error logging is done in meta data acquisition. */
- if (!path_exists(img->key.filename) || path_is_directory(img->key.filename)) {
- return false;
- }
-
- /* load image from file through OIIO */
- *in = unique_ptr<ImageInput>(ImageInput::create(img->key.filename));
-
- if (!*in)
- return false;
-
- ImageSpec spec = ImageSpec();
- ImageSpec config = ImageSpec();
-
- if (!image_associate_alpha(img)) {
- config.attribute("oiio:UnassociatedAlpha", 1);
- }
-
- if (!(*in)->open(img->key.filename, spec, config)) {
- return false;
- }
- }
- else {
- /* load image using builtin images callbacks */
- if (!builtin_image_info_cb || !builtin_image_pixels_cb)
- return false;
- }
-
- /* we only handle certain number of components */
- if (!(img->metadata.channels >= 1 && img->metadata.channels <= 4)) {
- if (*in) {
- (*in)->close();
- }
- return false;
- }
-
- return true;
+ return !(ColorSpaceManager::colorspace_is_data(img->params.colorspace) ||
+ img->params.alpha_type == IMAGE_ALPHA_IGNORE ||
+ img->params.alpha_type == IMAGE_ALPHA_CHANNEL_PACKED);
}
template<TypeDesc::BASETYPE FileFormat, typename StorageType, typename DeviceType>
@@ -494,8 +443,8 @@ bool ImageManager::file_load_image(Image *img,
int texture_limit,
device_vector<DeviceType> &tex_img)
{
- unique_ptr<ImageInput> in = NULL;
- if (!file_load_image_generic(img, &in)) {
+ /* we only handle certain number of components */
+ if (!(img->metadata.channels >= 1 && img->metadata.channels <= 4)) {
return false;
}
@@ -529,67 +478,9 @@ bool ImageManager::file_load_image(Image *img,
return false;
}
- bool cmyk = false;
const size_t num_pixels = ((size_t)width) * height * depth;
- if (in) {
- /* Read pixels through OpenImageIO. */
- StorageType *readpixels = pixels;
- vector<StorageType> tmppixels;
- if (components > 4) {
- tmppixels.resize(((size_t)width) * height * components);
- readpixels = &tmppixels[0];
- }
-
- if (depth <= 1) {
- size_t scanlinesize = ((size_t)width) * components * sizeof(StorageType);
- in->read_image(FileFormat,
- (uchar *)readpixels + (height - 1) * scanlinesize,
- AutoStride,
- -scanlinesize,
- AutoStride);
- }
- else {
- in->read_image(FileFormat, (uchar *)readpixels);
- }
-
- if (components > 4) {
- size_t dimensions = ((size_t)width) * height;
- for (size_t i = dimensions - 1, pixel = 0; pixel < dimensions; pixel++, i--) {
- pixels[i * 4 + 3] = tmppixels[i * components + 3];
- pixels[i * 4 + 2] = tmppixels[i * components + 2];
- pixels[i * 4 + 1] = tmppixels[i * components + 1];
- pixels[i * 4 + 0] = tmppixels[i * components + 0];
- }
- tmppixels.clear();
- }
-
- cmyk = strcmp(in->format_name(), "jpeg") == 0 && components == 4;
- in->close();
- }
- else {
- /* Read pixels through callback. */
- if (FileFormat == TypeDesc::FLOAT) {
- builtin_image_float_pixels_cb(img->key.filename,
- img->key.builtin_data,
- 0, /* TODO(lukas): Support tiles here? */
- (float *)&pixels[0],
- num_pixels * components,
- image_associate_alpha(img),
- img->metadata.builtin_free_cache);
- }
- else if (FileFormat == TypeDesc::UINT8) {
- builtin_image_pixels_cb(img->key.filename,
- img->key.builtin_data,
- 0, /* TODO(lukas): Support tiles here? */
- (uchar *)&pixels[0],
- num_pixels * components,
- image_associate_alpha(img),
- img->metadata.builtin_free_cache);
- }
- else {
- /* TODO(dingto): Support half for ImBuf. */
- }
- }
+ img->loader->load_pixels(
+ img->metadata, pixels, num_pixels * components, image_associate_alpha(img));
/* The kernel can handle 1 and 4 channel images. Anything that is not a single
* channel image is converted to RGBA format. */
@@ -601,20 +492,7 @@ bool ImageManager::file_load_image(Image *img,
if (is_rgba) {
const StorageType one = util_image_cast_from_float<StorageType>(1.0f);
- if (cmyk) {
- /* CMYK to RGBA. */
- for (size_t i = num_pixels - 1, pixel = 0; pixel < num_pixels; pixel++, i--) {
- 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) {
+ if (components == 2) {
/* Grayscale + alpha to RGBA. */
for (size_t i = num_pixels - 1, pixel = 0; pixel < num_pixels; pixel++, i--) {
pixels[i * 4 + 3] = pixels[i * 2 + 1];
@@ -643,7 +521,7 @@ bool ImageManager::file_load_image(Image *img,
}
/* Disable alpha if requested by the user. */
- if (img->key.alpha_type == IMAGE_ALPHA_IGNORE) {
+ if (img->params.alpha_type == IMAGE_ALPHA_IGNORE) {
for (size_t i = num_pixels - 1, pixel = 0; pixel < num_pixels; pixel++, i--) {
pixels[i * 4 + 3] = one;
}
@@ -690,7 +568,8 @@ bool ImageManager::file_load_image(Image *img,
while (max_size * scale_factor > texture_limit) {
scale_factor *= 0.5f;
}
- VLOG(1) << "Scaling image " << img->key.filename << " by a factor of " << scale_factor << ".";
+ VLOG(1) << "Scaling image " << img->loader->name() << " by a factor of " << scale_factor
+ << ".";
vector<StorageType> scaled_pixels;
size_t scaled_width, scaled_height, scaled_depth;
util_image_resize_pixels(pixels_storage,
@@ -721,25 +600,23 @@ static void image_set_device_memory(ImageManager::Image *img, device_memory *mem
{
img->mem = mem;
mem->image_data_type = img->metadata.type;
- mem->interpolation = img->key.interpolation;
- mem->extension = img->key.extension;
+ mem->interpolation = img->params.interpolation;
+ mem->extension = img->params.extension;
}
void ImageManager::device_load_image(Device *device, Scene *scene, int slot, Progress *progress)
{
- if (progress->get_cancel())
+ if (progress->get_cancel()) {
return;
+ }
Image *img = images[slot];
- if (osl_texture_system && !img->key.builtin_data)
- return;
-
- string filename = path_filename(images[slot]->key.filename);
- progress->set_status("Updating Images", "Loading " + filename);
+ progress->set_status("Updating Images", "Loading " + img->loader->name());
const int texture_limit = scene->params.texture_limit;
+ load_image_metadata(img);
ImageDataType type = img->metadata.type;
/* Slot assignment */
@@ -901,29 +778,36 @@ void ImageManager::device_load_image(Device *device, Scene *scene, int slot, Pro
thread_scoped_lock device_lock(device_mutex);
tex_img->copy_to_device();
}
+
+ /* Cleanup memory in image loader. */
+ img->loader->cleanup();
img->need_load = false;
}
void ImageManager::device_free_image(Device *, int slot)
{
Image *img = images[slot];
+ if (img == NULL) {
+ return;
+ }
- if (img) {
- if (osl_texture_system && !img->key.builtin_data) {
+ if (osl_texture_system) {
#ifdef WITH_OSL
- ustring filename(images[slot]->key.filename);
- ((OSL::TextureSystem *)osl_texture_system)->invalidate(filename);
-#endif
- }
-
- if (img->mem) {
- thread_scoped_lock device_lock(device_mutex);
- delete img->mem;
+ ustring filepath = img->loader->osl_filepath();
+ if (filepath) {
+ ((OSL::TextureSystem *)osl_texture_system)->invalidate(filepath);
}
+#endif
+ }
- delete img;
- images[slot] = NULL;
+ if (img->mem) {
+ thread_scoped_lock device_lock(device_mutex);
+ delete img->mem;
}
+
+ delete img->loader;
+ delete img;
+ images[slot] = NULL;
}
void ImageManager::device_update(Device *device, Scene *scene, Progress &progress)
@@ -934,20 +818,13 @@ void ImageManager::device_update(Device *device, Scene *scene, Progress &progres
TaskPool pool;
for (size_t slot = 0; slot < images.size(); slot++) {
- if (!images[slot])
- continue;
-
- if (images[slot]->users == 0) {
+ Image *img = images[slot];
+ if (img && img->users == 0) {
device_free_image(device, slot);
}
- else if (images[slot]->need_load) {
- if (osl_texture_system && !images[slot]->key.builtin_data) {
- images[slot]->need_load = false;
- }
- else {
- pool.push(
- function_bind(&ImageManager::device_load_image, this, device, scene, slot, &progress));
- }
+ else if (img && img->need_load) {
+ pool.push(
+ function_bind(&ImageManager::device_load_image, this, device, scene, slot, &progress));
}
}
@@ -958,19 +835,14 @@ void ImageManager::device_update(Device *device, Scene *scene, Progress &progres
void ImageManager::device_update_slot(Device *device, Scene *scene, int slot, Progress *progress)
{
- Image *image = images[slot];
- assert(image != NULL);
+ Image *img = images[slot];
+ assert(img != NULL);
- if (image->users == 0) {
+ if (img->users == 0) {
device_free_image(device, slot);
}
- else if (image->need_load) {
- if (osl_texture_system && !image->key.builtin_data) {
- images[slot]->need_load = false;
- }
- else {
- device_load_image(device, scene, slot, progress);
- }
+ else if (img->need_load) {
+ device_load_image(device, scene, slot, progress);
}
}
@@ -984,14 +856,10 @@ void ImageManager::device_load_builtin(Device *device, Scene *scene, Progress &p
TaskPool pool;
for (size_t slot = 0; slot < images.size(); slot++) {
- if (!images[slot])
- continue;
-
- if (images[slot]->need_load) {
- if (images[slot]->key.builtin_data) {
- pool.push(
- function_bind(&ImageManager::device_load_image, this, device, scene, slot, &progress));
- }
+ Image *img = images[slot];
+ if (img && img->need_load && img->builtin) {
+ pool.push(
+ function_bind(&ImageManager::device_load_image, this, device, scene, slot, &progress));
}
}
@@ -1001,8 +869,10 @@ void ImageManager::device_load_builtin(Device *device, Scene *scene, Progress &p
void ImageManager::device_free_builtin(Device *device)
{
for (size_t slot = 0; slot < images.size(); slot++) {
- if (images[slot] && images[slot]->key.builtin_data)
+ Image *img = images[slot];
+ if (img && img->builtin) {
device_free_image(device, slot);
+ }
}
}
@@ -1018,7 +888,7 @@ void ImageManager::collect_statistics(RenderStats *stats)
{
foreach (const Image *image, images) {
stats->image.textures.add_entry(
- NamedSizeEntry(path_filename(image->key.filename), image->mem->memory_size()));
+ NamedSizeEntry(image->loader->name(), image->mem->memory_size()));
}
}