Fix T82607: crash cancelling Cycles render during adaptive subdivision update
Now that the Blender sync mechanism deletes nodes from the scene, we need to ensure scene update is stopped before we do this. Also add some more early out in scene geometry update to ensure we do not continue working on incomplete geometry data, though that was not the cause of this crash.
This commit is contained in:
parent
5c01ecd2bf
commit
d59fa12f2a
Notes:
blender-bot
2023-02-14 01:07:44 +01:00
Referenced by issue #82607, Cycles: Blender crash on switching between tabs Referenced by issue #82608, Crash when adding subdivision surface modifier to object while in rendered mode
|
@ -260,6 +260,8 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg
|
|||
|
||||
void BlenderSession::free_session()
|
||||
{
|
||||
session->cancel();
|
||||
|
||||
delete sync;
|
||||
delete session;
|
||||
}
|
||||
|
|
|
@ -1275,12 +1275,17 @@ void GeometryManager::device_update(Device *device,
|
|||
true_displacement_used = true;
|
||||
}
|
||||
|
||||
if (progress.get_cancel())
|
||||
if (progress.get_cancel()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (progress.get_cancel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Tessellate meshes that are using subdivision */
|
||||
if (total_tess_needed) {
|
||||
scoped_callback_timer timer([scene](double time) {
|
||||
|
@ -1317,10 +1322,15 @@ void GeometryManager::device_update(Device *device,
|
|||
|
||||
i++;
|
||||
|
||||
if (progress.get_cancel())
|
||||
if (progress.get_cancel()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (progress.get_cancel()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update images needed for true displacement. */
|
||||
|
@ -1350,8 +1360,9 @@ void GeometryManager::device_update(Device *device,
|
|||
});
|
||||
device_update_mesh(device, dscene, scene, true, progress);
|
||||
}
|
||||
if (progress.get_cancel())
|
||||
if (progress.get_cancel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
scoped_callback_timer timer([scene](double time) {
|
||||
|
@ -1360,8 +1371,9 @@ void GeometryManager::device_update(Device *device,
|
|||
}
|
||||
});
|
||||
device_update_attributes(device, dscene, scene, progress);
|
||||
if (progress.get_cancel())
|
||||
if (progress.get_cancel()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update displacement. */
|
||||
|
@ -1391,11 +1403,16 @@ void GeometryManager::device_update(Device *device,
|
|||
}
|
||||
}
|
||||
|
||||
if (progress.get_cancel())
|
||||
if (progress.get_cancel()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (progress.get_cancel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Device re-update after displacement. */
|
||||
if (displacement_done) {
|
||||
scoped_callback_timer timer([scene](double time) {
|
||||
|
@ -1407,8 +1424,9 @@ void GeometryManager::device_update(Device *device,
|
|||
device_free(device, dscene);
|
||||
|
||||
device_update_attributes(device, dscene, scene, progress);
|
||||
if (progress.get_cancel())
|
||||
if (progress.get_cancel()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -1455,8 +1473,9 @@ void GeometryManager::device_update(Device *device,
|
|||
}
|
||||
}
|
||||
|
||||
if (progress.get_cancel())
|
||||
if (progress.get_cancel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
scoped_callback_timer timer([scene](double time) {
|
||||
|
@ -1465,8 +1484,9 @@ void GeometryManager::device_update(Device *device,
|
|||
}
|
||||
});
|
||||
device_update_bvh(device, dscene, scene, progress);
|
||||
if (progress.get_cancel())
|
||||
if (progress.get_cancel()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -1477,8 +1497,9 @@ void GeometryManager::device_update(Device *device,
|
|||
}
|
||||
});
|
||||
device_update_mesh(device, dscene, scene, false, progress);
|
||||
if (progress.get_cancel())
|
||||
if (progress.get_cancel()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
need_update = false;
|
||||
|
|
|
@ -94,21 +94,7 @@ Session::Session(const SessionParams ¶ms_)
|
|||
|
||||
Session::~Session()
|
||||
{
|
||||
if (session_thread) {
|
||||
/* wait for session thread to end */
|
||||
progress.set_cancel("Exiting");
|
||||
|
||||
gpu_need_display_buffer_update = false;
|
||||
gpu_need_display_buffer_update_cond.notify_all();
|
||||
|
||||
{
|
||||
thread_scoped_lock pause_lock(pause_mutex);
|
||||
pause = false;
|
||||
}
|
||||
pause_cond.notify_all();
|
||||
|
||||
wait();
|
||||
}
|
||||
cancel();
|
||||
|
||||
if (params.write_render_cb) {
|
||||
/* Copy to display buffer and write out image if requested */
|
||||
|
@ -142,6 +128,25 @@ void Session::start()
|
|||
}
|
||||
}
|
||||
|
||||
void Session::cancel()
|
||||
{
|
||||
if (session_thread) {
|
||||
/* wait for session thread to end */
|
||||
progress.set_cancel("Exiting");
|
||||
|
||||
gpu_need_display_buffer_update = false;
|
||||
gpu_need_display_buffer_update_cond.notify_all();
|
||||
|
||||
{
|
||||
thread_scoped_lock pause_lock(pause_mutex);
|
||||
pause = false;
|
||||
}
|
||||
pause_cond.notify_all();
|
||||
|
||||
wait();
|
||||
}
|
||||
}
|
||||
|
||||
bool Session::ready_to_reset()
|
||||
{
|
||||
double dt = time_dt() - reset_time;
|
||||
|
|
|
@ -146,6 +146,7 @@ class Session {
|
|||
~Session();
|
||||
|
||||
void start();
|
||||
void cancel();
|
||||
bool draw(BufferParams ¶ms, DeviceDrawParams &draw_params);
|
||||
void wait();
|
||||
|
||||
|
|
Loading…
Reference in New Issue