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:
Diffstat (limited to 'intern/cycles/render')
-rw-r--r--intern/cycles/render/image.cpp108
-rw-r--r--intern/cycles/render/image.h31
-rw-r--r--intern/cycles/render/mesh.cpp2
-rw-r--r--intern/cycles/render/scene.cpp2
-rw-r--r--intern/cycles/render/scene.h5
5 files changed, 121 insertions, 27 deletions
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 7465fbd43a7..11193bf4974 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -19,6 +19,7 @@
#include "scene.h"
#include "util_foreach.h"
+#include "util_logging.h"
#include "util_path.h"
#include "util_progress.h"
#include "util_texture.h"
@@ -476,6 +477,7 @@ template<TypeDesc::BASETYPE FileFormat,
typename DeviceType>
bool ImageManager::file_load_image(Image *img,
ImageDataType type,
+ int texture_limit,
device_vector<DeviceType>& tex_img)
{
const StorageType alpha_one = (FileFormat == TypeDesc::UINT8)? 255 : 1;
@@ -485,9 +487,15 @@ bool ImageManager::file_load_image(Image *img,
return false;
}
/* Read RGBA pixels. */
- StorageType *pixels = (StorageType*)tex_img.resize(width, height, depth);
- if(pixels == NULL) {
- return false;
+ vector<StorageType> pixels_storage;
+ StorageType *pixels;
+ const size_t max_size = max(max(width, height), depth);
+ if(texture_limit > 0 && max_size > texture_limit) {
+ pixels_storage.resize(((size_t)width)*height*depth*4);
+ pixels = &pixels_storage[0];
+ }
+ else {
+ pixels = (StorageType*)tex_img.resize(width, height, depth);
}
bool cmyk = false;
if(in) {
@@ -526,12 +534,12 @@ bool ImageManager::file_load_image(Image *img,
if(FileFormat == TypeDesc::FLOAT) {
builtin_image_float_pixels_cb(img->filename,
img->builtin_data,
- (float*)pixels);
+ (float*)&pixels[0]);
}
else if(FileFormat == TypeDesc::UINT8) {
builtin_image_pixels_cb(img->filename,
img->builtin_data,
- (uchar*)pixels);
+ (uchar*)&pixels[0]);
}
else {
/* TODO(dingto): Support half for ImBuf. */
@@ -540,10 +548,10 @@ bool ImageManager::file_load_image(Image *img,
/* Check if we actually have a float4 slot, in case components == 1,
* but device doesn't support single channel textures.
*/
- if(type == IMAGE_DATA_TYPE_FLOAT4 ||
- type == IMAGE_DATA_TYPE_HALF4 ||
- type == IMAGE_DATA_TYPE_BYTE4)
- {
+ bool is_rgba = (type == IMAGE_DATA_TYPE_FLOAT4 ||
+ type == IMAGE_DATA_TYPE_HALF4 ||
+ type == IMAGE_DATA_TYPE_BYTE4);
+ if(is_rgba) {
size_t num_pixels = ((size_t)width) * height * depth;
if(cmyk) {
/* CMYK */
@@ -587,14 +595,41 @@ bool ImageManager::file_load_image(Image *img,
}
}
}
+ if(pixels_storage.size() > 0) {
+ float scale_factor = 1.0f;
+ while(max_size * scale_factor > texture_limit) {
+ scale_factor *= 0.5f;
+ }
+ VLOG(1) << "Scaling image " << img->filename
+ << " by a factor of " << scale_factor << ".";
+ vector<StorageType> scaled_pixels;
+ size_t scaled_width, scaled_height, scaled_depth;
+ util_image_resize_pixels(pixels_storage,
+ width, height, depth,
+ is_rgba ? 4 : 1,
+ scale_factor,
+ &scaled_pixels,
+ &scaled_width, &scaled_height, &scaled_depth);
+ StorageType *texture_pixels = (StorageType*)tex_img.resize(scaled_width,
+ scaled_height,
+ scaled_depth);
+ memcpy(texture_pixels,
+ &scaled_pixels[0],
+ scaled_pixels.size() * sizeof(StorageType));
+ }
return true;
}
-void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageDataType type, int slot, Progress *progress)
+void ImageManager::device_load_image(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ ImageDataType type,
+ int slot,
+ Progress *progress)
{
if(progress->get_cancel())
return;
-
+
Image *img = images[type][slot];
if(osl_texture_system && !img->builtin_data)
@@ -603,6 +638,8 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
string filename = path_filename(images[type][slot]->filename);
progress->set_status("Updating Images", "Loading " + filename);
+ const int texture_limit = scene->params.texture_limit;
+
/* Slot assignment */
int flat_slot = type_index_to_flattened_slot(slot, type);
@@ -622,7 +659,11 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
device->tex_free(tex_img);
}
- if(!file_load_image<TypeDesc::FLOAT, float>(img, type, tex_img)) {
+ if(!file_load_image<TypeDesc::FLOAT, float>(img,
+ type,
+ texture_limit,
+ tex_img))
+ {
/* on failure to load, we set a 1x1 pixels pink image */
float *pixels = (float*)tex_img.resize(1, 1);
@@ -648,7 +689,11 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
device->tex_free(tex_img);
}
- if(!file_load_image<TypeDesc::FLOAT, float>(img, type, tex_img)) {
+ if(!file_load_image<TypeDesc::FLOAT, float>(img,
+ type,
+ texture_limit,
+ tex_img))
+ {
/* on failure to load, we set a 1x1 pixels pink image */
float *pixels = (float*)tex_img.resize(1, 1);
@@ -671,7 +716,11 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
device->tex_free(tex_img);
}
- if(!file_load_image<TypeDesc::UINT8, uchar>(img, type, tex_img)) {
+ if(!file_load_image<TypeDesc::UINT8, uchar>(img,
+ type,
+ texture_limit,
+ tex_img))
+ {
/* on failure to load, we set a 1x1 pixels pink image */
uchar *pixels = (uchar*)tex_img.resize(1, 1);
@@ -697,7 +746,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
device->tex_free(tex_img);
}
- if(!file_load_image<TypeDesc::UINT8, uchar>(img, type, tex_img)) {
+ if(!file_load_image<TypeDesc::UINT8, uchar>(img,
+ type,
+ texture_limit,
+ tex_img)) {
/* on failure to load, we set a 1x1 pixels pink image */
uchar *pixels = (uchar*)tex_img.resize(1, 1);
@@ -720,7 +772,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
device->tex_free(tex_img);
}
- if(!file_load_image<TypeDesc::HALF, half>(img, type, tex_img)) {
+ if(!file_load_image<TypeDesc::HALF, half>(img,
+ type,
+ texture_limit,
+ tex_img)) {
/* on failure to load, we set a 1x1 pixels pink image */
half *pixels = (half*)tex_img.resize(1, 1);
@@ -746,7 +801,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
device->tex_free(tex_img);
}
- if(!file_load_image<TypeDesc::HALF, half>(img, type, tex_img)) {
+ if(!file_load_image<TypeDesc::HALF, half>(img,
+ type,
+ texture_limit,
+ tex_img)) {
/* on failure to load, we set a 1x1 pixels pink image */
half *pixels = (half*)tex_img.resize(1, 1);
@@ -842,7 +900,10 @@ void ImageManager::device_free_image(Device *device, DeviceScene *dscene, ImageD
}
}
-void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress& progress)
+void ImageManager::device_update(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress& progress)
{
if(!need_update)
return;
@@ -859,7 +920,14 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress&
}
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, (ImageDataType)type, slot, &progress));
+ pool.push(function_bind(&ImageManager::device_load_image,
+ this,
+ device,
+ dscene,
+ scene,
+ (ImageDataType)type,
+ slot,
+ &progress));
}
}
}
@@ -874,6 +942,7 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress&
void ImageManager::device_update_slot(Device *device,
DeviceScene *dscene,
+ Scene *scene,
int flat_slot,
Progress *progress)
{
@@ -890,6 +959,7 @@ void ImageManager::device_update_slot(Device *device,
if(!osl_texture_system || image->builtin_data)
device_load_image(device,
dscene,
+ scene,
type,
slot,
progress);
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 1dc4bf180f8..3da7338985c 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -30,6 +30,7 @@ CCL_NAMESPACE_BEGIN
class Device;
class DeviceScene;
class Progress;
+class Scene;
class ImageManager {
public:
@@ -67,8 +68,15 @@ public:
ExtensionType extension);
ImageDataType get_image_metadata(const string& filename, void *builtin_data, bool& is_linear);
- void device_update(Device *device, DeviceScene *dscene, Progress& progress);
- void device_update_slot(Device *device, DeviceScene *dscene, int flat_slot, Progress *progress);
+ 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);
@@ -114,6 +122,7 @@ private:
typename DeviceType>
bool file_load_image(Image *img,
ImageDataType type,
+ int texture_limit,
device_vector<DeviceType>& tex_img);
int type_index_to_flattened_slot(int slot, ImageDataType type);
@@ -122,10 +131,20 @@ private:
uint8_t pack_image_options(ImageDataType type, size_t slot);
- void device_load_image(Device *device, DeviceScene *dscene, ImageDataType type, int slot, Progress *progess);
- void device_free_image(Device *device, DeviceScene *dscene, ImageDataType type, int slot);
-
- void device_pack_images(Device *device, DeviceScene *dscene, Progress& progess);
+ 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);
+
+ void device_pack_images(Device *device,
+ DeviceScene *dscene,
+ Progress& progess);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 32dba532f2b..df4327d021a 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -1665,6 +1665,7 @@ void MeshManager::device_update_displacement_images(Device *device,
*/
image_manager->device_update(device,
dscene,
+ scene,
progress);
return;
}
@@ -1682,6 +1683,7 @@ void MeshManager::device_update_displacement_images(Device *device,
image_manager,
device,
dscene,
+ scene,
slot,
&progress));
}
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index b341837b7e8..68124e78cb5 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -187,7 +187,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, progress);
+ image_manager->device_update(device, &dscene, this, progress);
if(progress.get_cancel() || device->have_error()) return;
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 8fec171b6fb..df9363cc768 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -145,6 +145,7 @@ public:
bool use_bvh_unaligned_nodes;
bool use_qbvh;
bool persistent_data;
+ int texture_limit;
SceneParams()
{
@@ -154,6 +155,7 @@ public:
use_bvh_unaligned_nodes = true;
use_qbvh = false;
persistent_data = false;
+ texture_limit = 0;
}
bool modified(const SceneParams& params)
@@ -162,7 +164,8 @@ public:
&& use_bvh_spatial_split == params.use_bvh_spatial_split
&& use_bvh_unaligned_nodes == params.use_bvh_unaligned_nodes
&& use_qbvh == params.use_qbvh
- && persistent_data == params.persistent_data); }
+ && persistent_data == params.persistent_data
+ && texture_limit == params.texture_limit); }
};
/* Scene */