Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/render/image.cpp
| Show First 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | if(in) { | ||||
| } | } | ||||
| delete in; | delete in; | ||||
| } | } | ||||
| return is_float; | return is_float; | ||||
| } | } | ||||
| int ImageManager::add_image(const string& filename, void *builtin_data, bool animated, bool& is_float, bool& is_linear) | int ImageManager::add_image(const string& filename, void *builtin_data, bool animated, bool& is_float, bool& is_linear, int interpolation) | ||||
| { | { | ||||
| Image *img; | Image *img; | ||||
| size_t slot; | size_t slot; | ||||
| /* load image info and find out if we need a float texture */ | /* load image info and find out if we need a float texture */ | ||||
| is_float = (pack_images)? false: is_float_image(filename, builtin_data, is_linear); | is_float = (pack_images)? false: is_float_image(filename, builtin_data, is_linear); | ||||
| if(is_float) { | if(is_float) { | ||||
| /* find existing image */ | /* find existing image */ | ||||
| for(slot = 0; slot < float_images.size(); slot++) { | for(slot = 0; slot < float_images.size(); slot++) { | ||||
| if(float_images[slot] && float_images[slot]->filename == filename) { | if(float_images[slot] && float_images[slot]->filename == filename && float_images[slot]->interpolation == interpolation) { | ||||
| float_images[slot]->users++; | float_images[slot]->users++; | ||||
| return slot; | return slot; | ||||
| } | } | ||||
| } | } | ||||
| /* find free slot */ | /* find free slot */ | ||||
| for(slot = 0; slot < float_images.size(); slot++) { | for(slot = 0; slot < float_images.size(); slot++) { | ||||
| if(!float_images[slot]) | if(!float_images[slot]) | ||||
| Show All 12 Lines | if(is_float) { | ||||
| } | } | ||||
| /* add new image */ | /* add new image */ | ||||
| img = new Image(); | img = new Image(); | ||||
| img->filename = filename; | img->filename = filename; | ||||
| img->builtin_data = builtin_data; | img->builtin_data = builtin_data; | ||||
| img->need_load = true; | img->need_load = true; | ||||
| img->animated = animated; | img->animated = animated; | ||||
| img->interpolation = interpolation; | |||||
| img->users = 1; | img->users = 1; | ||||
| float_images[slot] = img; | float_images[slot] = img; | ||||
| } | } | ||||
| else { | else { | ||||
| for(slot = 0; slot < images.size(); slot++) { | for(slot = 0; slot < images.size(); slot++) { | ||||
| if(images[slot] && images[slot]->filename == filename) { | if(images[slot] && images[slot]->filename == filename && images[slot]->interpolation == interpolation) { | ||||
| images[slot]->users++; | images[slot]->users++; | ||||
| return slot+tex_image_byte_start; | return slot+tex_image_byte_start; | ||||
| } | } | ||||
| } | } | ||||
| /* find free slot */ | /* find free slot */ | ||||
| for(slot = 0; slot < images.size(); slot++) { | for(slot = 0; slot < images.size(); slot++) { | ||||
| if(!images[slot]) | if(!images[slot]) | ||||
| Show All 12 Lines | else { | ||||
| } | } | ||||
| /* add new image */ | /* add new image */ | ||||
| img = new Image(); | img = new Image(); | ||||
| img->filename = filename; | img->filename = filename; | ||||
| img->builtin_data = builtin_data; | img->builtin_data = builtin_data; | ||||
| img->need_load = true; | img->need_load = true; | ||||
| img->animated = animated; | img->animated = animated; | ||||
| img->interpolation = interpolation; | |||||
| img->users = 1; | img->users = 1; | ||||
| images[slot] = img; | images[slot] = img; | ||||
| slot += tex_image_byte_start; | slot += tex_image_byte_start; | ||||
| } | } | ||||
| need_update = true; | need_update = true; | ||||
| return slot; | return slot; | ||||
| } | } | ||||
| void ImageManager::remove_image(const string& filename, void *builtin_data) | void ImageManager::remove_image(const string& filename, void *builtin_data, int interpolation) | ||||
| { | { | ||||
| size_t slot; | size_t slot; | ||||
| for(slot = 0; slot < images.size(); slot++) { | for(slot = 0; slot < images.size(); slot++) { | ||||
| if(images[slot] && images[slot]->filename == filename && images[slot]->builtin_data == builtin_data) { | if(images[slot] && images[slot]->filename == filename && images[slot]->interpolation == interpolation && images[slot]->builtin_data == builtin_data) { | ||||
| /* decrement user count */ | /* decrement user count */ | ||||
| images[slot]->users--; | images[slot]->users--; | ||||
| assert(images[slot]->users >= 0); | assert(images[slot]->users >= 0); | ||||
| /* don't remove immediately, rather do it all together later on. one of | /* don't remove immediately, rather do it all together later on. one of | ||||
| * the reasons for this is that on shader changes we add and remove nodes | * the reasons for this is that on shader changes we add and remove nodes | ||||
| * that use them, but we do not want to reload the image all the time. */ | * that use them, but we do not want to reload the image all the time. */ | ||||
| if(images[slot]->users == 0) | if(images[slot]->users == 0) | ||||
| need_update = true; | need_update = true; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if(slot == images.size()) { | if(slot == images.size()) { | ||||
| /* see if it's in a float texture slot */ | /* see if it's in a float texture slot */ | ||||
| for(slot = 0; slot < float_images.size(); slot++) { | for(slot = 0; slot < float_images.size(); slot++) { | ||||
| if(float_images[slot] && float_images[slot]->filename == filename && float_images[slot]->builtin_data == builtin_data) { | if(float_images[slot] && float_images[slot]->filename == filename | ||||
| && float_images[slot]->interpolation == interpolation | |||||
| && float_images[slot]->builtin_data == builtin_data) { | |||||
| /* decrement user count */ | /* decrement user count */ | ||||
| float_images[slot]->users--; | float_images[slot]->users--; | ||||
| assert(float_images[slot]->users >= 0); | assert(float_images[slot]->users >= 0); | ||||
| /* don't remove immediately, rather do it all together later on. one of | /* don't remove immediately, rather do it all together later on. one of | ||||
| * the reasons for this is that on shader changes we add and remove nodes | * the reasons for this is that on shader changes we add and remove nodes | ||||
| * that use them, but we do not want to reload the image all the time. */ | * that use them, but we do not want to reload the image all the time. */ | ||||
| if(float_images[slot]->users == 0) | if(float_images[slot]->users == 0) | ||||
| ▲ Show 20 Lines • Show All 200 Lines • ▼ Show 20 Lines | if(slot >= tex_image_byte_start) { | ||||
| img = images[slot - tex_image_byte_start]; | img = images[slot - tex_image_byte_start]; | ||||
| is_float = false; | is_float = false; | ||||
| } | } | ||||
| else { | else { | ||||
| img = float_images[slot]; | img = float_images[slot]; | ||||
| is_float = true; | is_float = true; | ||||
| } | } | ||||
| InterpolationType inter_type = img->interpolation == 1 ? INTERPOLATION_CLOSEST : INTERPOLATION_LINEAR; | |||||
| if(is_float) { | if(is_float) { | ||||
| string filename = path_filename(float_images[slot]->filename); | string filename = path_filename(float_images[slot]->filename); | ||||
| progress->set_status("Updating Images", "Loading " + filename); | progress->set_status("Updating Images", "Loading " + filename); | ||||
| device_vector<float4>& tex_img = dscene->tex_float_image[slot]; | device_vector<float4>& tex_img = dscene->tex_float_image[slot]; | ||||
| if(tex_img.device_pointer) { | if(tex_img.device_pointer) { | ||||
| thread_scoped_lock device_lock(device_mutex); | thread_scoped_lock device_lock(device_mutex); | ||||
| Show All 12 Lines | if(is_float) { | ||||
| string name; | string name; | ||||
| if(slot >= 10) name = string_printf("__tex_image_float_0%d", slot); | if(slot >= 10) name = string_printf("__tex_image_float_0%d", slot); | ||||
| else name = string_printf("__tex_image_float_00%d", slot); | else name = string_printf("__tex_image_float_00%d", slot); | ||||
| if(!pack_images) { | if(!pack_images) { | ||||
| thread_scoped_lock device_lock(device_mutex); | thread_scoped_lock device_lock(device_mutex); | ||||
| device->tex_alloc(name.c_str(), tex_img, true, true); | device->tex_alloc(name.c_str(), tex_img, inter_type, true); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| string filename = path_filename(images[slot - tex_image_byte_start]->filename); | string filename = path_filename(images[slot - tex_image_byte_start]->filename); | ||||
| progress->set_status("Updating Images", "Loading " + filename); | progress->set_status("Updating Images", "Loading " + filename); | ||||
| device_vector<uchar4>& tex_img = dscene->tex_image[slot - tex_image_byte_start]; | device_vector<uchar4>& tex_img = dscene->tex_image[slot - tex_image_byte_start]; | ||||
| Show All 14 Lines | else { | ||||
| string name; | string name; | ||||
| if(slot >= 10) name = string_printf("__tex_image_0%d", slot); | if(slot >= 10) name = string_printf("__tex_image_0%d", slot); | ||||
| else name = string_printf("__tex_image_00%d", slot); | else name = string_printf("__tex_image_00%d", slot); | ||||
| if(!pack_images) { | if(!pack_images) { | ||||
| thread_scoped_lock device_lock(device_mutex); | thread_scoped_lock device_lock(device_mutex); | ||||
| device->tex_alloc(name.c_str(), tex_img, true, true); | device->tex_alloc(name.c_str(), tex_img, inter_type, true); | ||||
| } | } | ||||
| } | } | ||||
| img->need_load = false; | img->need_load = false; | ||||
| } | } | ||||
| void ImageManager::device_free_image(Device *device, DeviceScene *dscene, int slot) | void ImageManager::device_free_image(Device *device, DeviceScene *dscene, int slot) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | void ImageManager::device_pack_images(Device *device, DeviceScene *dscene, Progress& progess) | ||||
| size_t offset = 0; | size_t offset = 0; | ||||
| for(size_t slot = 0; slot < images.size(); slot++) { | for(size_t slot = 0; slot < images.size(); slot++) { | ||||
| if(!images[slot]) | if(!images[slot]) | ||||
| continue; | continue; | ||||
| device_vector<uchar4>& tex_img = dscene->tex_image[slot]; | device_vector<uchar4>& tex_img = dscene->tex_image[slot]; | ||||
| info[slot] = make_uint4(tex_img.data_width, tex_img.data_height, offset, 1); | |||||
| int interpolation = (images[slot]->interpolation << 1) + 1; | |||||
| info[slot] = make_uint4(tex_img.data_width, tex_img.data_height, offset, interpolation); | |||||
| memcpy(pixels+offset, (void*)tex_img.data_pointer, tex_img.memory_size()); | memcpy(pixels+offset, (void*)tex_img.data_pointer, tex_img.memory_size()); | ||||
brecht: Better use `uint8_t` instead, that's the one we use elsewhere and ensure is available. | |||||
| offset += tex_img.size(); | offset += tex_img.size(); | ||||
| } | } | ||||
| if(dscene->tex_image_packed.size()) | if(dscene->tex_image_packed.size()) | ||||
| device->tex_alloc("__tex_image_packed", dscene->tex_image_packed); | device->tex_alloc("__tex_image_packed", dscene->tex_image_packed); | ||||
| if(dscene->tex_image_packed_info.size()) | if(dscene->tex_image_packed_info.size()) | ||||
| device->tex_alloc("__tex_image_packed_info", dscene->tex_image_packed_info); | device->tex_alloc("__tex_image_packed_info", dscene->tex_image_packed_info); | ||||
| } | } | ||||
| Show All 20 Lines | |||||
Better use uint8_t instead, that's the one we use elsewhere and ensure is available.