Cycles/Render API: changes for better copy-on-write support.

Mainly just passing the depsgraph and evaluated scene and camera, instead of
the original one. Patch by Sergey, further modifications by Brecht.
This commit is contained in:
2018-05-23 12:13:21 +02:00
committed by Brecht Van Lommel
parent d59b74adb3
commit b20449cc08
11 changed files with 118 additions and 104 deletions

View File

@@ -66,31 +66,32 @@ class CyclesRender(bpy.types.RenderEngine):
engine.free(self)
# final render
def update(self, data, scene):
def update(self, data, depsgraph):
if not self.session:
if self.is_preview:
cscene = bpy.context.scene.cycles
use_osl = cscene.shading_system and cscene.device == 'CPU'
engine.create(self, data, scene,
None, None, None, use_osl)
engine.create(self, data, preview_osl=use_osl)
else:
engine.create(self, data, scene)
else:
engine.reset(self, data, scene)
engine.create(self, data)
engine.reset(self, data, depsgraph)
def render_to_image(self, depsgraph):
engine.render(self, depsgraph)
def bake(self, depsgraph, scene, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result):
def bake(self, depsgraph, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result):
engine.bake(self, depsgraph, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result)
# viewport render
def view_update(self, context):
if not self.session:
engine.create(self, context.blend_data, context.scene,
engine.create(self, context.blend_data,
context.region, context.space_data, context.region_data)
engine.update(self, context.depsgraph, context.blend_data, context.scene)
engine.reset(self, context.blend_data, context.depsgraph)
engine.sync(self, context.depsgraph, context.blend_data)
def render_to_view(self, context):
engine.draw(self, context.depsgraph, context.region, context.space_data, context.region_data)

View File

@@ -123,13 +123,12 @@ def exit():
_cycles.exit()
def create(engine, data, scene, region=None, v3d=None, rv3d=None, preview_osl=False):
import bpy
def create(engine, data, region=None, v3d=None, rv3d=None, preview_osl=False):
import _cycles
import bpy
data = data.as_pointer()
userpref = bpy.context.user_preferences.as_pointer()
scene = scene.as_pointer()
if region:
region = region.as_pointer()
if v3d:
@@ -137,13 +136,8 @@ def create(engine, data, scene, region=None, v3d=None, rv3d=None, preview_osl=Fa
if rv3d:
rv3d = rv3d.as_pointer()
if bpy.app.debug_value == 256:
_cycles.debug_flags_update(scene)
else:
_cycles.debug_flags_reset()
engine.session = _cycles.create(
engine.as_pointer(), userpref, data, scene, region, v3d, rv3d, preview_osl)
engine.as_pointer(), userpref, data, region, v3d, rv3d, preview_osl)
def free(engine):
@@ -167,14 +161,21 @@ def bake(engine, depsgraph, obj, pass_type, pass_filter, object_id, pixel_array,
_cycles.bake(engine.session, depsgraph.as_pointer(), obj.as_pointer(), pass_type, pass_filter, object_id, pixel_array.as_pointer(), num_pixels, depth, result.as_pointer())
def reset(engine, data, scene):
def reset(engine, data, depsgraph):
import _cycles
import bpy
if bpy.app.debug_value == 256:
_cycles.debug_flags_update(depsgraph.scene)
else:
_cycles.debug_flags_reset()
data = data.as_pointer()
scene = scene.as_pointer()
_cycles.reset(engine.session, data, scene)
depsgraph = depsgraph.as_pointer()
_cycles.reset(engine.session, data, depsgraph)
def update(engine, depsgraph, data, scene):
def sync(engine, depsgraph, data):
import _cycles
_cycles.sync(engine.session, depsgraph.as_pointer())

View File

@@ -203,10 +203,10 @@ static PyObject *exit_func(PyObject * /*self*/, PyObject * /*args*/)
static PyObject *create_func(PyObject * /*self*/, PyObject *args)
{
PyObject *pyengine, *pyuserpref, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d;
PyObject *pyengine, *pyuserpref, *pydata, *pyregion, *pyv3d, *pyrv3d;
int preview_osl;
if(!PyArg_ParseTuple(args, "OOOOOOOi", &pyengine, &pyuserpref, &pydata, &pyscene,
if(!PyArg_ParseTuple(args, "OOOOOOi", &pyengine, &pyuserpref, &pydata,
&pyregion, &pyv3d, &pyrv3d, &preview_osl))
{
return NULL;
@@ -225,10 +225,6 @@ static PyObject *create_func(PyObject * /*self*/, PyObject *args)
RNA_main_pointer_create((Main*)PyLong_AsVoidPtr(pydata), &dataptr);
BL::BlendData data(dataptr);
PointerRNA sceneptr;
RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
BL::Scene scene(sceneptr);
PointerRNA regionptr;
RNA_pointer_create(NULL, &RNA_Region, pylong_as_voidptr_typesafe(pyregion), &regionptr);
BL::Region region(regionptr);
@@ -249,27 +245,13 @@ static PyObject *create_func(PyObject * /*self*/, PyObject *args)
int width = region.width();
int height = region.height();
session = new BlenderSession(engine, userpref, data, scene, v3d, rv3d, width, height);
session = new BlenderSession(engine, userpref, data, v3d, rv3d, width, height);
}
else {
/* override some settings for preview */
if(engine.is_preview()) {
PointerRNA cscene = RNA_pointer_get(&sceneptr, "cycles");
RNA_boolean_set(&cscene, "shading_system", preview_osl);
RNA_boolean_set(&cscene, "use_progressive_refine", true);
}
/* offline session or preview render */
session = new BlenderSession(engine, userpref, data, scene);
session = new BlenderSession(engine, userpref, data, preview_osl);
}
python_thread_state_save(&session->python_thread_state);
session->create();
python_thread_state_restore(&session->python_thread_state);
return PyLong_FromVoidPtr(session);
}
@@ -316,7 +298,7 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
PointerRNA depsgraphptr;
RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
BL::Depsgraph b_depsgraph(depsgraphptr);
PointerRNA objectptr;
@@ -360,9 +342,9 @@ static PyObject *draw_func(PyObject * /*self*/, PyObject *args)
static PyObject *reset_func(PyObject * /*self*/, PyObject *args)
{
PyObject *pysession, *pydata, *pyscene;
PyObject *pysession, *pydata, *pydepsgraph;
if(!PyArg_ParseTuple(args, "OOO", &pysession, &pydata, &pyscene))
if(!PyArg_ParseTuple(args, "OOO", &pysession, &pydata, &pydepsgraph))
return NULL;
BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
@@ -371,13 +353,13 @@ static PyObject *reset_func(PyObject * /*self*/, PyObject *args)
RNA_main_pointer_create((Main*)PyLong_AsVoidPtr(pydata), &dataptr);
BL::BlendData b_data(dataptr);
PointerRNA sceneptr;
RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
BL::Scene b_scene(sceneptr);
PointerRNA depsgraphptr;
RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
BL::Depsgraph b_depsgraph(depsgraphptr);
python_thread_state_save(&session->python_thread_state);
session->reset_session(b_data, b_scene);
session->reset_session(b_data, b_depsgraph);
python_thread_state_restore(&session->python_thread_state);
@@ -394,7 +376,7 @@ static PyObject *sync_func(PyObject * /*self*/, PyObject *args)
BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
PointerRNA depsgraphptr;
RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
BL::Depsgraph b_depsgraph(depsgraphptr);
python_thread_state_save(&session->python_thread_state);

View File

@@ -52,22 +52,22 @@ int BlenderSession::end_resumable_chunk = 0;
BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
BL::Scene& b_scene)
: b_engine(b_engine),
bool preview_osl)
: session(NULL),
b_engine(b_engine),
b_userpref(b_userpref),
b_data(b_data),
b_render(b_engine.render()),
b_depsgraph(PointerRNA_NULL),
b_scene(b_scene),
b_scene(PointerRNA_NULL),
b_v3d(PointerRNA_NULL),
b_rv3d(PointerRNA_NULL),
width(0),
height(0),
preview_osl(preview_osl),
python_thread_state(NULL)
{
/* offline render */
width = render_resolution_x(b_render);
height = render_resolution_y(b_render);
background = true;
last_redraw_time = 0.0;
start_resize_time = 0.0;
@@ -77,24 +77,24 @@ BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
BL::Scene& b_scene,
BL::SpaceView3D& b_v3d,
BL::RegionView3D& b_rv3d,
int width, int height)
: b_engine(b_engine),
: session(NULL),
b_engine(b_engine),
b_userpref(b_userpref),
b_data(b_data),
b_render(b_scene.render()),
b_render(b_engine.render()),
b_depsgraph(PointerRNA_NULL),
b_scene(b_scene),
b_scene(PointerRNA_NULL),
b_v3d(b_v3d),
b_rv3d(b_rv3d),
width(width),
height(height),
preview_osl(false),
python_thread_state(NULL)
{
/* 3d view render */
background = false;
last_redraw_time = 0.0;
start_resize_time = 0.0;
@@ -168,18 +168,40 @@ void BlenderSession::create_session()
update_resumable_tile_manager(session_params.samples);
}
void BlenderSession::reset_session(BL::BlendData& b_data_, BL::Scene& b_scene_)
void BlenderSession::reset_session(BL::BlendData& b_data, BL::Depsgraph& b_depsgraph)
{
b_data = b_data_;
b_render = b_engine.render();
b_scene = b_scene_;
this->b_data = b_data;
this->b_depsgraph = b_depsgraph;
this->b_scene = b_depsgraph.scene_eval();
if (preview_osl) {
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
RNA_boolean_set(&cscene, "shading_system", preview_osl);
}
if (b_v3d) {
this->b_render = b_scene.render();
}
else {
this->b_render = b_engine.render();
width = render_resolution_x(b_render);
height = render_resolution_y(b_render);
}
if (session == NULL) {
create();
}
if (b_v3d) {
/* NOTE: We need to create session, but all the code from below
* will make viewport render to stuck on initialization.
*/
return;
}
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
width = render_resolution_x(b_render);
height = render_resolution_y(b_render);
if(scene->params.modified(scene_params) ||
session->params.modified(session_params) ||
!scene_params.persistent_data)

View File

@@ -37,12 +37,11 @@ public:
BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
BL::Scene& b_scene);
bool preview_osl);
BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
BL::Scene& b_scene,
BL::SpaceView3D& b_v3d,
BL::RegionView3D& b_rv3d,
int width, int height);
@@ -56,7 +55,7 @@ public:
void free_session();
void reset_session(BL::BlendData& b_data,
BL::Scene& b_scene);
BL::Depsgraph& b_depsgraph);
/* offline render */
void render(BL::Depsgraph& b_depsgraph);
@@ -119,6 +118,7 @@ public:
double last_status_time;
int width, height;
bool preview_osl;
double start_resize_time;
void *python_thread_state;

