Fix T45702: Editing smoke while viewport render and blender bug

Issue was caused by blender internal accessing data from DNA during rendering.

There's no simple solution to make stuff thread safe, so for now simply restart
rendering on frame update.
This commit is contained in:
Sergey Sharybin 2015-08-27 12:10:01 +02:00
parent 43dab7833a
commit 067fe2719a
Notes: blender-bot 2023-02-14 08:47:31 +01:00
Referenced by commit db2a603f6e, Depsgraph: Remove workaround for Blender Internal in viewport
Referenced by issue #45702, editing smoke while viewport render and blender bug
8 changed files with 64 additions and 6 deletions

View File

@ -147,7 +147,10 @@ void DAG_pose_sort(struct Object *ob);
/* Editors: callbacks to notify editors of datablock changes */
void DAG_editors_update_cb(void (*id_func)(struct Main *bmain, struct ID *id),
void (*scene_func)(struct Main *bmain, struct Scene *scene, int updated));
void (*scene_func)(struct Main *bmain, struct Scene *scene, int updated),
void (*scene_pre_func)(struct Main *bmain, struct Scene *scene, bool time));
void DAG_editors_update_pre(struct Main *bmain, struct Scene *scene, bool time);
/* ** Threaded update ** */

View File

@ -1349,16 +1349,32 @@ void graph_print_adj_list(DagForest *dag)
* to do their own updates based on changes... */
static void (*EditorsUpdateIDCb)(Main *bmain, ID *id) = NULL;
static void (*EditorsUpdateSceneCb)(Main *bmain, Scene *scene, int updated) = NULL;
static void (*EditorsUpdateScenePreCb)(Main *bmain, Scene *scene, bool time) = NULL;
void DAG_editors_update_cb(void (*id_func)(Main *bmain, ID *id), void (*scene_func)(Main *bmain, Scene *scene, int updated))
void DAG_editors_update_cb(void (*id_func)(Main *bmain, ID *id),
void (*scene_func)(Main *bmain, Scene *scene, int updated),
void (*scene_pre_func)(Main *bmain, Scene *scene, bool time))
{
if (DEG_depsgraph_use_legacy()) {
EditorsUpdateIDCb = id_func;
EditorsUpdateSceneCb = scene_func;
EditorsUpdateScenePreCb = scene_pre_func;
}
else {
/* New dependency graph. */
DEG_editors_set_update_cb(id_func, scene_func);
DEG_editors_set_update_cb(id_func, scene_func, scene_pre_func);
}
}
void DAG_editors_update_pre(Main *bmain, Scene *scene, bool time)
{
if (DEG_depsgraph_use_legacy()) {
if (EditorsUpdateScenePreCb != NULL) {
EditorsUpdateScenePreCb(bmain, scene, time);
}
}
else {
DEG_editors_update_pre(bmain, scene, time);
}
}

View File

@ -1890,6 +1890,8 @@ void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain,
(void) do_invisible_flush;
#endif
DAG_editors_update_pre(bmain, sce, true);
/* keep this first */
BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_PRE);
BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_PRE);

View File

@ -205,10 +205,16 @@ typedef void (*DEG_EditorUpdateIDCb)(struct Main *bmain, struct ID *id);
typedef void (*DEG_EditorUpdateSceneCb)(struct Main *bmain,
struct Scene *scene,
int updated);
typedef void (*DEG_EditorUpdateScenePreCb)(struct Main *bmain,
struct Scene *scene,
bool time);
/* Set callbacks which are being called when depsgraph changes. */
void DEG_editors_set_update_cb(DEG_EditorUpdateIDCb id_func,
DEG_EditorUpdateSceneCb scene_func);
DEG_EditorUpdateSceneCb scene_func,
DEG_EditorUpdateScenePreCb scene_pre_func);
void DEG_editors_update_pre(struct Main *bmain, struct Scene *scene, bool time);
#ifdef __cplusplus
} /* extern "C" */

View File

@ -58,6 +58,7 @@ extern "C" {
static DEG_EditorUpdateIDCb deg_editor_update_id_cb = NULL;
static DEG_EditorUpdateSceneCb deg_editor_update_scene_cb = NULL;
static DEG_EditorUpdateScenePreCb deg_editor_update_scene_pre_cb = NULL;
Depsgraph::Depsgraph()
: root_node(NULL),
@ -467,10 +468,19 @@ void DEG_graph_free(Depsgraph *graph)
/* Set callbacks which are being called when depsgraph changes. */
void DEG_editors_set_update_cb(DEG_EditorUpdateIDCb id_func,
DEG_EditorUpdateSceneCb scene_func)
DEG_EditorUpdateSceneCb scene_func,
DEG_EditorUpdateScenePreCb scene_pre_func)
{
deg_editor_update_id_cb = id_func;
deg_editor_update_scene_cb = scene_func;
deg_editor_update_scene_pre_cb = scene_pre_func;
}
void DEG_editors_update_pre(Main *bmain, Scene *scene, bool time)
{
if (deg_editor_update_scene_pre_cb != NULL) {
deg_editor_update_scene_pre_cb(bmain, scene, time);
}
}
void deg_editors_id_update(Main *bmain, ID *id)

View File

@ -49,6 +49,7 @@ void ED_render_id_flush_update(struct Main *bmain, struct ID *id);
void ED_render_engine_changed(struct Main *bmain);
void ED_render_engine_area_exit(struct Main *bmain, struct ScrArea *sa);
void ED_render_scene_update(struct Main *bmain, struct Scene *scene, int updated);
void ED_render_scene_update_pre(struct Main *bmain, struct Scene *scene, bool time);
void ED_viewport_render_kill_jobs(struct wmWindowManager *wm, struct Main *bmain, bool free_database);
struct Scene *ED_render_job_get_scene(const struct bContext *C);

View File

@ -52,6 +52,7 @@
#include "BKE_material.h"
#include "BKE_node.h"
#include "BKE_paint.h"
#include "BKE_scene.h"
#include "GPU_material.h"
#include "GPU_buffers.h"
@ -142,6 +143,23 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated)
recursive_check = false;
}
void ED_render_scene_update_pre(Main *bmain, Scene *scene, bool time)
{
/* Blender internal might access to the data which is gonna to be freed
* by the scene update functions. This applies for example to simulation
* data like smoke and fire.
*/
if (time && !BKE_scene_use_new_shading_nodes(scene)) {
bScreen *sc;
ScrArea *sa;
for (sc = bmain->screen.first; sc; sc = sc->id.next) {
for (sa = sc->areabase.first; sa; sa = sa->next) {
ED_render_engine_area_exit(bmain, sa);
}
}
}
}
void ED_render_engine_area_exit(Main *bmain, ScrArea *sa)
{
/* clear all render engines in this area */

View File

@ -159,7 +159,9 @@ void WM_init(bContext *C, int argc, const char **argv)
BKE_library_callback_free_editor_id_reference_set(WM_main_remove_editor_id_reference); /* library.c */
BKE_blender_callback_test_break_set(wm_window_testbreak); /* blender.c */
BKE_spacedata_callback_id_unref_set(ED_spacedata_id_unref); /* screen.c */
DAG_editors_update_cb(ED_render_id_flush_update, ED_render_scene_update); /* depsgraph.c */
DAG_editors_update_cb(ED_render_id_flush_update,
ED_render_scene_update,
ED_render_scene_update_pre); /* depsgraph.c */
ED_spacetypes_init(); /* editors/space_api/spacetype.c */