Code refactor: simplify image device memory allocation.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Fri, 20 Oct 2017 02:20:37 +0000 (04:20 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Sat, 21 Oct 2017 18:58:28 +0000 (20:58 +0200)
intern/cycles/render/image.cpp
intern/cycles/render/image.h
intern/cycles/render/mesh.cpp
intern/cycles/render/mesh.h
intern/cycles/render/scene.cpp
intern/cycles/render/scene.h

index bb94b9bb82a66466d2ef45dd0b55d2d19e605a44..c9fbd237010dfee87760ee428ed5f589989f7b90 100644 (file)
@@ -364,6 +364,7 @@ int ImageManager::add_image(const string& filename,
        img->extension = extension;
        img->users = 1;
        img->use_alpha = use_alpha;
+       img->mem = NULL;
 
        images[type][slot] = img;
 
@@ -696,7 +697,6 @@ bool ImageManager::file_load_image(Image *img,
 }
 
 void ImageManager::device_load_image(Device *device,
-                                     DeviceScene *dscene,
                                      Scene *scene,
                                      ImageDataType type,
                                      int slot,
@@ -717,26 +717,27 @@ void ImageManager::device_load_image(Device *device,
 
        /* Slot assignment */
        int flat_slot = type_index_to_flattened_slot(slot, type);
-
        string name = string_printf("__tex_image_%s_%03d", name_from_type(type).c_str(), flat_slot);
 
-       if(type == IMAGE_DATA_TYPE_FLOAT4) {
-               if(dscene->tex_float4_image[slot] == NULL)
-                       dscene->tex_float4_image[slot] = new device_vector<float4>();
-               device_vector<float4>& tex_img = *dscene->tex_float4_image[slot];
+       /* Free previous texture in slot. */
+       if(img->mem) {
+               thread_scoped_lock device_lock(device_mutex);
+               device->tex_free(*img->mem);
+               delete img->mem;
+               img->mem = NULL;
+       }
 
-               if(tex_img.device_pointer) {
-                       thread_scoped_lock device_lock(device_mutex);
-                       device->tex_free(tex_img);
-               }
+       /* Create new texture. */
+       if(type == IMAGE_DATA_TYPE_FLOAT4) {
+               device_vector<float4> *tex_img = new device_vector<float4>();
 
                if(!file_load_image<TypeDesc::FLOAT, float>(img,
                                                            type,
                                                            texture_limit,
-                                                           tex_img))
+                                                           *tex_img))
                {
                        /* on failure to load, we set a 1x1 pixels pink image */
-                       float *pixels = (float*)tex_img.resize(1, 1);
+                       float *pixels = (float*)tex_img->resize(1, 1);
 
                        pixels[0] = TEX_IMAGE_MISSING_R;
                        pixels[1] = TEX_IMAGE_MISSING_G;
@@ -744,60 +745,34 @@ void ImageManager::device_load_image(Device *device,
                        pixels[3] = TEX_IMAGE_MISSING_A;
                }
 
-               {
-                       thread_scoped_lock device_lock(device_mutex);
-                       device->tex_alloc(name.c_str(),
-                                         tex_img,
-                                         img->interpolation,
-                                         img->extension);
-               }
+               img->mem = tex_img;
        }
        else if(type == IMAGE_DATA_TYPE_FLOAT) {
-               if(dscene->tex_float_image[slot] == NULL)
-                       dscene->tex_float_image[slot] = new device_vector<float>();
-               device_vector<float>& tex_img = *dscene->tex_float_image[slot];
-
-               if(tex_img.device_pointer) {
-                       thread_scoped_lock device_lock(device_mutex);
-                       device->tex_free(tex_img);
-               }
+               device_vector<float> *tex_img = new device_vector<float>();
 
                if(!file_load_image<TypeDesc::FLOAT, float>(img,
                                                            type,
                                                            texture_limit,
-                                                           tex_img))
+                                                           *tex_img))
                {
                        /* on failure to load, we set a 1x1 pixels pink image */
-                       float *pixels = (float*)tex_img.resize(1, 1);
+                       float *pixels = (float*)tex_img->resize(1, 1);
 
                        pixels[0] = TEX_IMAGE_MISSING_R;
                }
 
-               {
-                       thread_scoped_lock device_lock(device_mutex);
-                       device->tex_alloc(name.c_str(),
-                                         tex_img,
-                                         img->interpolation,
-                                         img->extension);
-               }
+               img->mem = tex_img;
        }
        else if(type == IMAGE_DATA_TYPE_BYTE4) {
-               if(dscene->tex_byte4_image[slot] == NULL)
-                       dscene->tex_byte4_image[slot] = new device_vector<uchar4>();
-               device_vector<uchar4>& tex_img = *dscene->tex_byte4_image[slot];
-
-               if(tex_img.device_pointer) {
-                       thread_scoped_lock device_lock(device_mutex);
-                       device->tex_free(tex_img);
-               }
+               device_vector<uchar4> *tex_img = new device_vector<uchar4>();
 
                if(!file_load_image<TypeDesc::UINT8, uchar>(img,
                                                            type,
                                                            texture_limit,
-                                                           tex_img))
+                                                           *tex_img))
                {
                        /* on failure to load, we set a 1x1 pixels pink image */
-                       uchar *pixels = (uchar*)tex_img.resize(1, 1);
+                       uchar *pixels = (uchar*)tex_img->resize(1, 1);
 
                        pixels[0] = (TEX_IMAGE_MISSING_R * 255);
                        pixels[1] = (TEX_IMAGE_MISSING_G * 255);
@@ -805,58 +780,32 @@ void ImageManager::device_load_image(Device *device,
                        pixels[3] = (TEX_IMAGE_MISSING_A * 255);
                }
 
-               {
-                       thread_scoped_lock device_lock(device_mutex);
-                       device->tex_alloc(name.c_str(),
-                                         tex_img,
-                                         img->interpolation,
-                                         img->extension);
-               }
+               img->mem = tex_img;
        }
-       else if(type == IMAGE_DATA_TYPE_BYTE){
-               if(dscene->tex_byte_image[slot] == NULL)
-                       dscene->tex_byte_image[slot] = new device_vector<uchar>();
-               device_vector<uchar>& tex_img = *dscene->tex_byte_image[slot];
-
-               if(tex_img.device_pointer) {
-                       thread_scoped_lock device_lock(device_mutex);
-                       device->tex_free(tex_img);
-               }
+       else if(type == IMAGE_DATA_TYPE_BYTE) {
+               device_vector<uchar> *tex_img = new device_vector<uchar>();
 
                if(!file_load_image<TypeDesc::UINT8, uchar>(img,
                                                            type,
                                                            texture_limit,
-                                                           tex_img)) {
+                                                           *tex_img)) {
                        /* on failure to load, we set a 1x1 pixels pink image */
-                       uchar *pixels = (uchar*)tex_img.resize(1, 1);
+                       uchar *pixels = (uchar*)tex_img->resize(1, 1);
 
                        pixels[0] = (TEX_IMAGE_MISSING_R * 255);
                }
 
-               {
-                       thread_scoped_lock device_lock(device_mutex);
-                       device->tex_alloc(name.c_str(),
-                                         tex_img,
-                                         img->interpolation,
-                                         img->extension);
-               }
+               img->mem = tex_img;
        }
-       else if(type == IMAGE_DATA_TYPE_HALF4){
-               if(dscene->tex_half4_image[slot] == NULL)
-                       dscene->tex_half4_image[slot] = new device_vector<half4>();
-               device_vector<half4>& tex_img = *dscene->tex_half4_image[slot];
-
-               if(tex_img.device_pointer) {
-                       thread_scoped_lock device_lock(device_mutex);
-                       device->tex_free(tex_img);
-               }
+       else if(type == IMAGE_DATA_TYPE_HALF4) {
+               device_vector<half4> *tex_img = new device_vector<half4>();
 
                if(!file_load_image<TypeDesc::HALF, half>(img,
                                                          type,
                                                          texture_limit,
-                                                         tex_img)) {
+                                                         *tex_img)) {
                        /* on failure to load, we set a 1x1 pixels pink image */
-                       half *pixels = (half*)tex_img.resize(1, 1);
+                       half *pixels = (half*)tex_img->resize(1, 1);
 
                        pixels[0] = TEX_IMAGE_MISSING_R;
                        pixels[1] = TEX_IMAGE_MISSING_G;
@@ -864,47 +813,38 @@ void ImageManager::device_load_image(Device *device,
                        pixels[3] = TEX_IMAGE_MISSING_A;
                }
 
-               {
-                       thread_scoped_lock device_lock(device_mutex);
-                       device->tex_alloc(name.c_str(),
-                                         tex_img,
-                                         img->interpolation,
-                                         img->extension);
-               }
+               img->mem = tex_img;
        }
-       else if(type == IMAGE_DATA_TYPE_HALF){
-               if(dscene->tex_half_image[slot] == NULL)
-                       dscene->tex_half_image[slot] = new device_vector<half>();
-               device_vector<half>& tex_img = *dscene->tex_half_image[slot];
-
-               if(tex_img.device_pointer) {
-                       thread_scoped_lock device_lock(device_mutex);
-                       device->tex_free(tex_img);
-               }
+       else if(type == IMAGE_DATA_TYPE_HALF) {
+               device_vector<half> *tex_img = new device_vector<half>();
 
                if(!file_load_image<TypeDesc::HALF, half>(img,
                                                          type,
                                                          texture_limit,
-                                                         tex_img)) {
+                                                         *tex_img)) {
                        /* on failure to load, we set a 1x1 pixels pink image */
-                       half *pixels = (half*)tex_img.resize(1, 1);
+                       half *pixels = (half*)tex_img->resize(1, 1);
 
                        pixels[0] = TEX_IMAGE_MISSING_R;
                }
 
-               {
-                       thread_scoped_lock device_lock(device_mutex);
-                       device->tex_alloc(name.c_str(),
-                                         tex_img,
-                                         img->interpolation,
-                                         img->extension);
-               }
+               img->mem = tex_img;
        }
 
+       /* Copy to device. */
+       if(img->mem) {
+               thread_scoped_lock device_lock(device_mutex);
+               device->tex_alloc(name.c_str(),
+                                                 *img->mem,
+                                                 img->interpolation,
+                                                 img->extension);
+       }
+
+
        img->need_load = false;
 }
 
-void ImageManager::device_free_image(Device *device, DeviceScene *dscene, ImageDataType type, int slot)
+void ImageManager::device_free_image(Device *device, ImageDataType type, int slot)
 {
        Image *img = images[type][slot];
 
@@ -915,105 +855,20 @@ void ImageManager::device_free_image(Device *device, DeviceScene *dscene, ImageD
                        ((OSL::TextureSystem*)osl_texture_system)->invalidate(filename);
 #endif
                }
-               else {
-                       device_memory *tex_img = NULL;
-                       switch(type) {
-                               case IMAGE_DATA_TYPE_FLOAT4:
-                                       if(slot >= dscene->tex_float4_image.size()) {
-                                               break;
-                                       }
-                                       tex_img = dscene->tex_float4_image[slot];
-                                       dscene->tex_float4_image[slot] = NULL;
-                                       break;
-                               case IMAGE_DATA_TYPE_BYTE4:
-                                       if(slot >= dscene->tex_byte4_image.size()) {
-                                               break;
-                                       }
-                                       tex_img = dscene->tex_byte4_image[slot];
-                                       dscene->tex_byte4_image[slot]= NULL;
-                                       break;
-                               case IMAGE_DATA_TYPE_HALF4:
-                                       if(slot >= dscene->tex_half4_image.size()) {
-                                               break;
-                                       }
-                                       tex_img = dscene->tex_half4_image[slot];
-                                       dscene->tex_half4_image[slot]= NULL;
-                                       break;
-                               case IMAGE_DATA_TYPE_FLOAT:
-                                       if(slot >= dscene->tex_float_image.size()) {
-                                               break;
-                                       }
-                                       tex_img = dscene->tex_float_image[slot];
-                                       dscene->tex_float_image[slot] = NULL;
-                                       break;
-                               case IMAGE_DATA_TYPE_BYTE:
-                                       if(slot >= dscene->tex_byte_image.size()) {
-                                               break;
-                                       }
-                                       tex_img = dscene->tex_byte_image[slot];
-                                       dscene->tex_byte_image[slot]= NULL;
-                                       break;
-                               case IMAGE_DATA_TYPE_HALF:
-                                       if(slot >= dscene->tex_half_image.size()) {
-                                               break;
-                                       }
-                                       tex_img = dscene->tex_half_image[slot];
-                                       dscene->tex_half_image[slot]= NULL;
-                                       break;
-                               default:
-                                       assert(0);
-                                       tex_img = NULL;
-                       }
-                       if(tex_img) {
-                               if(tex_img->device_pointer) {
-                                       thread_scoped_lock device_lock(device_mutex);
-                                       device->tex_free(*tex_img);
-                               }
 
-                               delete tex_img;
-                       }
+               if(img->mem) {
+                       thread_scoped_lock device_lock(device_mutex);
+                       device->tex_free(*img->mem);
+                       delete img->mem;
                }
 
-               delete images[type][slot];
+               delete img;
                images[type][slot] = NULL;
                --tex_num_images[type];
        }
 }
 
-void ImageManager::device_prepare_update(DeviceScene *dscene)
-{
-       for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
-               switch(type) {
-                       case IMAGE_DATA_TYPE_FLOAT4:
-                               if(dscene->tex_float4_image.size() <= tex_num_images[IMAGE_DATA_TYPE_FLOAT4])
-                                       dscene->tex_float4_image.resize(tex_num_images[IMAGE_DATA_TYPE_FLOAT4]);
-                               break;
-                       case IMAGE_DATA_TYPE_BYTE4:
-                               if(dscene->tex_byte4_image.size() <= tex_num_images[IMAGE_DATA_TYPE_BYTE4])
-                                       dscene->tex_byte4_image.resize(tex_num_images[IMAGE_DATA_TYPE_BYTE4]);
-                               break;
-                       case IMAGE_DATA_TYPE_HALF4:
-                               if(dscene->tex_half4_image.size() <= tex_num_images[IMAGE_DATA_TYPE_HALF4])
-                                       dscene->tex_half4_image.resize(tex_num_images[IMAGE_DATA_TYPE_HALF4]);
-                               break;
-                       case IMAGE_DATA_TYPE_BYTE:
-                               if(dscene->tex_byte_image.size() <= tex_num_images[IMAGE_DATA_TYPE_BYTE])
-                                       dscene->tex_byte_image.resize(tex_num_images[IMAGE_DATA_TYPE_BYTE]);
-                               break;
-                       case IMAGE_DATA_TYPE_FLOAT:
-                               if(dscene->tex_float_image.size() <= tex_num_images[IMAGE_DATA_TYPE_FLOAT])
-                                       dscene->tex_float_image.resize(tex_num_images[IMAGE_DATA_TYPE_FLOAT]);
-                               break;
-                       case IMAGE_DATA_TYPE_HALF:
-                               if(dscene->tex_half_image.size() <= tex_num_images[IMAGE_DATA_TYPE_HALF])
-                                       dscene->tex_half_image.resize(tex_num_images[IMAGE_DATA_TYPE_HALF]);
-                               break;
-               }
-       }
-}
-
 void ImageManager::device_update(Device *device,
-                                 DeviceScene *dscene,
                                  Scene *scene,
                                  Progress& progress)
 {
@@ -1021,9 +876,6 @@ void ImageManager::device_update(Device *device,
                return;
        }
 
-       /* Make sure arrays are proper size. */
-       device_prepare_update(dscene);
-
        TaskPool pool;
        for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
                for(size_t slot = 0; slot < images[type].size(); slot++) {
@@ -1031,14 +883,13 @@ void ImageManager::device_update(Device *device,
                                continue;
 
                        if(images[type][slot]->users == 0) {
-                               device_free_image(device, dscene, (ImageDataType)type, slot);
+                               device_free_image(device, (ImageDataType)type, slot);
                        }
                        else if(images[type][slot]->need_load) {
                                if(!osl_texture_system || images[type][slot]->builtin_data)
                                        pool.push(function_bind(&ImageManager::device_load_image,
                                                                this,
                                                                device,
-                                                               dscene,
                                                                scene,
                                                                (ImageDataType)type,
                                                                slot,
@@ -1053,7 +904,6 @@ void ImageManager::device_update(Device *device,
 }
 
 void ImageManager::device_update_slot(Device *device,
-                                      DeviceScene *dscene,
                                       Scene *scene,
                                       int flat_slot,
                                       Progress *progress)
@@ -1065,12 +915,11 @@ void ImageManager::device_update_slot(Device *device,
        assert(image != NULL);
 
        if(image->users == 0) {
-               device_free_image(device, dscene, type, slot);
+               device_free_image(device, type, slot);
        }
        else if(image->need_load) {
                if(!osl_texture_system || image->builtin_data)
                        device_load_image(device,
-                                         dscene,
                                          scene,
                                          type,
                                          slot,
@@ -1078,31 +927,24 @@ void ImageManager::device_update_slot(Device *device,
        }
 }
 
-void ImageManager::device_free_builtin(Device *device, DeviceScene *dscene)
+void ImageManager::device_free_builtin(Device *device)
 {
        for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
                for(size_t slot = 0; slot < images[type].size(); slot++) {
                        if(images[type][slot] && images[type][slot]->builtin_data)
-                               device_free_image(device, dscene, (ImageDataType)type, slot);
+                               device_free_image(device, (ImageDataType)type, slot);
                }
        }
 }
 
-void ImageManager::device_free(Device *device, DeviceScene *dscene)
+void ImageManager::device_free(Device *device)
 {
        for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
                for(size_t slot = 0; slot < images[type].size(); slot++) {
-                       device_free_image(device, dscene, (ImageDataType)type, slot);
+                       device_free_image(device, (ImageDataType)type, slot);
                }
                images[type].clear();
        }
-
-       dscene->tex_float4_image.clear();
-       dscene->tex_byte4_image.clear();
-       dscene->tex_half4_image.clear();
-       dscene->tex_float_image.clear();
-       dscene->tex_byte_image.clear();
-       dscene->tex_half_image.clear();
 }
 
 CCL_NAMESPACE_END
index c86d1cbedbf50f2065b5d83d7fece843eae414d2..cc7c8544bedc936e5ea62f3b0cf8c80efe28c1d8 100644 (file)
@@ -28,7 +28,6 @@
 CCL_NAMESPACE_BEGIN
 
 class Device;
-class DeviceScene;
 class Progress;
 class Scene;
 
@@ -62,18 +61,15 @@ public:
                                         bool& is_linear,
                                         bool& builtin_free_cache);
 
-       void device_prepare_update(DeviceScene *dscene);
        void device_update(Device *device,
-                          DeviceScene *dscene,
                           Scene *scene,
                           Progress& progress);
        void device_update_slot(Device *device,
-                               DeviceScene *dscene,
                                Scene *scene,
                                int flat_slot,
                                Progress *progress);
-       void device_free(Device *device, DeviceScene *dscene);
-       void device_free_builtin(Device *device, DeviceScene *dscene);
+       void device_free(Device *device);
+       void device_free_builtin(Device *device);
 
        void set_osl_texture_system(void *texture_system);
        bool set_animation_frame_update(int frame);
@@ -115,6 +111,8 @@ public:
                InterpolationType interpolation;
                ExtensionType extension;
 
+               device_memory *mem;
+
                int users;
        };
 
@@ -151,13 +149,11 @@ private:
        string name_from_type(int type);
 
        void device_load_image(Device *device,
-                              DeviceScene *dscene,
                               Scene *scene,
                               ImageDataType type,
                               int slot,
                               Progress *progess);
        void device_free_image(Device *device,
-                              DeviceScene *dscene,
                               ImageDataType type,
                               int slot);
 };
index 6470b3b10757c100a4914a14172b1c9a7ce88bb1..efec1d3e49197a918c4f2dacff3f931736458622 100644 (file)
@@ -1913,7 +1913,6 @@ void MeshManager::device_update_flags(Device * /*device*/,
 }
 
 void MeshManager::device_update_displacement_images(Device *device,
-                                                    DeviceScene *dscene,
                                                     Scene *scene,
                                                     Progress& progress)
 {
@@ -1941,12 +1940,10 @@ void MeshManager::device_update_displacement_images(Device *device,
                        }
                }
        }
-       image_manager->device_prepare_update(dscene);
        foreach(int slot, bump_images) {
                pool.push(function_bind(&ImageManager::device_update_slot,
                                        image_manager,
                                        device,
-                                       dscene,
                                        scene,
                                        slot,
                                        &progress));
@@ -2029,7 +2026,7 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
        }
        if(true_displacement_used) {
                VLOG(1) << "Updating images used for true displacement.";
-               device_update_displacement_images(device, dscene, scene, progress);
+               device_update_displacement_images(device, scene, progress);
                old_need_object_flags_update = scene->object_manager->need_flags_update;
                scene->object_manager->device_update_flags(device,
                                                           dscene,
index ed7cb881e91833aa637d7497baa9303d8a80b41f..f663275ffc1cf65cbfe85218979fed97b5d34b69 100644 (file)
@@ -368,7 +368,6 @@ protected:
                               Progress& progress);
 
        void device_update_displacement_images(Device *device,
-                                              DeviceScene *dscene,
                                               Scene *scene,
                                               Progress& progress);
 };
index c59a5d97df530f4adf47dc01dfb91de499df630a..cf89385a33d2a7d28bf4fc44e77ceb8fd517826c 100644 (file)
@@ -107,9 +107,9 @@ void Scene::free_memory(bool final)
                bake_manager->device_free(device, &dscene);
 
                if(!params.persistent_data || final)
-                       image_manager->device_free(device, &dscene);
+                       image_manager->device_free(device);
                else
-                       image_manager->device_free_builtin(device, &dscene);
+                       image_manager->device_free_builtin(device);
 
                lookup_tables->device_free(device, &dscene);
        }
@@ -185,7 +185,7 @@ void Scene::device_update(Device *device_, Progress& progress)
        if(progress.get_cancel() || device->have_error()) return;
 
        progress.set_status("Updating Images");
-       image_manager->device_update(device, &dscene, this, progress);
+       image_manager->device_update(device, this, progress);
 
        if(progress.get_cancel() || device->have_error()) return;
 
index a1966afd23b5c471456ead9a87ab8bfb137160c8..32d5c0943e4bdc7a3b123cada6f39a9c7b05f4d9 100644 (file)
@@ -113,14 +113,6 @@ public:
        /* integrator */
        device_vector<uint> sobol_directions;
 
-       /* cpu images */
-       vector<device_vector<float4>* > tex_float4_image;
-       vector<device_vector<uchar4>* > tex_byte4_image;
-       vector<device_vector<half4>* > tex_half4_image;
-       vector<device_vector<float>* > tex_float_image;
-       vector<device_vector<uchar>* > tex_byte_image;
-       vector<device_vector<half>* > tex_half_image;
-
        KernelData data;
 };