View File

@@ -796,7 +796,8 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine,
params.text_timeout = (double)get_float(cscene, "debug_text_timeout");
/* progressive refine */
params.progressive_refine = get_boolean(cscene, "use_progressive_refine") &&
params.progressive_refine = (b_engine.is_preview() ||
get_boolean(cscene, "use_progressive_refine")) &&
!b_r.use_save_buffers();
if(params.progressive_refine) {

View File

@@ -893,7 +893,7 @@ static int bake(
/* the baking itself */
for (i = 0; i < tot_highpoly; i++) {
ok = RE_bake_engine(re, view_layer, highpoly[i].ob, i, pixel_array_high,
ok = RE_bake_engine(re, depsgraph, highpoly[i].ob, i, pixel_array_high,
num_pixels, depth, pass_type, pass_filter, result);
if (!ok) {
BKE_reportf(reports, RPT_ERROR, "Error baking from object \"%s\"", highpoly[i].ob->id.name + 2);
@@ -920,7 +920,7 @@ cage_cleanup:
ob_low->restrictflag &= ~OB_RESTRICT_RENDER;
if (RE_bake_has_engine(re)) {
ok = RE_bake_engine(re, view_layer, ob_low, 0, pixel_array_low, num_pixels, depth, pass_type, pass_filter, result);
ok = RE_bake_engine(re, depsgraph, ob_low, 0, pixel_array_low, num_pixels, depth, pass_type, pass_filter, result);
}
else {
BKE_report(reports, RPT_ERROR, "Current render engine does not support baking");
@@ -1120,6 +1120,8 @@ cleanup:
if (me_cage)
BKE_libblock_free(bmain, me_cage);
DEG_graph_free(depsgraph);
return op_result;
}

View File

@@ -113,6 +113,8 @@ const EnumPropertyItem rna_enum_bake_pass_type_items[] = {
#include "IMB_colormanagement.h"
#include "GPU_extensions.h"
#include "DEG_depsgraph_query.h"
/* RenderEngine Callbacks */
static void engine_tag_redraw(RenderEngine *engine)
@@ -148,7 +150,7 @@ static void engine_unbind_display_space_shader(RenderEngine *UNUSED(engine))
IMB_colormanagement_finish_glsl_draw();
}
static void engine_update(RenderEngine *engine, Main *bmain, Scene *scene)
static void engine_update(RenderEngine *engine, Main *bmain, Depsgraph *depsgraph)
{
extern FunctionRNA rna_RenderEngine_update_func;
PointerRNA ptr;
@@ -160,7 +162,7 @@ static void engine_update(RenderEngine *engine, Main *bmain, Scene *scene)
RNA_parameter_list_create(&list, &ptr, func);
RNA_parameter_set_lookup(&list, "data", &bmain);
RNA_parameter_set_lookup(&list, "scene", &scene);
RNA_parameter_set_lookup(&list, "depsgraph", &depsgraph);
engine->type->ext.call(NULL, &ptr, func, &list);
RNA_parameter_list_free(&list);
@@ -183,7 +185,7 @@ static void engine_render_to_image(RenderEngine *engine, Depsgraph *depsgraph)
RNA_parameter_list_free(&list);
}
static void engine_bake(RenderEngine *engine, struct Depsgraph *depsgraph, struct Scene *scene,
static void engine_bake(RenderEngine *engine, struct Depsgraph *depsgraph,
struct Object *object, const int pass_type, const int pass_filter,
const int object_id, const struct BakePixel *pixel_array,
const int num_pixels, const int depth, void *result)
@@ -198,7 +200,6 @@ static void engine_bake(RenderEngine *engine, struct Depsgraph *depsgraph, struc
RNA_parameter_list_create(&list, &ptr, func);
RNA_parameter_set_lookup(&list, "depsgraph", &depsgraph);
RNA_parameter_set_lookup(&list, "scene", &scene);
RNA_parameter_set_lookup(&list, "object", &object);
RNA_parameter_set_lookup(&list, "pass_type", &pass_type);
RNA_parameter_set_lookup(&list, "pass_filter", &pass_filter);
@@ -384,10 +385,11 @@ static PointerRNA rna_RenderEngine_render_get(PointerRNA *ptr)
static PointerRNA rna_RenderEngine_camera_override_get(PointerRNA *ptr)
{
RenderEngine *engine = (RenderEngine *)ptr->data;
/* TODO(sergey): Shouldn't engine point to an evaluated datablocks already? */
if (engine->re) {
Object *cam = RE_GetCamera(engine->re);
return rna_pointer_inherit_refine(ptr, &RNA_Object, cam);
Object *cam_eval = DEG_get_evaluated_object(engine->depsgraph, cam);
return rna_pointer_inherit_refine(ptr, &RNA_Object, cam_eval);
}
else {
return rna_pointer_inherit_refine(ptr, &RNA_Object, engine->camera_override);
@@ -485,7 +487,7 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_function_ui_description(func, "Export scene data for render");
RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
RNA_def_pointer(func, "data", "BlendData", "", "");
RNA_def_pointer(func, "scene", "Scene", "", "");
RNA_def_pointer(func, "depsgraph", "Depsgraph", "", "");
func = RNA_def_function(srna, "render_to_image", NULL);
RNA_def_function_ui_description(func, "Render scene into an image");
@@ -498,8 +500,6 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
parm = RNA_def_pointer(func, "depsgraph", "Depsgraph", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_pointer(func, "scene", "Scene", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_pointer(func, "object", "Object", "", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_enum(func, "pass_type", rna_enum_bake_pass_type_items, 0, "Pass", "Pass to bake");

View File

@@ -35,7 +35,7 @@
struct ImBuf;
struct Render;
struct Mesh;
struct ViewLayer;
struct Depsgraph;
typedef struct BakeImage {
struct Image *image;
@@ -72,7 +72,7 @@ typedef struct BakeHighPolyData {
bool RE_bake_has_engine(struct Render *re);
bool RE_bake_engine(
struct Render *re, struct ViewLayer *view_layer, struct Object *object, const int object_id, const BakePixel pixel_array[],
struct Render *re, struct Depsgraph *depsgraph, struct Object *object, const int object_id, const BakePixel pixel_array[],
const size_t num_pixels, const int depth, const eScenePassType pass_type, const int pass_filter, float result[]);
/* bake.c */

View File

@@ -41,8 +41,6 @@ struct bNode;
struct bNodeTree;
struct BakePixel;
struct Depsgraph;
struct Depsgraph;
struct Depsgraph;
struct IDProperty;
struct Main;
struct Object;
@@ -94,10 +92,10 @@ typedef struct RenderEngineType {
char name[64];
int flag;
void (*update)(struct RenderEngine *engine, struct Main *bmain, struct Scene *scene);
void (*update)(struct RenderEngine *engine, struct Main *bmain, struct Depsgraph *depsgraph);
void (*render_to_image)(struct RenderEngine *engine, struct Depsgraph *depsgraph);
void (*bake)(struct RenderEngine *engine, struct Depsgraph *depsgraph,
struct Scene *scene, struct Object *object, const int pass_type,
struct Object *object, const int pass_type,
const int pass_filter, const int object_id, const struct BakePixel *pixel_array, const int num_pixels,
const int depth, void *result);

View File

@@ -546,7 +546,7 @@ bool RE_bake_has_engine(Render *re)
}
bool RE_bake_engine(
Render *re, ViewLayer *view_layer, Object *object,
Render *re, Depsgraph *depsgraph, Object *object,
const int object_id, const BakePixel pixel_array[],
const size_t num_pixels, const int depth,
const eScenePassType pass_type, const int pass_filter,
@@ -581,16 +581,15 @@ bool RE_bake_engine(
engine->tile_x = re->r.tilex;
engine->tile_y = re->r.tiley;
if (type->bake) {
engine->depsgraph = depsgraph;
/* update is only called so we create the engine.session */
if (type->update)
type->update(engine, re->main, re->scene);
if (type->bake) {
engine_depsgraph_init(engine, view_layer);
type->update(engine, re->main, engine->depsgraph);
type->bake(engine,
engine->depsgraph,
re->scene,
object,
pass_type,
pass_filter,
@@ -600,7 +599,7 @@ bool RE_bake_engine(
depth,
result);
engine_depsgraph_free(engine);
engine->depsgraph = NULL;
}
engine->tile_x = 0;
@@ -715,10 +714,6 @@ int RE_engine_render(Render *re, int do_all)
if (re->result->do_exr_tile)
render_result_exr_file_begin(re);
if (type->update) {
type->update(engine, re->main, re->scene);
}
/* Clear UI drawing locks. */
if (re->draw_lock) {
re->draw_lock(re->dlh, 0);
@@ -727,9 +722,21 @@ int RE_engine_render(Render *re, int do_all)
if (type->render_to_image) {
FOREACH_VIEW_LAYER_TO_RENDER_BEGIN(re, view_layer_iter)
{
if (re->draw_lock) {
re->draw_lock(re->dlh, 1);
}
ViewLayer *view_layer = BLI_findstring(&re->scene->view_layers, view_layer_iter->name, offsetof(ViewLayer, name));
engine_depsgraph_init(engine, view_layer);
if (type->update) {
type->update(engine, re->main, engine->depsgraph);
}
if (re->draw_lock) {
re->draw_lock(re->dlh, 0);
}
type->render_to_image(engine, engine->depsgraph);
engine_depsgraph_free(engine);