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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-09-04 17:29:07 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-09-04 17:29:07 +0400
commitadea12cb01e4c4f18f345dfbbf49e9e622192e4e (patch)
treeb43018344c696e4d59437fabc7f17f5b9d6a8e80 /intern/cycles/blender/blender_session.cpp
parent68563134d4800be4eb46aa6b598fd719cdaf2980 (diff)
Cycles: merge of changes from tomato branch.
Regular rendering now works tiled, and supports save buffers to save memory during render and cache render results. Brick texture node by Thomas. http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/Textures#Brick_Texture Image texture Blended Box Mapping. http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/Textures#Image_Texture http://mango.blender.org/production/blended_box/ Various bug fixes by Sergey and Campbell. * Fix for reading freed memory in some node setups. * Fix incorrect memory read when synchronizing mesh motion. * Fix crash appearing when direct light usage is different on different layers. * Fix for vector pass gives wrong result in some circumstances. * Fix for wrong resolution used for rendering Render Layer node. * Option to cancel rendering when doing initial synchronization. * No more texture limit when using CPU render. * Many fixes for new tiled rendering.
Diffstat (limited to 'intern/cycles/blender/blender_session.cpp')
-rw-r--r--intern/cycles/blender/blender_session.cpp209
1 files changed, 145 insertions, 64 deletions
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index d09e43bd76d..7b80c520e72 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -42,14 +42,13 @@ CCL_NAMESPACE_BEGIN
BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::UserPreferences b_userpref_,
BL::BlendData b_data_, BL::Scene b_scene_)
: b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_scene(b_scene_),
- b_v3d(PointerRNA_NULL), b_rv3d(PointerRNA_NULL),
- b_rr(PointerRNA_NULL), b_rlay(PointerRNA_NULL)
+ b_v3d(PointerRNA_NULL), b_rv3d(PointerRNA_NULL)
{
/* offline render */
- BL::RenderSettings r = b_scene.render();
- width = (int)(r.resolution_x()*r.resolution_percentage()/100);
- height = (int)(r.resolution_y()*r.resolution_percentage()/100);
+ width = b_engine.resolution_x();
+ height = b_engine.resolution_y();
+
background = true;
last_redraw_time = 0.0f;
@@ -60,7 +59,7 @@ BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::UserPreferences b
BL::BlendData b_data_, BL::Scene b_scene_,
BL::SpaceView3D b_v3d_, BL::RegionView3D b_rv3d_, int width_, int height_)
: b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_scene(b_scene_),
- b_v3d(b_v3d_), b_rv3d(b_rv3d_), b_rr(PointerRNA_NULL), b_rlay(PointerRNA_NULL)
+ b_v3d(b_v3d_), b_rv3d(b_rv3d_)
{
/* 3d view render */
width = width_;
@@ -80,17 +79,24 @@ BlenderSession::~BlenderSession()
void BlenderSession::create_session()
{
SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
- SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background);
+ SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
/* reset status/progress */
last_status = "";
last_progress = -1.0f;
/* create scene */
- scene = new Scene(scene_params);
+ scene = new Scene(scene_params, session_params.device);
+
+ /* create session */
+ session = new Session(session_params);
+ session->scene = scene;
+ session->progress.set_update_callback(function_bind(&BlenderSession::tag_redraw, this));
+ session->progress.set_cancel_callback(function_bind(&BlenderSession::test_cancel, this));
+ session->set_pause(BlenderSync::get_session_pause(b_scene, background));
/* create sync */
- sync = new BlenderSync(b_data, b_scene, scene, !background);
+ sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
sync->sync_data(b_v3d, b_engine.camera_override());
if(b_rv3d)
@@ -98,13 +104,6 @@ void BlenderSession::create_session()
else
sync->sync_camera(b_engine.camera_override(), width, height);
- /* create session */
- session = new Session(session_params);
- session->scene = scene;
- session->progress.set_update_callback(function_bind(&BlenderSession::tag_redraw, this));
- session->progress.set_cancel_callback(function_bind(&BlenderSession::test_cancel, this));
- session->set_pause(BlenderSync::get_session_pause(b_scene, background));
-
/* set buffer parameters */
BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height);
session->reset(buffer_params, session_params.samples);
@@ -177,35 +176,100 @@ static PassType get_pass_type(BL::RenderPass b_pass)
return PASS_NONE;
}
+static BL::RenderResult begin_render_result(BL::RenderEngine b_engine, int x, int y, int w, int h, const char *layername)
+{
+ RenderResult *rrp = RE_engine_begin_result((RenderEngine*)b_engine.ptr.data, x, y, w, h, layername);
+ PointerRNA rrptr;
+ RNA_pointer_create(NULL, &RNA_RenderResult, rrp, &rrptr);
+ return BL::RenderResult(rrptr);
+}
+
+static void end_render_result(BL::RenderEngine b_engine, BL::RenderResult b_rr, bool cancel = false)
+{
+ RE_engine_end_result((RenderEngine*)b_engine.ptr.data, (RenderResult*)b_rr.ptr.data, (int)cancel);
+}
+
+void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_update_only)
+{
+ BufferParams& params = rtile.buffers->params;
+ int x = params.full_x - session->tile_manager.params.full_x;
+ int y = params.full_y - session->tile_manager.params.full_y;
+ int w = params.width;
+ int h = params.height;
+
+ /* get render result */
+ BL::RenderResult b_rr = begin_render_result(b_engine, x, y, w, h, b_rlay_name.c_str());
+
+ /* can happen if the intersected rectangle gives 0 width or height */
+ if (b_rr.ptr.data == NULL) {
+ return;
+ }
+
+ BL::RenderResult::layers_iterator b_single_rlay;
+ b_rr.layers.begin(b_single_rlay);
+ BL::RenderLayer b_rlay = *b_single_rlay;
+
+ if (do_update_only) {
+ /* update only needed */
+ update_render_result(b_rr, b_rlay, rtile);
+ end_render_result(b_engine, b_rr, true);
+ }
+ else {
+ /* write result */
+ write_render_result(b_rr, b_rlay, rtile);
+ end_render_result(b_engine, b_rr);
+ }
+}
+
+void BlenderSession::write_render_tile(RenderTile& rtile)
+{
+ do_write_update_render_tile(rtile, false);
+}
+
+void BlenderSession::update_render_tile(RenderTile& rtile)
+{
+ do_write_update_render_tile(rtile, true);
+}
+
void BlenderSession::render()
{
+ /* set callback to write out render results */
+ session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1);
+ session->update_render_tile_cb = function_bind(&BlenderSession::update_render_tile, this, _1);
+
/* get buffer parameters */
- SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background);
+ SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height);
- int w = buffer_params.width, h = buffer_params.height;
-
- /* create render result */
- RenderResult *rrp = RE_engine_begin_result((RenderEngine*)b_engine.ptr.data, 0, 0, w, h);
- PointerRNA rrptr;
- RNA_pointer_create(NULL, &RNA_RenderResult, rrp, &rrptr);
- b_rr = BL::RenderResult(rrptr);
+ /* render each layer */
BL::RenderSettings r = b_scene.render();
- BL::RenderResult::layers_iterator b_iter;
- BL::RenderLayers b_rr_layers(r.ptr);
+ BL::RenderSettings::layers_iterator b_iter;
- /* render each layer */
- for(b_rr.layers.begin(b_iter); b_iter != b_rr.layers.end(); ++b_iter) {
- /* set layer */
- b_rlay = *b_iter;
+ for(r.layers.begin(b_iter); b_iter != r.layers.end(); ++b_iter) {
+ b_rlay_name = b_iter->name();
+
+ /* temporary render result to find needed passes */
+ BL::RenderResult b_rr = begin_render_result(b_engine, 0, 0, 1, 1, b_rlay_name.c_str());
+ BL::RenderResult::layers_iterator b_single_rlay;
+ b_rr.layers.begin(b_single_rlay);
+
+ /* layer will be missing if it was disabled in the UI */
+ if(b_single_rlay == b_rr.layers.end()) {
+ end_render_result(b_engine, b_rr, true);
+ continue;
+ }
+
+ BL::RenderLayer b_rlay = *b_single_rlay;
/* add passes */
vector<Pass> passes;
Pass::add(PASS_COMBINED, passes);
if(session_params.device.advanced_shading) {
+
+ /* loop over passes */
BL::RenderLayer::passes_iterator b_pass_iter;
-
+
for(b_rlay.passes.begin(b_pass_iter); b_pass_iter != b_rlay.passes.end(); ++b_pass_iter) {
BL::RenderPass b_pass(*b_pass_iter);
PassType pass_type = get_pass_type(b_pass);
@@ -217,13 +281,16 @@ void BlenderSession::render()
}
}
+ /* free result without merging */
+ end_render_result(b_engine, b_rr, true);
+
buffer_params.passes = passes;
scene->film->tag_passes_update(scene, passes);
scene->film->tag_update(scene);
scene->integrator->tag_update(scene);
/* update scene */
- sync->sync_data(b_v3d, b_engine.camera_override(), b_iter->name().c_str());
+ sync->sync_data(b_v3d, b_engine.camera_override(), b_rlay_name.c_str());
/* update session */
int samples = sync->get_layer_samples();
@@ -235,19 +302,16 @@ void BlenderSession::render()
if(session->progress.get_cancel())
break;
-
- /* write result */
- write_render_result();
}
- /* delete render result */
- RE_engine_end_result((RenderEngine*)b_engine.ptr.data, (RenderResult*)b_rr.ptr.data);
+ /* clear callback */
+ session->write_render_tile_cb = NULL;
+ session->update_render_tile_cb = NULL;
}
-void BlenderSession::write_render_result()
+void BlenderSession::do_write_update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile, bool do_update_only)
{
- /* get state */
- RenderBuffers *buffers = session->buffers;
+ RenderBuffers *buffers = rtile.buffers;
/* copy data from device */
if(!buffers->copy_from_device())
@@ -255,41 +319,49 @@ void BlenderSession::write_render_result()
BufferParams& params = buffers->params;
float exposure = scene->film->exposure;
- double total_time, sample_time;
- int sample;
-
- session->progress.get_sample(sample, total_time, sample_time);
vector<float> pixels(params.width*params.height*4);
- /* copy each pass */
- BL::RenderLayer::passes_iterator b_iter;
-
- for(b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) {
- BL::RenderPass b_pass(*b_iter);
+ if (!do_update_only) {
+ /* copy each pass */
+ BL::RenderLayer::passes_iterator b_iter;
+
+ for(b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) {
+ BL::RenderPass b_pass(*b_iter);
- /* find matching pass type */
- PassType pass_type = get_pass_type(b_pass);
- int components = b_pass.channels();
+ /* find matching pass type */
+ PassType pass_type = get_pass_type(b_pass);
+ int components = b_pass.channels();
- /* copy pixels */
- if(buffers->get_pass(pass_type, exposure, sample, components, &pixels[0]))
- rna_RenderPass_rect_set(&b_pass.ptr, &pixels[0]);
+ /* copy pixels */
+ if(buffers->get_pass_rect(pass_type, exposure, rtile.sample, components, &pixels[0]))
+ rna_RenderPass_rect_set(&b_pass.ptr, &pixels[0]);
+ }
}
/* copy combined pass */
- if(buffers->get_pass(PASS_COMBINED, exposure, sample, 4, &pixels[0]))
+ if(buffers->get_pass_rect(PASS_COMBINED, exposure, rtile.sample, 4, &pixels[0]))
rna_RenderLayer_rect_set(&b_rlay.ptr, &pixels[0]);
/* tag result as updated */
RE_engine_update_result((RenderEngine*)b_engine.ptr.data, (RenderResult*)b_rr.ptr.data);
}
+void BlenderSession::write_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile)
+{
+ do_write_update_render_result(b_rr, b_rlay, rtile, false);
+}
+
+void BlenderSession::update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile)
+{
+ do_write_update_render_result(b_rr, b_rlay, rtile, true);
+}
+
void BlenderSession::synchronize()
{
/* on session/scene parameter changes, we recreate session entirely */
SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
- SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background);
+ SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
if(session->params.modified(session_params) ||
scene->params.modified(scene_params))
@@ -364,7 +436,7 @@ bool BlenderSession::draw(int w, int h)
/* reset if requested */
if(reset) {
- SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background);
+ SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, w, h);
session->reset(buffer_params, session_params.samples);
@@ -387,11 +459,16 @@ void BlenderSession::get_status(string& status, string& substatus)
void BlenderSession::get_progress(float& progress, double& total_time)
{
- double sample_time;
- int sample;
+ double tile_time;
+ int tile, sample, samples_per_tile;
+ int tile_total = session->tile_manager.state.num_tiles;
+
+ session->progress.get_tile(tile, total_time, tile_time);
- session->progress.get_sample(sample, total_time, sample_time);
- progress = ((float)sample/(float)session->params.samples);
+ sample = session->progress.get_sample();
+ samples_per_tile = session->tile_manager.state.num_samples;
+
+ progress = ((float)sample/(float)(tile_total * samples_per_tile));
}
void BlenderSession::update_status_progress()
@@ -404,8 +481,13 @@ void BlenderSession::update_status_progress()
get_status(status, substatus);
get_progress(progress, total_time);
+ timestatus = b_scene.name();
+ if(b_rlay_name != "")
+ timestatus += ", " + b_rlay_name;
+ timestatus += " | ";
+
BLI_timestr(total_time, time_str);
- timestatus = "Elapsed: " + string(time_str) + " | ";
+ timestatus += "Elapsed: " + string(time_str) + " | ";
if(substatus.size() > 0)
status += " | " + substatus;
@@ -435,7 +517,6 @@ void BlenderSession::tag_redraw()
/* offline render, redraw if timeout passed */
if(time_dt() - last_redraw_time > 1.0) {
- write_render_result();
engine_tag_redraw((RenderEngine*)b_engine.ptr.data);
last_redraw_time = time_dt();
}