Render: Incremental steps to move callbacks to base class methods #111047

Merged
Sergey Sharybin merged 10 commits from Sergey/blender:render_result into main 2023-08-14 11:18:35 +02:00
6 changed files with 212 additions and 99 deletions

View File

@ -280,13 +280,13 @@ static void prepare(Render *re, ViewLayer *view_layer, Depsgraph *depsgraph)
{
// load mesh
re->i.infostr = TIP_("Freestyle: Mesh loading");
re->stats_draw(re->sdh, &re->i);
re->stats_draw(&re->i);
re->i.infostr = nullptr;
if (controller->LoadMesh(re, view_layer, depsgraph)) {
/* Returns if scene cannot be loaded or if empty. */
return;
}
if (re->test_break(re->tbh)) {
if (re->test_break()) {
return;
}
@ -467,7 +467,7 @@ static void prepare(Render *re, ViewLayer *view_layer, Depsgraph *depsgraph)
// compute view map
re->i.infostr = TIP_("Freestyle: View map creation");
re->stats_draw(re->sdh, &re->i);
re->stats_draw(&re->i);
re->i.infostr = nullptr;
controller->ComputeViewMap();
}
@ -630,7 +630,7 @@ void FRS_do_stroke_rendering(Render *re, ViewLayer *view_layer)
// - compute view map
prepare(re, view_layer, depsgraph);
if (re->test_break(re->tbh)) {
if (re->test_break()) {
controller->CloseFile();
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "Break" << endl;
@ -641,7 +641,7 @@ void FRS_do_stroke_rendering(Render *re, ViewLayer *view_layer)
if (controller->_ViewMap) {
// render strokes
re->i.infostr = TIP_("Freestyle: Stroke rendering");
re->stats_draw(re->sdh, &re->i);
re->stats_draw(&re->i);
re->i.infostr = nullptr;
g_freestyle.scene = DEG_get_evaluated_scene(depsgraph);
int strokeCount = controller->DrawStrokes();

View File

@ -30,7 +30,7 @@ class RenderMonitor {
{
if (_re && !info.empty()) {
_re->i.infostr = info.c_str();
_re->stats_draw(_re->sdh, &_re->i);
_re->stats_draw(&_re->i);
_re->i.infostr = nullptr;
}
}
@ -38,13 +38,13 @@ class RenderMonitor {
inline void progress(float i)
{
if (_re) {
_re->progress(_re->prh, i);
_re->progress(i);
}
}
inline bool testBreak()
{
return _re && _re->test_break(_re->tbh);
return _re && _re->test_break();
}
protected:

View File

@ -380,7 +380,7 @@ void RE_engine_update_result(RenderEngine *engine, RenderResult *result)
render_result_merge(re->result, result);
result->renlay = static_cast<RenderLayer *>(
result->layers.first); /* weak, draws first layer always */
re->display_update(re->duh, result, nullptr);
re->display_update(result, nullptr);
}
}
@ -431,16 +431,16 @@ void RE_engine_end_result(
}
if (!cancel || merge_results) {
if (!(re->test_break(re->tbh) && (re->r.scemode & R_BUTS_PREVIEW))) {
if (!(re->test_break() && (re->r.scemode & R_BUTS_PREVIEW))) {
re_ensure_passes_allocated_thread_safe(re);
render_result_merge(re->result, result);
}
/* draw */
if (!re->test_break(re->tbh)) {
if (!re->test_break()) {
result->renlay = static_cast<RenderLayer *>(
result->layers.first); /* weak, draws first layer always */
re->display_update(re->duh, result, nullptr);
re->display_update(result, nullptr);
}
}
@ -461,7 +461,7 @@ bool RE_engine_test_break(RenderEngine *engine)
Render *re = engine->re;
if (re) {
return re->test_break(re->tbh);
return re->test_break();
}
return false;
@ -477,7 +477,7 @@ void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char
if (re) {
re->i.statstr = stats;
re->i.infostr = info;
re->stats_draw(re->sdh, &re->i);
re->stats_draw(&re->i);
re->i.infostr = nullptr;
re->i.statstr = nullptr;
}
@ -502,7 +502,7 @@ void RE_engine_update_progress(RenderEngine *engine, float progress)
if (re) {
CLAMP(progress, 0.0f, 1.0f);
re->progress(re->prh, progress);
re->progress(progress);
}
}
@ -842,20 +842,14 @@ static void engine_render_view_layer(Render *re,
const bool use_grease_pencil)
{
/* Lock UI so scene can't be edited while we read from it in this render thread. */
if (re->draw_lock) {
re->draw_lock(re->dlh, true);
}
re->draw_lock();
/* Create depsgraph with scene evaluated at render resolution. */
ViewLayer *view_layer = static_cast<ViewLayer *>(
BLI_findstring(&re->scene->view_layers, view_layer_iter->name, offsetof(ViewLayer, name)));
if (re->prepare_viewlayer) {
if (!re->prepare_viewlayer(re->prepare_vl_handle, view_layer, engine->depsgraph)) {
if (re->draw_lock) {
re->draw_lock(re->dlh, false);
}
return;
}
if (!re->prepare_viewlayer(view_layer, engine->depsgraph)) {
re->draw_unlock();
return;
}
engine_depsgraph_init(engine, view_layer);
@ -873,9 +867,7 @@ static void engine_render_view_layer(Render *re,
}
}
if (re->draw_lock) {
re->draw_lock(re->dlh, false);
}
re->draw_unlock();
/* Perform render with engine. */
if (use_engine) {
@ -968,15 +960,11 @@ bool RE_engine_render(Render *re, bool do_all)
}
/* Lock drawing in UI during data phase. */
if (re->draw_lock) {
re->draw_lock(re->dlh, true);
}
re->draw_lock();
if ((type->flag & RE_USE_GPU_CONTEXT) && !GPU_backend_supported()) {
/* Clear UI drawing locks. */
if (re->draw_lock) {
re->draw_lock(re->dlh, false);
}
re->draw_unlock();
BKE_report(re->reports, RPT_ERROR, "Can not initialize the GPU");
G.is_break = true;
return true;
@ -1008,9 +996,7 @@ bool RE_engine_render(Render *re, bool do_all)
if (re->result == nullptr) {
/* Clear UI drawing locks. */
if (re->draw_lock) {
re->draw_lock(re->dlh, false);
}
re->draw_unlock();
/* Free engine. */
RE_engine_free(engine);
re->engine = nullptr;
@ -1043,9 +1029,7 @@ bool RE_engine_render(Render *re, bool do_all)
engine->resolution_y = re->winy;
/* Clear UI drawing locks. */
if (re->draw_lock) {
re->draw_lock(re->dlh, false);
}
re->draw_unlock();
/* Render view layers. */
bool delay_grease_pencil = false;

View File

@ -549,18 +549,18 @@ Render *RE_NewSceneRender(const Scene *scene)
void RE_InitRenderCB(Render *re)
{
/* set default empty callbacks */
re->display_init = result_nothing;
re->display_clear = result_nothing;
re->display_update = result_rcti_nothing;
re->current_scene_update = current_scene_nothing;
re->prepare_viewlayer = prepare_viewlayer_nothing;
re->progress = float_nothing;
re->test_break = default_break;
re->display_init_cb = result_nothing;
re->display_clear_cb = result_nothing;
re->display_update_cb = result_rcti_nothing;
re->current_scene_update_cb = current_scene_nothing;
re->prepare_viewlayer_cb = prepare_viewlayer_nothing;
re->progress_cb = float_nothing;
re->test_break_cb = default_break;
if (G.background) {
re->stats_draw = stats_background;
re->stats_draw_cb = stats_background;
}
else {
re->stats_draw = stats_nothing;
re->stats_draw_cb = stats_nothing;
}
/* clear callback handles */
re->dih = re->dch = re->duh = re->sdh = re->prh = re->tbh = nullptr;
@ -879,46 +879,46 @@ void RE_InitState(Render *re,
void RE_display_init_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr))
{
re->display_init = f;
re->display_init_cb = f;
re->dih = handle;
}
void RE_display_clear_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr))
{
re->display_clear = f;
re->display_clear_cb = f;
re->dch = handle;
}
void RE_display_update_cb(Render *re,
void *handle,
void (*f)(void *handle, RenderResult *rr, rcti *rect))
{
re->display_update = f;
re->display_update_cb = f;
re->duh = handle;
}
void RE_current_scene_update_cb(Render *re, void *handle, void (*f)(void *handle, Scene *scene))
{
re->current_scene_update = f;
re->current_scene_update_cb = f;
re->suh = handle;
}
void RE_stats_draw_cb(Render *re, void *handle, void (*f)(void *handle, RenderStats *rs))
{
re->stats_draw = f;
re->stats_draw_cb = f;
re->sdh = handle;
}
void RE_progress_cb(Render *re, void *handle, void (*f)(void *handle, float))
{
re->progress = f;
re->progress_cb = f;
re->prh = handle;
}
void RE_draw_lock_cb(Render *re, void *handle, void (*f)(void *handle, bool lock))
{
re->draw_lock = f;
re->draw_lock_cb = f;
re->dlh = handle;
}
void RE_test_break_cb(Render *re, void *handle, bool (*f)(void *handle))
{
re->test_break = f;
re->test_break_cb = f;
re->tbh = handle;
}
@ -926,7 +926,7 @@ void RE_prepare_viewlayer_cb(Render *re,
void *handle,
bool (*f)(void *handle, ViewLayer *vl, Depsgraph *depsgraph))
{
re->prepare_viewlayer = f;
re->prepare_viewlayer_cb = f;
re->prepare_vl_handle = handle;
}
@ -1048,8 +1048,8 @@ static void render_result_uncrop(Render *re)
BLI_rw_mutex_unlock(&re->resultmutex);
re->display_init(re->dih, re->result);
re->display_update(re->duh, re->result, nullptr);
re->display_init(re->result);
re->display_update(re->result, nullptr);
/* restore the disprect from border */
re->disprect = orig_disprect;
@ -1078,7 +1078,7 @@ static void do_render_engine(Render *re)
/* now use renderdata and camera to set viewplane */
RE_SetCamera(re, camera);
re->current_scene_update(re->suh, re->scene);
re->current_scene_update(re->scene);
RE_engine_render(re, false);
/* when border render, check if we have to insert it in black */
@ -1112,13 +1112,13 @@ static void do_render_compositor_scene(Render *re, Scene *sce, int cfra)
resc->scene = sce;
/* copy callbacks */
resc->display_update = re->display_update;
resc->display_update_cb = re->display_update_cb;
resc->duh = re->duh;
resc->test_break = re->test_break;
resc->test_break_cb = re->test_break_cb;
resc->tbh = re->tbh;
resc->stats_draw = re->stats_draw;
resc->stats_draw_cb = re->stats_draw_cb;
resc->sdh = re->sdh;
resc->current_scene_update = re->current_scene_update;
resc->current_scene_update_cb = re->current_scene_update_cb;
resc->suh = re->suh;
do_render_engine(resc);
@ -1188,7 +1188,7 @@ static void do_render_compositor_scenes(Render *re)
if (changed_scene) {
/* If rendered another scene, switch back to the current scene with compositing nodes. */
re->current_scene_update(re->suh, re->scene);
re->current_scene_update(re->scene);
}
}
@ -1200,7 +1200,7 @@ static void render_compositor_stats(void *arg, const char *str)
RenderStats i;
memcpy(&i, &re->i, sizeof(i));
i.infostr = str;
re->stats_draw(re->sdh, &i);
re->stats_draw(&i);
}
/* Render compositor nodes, along with any scenes required for them.
@ -1242,7 +1242,7 @@ static void do_render_compositor(Render *re)
BLI_rw_mutex_unlock(&re->resultmutex);
}
if (!re->test_break(re->tbh)) {
if (!re->test_break()) {
if (ntree) {
ntreeCompositTagRender(re->pipeline_scene_eval);
@ -1254,10 +1254,10 @@ static void do_render_compositor(Render *re)
do_render_compositor_scenes(re);
}
if (!re->test_break(re->tbh)) {
if (!re->test_break()) {
ntree->runtime->stats_draw = render_compositor_stats;
ntree->runtime->test_break = re->test_break;
ntree->runtime->progress = re->progress;
ntree->runtime->test_break = re->test_break_cb;
ntree->runtime->progress = re->progress_cb;
ntree->runtime->sdh = re;
ntree->runtime->tbh = re->tbh;
ntree->runtime->prh = re->prh;
@ -1282,7 +1282,7 @@ static void do_render_compositor(Render *re)
/* Weak: the display callback wants an active render-layer pointer. */
if (re->result != nullptr) {
re->result->renlay = render_get_single_layer(re, re->result);
re->display_update(re->duh, re->result, nullptr);
re->display_update(re->result, nullptr);
}
}
@ -1420,7 +1420,7 @@ static void do_render_sequencer(Render *re)
/* would mark display buffers as invalid */
RE_SetActiveRenderView(re, rv->name);
re->display_update(re->duh, re->result, nullptr);
re->display_update(re->result, nullptr);
}
recurs_depth--;
@ -1430,10 +1430,10 @@ static void do_render_sequencer(Render *re)
/* set overall progress of sequence rendering */
if (re->r.efra != re->r.sfra) {
re->progress(re->prh, float(cfra - re->r.sfra) / (re->r.efra - re->r.sfra));
re->progress(float(cfra - re->r.sfra) / (re->r.efra - re->r.sfra));
}
else {
re->progress(re->prh, 1.0f);
re->progress(1.0f);
}
}
@ -1444,7 +1444,7 @@ static void do_render_full_pipeline(Render *re)
{
bool render_seq = false;
re->current_scene_update(re->suh, re->scene);
re->current_scene_update_cb(re->suh, re->scene);
BKE_scene_camera_switch_update(re->scene);
@ -1459,13 +1459,13 @@ static void do_render_full_pipeline(Render *re)
}
else if (RE_seq_render_active(re->scene, &re->r)) {
/* NOTE: do_render_sequencer() frees rect32 when sequencer returns float images. */
if (!re->test_break(re->tbh)) {
if (!re->test_break()) {
do_render_sequencer(re);
render_seq = true;
}
re->stats_draw(re->sdh, &re->i);
re->display_update(re->duh, re->result, nullptr);
re->stats_draw(&re->i);
re->display_update(re->result, nullptr);
}
else {
do_render_compositor(re);
@ -1473,7 +1473,7 @@ static void do_render_full_pipeline(Render *re)
re->i.lastframetime = PIL_check_seconds_timer() - re->i.starttime;
re->stats_draw(re->sdh, &re->i);
re->stats_draw(&re->i);
/* save render result stamp if needed */
if (re->result != nullptr) {
@ -1486,7 +1486,7 @@ static void do_render_full_pipeline(Render *re)
/* stamp image info here */
if ((re->r.stamp & R_STAMP_ALL) && (re->r.stamp & R_STAMP_DRAW)) {
renderresult_stampinfo(re);
re->display_update(re->duh, re->result, nullptr);
re->display_update(re->result, nullptr);
}
}
}
@ -1778,8 +1778,8 @@ static bool render_init_from_main(Render *re,
/* Init-state makes new result, have to send changed tags around. */
ntreeCompositTagRender(re->scene);
re->display_init(re->dih, re->result);
re->display_clear(re->dch, re->result);
re->display_init(re->result);
re->display_clear(re->result);
return true;
}
@ -1948,7 +1948,7 @@ void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, const bool
void RE_RenderFreestyleExternal(Render *re)
{
if (re->test_break(re->tbh)) {
if (re->test_break()) {
return;
}
@ -2380,7 +2380,7 @@ void RE_RenderAnim(Render *re,
do_render_full_pipeline(re);
totrendered++;
if (re->test_break(re->tbh) == 0) {
if (re->test_break_cb(re->tbh) == 0) {
if (!G.is_break) {
if (!do_write_image_or_movie(re, bmain, scene, mh, totvideos, nullptr)) {
G.is_break = true;

View File

@ -40,3 +40,76 @@ Render::~Render()
render_result_free(pushedresult);
}
void Render::display_init(RenderResult *render_result)
{
if (display_init_cb) {
display_init_cb(dih, render_result);
}
}
void Render::display_clear(RenderResult *render_result)
{
if (display_clear_cb) {
display_clear_cb(dch, render_result);
}
}
void Render::display_update(RenderResult *render_result, rcti *rect)
{
if (display_update_cb) {
display_update_cb(duh, render_result, rect);
}
}
void Render::current_scene_update(struct Scene *scene)
{
if (current_scene_update_cb) {
current_scene_update_cb(suh, scene);
}
}
void Render::stats_draw(RenderStats *render_stats)
{
if (stats_draw_cb) {
stats_draw_cb(sdh, render_stats);
}
}
void Render::progress(float progress)
{
if (progress_cb) {
progress_cb(prh, progress);
}
}
void Render::draw_lock()
{
if (draw_lock_cb) {
draw_lock_cb(dlh, true);
}
}
void Render::draw_unlock()
{
if (draw_lock_cb) {
draw_lock_cb(dlh, false);
}
}
bool Render::test_break()
{
if (!test_break_cb) {
return false;
}
return test_break_cb(tbh);
}
bool Render::prepare_viewlayer(struct ViewLayer *view_layer, struct Depsgraph *depsgraph)
{
if (!prepare_viewlayer_cb) {
return true;
}
return prepare_viewlayer_cb(prepare_vl_handle, view_layer, depsgraph);
}

View File

@ -49,6 +49,29 @@ struct BaseRender {
const char *view_name) = 0;
virtual void compositor_free() = 0;
virtual void display_init(RenderResult *render_result) = 0;
virtual void display_clear(RenderResult *render_result) = 0;
virtual void display_update(RenderResult *render_result, rcti *rect) = 0;
virtual void current_scene_update(struct Scene *scene) = 0;
virtual void stats_draw(RenderStats *render_stats) = 0;
virtual void progress(float progress) = 0;
virtual void draw_lock() = 0;
virtual void draw_unlock() = 0;
/* Test whether render is to be stopped: if the function returns true rendering will be stopped
* as soon as the render pipeline allows it. */
virtual bool test_break() = 0;
/**
* Executed right before the initialization of the depsgraph, in order to modify some stuff in
* the viewlayer. The modified ids must be tagged in the depsgraph.
*
* If false is returned then rendering is aborted,
*/
virtual bool prepare_viewlayer(struct ViewLayer *view_layer, struct Depsgraph *depsgraph) = 0;
/* Result of rendering */
RenderResult *result = nullptr;
@ -78,6 +101,28 @@ struct ViewRender : public BaseRender {
{
}
void compositor_free() override {}
void display_init(RenderResult * /*render_result*/) override {}
void display_clear(RenderResult * /*render_result*/) override {}
void display_update(RenderResult * /*render_result*/, rcti * /*rect*/) override {}
void current_scene_update(struct Scene * /*scene*/) override {}
void stats_draw(RenderStats * /*render_stats*/) override {}
void progress(const float /*progress*/) override {}
void draw_lock() override {}
void draw_unlock() override {}
bool test_break() override
{
return false;
}
bool prepare_viewlayer(struct ViewLayer * /*view_layer*/,
struct Depsgraph * /*depsgraph*/) override
{
return true;
}
};
/* Controls state of render, everything that's read-only during render stage */
@ -99,6 +144,21 @@ struct Render : public BaseRender {
const char *view_name) override;
void compositor_free() override;
void display_init(RenderResult *render_result) override;
void display_clear(RenderResult *render_result) override;
void display_update(RenderResult *render_result, rcti *rect) override;
void current_scene_update(struct Scene *scene) override;
void stats_draw(RenderStats *render_stats) override;
void progress(float progress) override;
void draw_lock() override;
void draw_unlock() override;
bool test_break() override;
bool prepare_viewlayer(struct ViewLayer *view_layer, struct Depsgraph *depsgraph) override;
char name[RE_MAXNAME] = "";
int slot = 0;
@ -150,31 +210,27 @@ struct Render : public BaseRender {
blender::render::RealtimeCompositor *gpu_compositor = nullptr;
std::mutex gpu_compositor_mutex;
/* callbacks */
void (*display_init)(void *handle, RenderResult *rr) = nullptr;
/* Callbacks for the corresponding base class method implementation. */
void (*display_init_cb)(void *handle, RenderResult *rr) = nullptr;
void *dih = nullptr;
void (*display_clear)(void *handle, RenderResult *rr) = nullptr;
void (*display_clear_cb)(void *handle, RenderResult *rr) = nullptr;
void *dch = nullptr;
void (*display_update)(void *handle, RenderResult *rr, rcti *rect) = nullptr;
void (*display_update_cb)(void *handle, RenderResult *rr, rcti *rect) = nullptr;
void *duh = nullptr;
void (*current_scene_update)(void *handle, struct Scene *scene) = nullptr;
void (*current_scene_update_cb)(void *handle, struct Scene *scene) = nullptr;
void *suh = nullptr;
void (*stats_draw)(void *handle, RenderStats *ri) = nullptr;
void (*stats_draw_cb)(void *handle, RenderStats *ri) = nullptr;
void *sdh = nullptr;
void (*progress)(void *handle, float i) = nullptr;
void (*progress_cb)(void *handle, float i) = nullptr;
void *prh = nullptr;
void (*draw_lock)(void *handle, bool lock) = nullptr;
void (*draw_lock_cb)(void *handle, bool lock) = nullptr;
void *dlh = nullptr;
bool (*test_break)(void *handle) = nullptr;
bool (*test_break_cb)(void *handle) = nullptr;
void *tbh = nullptr;
/**
* Executed right before the initialization of the depsgraph, in order to modify some stuff in
* the viewlayer. The modified ids must be tagged in the depsgraph.
*/
bool (*prepare_viewlayer)(void *handle, struct ViewLayer *vl, struct Depsgraph *depsgraph);
bool (*prepare_viewlayer_cb)(void *handle, struct ViewLayer *vl, struct Depsgraph *depsgraph);
void *prepare_vl_handle;
RenderStats i = {};