diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2016-12-01 12:29:46 +0300 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2016-12-01 12:29:46 +0300 |
commit | ff2a74906a7b70625a4e941c6a805f7734491204 (patch) | |
tree | 562f5ccdd9f4e377d20fe22eadca48201924b4b3 /intern | |
parent | 73c1c92c0e86ce1b5a8abeaa16be2bf2c259412b (diff) | |
parent | 58877d6d082d82185ca611b704364168e5984bd7 (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'intern')
32 files changed, 881 insertions, 256 deletions
diff --git a/intern/audaspace/FX/AUD_LimiterReader.cpp b/intern/audaspace/FX/AUD_LimiterReader.cpp index 9c1d4443b06..7d850ac7b5f 100644 --- a/intern/audaspace/FX/AUD_LimiterReader.cpp +++ b/intern/audaspace/FX/AUD_LimiterReader.cpp @@ -110,10 +110,10 @@ void AUD_LimiterReader::read(int& length, bool& eos, sample_t* buffer) eos = true; } - if(position < m_start * rate) + if(position < int(m_start * rate)) { int len2 = length; - for(int len = m_start * rate - position; + for(int len = int(m_start * rate) - position; len2 == length && !eos; len -= length) { diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index fc08a913f58..3346beea3b2 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -30,7 +30,7 @@ import _cycles enum_devices = ( ('CPU', "CPU", "Use CPU for rendering"), - ('GPU', "GPU Compute", "Use GPU compute device for rendering, configured in user preferences"), + ('GPU', "GPU Compute", "Use GPU compute device for rendering, configured in the system tab in the user preferences"), ) if _cycles.with_network: @@ -129,6 +129,16 @@ enum_device_type = ( ('OPENCL', "OpenCL", "OpenCL", 2) ) +enum_texture_limit = ( + ('OFF', "No Limit", "No texture size limit", 0), + ('128', "128", "Limit texture size to 128 pixels", 1), + ('256', "256", "Limit texture size to 256 pixels", 2), + ('512', "512", "Limit texture size to 512 pixels", 3), + ('1024', "1024", "Limit texture size to 1024 pixels", 4), + ('2048', "2048", "Limit texture size to 2048 pixels", 5), + ('4096', "4096", "Limit texture size to 4096 pixels", 6), + ('8192', "8192", "Limit texture size to 8192 pixels", 7), + ) class CyclesRenderSettings(bpy.types.PropertyGroup): @classmethod @@ -566,6 +576,19 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): min=0.0, max=5.0 ) + cls.use_distance_cull = BoolProperty( + name="Use Distance Cull", + description="Allow objects to be culled based on the distance from camera", + default=False, + ) + + cls.distance_cull_margin = FloatProperty( + name="Cull Distance", + description="Cull objects which are further away from camera than this distance", + default=50, + min=0.0 + ) + cls.motion_blur_position = EnumProperty( name="Motion Blur Position", default='CENTER', @@ -595,6 +618,20 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): min=0.0, max=1.0, ) + cls.texture_limit = EnumProperty( + name="Viewport Texture Limit", + default='OFF', + description="Limit texture size used by viewport rendering", + items=enum_texture_limit + ) + + cls.texture_limit_render = EnumProperty( + name="Render Texture Limit", + default='OFF', + description="Limit texture size used by final rendering", + items=enum_texture_limit + ) + # Various fine-tuning debug flags def devices_update_callback(self, context): @@ -1016,6 +1053,12 @@ class CyclesObjectSettings(bpy.types.PropertyGroup): default=False, ) + cls.use_distance_cull = BoolProperty( + name="Use Distance Cull", + description="Allow this object and its duplicators to be culled by distance from camera", + default=False, + ) + cls.use_adaptive_subdivision = BoolProperty( name="Use Adaptive Subdivision", description="Use adaptive render time subdivision", @@ -1126,7 +1169,7 @@ class CyclesPreferences(bpy.types.AddonPreferences): def get_devices(self): import _cycles - # Layout of the device tuples: (Name, Type, Internal ID, Persistent ID) + # Layout of the device tuples: (Name, Type, Persistent ID) device_list = _cycles.available_devices() cuda_devices = [] @@ -1174,21 +1217,19 @@ class CyclesPreferences(bpy.types.AddonPreferences): def draw_impl(self, layout, context): - layout.label(text="Compute Device:") + layout.label(text="Cycles Compute Device:") layout.row().prop(self, "compute_device_type", expand=True) cuda_devices, opencl_devices = self.get_devices() row = layout.row() - if cuda_devices: + if self.compute_device_type == 'CUDA' and cuda_devices: col = row.column(align=True) - col.label(text="CUDA devices:") for device in cuda_devices: col.prop(device, "use", text=device.name, toggle=True) - if opencl_devices: + if self.compute_device_type == 'OPENCL' and opencl_devices: col = row.column(align=True) - col.label(text="OpenCL devices:") for device in opencl_devices: col.prop(device, "use", text=device.name, toggle=True) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 7ed8c5f0a13..95731562c79 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -769,6 +769,8 @@ class CyclesObject_PT_cycles_settings(CyclesButtonsPanel, Panel): row = col.row() row.active = scene.render.use_simplify and cscene.use_camera_cull row.prop(cob, "use_camera_cull") + row.active = scene.render.use_simplify and cscene.use_distance_cull + row.prop(cob, "use_distance_cull") class CYCLES_OT_use_shading_nodes(Operator): @@ -1523,22 +1525,35 @@ class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel): cscene = scene.cycles layout.active = rd.use_simplify - split = layout.split() - col = split.column() - col.label(text="Viewport:") - col.prop(rd, "simplify_subdivision", text="Subdivision") + col = layout.column(align=True) + col.label(text="Subdivision") + row = col.row(align=True) + row.prop(rd, "simplify_subdivision", text="Viewport") + row.prop(rd, "simplify_subdivision_render", text="Render") - col = split.column() - col.label(text="Render:") - col.prop(rd, "simplify_subdivision_render", text="Subdivision") - col = layout.column() + col = layout.column(align=True) + split = col.split() + sub = split.column() + sub.label(text="Texture Limit Viewport") + sub.prop(cscene, "texture_limit", text="") + sub = split.column() + sub.label(text="Texture Limit Render") + sub.prop(cscene, "texture_limit_render", text="") + + split = layout.split() + col = split.column() col.prop(cscene, "use_camera_cull") - subsub = col.column() - subsub.active = cscene.use_camera_cull - subsub.prop(cscene, "camera_cull_margin") + row = col.row() + row.active = cscene.use_camera_cull + row.prop(cscene, "camera_cull_margin") + col = split.column() + col.prop(cscene, "use_distance_cull") + row = col.row() + row.active = cscene.use_distance_cull + row.prop(cscene, "distance_cull_margin", text="Distance") def draw_device(self, context): scene = context.scene @@ -1552,11 +1567,9 @@ def draw_device(self, context): split = layout.split(percentage=1/3) split.label("Device:") - row = split.row(align=True) - sub = row.split(align=True) - sub.active = show_device_selection(context) - sub.prop(cscene, "device", text="") - row.operator("wm.addon_userpref_show", text="", icon='PREFERENCES').module = __package__ + row = split.row() + row.active = show_device_selection(context) + row.prop(cscene, "device", text="") if engine.with_osl() and use_cpu(context): layout.prop(cscene, "shading_system") diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py index 951afd37a92..b2a745500a1 100644 --- a/intern/cycles/blender/addon/version_update.py +++ b/intern/cycles/blender/addon/version_update.py @@ -172,6 +172,24 @@ def custom_bake_remap(scene): @persistent def do_versions(self): + if bpy.context.user_preferences.version <= (2, 78, 1): + prop = bpy.context.user_preferences.addons[__package__].preferences + system = bpy.context.user_preferences.system + if not prop.is_property_set("compute_device_type"): + # Device might not currently be available so this can fail + try: + if system.legacy_compute_device_type == 1: + prop.compute_device_type = 'OPENCL' + elif system.legacy_compute_device_type == 2: + prop.compute_device_type = 'CUDA' + else: + prop.compute_device_type = 'NONE' + except: + pass + + # Init device list for UI + prop.get_devices() + # We don't modify startup file because it assumes to # have all the default values only. if not bpy.data.is_saved: diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 16e32cb47e0..0d1b2fc4737 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -88,6 +88,143 @@ static uint object_ray_visibility(BL::Object& b_ob) return flag; } +/* Culling */ + +class BlenderObjectCulling +{ +public: + BlenderObjectCulling(Scene *scene, BL::Scene& b_scene) + : use_scene_camera_cull(false), + use_camera_cull(false), + camera_cull_margin(0.0f), + use_scene_distance_cull(false), + use_distance_cull(false), + distance_cull_margin(0.0f) + { + if(b_scene.render().use_simplify()) { + PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); + + use_scene_camera_cull = scene->camera->type != CAMERA_PANORAMA && + !b_scene.render().use_multiview() && + get_boolean(cscene, "use_camera_cull"); + use_scene_distance_cull = scene->camera->type != CAMERA_PANORAMA && + !b_scene.render().use_multiview() && + get_boolean(cscene, "use_distance_cull"); + + camera_cull_margin = get_float(cscene, "camera_cull_margin"); + distance_cull_margin = get_float(cscene, "distance_cull_margin"); + + if (distance_cull_margin == 0.0f) { + use_scene_distance_cull = false; + } + } + } + + void init_object(Scene *scene, BL::Object& b_ob) + { + if(!use_scene_camera_cull && !use_scene_distance_cull) { + return; + } + + PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles"); + + use_camera_cull = use_scene_camera_cull && get_boolean(cobject, "use_camera_cull"); + use_distance_cull = use_scene_distance_cull && get_boolean(cobject, "use_distance_cull"); + + if(use_camera_cull || use_distance_cull) { + /* Need to have proper projection matrix. */ + scene->camera->update(); + } + } + + bool test(Scene *scene, BL::Object& b_ob, Transform& tfm) + { + if(!use_camera_cull && !use_distance_cull) { + return false; + } + + /* Compute world space bounding box corners. */ + float3 bb[8]; + BL::Array<float, 24> boundbox = b_ob.bound_box(); + for(int i = 0; i < 8; ++i) { + float3 p = make_float3(boundbox[3 * i + 0], + boundbox[3 * i + 1], + boundbox[3 * i + 2]); + bb[i] = transform_point(&tfm, p); + } + + bool camera_culled = use_camera_cull && test_camera(scene, bb); + bool distance_culled = use_distance_cull && test_distance(scene, bb); + + return ((camera_culled && distance_culled) || + (camera_culled && !use_distance_cull) || + (distance_culled && !use_camera_cull)); + } + +private: + /* TODO(sergey): Not really optimal, consider approaches based on k-DOP in order + * to reduce number of objects which are wrongly considered visible. + */ + bool test_camera(Scene *scene, float3 bb[8]) + { + Camera *cam = scene->camera; + Transform& worldtondc = cam->worldtondc; + float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX), + bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX); + bool all_behind = true; + for(int i = 0; i < 8; ++i) { + float3 p = bb[i]; + float4 b = make_float4(p.x, p.y, p.z, 1.0f); + float4 c = make_float4(dot(worldtondc.x, b), + dot(worldtondc.y, b), + dot(worldtondc.z, b), + dot(worldtondc.w, b)); + p = float4_to_float3(c / c.w); + if(c.z < 0.0f) { + p.x = 1.0f - p.x; + p.y = 1.0f - p.y; + } + if(c.z >= -camera_cull_margin) { + all_behind = false; + } + bb_min = min(bb_min, p); + bb_max = max(bb_max, p); + } + if(all_behind) { + return true; + } + return (bb_min.x >= 1.0f + camera_cull_margin || + bb_min.y >= 1.0f + camera_cull_margin || + bb_max.x <= -camera_cull_margin || + bb_max.y <= -camera_cull_margin); + } + + bool test_distance(Scene *scene, float3 bb[8]) + { + float3 camera_position = transform_get_column(&scene->camera->matrix, 3); + float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX), + bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX); + + /* Find min & max points for x & y & z on bounding box */ + for(int i = 0; i < 8; ++i) { + float3 p = bb[i]; + bb_min = min(bb_min, p); + bb_max = max(bb_max, p); + } + + float3 closest_point = max(min(bb_max,camera_position),bb_min); + return (len_squared(camera_position - closest_point) > + distance_cull_margin * distance_cull_margin); + } + + bool use_scene_camera_cull; + bool use_camera_cull; + float camera_cull_margin; + bool use_scene_distance_cull; + bool use_distance_cull; + float distance_cull_margin; +}; + /* Light */ void BlenderSync::sync_light(BL::Object& b_parent, @@ -235,55 +372,6 @@ void BlenderSync::sync_background_light(bool use_portal) /* Object */ -/* TODO(sergey): Not really optimal, consider approaches based on k-DOP in order - * to reduce number of objects which are wrongly considered visible. - */ -static bool object_boundbox_clip(Scene *scene, - BL::Object& b_ob, - Transform& tfm, - float margin) -{ - Camera *cam = scene->camera; - Transform& worldtondc = cam->worldtondc; - BL::Array<float, 24> boundbox = b_ob.bound_box(); - float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX), - bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX); - bool all_behind = true; - for(int i = 0; i < 8; ++i) { - float3 p = make_float3(boundbox[3 * i + 0], - boundbox[3 * i + 1], - boundbox[3 * i + 2]); - p = transform_point(&tfm, p); - - float4 b = make_float4(p.x, p.y, p.z, 1.0f); - float4 c = make_float4(dot(worldtondc.x, b), - dot(worldtondc.y, b), - dot(worldtondc.z, b), - dot(worldtondc.w, b)); - p = float4_to_float3(c / c.w); - if(c.z < 0.0f) { - p.x = 1.0f - p.x; - p.y = 1.0f - p.y; - } - if(c.z >= -margin) { - all_behind = false; - } - bb_min = min(bb_min, p); - bb_max = max(bb_max, p); - } - if(!all_behind) { - if(bb_min.x >= 1.0f + margin || - bb_min.y >= 1.0f + margin || - bb_max.x <= -margin || - bb_max.y <= -margin) - { - return true; - } - return false; - } - return true; -} - Object *BlenderSync::sync_object(BL::Object& b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject& b_dupli_ob, @@ -291,8 +379,7 @@ Object *BlenderSync::sync_object(BL::Object& b_parent, uint layer_flag, float motion_time, bool hide_tris, - bool use_camera_cull, - float camera_cull_margin, + BlenderObjectCulling& culling, bool *use_portal) { BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent); @@ -308,11 +395,12 @@ Object *BlenderSync::sync_object(BL::Object& b_parent, } /* only interested in object that we can create meshes from */ - if(!object_is_mesh(b_ob)) + if(!object_is_mesh(b_ob)) { return NULL; + } - /* Perform camera space culling. */ - if(use_camera_cull && object_boundbox_clip(scene, b_ob, tfm, camera_cull_margin)) { + /* Perform object culling. */ + if(culling.test(scene, b_ob, tfm)) { return NULL; } @@ -519,17 +607,8 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time) mesh_motion_synced.clear(); } - bool allow_camera_cull = false; - float camera_cull_margin = 0.0f; - if(b_scene.render().use_simplify()) { - PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); - allow_camera_cull = scene->camera->type != CAMERA_PANORAMA && - !b_scene.render().use_multiview() && - get_boolean(cscene, "use_camera_cull"); - if(allow_camera_cull) { - camera_cull_margin = get_float(cscene, "camera_cull_margin"); - } - } + /* initialize culling */ + BlenderObjectCulling culling(scene, b_scene); /* object loop */ BL::Scene::object_bases_iterator b_base; @@ -561,12 +640,9 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time) if(!hide) { progress.set_sync_status("Synchronizing object", b_ob.name()); - PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles"); - bool use_camera_cull = allow_camera_cull && get_boolean(cobject, "use_camera_cull"); - if(use_camera_cull) { - /* Need to have proper projection matrix. */ - scene->camera->update(); - } + /* load per-object culling data */ + culling.init_object(scene, b_ob); + if(b_ob.is_duplicator() && !object_render_hide_duplis(b_ob)) { /* dupli objects */ b_ob.dupli_list_create(b_scene, dupli_settings); @@ -593,8 +669,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time) ob_layer, motion_time, hide_tris, - use_camera_cull, - camera_cull_margin, + culling, &use_portal); } } @@ -616,8 +691,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time) ob_layer, motion_time, hide_tris, - use_camera_cull, - camera_cull_margin, + culling, &use_portal); } } diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 171153dd440..e16cea0ebaf 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -126,8 +126,8 @@ void BlenderSession::create_session() /* setup callbacks for builtin image support */ scene->image_manager->builtin_image_info_cb = function_bind(&BlenderSession::builtin_image_info, this, _1, _2, _3, _4, _5, _6, _7); - scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3); - scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3); + scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3, _4); + scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3, _4); /* create session */ session = new Session(session_params); @@ -1080,7 +1080,13 @@ int BlenderSession::builtin_image_frame(const string &builtin_name) return atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str()); } -void BlenderSession::builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels) +void BlenderSession::builtin_image_info(const string &builtin_name, + void *builtin_data, + bool &is_float, + int &width, + int &height, + int &depth, + int &channels) { /* empty image */ is_float = false; @@ -1158,60 +1164,67 @@ void BlenderSession::builtin_image_info(const string &builtin_name, void *builti } } -bool BlenderSession::builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels) +bool BlenderSession::builtin_image_pixels(const string &builtin_name, + void *builtin_data, + unsigned char *pixels, + const size_t pixels_size) { - if(!builtin_data) + if(!builtin_data) { return false; + } - int frame = builtin_image_frame(builtin_name); + const int frame = builtin_image_frame(builtin_name); PointerRNA ptr; RNA_id_pointer_create((ID*)builtin_data, &ptr); BL::Image b_image(ptr); - int width = b_image.size()[0]; - int height = b_image.size()[1]; - int channels = b_image.channels(); + const int width = b_image.size()[0]; + const int height = b_image.size()[1]; + const int channels = b_image.channels(); - unsigned char *image_pixels; - image_pixels = image_get_pixels_for_frame(b_image, frame); - size_t num_pixels = ((size_t)width) * height; + unsigned char *image_pixels = image_get_pixels_for_frame(b_image, frame); + const size_t num_pixels = ((size_t)width) * height; - if(image_pixels) { - memcpy(pixels, image_pixels, num_pixels * channels * sizeof(unsigned char)); + if(image_pixels && num_pixels * channels == pixels_size) { + memcpy(pixels, image_pixels, pixels_size * sizeof(unsigned char)); MEM_freeN(image_pixels); } else { if(channels == 1) { - memset(pixels, 0, num_pixels * sizeof(unsigned char)); + memset(pixels, 0, pixels_size * sizeof(unsigned char)); } else { + const size_t num_pixels_safe = pixels_size / channels; unsigned char *cp = pixels; - for(size_t i = 0; i < num_pixels; i++, cp += channels) { + for(size_t i = 0; i < num_pixels_safe; i++, cp += channels) { cp[0] = 255; cp[1] = 0; cp[2] = 255; - if(channels == 4) + if(channels == 4) { cp[3] = 255; + } } } } - - /* premultiply, byte images are always straight for blender */ + /* Premultiply, byte images are always straight for Blender. */ unsigned char *cp = pixels; for(size_t i = 0; i < num_pixels; i++, cp += channels) { cp[0] = (cp[0] * cp[3]) >> 8; cp[1] = (cp[1] * cp[3]) >> 8; cp[2] = (cp[2] * cp[3]) >> 8; } - return true; } -bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels) +bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, + void *builtin_data, + float *pixels, + const size_t pixels_size) { - if(!builtin_data) + if(!builtin_data) { return false; + } PointerRNA ptr; RNA_id_pointer_create((ID*)builtin_data, &ptr); @@ -1222,16 +1235,16 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void BL::Image b_image(b_id); int frame = builtin_image_frame(builtin_name); - int width = b_image.size()[0]; - int height = b_image.size()[1]; - int channels = b_image.channels(); + const int width = b_image.size()[0]; + const int height = b_image.size()[1]; + const int channels = b_image.channels(); float *image_pixels; image_pixels = image_get_float_pixels_for_frame(b_image, frame); - size_t num_pixels = ((size_t)width) * height; + const size_t num_pixels = ((size_t)width) * height; - if(image_pixels) { - memcpy(pixels, image_pixels, num_pixels * channels * sizeof(float)); + if(image_pixels && num_pixels * channels == pixels_size) { + memcpy(pixels, image_pixels, pixels_size * sizeof(float)); MEM_freeN(image_pixels); } else { @@ -1239,13 +1252,15 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void memset(pixels, 0, num_pixels * sizeof(float)); } else { + const size_t num_pixels_safe = pixels_size / channels; float *fp = pixels; - for(int i = 0; i < num_pixels; i++, fp += channels) { + for(int i = 0; i < num_pixels_safe; i++, fp += channels) { fp[0] = 1.0f; fp[1] = 0.0f; fp[2] = 1.0f; - if(channels == 4) + if(channels == 4) { fp[3] = 1.0f; + } } } } @@ -1257,8 +1272,9 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void BL::Object b_ob(b_id); BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob); - if(!b_domain) + if(!b_domain) { return false; + } int3 resolution = get_int3(b_domain.domain_resolution()); int length, amplify = (b_domain.use_high_resolution())? b_domain.amplify() + 1: 1; @@ -1270,10 +1286,10 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void amplify = 1; } - int width = resolution.x * amplify; - int height = resolution.y * amplify; - int depth = resolution.z * amplify; - size_t num_pixels = ((size_t)width) * height * depth; + const int width = resolution.x * amplify; + const int height = resolution.y * amplify; + const int depth = resolution.z * amplify; + const size_t num_pixels = ((size_t)width) * height * depth; if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) { SmokeDomainSettings_density_grid_get_length(&b_domain.ptr, &length); diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h index 66a6945cbc1..82fe218b4ce 100644 --- a/intern/cycles/blender/blender_session.h +++ b/intern/cycles/blender/blender_session.h @@ -145,9 +145,21 @@ protected: void do_write_update_render_tile(RenderTile& rtile, bool do_update_only); int builtin_image_frame(const string &builtin_name); - void builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels); - bool builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels); - bool builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels); + void builtin_image_info(const string &builtin_name, + void *builtin_data, + bool &is_float, + int &width, + int &height, + int &depth, + int &channels); + bool builtin_image_pixels(const string &builtin_name, + void *builtin_data, + unsigned char *pixels, + const size_t pixels_size); + bool builtin_image_float_pixels(const string &builtin_name, + void *builtin_data, + float *pixels, + const size_t pixels_size); /* Update tile manager to reflect resumable render settings. */ void update_resumable_tile_manager(int num_samples); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 49ddc8af9a8..cfb32651c50 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -496,6 +496,20 @@ SceneParams BlenderSync::get_scene_params(BL::Scene& b_scene, else params.persistent_data = false; + int texture_limit; + if(background) { + texture_limit = RNA_enum_get(&cscene, "texture_limit_render"); + } + else { + texture_limit = RNA_enum_get(&cscene, "texture_limit"); + } + if(texture_limit > 0 && b_scene.render().use_simplify()) { + params.texture_limit = 1 << (texture_limit + 6); + } + else { + params.texture_limit = 0; + } + #if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86))) if(is_cpu) { params.use_qbvh = DebugFlags().cpu.qbvh && system_cpu_support_sse2(); diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 2fad7d5fe71..08e0a9bd82f 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -35,6 +35,7 @@ CCL_NAMESPACE_BEGIN class Background; +class BlenderObjectCulling; class Camera; class Film; class Light; @@ -122,8 +123,7 @@ private: uint layer_flag, float motion_time, bool hide_tris, - bool use_camera_cull, - float camera_cull_margin, + BlenderObjectCulling& culling, bool *use_portal); void sync_light(BL::Object& b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index a4818aa3b8d..fbb97f78e70 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -1418,7 +1418,11 @@ void device_cuda_info(vector<DeviceInfo>& devices) cuDeviceGetAttribute(&pci_location[0], CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, num); cuDeviceGetAttribute(&pci_location[1], CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, num); cuDeviceGetAttribute(&pci_location[2], CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID, num); - info.id = string_printf("CUDA_%s_%04x:%02x:%02x", name, pci_location[0], pci_location[1], pci_location[2]); + info.id = string_printf("CUDA_%s_%04x:%02x:%02x", + name, + (unsigned int)pci_location[0], + (unsigned int)pci_location[1], + (unsigned int)pci_location[2]); /* if device has a kernel timeout, assume it is used for display */ if(cuDeviceGetAttribute(&attr, CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT, num) == CUDA_SUCCESS && attr == 1) { diff --git a/intern/cycles/device/opencl/opencl.h b/intern/cycles/device/opencl/opencl.h index 054ac9014f0..4023ba89a10 100644 --- a/intern/cycles/device/opencl/opencl.h +++ b/intern/cycles/device/opencl/opencl.h @@ -16,14 +16,14 @@ #ifdef WITH_OPENCL -#include "clew.h" - #include "device.h" #include "util_map.h" #include "util_param.h" #include "util_string.h" +#include "clew.h" + CCL_NAMESPACE_BEGIN #define CL_MEM_PTR(p) ((cl_mem)(uintptr_t)(p)) diff --git a/intern/cycles/device/opencl/opencl_util.cpp b/intern/cycles/device/opencl/opencl_util.cpp index 36eb70b8c85..82e1640e508 100644 --- a/intern/cycles/device/opencl/opencl_util.cpp +++ b/intern/cycles/device/opencl/opencl_util.cpp @@ -667,7 +667,10 @@ string OpenCLInfo::get_hardware_id(string platform_name, cl_device_id device_id) /* Use cl_amd_device_topology extension. */ cl_char topology[24]; if(clGetDeviceInfo(device_id, 0x4037, sizeof(topology), topology, NULL) == CL_SUCCESS && topology[0] == 1) { - return string_printf("%02x:%02x.%01x", topology[21], topology[22], topology[23]); + return string_printf("%02x:%02x.%01x", + (unsigned int)topology[21], + (unsigned int)topology[22], + (unsigned int)topology[23]); } } else if(platform_name == "NVIDIA CUDA") { @@ -675,7 +678,10 @@ string OpenCLInfo::get_hardware_id(string platform_name, cl_device_id device_id) cl_int bus_id, slot_id; if(clGetDeviceInfo(device_id, 0x4008, sizeof(cl_int), &bus_id, NULL) == CL_SUCCESS && clGetDeviceInfo(device_id, 0x4009, sizeof(cl_int), &slot_id, NULL) == CL_SUCCESS) { - return string_printf("%02x:%02x.%01x", bus_id, slot_id>>3, slot_id & 0x7); + return string_printf("%02x:%02x.%01x", + (unsigned int)(bus_id), + (unsigned int)(slot_id >> 3), + (unsigned int)(slot_id & 0x7)); } } /* No general way to get a hardware ID from OpenCL => give up. */ diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h index 0f45b0e7d60..dd7b0d9812d 100644 --- a/intern/cycles/kernel/kernel_volume.h +++ b/intern/cycles/kernel/kernel_volume.h @@ -245,11 +245,18 @@ ccl_device float kernel_volume_equiangular_sample(Ray *ray, float3 light_P, floa float t = ray->t; float delta = dot((light_P - ray->P) , ray->D); - float D = sqrtf(len_squared(light_P - ray->P) - delta * delta); + float D = safe_sqrtf(len_squared(light_P - ray->P) - delta * delta); + if(UNLIKELY(D == 0.0f)) { + *pdf = 0.0f; + return 0.0f; + } float theta_a = -atan2f(delta, D); float theta_b = atan2f(t - delta, D); float t_ = D * tanf((xi * theta_b) + (1 - xi) * theta_a); - + if(UNLIKELY(theta_b == theta_a)) { + *pdf = 0.0f; + return 0.0f; + } *pdf = D / ((theta_b - theta_a) * (D * D + t_ * t_)); return min(t, delta + t_); /* min is only for float precision errors */ @@ -258,13 +265,19 @@ ccl_device float kernel_volume_equiangular_sample(Ray *ray, float3 light_P, floa ccl_device float kernel_volume_equiangular_pdf(Ray *ray, float3 light_P, float sample_t) { float delta = dot((light_P - ray->P) , ray->D); - float D = sqrtf(len_squared(light_P - ray->P) - delta * delta); + float D = safe_sqrtf(len_squared(light_P - ray->P) - delta * delta); + if(UNLIKELY(D == 0.0f)) { + return 0.0f; + } float t = ray->t; float t_ = sample_t - delta; float theta_a = -atan2f(delta, D); float theta_b = atan2f(t - delta, D); + if(UNLIKELY(theta_b == theta_a)) { + return 0.0f; + } float pdf = D / ((theta_b - theta_a) * (D * D + t_ * t_)); @@ -958,6 +971,9 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter( mis_weight = 2.0f*power_heuristic(pdf, distance_pdf); } } + if(sample_t < 1e-6f) { + return VOLUME_PATH_SCATTERED; + } /* compute transmittance up to this step */ if(step != segment->steps) diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 7465fbd43a7..ab830b19c57 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,11 +487,18 @@ 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; + const size_t num_pixels = ((size_t)width) * height * depth; if(in) { StorageType *readpixels = pixels; vector<StorageType> tmppixels; @@ -526,12 +535,14 @@ 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], + num_pixels * components); } else if(FileFormat == TypeDesc::UINT8) { builtin_image_pixels_cb(img->filename, img->builtin_data, - (uchar*)pixels); + (uchar*)&pixels[0], + num_pixels * components); } else { /* TODO(dingto): Support half for ImBuf. */ @@ -540,11 +551,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) - { - size_t num_pixels = ((size_t)width) * height * depth; + bool is_rgba = (type == IMAGE_DATA_TYPE_FLOAT4 || + type == IMAGE_DATA_TYPE_HALF4 || + type == IMAGE_DATA_TYPE_BYTE4); + if(is_rgba) { if(cmyk) { /* CMYK */ for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { @@ -587,14 +597,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 +640,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 +661,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 +691,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 +718,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 +748,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 +774,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 +803,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 +902,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 +922,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 +944,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 +961,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..47bbd92347c 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); @@ -78,9 +86,25 @@ public: bool need_update; - function<void(const string &filename, void *data, bool &is_float, int &width, int &height, int &depth, int &channels)> builtin_image_info_cb; - function<bool(const string &filename, void *data, unsigned char *pixels)> builtin_image_pixels_cb; - function<bool(const string &filename, void *data, float *pixels)> builtin_image_float_pixels_cb; + /* NOTE: Here pixels_size is a size of storage, which equals to + * width * height * depth. + * Use this to avoid some nasty memory corruptions. + */ + function<void(const string &filename, + void *data, + bool &is_float, + int &width, + int &height, + int &depth, + int &channels)> builtin_image_info_cb; + function<bool(const string &filename, + void *data, + unsigned char *pixels, + const size_t pixels_size)> builtin_image_pixels_cb; + function<bool(const string &filename, + void *data, + float *pixels, + const size_t pixels_size)> builtin_image_float_pixels_cb; struct Image { string filename; @@ -114,6 +138,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 +147,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 ac369a0d5f8..df4327d021a 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -1084,7 +1084,7 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce } /* terminator */ - for(int i = 0; i < ATTR_PRIM_TYPES; i++) { + for(int j = 0; j < ATTR_PRIM_TYPES; j++) { attr_map[index].x = ATTR_STD_NONE; attr_map[index].y = 0; attr_map[index].z = 0; @@ -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/nodes.cpp b/intern/cycles/render/nodes.cpp index f293af3c40a..3fb2bb1cf92 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -3993,7 +3993,7 @@ NODE_DEFINE(SeparateRGBNode) SOCKET_IN_COLOR(color, "Image", make_float3(0.0f, 0.0f, 0.0f)); - SOCKET_OUT_FLOAT(g, "R"); + SOCKET_OUT_FLOAT(r, "R"); SOCKET_OUT_FLOAT(g, "G"); SOCKET_OUT_FLOAT(b, "B"); 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 */ diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index 9d3f49a3c84..955b892f4c3 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -71,14 +71,13 @@ void SVMShaderManager::device_update_shader(Scene *scene, scene->light_manager->need_update = true; } - /* We only calculate offset and do re-allocation from the locked block, - * actual copy we do after the lock is releases to hopefully gain some - * percent of performance. + /* The copy needs to be done inside the lock, if another thread resizes the array + * while memcpy is running, it'll be copying into possibly invalid/freed ram. */ nodes_lock_.lock(); size_t global_nodes_size = global_svm_nodes->size(); global_svm_nodes->resize(global_nodes_size + svm_nodes.size()); - nodes_lock_.unlock(); + /* Offset local SVM nodes to a global address space. */ int4& jump_node = global_svm_nodes->at(shader->id); jump_node.y = svm_nodes[0].y + global_nodes_size - 1; @@ -88,6 +87,7 @@ void SVMShaderManager::device_update_shader(Scene *scene, memcpy(&global_svm_nodes->at(global_nodes_size), &svm_nodes[1], sizeof(int4) * (svm_nodes.size() - 1)); + nodes_lock_.unlock(); } void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt index 02ee4cd6774..d8abf671bd6 100644 --- a/intern/cycles/util/CMakeLists.txt +++ b/intern/cycles/util/CMakeLists.txt @@ -45,6 +45,7 @@ set(SRC_HEADERS util_half.h util_hash.h util_image.h + util_image_impl.h util_list.h util_logging.h util_map.h diff --git a/intern/cycles/util/util_image.h b/intern/cycles/util/util_image.h index bb8a31c6fec..c8efc551d97 100644 --- a/intern/cycles/util/util_image.h +++ b/intern/cycles/util/util_image.h @@ -21,11 +21,25 @@ #include <OpenImageIO/imageio.h> +#include "util_vector.h" + CCL_NAMESPACE_BEGIN OIIO_NAMESPACE_USING +template<typename T> +void util_image_resize_pixels(const vector<T>& input_pixels, + const size_t input_width, + const size_t input_height, + const size_t input_depth, + const size_t components, + vector<T> *output_pixels, + size_t *output_width, + size_t *output_height, + size_t *output_depth); + CCL_NAMESPACE_END #endif /* __UTIL_IMAGE_H__ */ +#include "util_image_impl.h" diff --git a/intern/cycles/util/util_image_impl.h b/intern/cycles/util/util_image_impl.h new file mode 100644 index 00000000000..73ecfda0855 --- /dev/null +++ b/intern/cycles/util/util_image_impl.h @@ -0,0 +1,168 @@ +/* + * Copyright 2011-2016 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTIL_IMAGE_IMPL_H__ +#define __UTIL_IMAGE_IMPL_H__ + +#include "util_algorithm.h" +#include "util_debug.h" +#include "util_image.h" + +CCL_NAMESPACE_BEGIN + +namespace { + +template<typename T> +const T *util_image_read(const vector<T>& pixels, + const size_t width, + const size_t height, + const size_t /*depth*/, + const size_t components, + const size_t x, const size_t y, const size_t z) { + const size_t index = ((size_t)z * (width * height) + + (size_t)y * width + + (size_t)x) * components; + return &pixels[index]; +} + +template<typename T> +void util_image_downscale_sample(const vector<T>& pixels, + const size_t width, + const size_t height, + const size_t depth, + const size_t components, + const size_t kernel_size, + const float x, + const float y, + const float z, + T *result) +{ + assert(components <= 4); + const size_t ix = (size_t)x, + iy = (size_t)y, + iz = (size_t)z; + /* TODO(sergey): Support something smarter than box filer. */ + float accum[4] = {0}; + size_t count = 0; + for(size_t dz = 0; dz < kernel_size; ++dz) { + for(size_t dy = 0; dy < kernel_size; ++dy) { + for(size_t dx = 0; dx < kernel_size; ++dx) { + const size_t nx = ix + dx, + ny = iy + dy, + nz = iz + dz; + if(nx >= width || ny >= height || nz >= depth) { + continue; + } + const T *pixel = util_image_read(pixels, + width, height, depth, + components, + nx, ny, nz); + for(size_t k = 0; k < components; ++k) { + accum[k] += pixel[k]; + } + ++count; + } + } + } + const float inv_count = 1.0f / (float)count; + for(size_t k = 0; k < components; ++k) { + result[k] = T(accum[k] * inv_count); + } +} + +template<typename T> +void util_image_downscale_pixels(const vector<T>& input_pixels, + const size_t input_width, + const size_t input_height, + const size_t input_depth, + const size_t components, + const float inv_scale_factor, + const size_t output_width, + const size_t output_height, + const size_t output_depth, + vector<T> *output_pixels) +{ + const size_t kernel_size = (size_t)(inv_scale_factor + 0.5f); + for(size_t z = 0; z < output_depth; ++z) { + for(size_t y = 0; y < output_height; ++y) { + for(size_t x = 0; x < output_width; ++x) { + const float input_x = (float)x * inv_scale_factor, + input_y = (float)y * inv_scale_factor, + input_z = (float)z * inv_scale_factor; + const size_t output_index = + (z * output_width * output_height + + y * output_width + x) * components; + util_image_downscale_sample(input_pixels, + input_width, input_height, input_depth, + components, + kernel_size, + input_x, input_y, input_z, + &output_pixels->at(output_index)); + } + } + } +} + +} /* namespace */ + +template<typename T> +void util_image_resize_pixels(const vector<T>& input_pixels, + const size_t input_width, + const size_t input_height, + const size_t input_depth, + const size_t components, + const float scale_factor, + vector<T> *output_pixels, + size_t *output_width, + size_t *output_height, + size_t *output_depth) +{ + /* Early output for case when no scaling is applied. */ + if(scale_factor == 1.0f) { + *output_width = input_width; + *output_height = input_height; + *output_depth = input_depth; + *output_pixels = input_pixels; + return; + } + /* First of all, we calculate output image dimensions. + * We clamp them to be 1 pixel at least so we do not generate degenerate + * image. + */ + *output_width = max((size_t)((float)input_width * scale_factor), (size_t)1); + *output_height = max((size_t)((float)input_height * scale_factor), (size_t)1); + *output_depth = max((size_t)((float)input_depth * scale_factor), (size_t)1); + /* Prepare pixel storage for the result. */ + const size_t num_output_pixels = ((*output_width) * + (*output_height) * + (*output_depth)) * components; + output_pixels->resize(num_output_pixels); + if(scale_factor < 1.0f) { + const float inv_scale_factor = 1.0f / scale_factor; + util_image_downscale_pixels(input_pixels, + input_width, input_height, input_depth, + components, + inv_scale_factor, + *output_width, *output_height, *output_depth, + output_pixels); + } else { + /* TODO(sergey): Needs implementation. */ + } +} + +CCL_NAMESPACE_END + +#endif /* __UTIL_IMAGE_IMPL_H__ */ diff --git a/intern/cycles/util/util_simd.h b/intern/cycles/util/util_simd.h index f4f460d6cf6..756bd15ed25 100644 --- a/intern/cycles/util/util_simd.h +++ b/intern/cycles/util/util_simd.h @@ -229,7 +229,7 @@ __forceinline int __btr(int v, int i) { int r = 0; asm ("btr %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r; } -#if defined(__KERNEL_64_BIT__) || defined(__APPLE__) +#if (defined(__KERNEL_64_BIT__) || defined(__APPLE__)) && !(defined(__ILP32__) && defined(__x86_64__)) __forceinline size_t __bsf(size_t v) { size_t r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r; } @@ -271,7 +271,7 @@ __forceinline unsigned int bitscan(unsigned int v) { #endif } -#if defined(__KERNEL_64_BIT__) || defined(__APPLE__) +#if (defined(__KERNEL_64_BIT__) || defined(__APPLE__)) && !(defined(__ILP32__) && defined(__x86_64__)) __forceinline size_t bitscan(size_t v) { #if defined(__KERNEL_AVX2__) #if defined(__KERNEL_64_BIT__) @@ -313,7 +313,7 @@ __forceinline unsigned int __bscf(unsigned int& v) return i; } -#if defined(__KERNEL_64_BIT__) || defined(__APPLE__) +#if (defined(__KERNEL_64_BIT__) || defined(__APPLE__)) && !(defined(__ILP32__) && defined(__x86_64__)) __forceinline size_t __bscf(size_t& v) { size_t i = bitscan(v); diff --git a/intern/cycles/util/util_system.cpp b/intern/cycles/util/util_system.cpp index d5fac9a0e34..87d885c44cf 100644 --- a/intern/cycles/util/util_system.cpp +++ b/intern/cycles/util/util_system.cpp @@ -89,6 +89,22 @@ int system_cpu_thread_count() return count; } +unsigned short system_cpu_process_groups(unsigned short max_groups, + unsigned short *groups) +{ +#ifdef _WIN32 + unsigned short group_count = max_groups; + if(!GetProcessGroupAffinity(GetCurrentProcess(), &group_count, groups)) { + return 0; + } + return group_count; +#else + (void) max_groups; + (void) groups; + return 0; +#endif +} + #if !defined(_WIN32) || defined(FREE_WINDOWS) static void __cpuid(int data[4], int selector) { diff --git a/intern/cycles/util/util_system.h b/intern/cycles/util/util_system.h index 557aab6cbae..ff61b260bed 100644 --- a/intern/cycles/util/util_system.h +++ b/intern/cycles/util/util_system.h @@ -30,6 +30,10 @@ int system_cpu_group_thread_count(int group); /* Get total number of threads in all groups. */ int system_cpu_thread_count(); +/* Get current process groups. */ +unsigned short system_cpu_process_groups(unsigned short max_groups, + unsigned short *grpups); + string system_cpu_brand_string(); int system_cpu_bits(); bool system_cpu_support_sse2(); diff --git a/intern/cycles/util/util_task.cpp b/intern/cycles/util/util_task.cpp index 352ba81c95a..0d1fed3ebbf 100644 --- a/intern/cycles/util/util_task.cpp +++ b/intern/cycles/util/util_task.cpp @@ -195,7 +195,8 @@ void TaskScheduler::init(int num_threads) if(users == 0) { do_exit = false; - if(num_threads == 0) { + const bool use_auto_threads = (num_threads == 0); + if(use_auto_threads) { /* automatic number of threads */ num_threads = system_cpu_thread_count(); } @@ -204,7 +205,18 @@ void TaskScheduler::init(int num_threads) /* launch threads that will be waiting for work */ threads.resize(num_threads); - int num_groups = system_cpu_group_count(); + const int num_groups = system_cpu_group_count(); + unsigned short num_process_groups; + vector<unsigned short> process_groups; + int current_group_threads; + if(num_groups > 1) { + process_groups.resize(num_groups); + num_process_groups = system_cpu_process_groups(num_groups, + &process_groups[0]); + if(num_process_groups == 1) { + current_group_threads = system_cpu_group_thread_count(process_groups[0]); + } + } int thread_index = 0; for(int group = 0; group < num_groups; ++group) { /* NOTE: That's not really efficient from threading point of view, @@ -218,9 +230,25 @@ void TaskScheduler::init(int num_threads) group_thread < num_group_threads && thread_index < threads.size(); ++group_thread, ++thread_index) { + /* NOTE: Thread group of -1 means we would not force thread affinity. */ + int thread_group; + if(num_groups == 1) { + /* Use default affinity if there's only one CPU group in the system. */ + thread_group = -1; + } + else if(use_auto_threads && + num_process_groups == 1 && + num_threads <= current_group_threads) + { + /* If we fit into curent CPU group we also don't force any affinity. */ + thread_group = -1; + } + else { + thread_group = group; + } threads[thread_index] = new thread(function_bind(&TaskScheduler::thread_run, thread_index + 1), - group); + thread_group); } } } diff --git a/intern/cycles/util/util_windows.cpp b/intern/cycles/util/util_windows.cpp index ee5b3fd73c0..4de8483564b 100644 --- a/intern/cycles/util/util_windows.cpp +++ b/intern/cycles/util/util_windows.cpp @@ -28,6 +28,7 @@ CCL_NAMESPACE_BEGIN tGetActiveProcessorGroupCount *GetActiveProcessorGroupCount; tGetActiveProcessorCount *GetActiveProcessorCount; tSetThreadGroupAffinity *SetThreadGroupAffinity; +tGetProcessGroupAffinity *GetProcessGroupAffinity; #endif static WORD GetActiveProcessorGroupCount_stub() @@ -50,6 +51,18 @@ static BOOL SetThreadGroupAffinity_stub( return TRUE; } +static BOOL GetProcessGroupAffinity_stub(HANDLE hProcess, + PUSHORT GroupCount, + PUSHORT GroupArray) +{ + if(*GroupCount < 1) { + return FALSE; + } + *GroupCount = 1; + GroupArray[0] = 0; + return TRUE; +} + static bool supports_numa() { #ifndef _M_X64 @@ -72,6 +85,7 @@ void util_windows_init_numa_groups() GetActiveProcessorGroupCount = GetActiveProcessorGroupCount_stub; GetActiveProcessorCount = GetActiveProcessorCount_stub; SetThreadGroupAffinity = SetThreadGroupAffinity_stub; + GetProcessGroupAffinity = GetProcessGroupAffinity_stub; return; } HMODULE kernel = GetModuleHandleA("kernel32.dll"); @@ -79,6 +93,7 @@ void util_windows_init_numa_groups() READ_SYMBOL(GetActiveProcessorGroupCount); READ_SYMBOL(GetActiveProcessorCount); READ_SYMBOL(SetThreadGroupAffinity); + READ_SYMBOL(GetProcessGroupAffinity); # undef READ_SUMBOL #endif } diff --git a/intern/cycles/util/util_windows.h b/intern/cycles/util/util_windows.h index ac61d5348c3..7ea3e65c2c5 100644 --- a/intern/cycles/util/util_windows.h +++ b/intern/cycles/util/util_windows.h @@ -39,10 +39,14 @@ typedef DWORD tGetActiveProcessorCount(WORD GroupNumber); typedef BOOL tSetThreadGroupAffinity(HANDLE hThread, const GROUP_AFFINITY *GroupAffinity, PGROUP_AFFINITY PreviousGroupAffinity); +typedef BOOL tGetProcessGroupAffinity(HANDLE hProcess, + PUSHORT GroupCount, + PUSHORT GroupArray); extern tGetActiveProcessorGroupCount *GetActiveProcessorGroupCount; extern tGetActiveProcessorCount *GetActiveProcessorCount; extern tSetThreadGroupAffinity *SetThreadGroupAffinity; +extern tGetProcessGroupAffinity *GetProcessGroupAffinity; #endif /* Make sure NUMA and processor groups API is initialized. */ diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 1f49adecdef..58aa0b87045 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -353,7 +353,7 @@ GHOST_WindowWin32::~GHOST_WindowWin32() // Release our reference of the DropTarget and it will delete itself eventually. m_dropTarget->Release(); } - + ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, NULL); ::DestroyWindow(m_hWnd); m_hWnd = 0; } diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index a02117d517e..992200a0b09 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -861,24 +861,32 @@ void GHOST_WindowX11::icccmSetState(int state) int GHOST_WindowX11::icccmGetState(void) const { - Atom *prop_ret; + struct { + CARD32 state; + XID icon; + } *prop_ret; unsigned long bytes_after, num_ret; Atom type_ret; - int format_ret, st; + int ret, format_ret; + CARD32 st; prop_ret = NULL; - st = XGetWindowProperty( + ret = XGetWindowProperty( m_display, m_window, m_system->m_atom.WM_STATE, 0, 2, False, m_system->m_atom.WM_STATE, &type_ret, &format_ret, &num_ret, &bytes_after, ((unsigned char **)&prop_ret)); - if ((st == Success) && (prop_ret) && (num_ret == 2)) - st = prop_ret[0]; - else + if ((ret == Success) && (prop_ret != NULL) && (num_ret == 2)) { + st = prop_ret->state; + } + else { st = NormalState; + } - if (prop_ret) + if (prop_ret) { XFree(prop_ret); - return (st); + } + + return st; } void GHOST_WindowX11::netwmMaximized(bool set) diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc index 1124e7fd8ab..d0a129360b0 100644 --- a/intern/opencolorio/fallback_impl.cc +++ b/intern/opencolorio/fallback_impl.cc @@ -77,7 +77,8 @@ int FallbackImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr * /*config*/) return 2; } -const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr * /*config*/, int index) +const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr * /*config*/, + int index) { if (index == 0) return "Linear"; @@ -87,7 +88,8 @@ const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr * return NULL; } -OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcPtr * /*config*/, const char *name) +OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcPtr * /*config*/, + const char *name) { if (strcmp(name, "scene_linear") == 0) return COLORSPACE_LINEAR; @@ -109,15 +111,17 @@ OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcP return NULL; } -int FallbackImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) +int FallbackImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, + const char *name) { OCIO_ConstColorSpaceRcPtr *cs = configGetColorSpace(config, name); - if (cs == COLORSPACE_LINEAR) + if (cs == COLORSPACE_LINEAR) { return 0; - else if (cs == COLORSPACE_SRGB) + } + else if (cs == COLORSPACE_SRGB) { return 1; - + } return -1; } @@ -131,44 +135,51 @@ int FallbackImpl::configGetNumDisplays(OCIO_ConstConfigRcPtr * /*config*/) return 1; } -const char *FallbackImpl::configGetDisplay(OCIO_ConstConfigRcPtr * /*config*/, int index) +const char *FallbackImpl::configGetDisplay(OCIO_ConstConfigRcPtr * /*config*/, + int index) { - if (index == 0) + if (index == 0) { return "sRGB"; - + } return NULL; } -const char *FallbackImpl::configGetDefaultView(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/) +const char *FallbackImpl::configGetDefaultView(OCIO_ConstConfigRcPtr * /*config*/, + const char * /*display*/) { return "Default"; } -int FallbackImpl::configGetNumViews(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/) +int FallbackImpl::configGetNumViews(OCIO_ConstConfigRcPtr * /*config*/, + const char * /*display*/) { return 1; } -const char *FallbackImpl::configGetView(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/, int index) +const char *FallbackImpl::configGetView(OCIO_ConstConfigRcPtr * /*config*/, + const char * /*display*/, int index) { - if (index == 0) + if (index == 0) { return "Default"; - + } return NULL; } -const char *FallbackImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/, const char * /*view*/) +const char *FallbackImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr * /*config*/, + const char * /*display*/, + const char * /*view*/) { return "sRGB"; } -void FallbackImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr * /*config*/, float *rgb) +void FallbackImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr * /*config*/, + float *rgb) { - /* Here we simply use the older Blender assumed primaries of - * ITU-BT.709 / sRGB, or 0.2126729 0.7151522 0.0721750. Brute - * force stupid, but only plausible option given no color management - * system in place. - */ + /* Here we simply use the older Blender assumed primaries of + * ITU-BT.709 / sRGB, or 0.2126729 0.7151522 0.0721750. Brute + * force stupid, but only plausible option given no color management + * system in place. + */ rgb[0] = 0.2126f; rgb[1] = 0.7152f; @@ -180,12 +191,14 @@ int FallbackImpl::configGetNumLooks(OCIO_ConstConfigRcPtr * /*config*/) return 0; } -const char *FallbackImpl::configGetLookNameByIndex(OCIO_ConstConfigRcPtr * /*config*/, int /*index*/) +const char *FallbackImpl::configGetLookNameByIndex(OCIO_ConstConfigRcPtr * /*config*/, + int /*index*/) { return ""; } -OCIO_ConstLookRcPtr *FallbackImpl::configGetLook(OCIO_ConstConfigRcPtr * /*config*/, const char * /*name*/) +OCIO_ConstLookRcPtr *FallbackImpl::configGetLook(OCIO_ConstConfigRcPtr * /*config*/, + const char * /*name*/) { return NULL; } @@ -213,25 +226,30 @@ void FallbackImpl::colorSpaceRelease(OCIO_ConstColorSpaceRcPtr * /*cs*/) { } -OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName) +OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames( + OCIO_ConstConfigRcPtr *config, + const char *srcName, + const char *dstName) { OCIO_ConstColorSpaceRcPtr *cs_src = configGetColorSpace(config, srcName); OCIO_ConstColorSpaceRcPtr *cs_dst = configGetColorSpace(config, dstName); - - if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) + if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) { return PROCESSOR_LINEAR_TO_SRGB; - else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) + } + else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) { return PROCESSOR_SRGB_TO_LINEAR; - + } return 0; } -OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessor(OCIO_ConstConfigRcPtr * /*config*/, OCIO_ConstTransformRcPtr *tfm) +OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessor(OCIO_ConstConfigRcPtr * /*config*/, + OCIO_ConstTransformRcPtr *tfm) { return (OCIO_ConstProcessorRcPtr*)tfm; } -void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) +void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, + OCIO_PackedImageDesc *img) { /* OCIO_TODO stride not respected, channels must be 3 or 4 */ OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)img; @@ -253,7 +271,8 @@ void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_Pack } } -void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) +void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, + OCIO_PackedImageDesc *img) { /* OCIO_TODO stride not respected, channels must be 3 or 4 */ OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)img; @@ -275,15 +294,19 @@ void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, } } -void FallbackImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel) +void FallbackImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, + float *pixel) { - if (processor == PROCESSOR_LINEAR_TO_SRGB) + if (processor == PROCESSOR_LINEAR_TO_SRGB) { linearrgb_to_srgb_v3_v3(pixel, pixel); - else if (processor == PROCESSOR_SRGB_TO_LINEAR) + } + else if (processor == PROCESSOR_SRGB_TO_LINEAR) { srgb_to_linearrgb_v3_v3(pixel, pixel); + } } -void FallbackImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel) +void FallbackImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, + float *pixel) { if (processor == PROCESSOR_LINEAR_TO_SRGB) linearrgb_to_srgb_v4(pixel, pixel); @@ -291,7 +314,8 @@ void FallbackImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float srgb_to_linearrgb_v4(pixel, pixel); } -void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel) +void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, + float *pixel) { if (pixel[3] == 1.0f || pixel[3] == 0.0f) { processorApplyRGBA(processor, pixel); @@ -320,11 +344,12 @@ void FallbackImpl::processorRelease(OCIO_ConstProcessorRcPtr * /*p*/) const char *FallbackImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs) { - if (cs == COLORSPACE_LINEAR) + if (cs == COLORSPACE_LINEAR) { return "Linear"; - else if (cs == COLORSPACE_SRGB) + } + else if (cs == COLORSPACE_SRGB) { return "sRGB"; - + } return NULL; } @@ -343,31 +368,38 @@ OCIO_DisplayTransformRcPtr *FallbackImpl::createDisplayTransform(void) return (OCIO_DisplayTransformRcPtr*)PROCESSOR_LINEAR_TO_SRGB; } -void FallbackImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr * /*dt*/, const char * /*name*/) +void FallbackImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr * /*dt*/, + const char * /*name*/) { } -void FallbackImpl::displayTransformSetDisplay(OCIO_DisplayTransformRcPtr * /*dt*/, const char * /*name*/) +void FallbackImpl::displayTransformSetDisplay(OCIO_DisplayTransformRcPtr * /*dt*/, + const char * /*name*/) { } -void FallbackImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr * /*dt*/, const char * /*name*/) +void FallbackImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr * /*dt*/, + const char * /*name*/) { } -void FallbackImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr * /*dt*/, OCIO_ConstTransformRcPtr * /*et*/) +void FallbackImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr * /*dt*/, + OCIO_ConstTransformRcPtr * /*et*/) { } -void FallbackImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr * /*dt*/, OCIO_ConstTransformRcPtr * /*et*/) +void FallbackImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr * /*dt*/, + OCIO_ConstTransformRcPtr * /*et*/) { } -void FallbackImpl::displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr * /*dt*/, const char * /*looks*/) +void FallbackImpl::displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr * /*dt*/, + const char * /*looks*/) { } -void FallbackImpl::displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr * /*dt*/, bool /*enabled*/) +void FallbackImpl::displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr * /*dt*/, + bool /*enabled*/) { } @@ -375,11 +407,14 @@ void FallbackImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr * /*dt*/) { } -OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, - long chanStrideBytes, long xStrideBytes, long yStrideBytes) +OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc( + float *data, + long width, long height, long numChannels, + long chanStrideBytes, long xStrideBytes, long yStrideBytes) { - OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)MEM_callocN(sizeof(OCIO_PackedImageDescription), "OCIO_PackedImageDescription"); - + OCIO_PackedImageDescription *desc = + (OCIO_PackedImageDescription*)MEM_callocN(sizeof(OCIO_PackedImageDescription), + "OCIO_PackedImageDescription"); desc->data = data; desc->width = width; desc->height = height; @@ -387,7 +422,6 @@ OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data, long desc->chanStrideBytes = chanStrideBytes; desc->xStrideBytes = xStrideBytes; desc->yStrideBytes = yStrideBytes; - return (OCIO_PackedImageDesc*)desc; } @@ -401,7 +435,8 @@ OCIO_ExponentTransformRcPtr *FallbackImpl::createExponentTransform(void) return (OCIO_ExponentTransformRcPtr*)PROCESSOR_UNKNOWN; } -void FallbackImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr * /*et*/, const float * /*exponent*/) +void FallbackImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr * /*et*/, + const float * /*exponent*/) { } @@ -414,7 +449,9 @@ OCIO_MatrixTransformRcPtr *FallbackImpl::createMatrixTransform(void) return (OCIO_MatrixTransformRcPtr*)PROCESSOR_UNKNOWN; } -void FallbackImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr * /*mt*/, const float * /*m44*/, const float * /*offset4*/) +void FallbackImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr * /*mt*/, + const float * /*m44*/, + const float * /*offset4*/) { } @@ -422,7 +459,9 @@ void FallbackImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr * /*mt*/) { } -void FallbackImpl::matrixTransformScale(float * /*m44*/, float * /*offset44*/, const float * /*scale4*/) +void FallbackImpl::matrixTransformScale(float * /*m44*/, + float * /*offset44*/, + const float * /*scale4*/) { } @@ -431,9 +470,11 @@ bool FallbackImpl::supportGLSLDraw(void) return false; } -bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState ** /*state_r*/, OCIO_ConstProcessorRcPtr * /*processor*/, +bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState ** /*state_r*/, + OCIO_ConstProcessorRcPtr * /*processor*/, OCIO_CurveMappingSettings * /*curve_mapping_settings*/, - float /*dither*/, bool /*predivide*/) + float /*dither*/, + bool /*predivide*/) { return false; } |