lineart bake w/ object keyframes + camera binds = crash #104982

Closed
opened 2023-02-20 18:56:48 +01:00 by Stephen Boddy · 20 comments

System Information
Operating system: Windows-10-10.0.19044-SP0 64 Bits
Graphics card: NVIDIA GeForce GTX 1050/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 526.98

Blender Version
Broken: version: 3.4.1, branch: blender-v3.4-release, commit date: 2022-12-19 17:00, hash: rB55485cb379f7
Worked: (newest version of Blender that worked as expected)

Short description of error
A crash (instant program exit) happens when trying to bake line art with both keyframes on object visibility and cameras bound to a frame in the timeline.

Exact steps for others to reproduce the error

  1. Open the attached blend file. Select the Line Art modifier, and click "Bake Line Art". The baking starts, gets to frame 7 (the one after the TriAllFree bound camera) and crashes.
  2. Open the attached blend file. Delete the camera binding marker on frame 6. Select the Line Art modifier, and click "Bake Line Art". The baking starts, gets to frame 7 (the one after where the TriAllFree bound camera was) and crashes.
  3. Open the attached blend file. Delete the camera binding marker on frame 6. Save the file to a new filename. Exit blender. Open the blend file with the new filename. Select the Line Art modifier, and click "Bake Line Art". The baking completes with no issue.
  4. Open the original attached blend file (not the new one without the camera bind). Delete the timeline channel on the Suzanne model that changes the render visibility. Select the Line Art modifier, and click "Bake Line Art". The baking completes with no issue.

Tested with daily builds of 3.4.1, 3.5.0 beta, and 3.6.0 alpha. Issue still present in all cases.

**System Information** Operating system: Windows-10-10.0.19044-SP0 64 Bits Graphics card: NVIDIA GeForce GTX 1050/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 526.98 **Blender Version** Broken: version: 3.4.1, branch: blender-v3.4-release, commit date: 2022-12-19 17:00, hash: `rB55485cb379f7` Worked: (newest version of Blender that worked as expected) **Short description of error** A crash (instant program exit) happens when trying to bake line art with *both* keyframes on object visibility *and* cameras bound to a frame in the timeline. **Exact steps for others to reproduce the error** 1. Open the attached blend file. Select the Line Art modifier, and click "Bake Line Art". The baking starts, gets to frame 7 (the one after the TriAllFree bound camera) and crashes. 2. Open the attached blend file. Delete the camera binding marker on frame 6. Select the Line Art modifier, and click "Bake Line Art". The baking starts, gets to frame 7 (the one after where the TriAllFree bound camera was) and crashes. 3. Open the attached blend file. Delete the camera binding marker on frame 6. Save the file to a new filename. **Exit blender**. Open the blend file with the new filename. Select the Line Art modifier, and click "Bake Line Art". The baking completes with no issue. 4. Open the original attached blend file (not the new one without the camera bind). Delete the timeline channel on the Suzanne model that changes the render visibility. Select the Line Art modifier, and click "Bake Line Art". The baking completes with no issue. Tested with daily builds of 3.4.1, 3.5.0 beta, and 3.6.0 alpha. Issue still present in all cases.
Author

Adding pre-emptively.

Adding pre-emptively.
Member

Hi, thanks for the report. Can confirm the crash.
cc @ChengduLittleA

blender.exe         :0x00007FF64F472EA0  BKE_object_eval_eval_base_flags C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\blenkernel\intern\object_update.cc:402
blender.exe         :0x00007FF64F6A0DA0  std::_Func_impl_no_alloc<`blender::deg::DepsgraphNodeBuilder::build_object_flags'::`2'::<lambda_1>, C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\functional:834
blender.exe         :0x00007FF64F6981C0  blender::deg::`anonymous namespace'::evaluate_node C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:108
blender.exe         :0x00007FF64F697FF0  blender::deg::`anonymous namespace'::deg_task_run_func C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:121
blender.exe         :0x00007FF650310530  BLI_task_pool_push C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\blenlib\intern\task_pool.cc:471
blender.exe         :0x00007FF64F697CA0  blender::FunctionRef<void __cdecl(blender::deg::OperationNode *)>::callback_fn<`blender::deg::`anon C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\blenlib\BLI_function_ref.hh:95
blender.exe         :0x00007FF64F698260  blender::deg::`anonymous namespace'::schedule_children C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:298
blender.exe         :0x00007FF64F698260  blender::deg::`anonymous namespace'::schedule_children C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:305
blender.exe         :0x00007FF64F698260  blender::deg::`anonymous namespace'::schedule_children C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:305
blender.exe         :0x00007FF64F697FF0  blender::deg::`anonymous namespace'::deg_task_run_func C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:124
blender.exe         :0x00007FF650310530  BLI_task_pool_push C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\blenlib\intern\task_pool.cc:471
blender.exe         :0x00007FF64F697CA0  blender::FunctionRef<void __cdecl(blender::deg::OperationNode *)>::callback_fn<`blender::deg::`anon C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\blenlib\BLI_function_ref.hh:95
blender.exe         :0x00007FF64F698260  blender::deg::`anonymous namespace'::schedule_children C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:298
blender.exe         :0x00007FF64F698260  blender::deg::`anonymous namespace'::schedule_children C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:305
blender.exe         :0x00007FF64F698400  blender::deg::`anonymous namespace'::schedule_graph C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:290
blender.exe         :0x00007FF64F698060  blender::deg::`anonymous namespace'::evaluate_graph_threaded_stage C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:323
blender.exe         :0x00007FF64F697CF0  blender::deg::deg_evaluate_on_refresh C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:446
blender.exe         :0x00007FF64F2CB470  BKE_scene_graph_update_for_newframe C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\blenkernel\intern\scene.cc:2814
blender.exe         :0x00007FF64FF6AE00  lineart_gpencil_bake_startjob C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\gpencil_modifiers\intern\lineart\lineart_ops.c:243
blender.exe         :0x00007FF64F216070  do_job_thread C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\windowmanager\intern\wm_jobs.c:385
blender.exe         :0x00007FF65042A6E0  _ptw32_threadStart
ucrtbase.dll        :0x00007FFFD9C56BB0  recalloc
KERNEL32.DLL        :0x00007FFFDB8A5590  BaseThreadInitThunk
ntdll.dll           :0x00007FFFDC084830  RtlUserThreadStart```
Hi, thanks for the report. Can confirm the crash. cc @ChengduLittleA ```Stack trace: blender.exe :0x00007FF64F472EA0 BKE_object_eval_eval_base_flags C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\blenkernel\intern\object_update.cc:402 blender.exe :0x00007FF64F6A0DA0 std::_Func_impl_no_alloc<`blender::deg::DepsgraphNodeBuilder::build_object_flags'::`2'::<lambda_1>, C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\functional:834 blender.exe :0x00007FF64F6981C0 blender::deg::`anonymous namespace'::evaluate_node C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:108 blender.exe :0x00007FF64F697FF0 blender::deg::`anonymous namespace'::deg_task_run_func C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:121 blender.exe :0x00007FF650310530 BLI_task_pool_push C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\blenlib\intern\task_pool.cc:471 blender.exe :0x00007FF64F697CA0 blender::FunctionRef<void __cdecl(blender::deg::OperationNode *)>::callback_fn<`blender::deg::`anon C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\blenlib\BLI_function_ref.hh:95 blender.exe :0x00007FF64F698260 blender::deg::`anonymous namespace'::schedule_children C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:298 blender.exe :0x00007FF64F698260 blender::deg::`anonymous namespace'::schedule_children C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:305 blender.exe :0x00007FF64F698260 blender::deg::`anonymous namespace'::schedule_children C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:305 blender.exe :0x00007FF64F697FF0 blender::deg::`anonymous namespace'::deg_task_run_func C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:124 blender.exe :0x00007FF650310530 BLI_task_pool_push C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\blenlib\intern\task_pool.cc:471 blender.exe :0x00007FF64F697CA0 blender::FunctionRef<void __cdecl(blender::deg::OperationNode *)>::callback_fn<`blender::deg::`anon C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\blenlib\BLI_function_ref.hh:95 blender.exe :0x00007FF64F698260 blender::deg::`anonymous namespace'::schedule_children C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:298 blender.exe :0x00007FF64F698260 blender::deg::`anonymous namespace'::schedule_children C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:305 blender.exe :0x00007FF64F698400 blender::deg::`anonymous namespace'::schedule_graph C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:290 blender.exe :0x00007FF64F698060 blender::deg::`anonymous namespace'::evaluate_graph_threaded_stage C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:323 blender.exe :0x00007FF64F697CF0 blender::deg::deg_evaluate_on_refresh C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\depsgraph\intern\eval\deg_eval.cc:446 blender.exe :0x00007FF64F2CB470 BKE_scene_graph_update_for_newframe C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\blenkernel\intern\scene.cc:2814 blender.exe :0x00007FF64FF6AE00 lineart_gpencil_bake_startjob C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\gpencil_modifiers\intern\lineart\lineart_ops.c:243 blender.exe :0x00007FF64F216070 do_job_thread C:\Users\prati\OneDrive\Desktop\BlenderOSP\blender\source\blender\windowmanager\intern\wm_jobs.c:385 blender.exe :0x00007FF65042A6E0 _ptw32_threadStart ucrtbase.dll :0x00007FFFD9C56BB0 recalloc KERNEL32.DLL :0x00007FFFDB8A5590 BaseThreadInitThunk ntdll.dll :0x00007FFFDC084830 RtlUserThreadStart```
Pratik Borhade added the
Status
Confirmed
label 2023-02-21 06:18:54 +01:00
Member

Seems pretty nasty... I shall take a look

Seems pretty nasty... I shall take a look
Philipp Oeser added the
Module
Grease Pencil
label 2023-03-17 14:40:48 +01:00
Author

Retested with latest 4.0.1, and 4.1 Alpha. Issue is still present, and still causes a hard crash.

Edit: I should also mention these two tests were on Linux (Ubuntu 22.04 LTS) so not a platform dependent issue either.

Retested with latest 4.0.1, and 4.1 Alpha. Issue is still present, and still causes a hard crash. Edit: I should also mention these two tests were on Linux (Ubuntu 22.04 LTS) so not a platform dependent issue either.
Author

I managed to build a debug build of main, and identified the specific problem a bit closer.
BLI_assert failed: source/blender/blenkernel/intern/object_update.cc:407, BKE_object_eval_eval_base_flags(), at 'view_layer->object_bases_array != nullptr'
So it looks like the core dump happens 3 lines later on 410 when it tries to do:
Base *base = view_layer->object_bases_array[base_index];
Because it is trying to grab an array item by index from object_bases_array when object_bases_array is a nullptr.
I'm so far out of my depth here it is not even funny. I know this is going to look like a really dumb thing to do, but I added:
if (view_layer->object_bases_array == nullptr) { return; }
before the BLI_assert statement out of curiosity, and surprisingly the bake process completed seemingly OK. Probably broke numerous things elsewhere however.

I managed to build a debug build of main, and identified the specific problem a bit closer. `BLI_assert failed: source/blender/blenkernel/intern/object_update.cc:407, BKE_object_eval_eval_base_flags(), at 'view_layer->object_bases_array != nullptr'` So it looks like the core dump happens 3 lines later on 410 when it tries to do: `Base *base = view_layer->object_bases_array[base_index];` Because it is trying to grab an array item by index from object_bases_array when object_bases_array is a nullptr. I'm so far out of my depth here it is not even funny. I know this is going to look like a really dumb thing to do, but I added: `if (view_layer->object_bases_array == nullptr) { return; }` before the BLI_assert statement out of curiosity, and surprisingly the bake process completed seemingly OK. Probably broke numerous things elsewhere however.
Member

This does seem to be a evaluation order issue. By adding a null check it will probably work fine but possibly causing some issue downstream in the depsgraph. This is likely caused by grease pencil updating while itself is depending on the scene (or the objects in it etc, and itself is part of the scene).

I couldn't check it right now, but I'll make sure to so some investigation.

This does seem to be a evaluation order issue. By adding a null check it will probably work fine but possibly causing some issue downstream in the depsgraph. This is likely caused by grease pencil updating while itself is depending on the scene (or the objects in it etc, and itself is part of the scene). I couldn't check it right now, but I'll make sure to so some investigation.
Author

I don't mean to be a nag, but based on https://wiki.blender.org/wiki/Process/Bug_Reports/Triaging_Playbook shouldn't the priority label of the issue be "High"? It would be really nice to have this fixed for the 4.1 release. 😃

I don't mean to be a nag, but based on https://wiki.blender.org/wiki/Process/Bug_Reports/Triaging_Playbook shouldn't the priority label of the issue be "High"? It would be _really_ nice to have this fixed for the 4.1 release. 😃
Member

@Stephen-Boddy hi, priority remains "normal" unless it is a regression. AFAICS, crash persists in older releases as well (3.0 for example)

Line art is more of Yiming's turf, I don't have much idea about the fix 🙂

@Stephen-Boddy hi, priority remains "normal" unless it is a regression. AFAICS, crash persists in older releases as well (3.0 for example) Line art is more of Yiming's turf, I don't have much idea about the fix 🙂
Author

Sorry to disagree, Pratik, but the page doesn't say that. Quote:

Priority Clarifications

  • High - Most crashes and recent regressions.

Emphasis mine. It does not say:

  • High - Most crashes that are recent regressions.

I don't think I've ever seen a bug tracker (professional or other opensource) where a full crash of the application has a normal priority after triage. They either have a dedicated priority, or are marked as the highest level available. Blender is a wonderful project, and I have nothing but respect for everyone that contributes, but this is a 100% reproducible crash that, after being confirmed, has now gone out in three releases, including an LTS. From the outside it seems like it is too easy for a crash that is given a normal priority to disappear into the huge volume of other normal priority issues.

Sorry to disagree, Pratik, but the page doesn't say that. Quote: > **Priority Clarifications** > - High - Most crashes *and* recent regressions. Emphasis mine. It does not say: > - High - Most crashes *that are* recent regressions. I don't think I've ever seen a bug tracker (professional or other opensource) where a full crash of the application has a normal priority after triage. They either have a dedicated priority, or are marked as the highest level available. Blender is a wonderful project, and I have nothing but respect for everyone that contributes, but this is a 100% reproducible crash that, _after being confirmed_, has now gone out in *three* releases, including an _LTS_. From the outside it seems like it is too easy for a crash that is given a normal priority to disappear into the huge volume of other normal priority issues.
Blender Bot added
Status
Archived
and removed
Status
Confirmed
labels 2023-12-07 17:28:54 +01:00
Author

What the heck!!! I didn't close this issue, I was commenting!

What the heck!!! I didn't close this issue, I was commenting!
Blender Bot added
Status
Needs Triage
and removed
Status
Archived
labels 2023-12-07 17:31:37 +01:00
Author

Ugh! Please re-add the Status: Confirmed. I think I must have clicked the nice high contrast "Comment and Close" instead of the bad UI low-contrast "Comment". My bad. ☹️

Ugh! Please re-add the Status: Confirmed. I think I must have clicked the nice high contrast "Comment and Close" instead of the bad UI low-contrast "Comment". My bad. ☹️
Pratik Borhade added
Status
Confirmed
and removed
Status
Needs Triage
labels 2023-12-11 04:51:18 +01:00
Author

I've been gdb'ing this trying to understand what/why this is happening.

It is important to note that this is triggered when both a bound camera and object keyframes are used, when using the lineart. Neither one on it's own cause the crash, as it is the interaction between the two that is causing the problem.

As part of the lineart_gpencil_bake_startjob, BKE_scene_graph_update_for_newframe is called on each frame in turn.
When a camera is bound to a frame, and line art baking is started the following is observed:
Up until the frame where the camera changes (frame 6 in my example) the view_layer->object_bases_array is not changed.
In depsgraph_ensure_view_layer the test:

(deg_copy_on_write_is_expanded(&scene_cow->id) &&
      (scene_cow->id.recalc & ID_RECALC_COPY_ON_WRITE) == 0)

is true, and just returns. I don't understand the why behind this test, so I may dig a bit to see if I can understand this further.

When the camera changes on frame 6, it causes this test to evaluate false on the following frame 7, and instead the depsgraph_ensure_view_layer code calls deg_update_copy_on_write_datablock which ends up at BKE_view_layer_free_ex calling

MEM_SAFE_FREE(view_layer->object_bases_array)

This sets view_layer->object_bases_array to be a nullptr. Notably it calls this on every frame after, so it keeps resetting this value on every following frame.

Only if we also have object keyframes does this matter, because then BKE_object_eval_eval_base_flags is called which requires view_layer->object_bases_array to not be a nullptr.

My previous dumb hack to fix this was to just return from BKE_object_eval_eval_base_flags if view_layer->object_bases_array == nullptr. I came up with another "fix" that is more useful, by calling BKE_layer_eval_view_layer_indexed(depsgraph, scene, view_layer_index) instead, populating view_layer->object_bases_array with valid data. This works in as much as the rest of BKE_object_eval_eval_base_flags completes without crash/error.

The only caveat: Before frame 7 the address of view_layer->object_bases_array is constant across frames. Because deg_update_copy_on_write_datablock keeps resetting view_layer->object_bases_array to be a nullptr, the address of view_layer->object_bases_array changes every following frame by the call to BKE_layer_eval_view_layer_indexed. i.e. This is dumb and not optimal; cached vs. uncached? Ideally the BKE_layer_eval_view_layer_indexed would only be called once after the camera changes, but exactly where this should happen is not something my limited skills can figure out. Or maybe some other function needs to be called to prevent the depsgraph_ensure_view_layer test from evaluating false.

Some output from my investigative cerr lines:

Processing frame 0x1
depsgraph_ensure_view_layer test true, returning.
BEFORE: object_bases_array check...
                     scene frame: 1
  view_layer->object_bases_array: 0x7f39a524f388
Processing frame 0x2
depsgraph_ensure_view_layer test true, returning.
BEFORE: object_bases_array check...
                     scene frame: 2
  view_layer->object_bases_array: 0x7f39a524f388
Processing frame 0x3
depsgraph_ensure_view_layer test true, returning.
BEFORE: object_bases_array check...
                     scene frame: 3
  view_layer->object_bases_array: 0x7f39a524f388
Processing frame 0x4
depsgraph_ensure_view_layer test true, returning.
BEFORE: object_bases_array check...
                     scene frame: 4
  view_layer->object_bases_array: 0x7f39a524f388
Processing frame 0x5
depsgraph_ensure_view_layer test true, returning.
BEFORE: object_bases_array check...
                     scene frame: 5
  view_layer->object_bases_array: 0x7f39a524f388
Processing frame 0x6
depsgraph_ensure_view_layer test true, returning.
BEFORE: object_bases_array check...
                     scene frame: 6
  view_layer->object_bases_array: 0x7f39a524f388
Processing frame 0x7
depsgraph_ensure_view_layer test false, will call deg_update_copy_on_write_datablock
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
BEFORE: object_bases_array check...
                     scene frame: 7
  view_layer->object_bases_array: 0
MSF called in layer_eval_view_layer
AFTER: BKE_layer_eval_view_layer_indexed called...
                     scene frame: 7
  view_layer->object_bases_array: 0x7f39a662ee08
Processing frame 0x8
depsgraph_ensure_view_layer test false, will call deg_update_copy_on_write_datablock
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
BEFORE: object_bases_array check...
                     scene frame: 8
  view_layer->object_bases_array: 0
MSF called in layer_eval_view_layer
AFTER: BKE_layer_eval_view_layer_indexed called...
                     scene frame: 8
  view_layer->object_bases_array: 0x7f39a662eee8
Processing frame 0x9
depsgraph_ensure_view_layer test false, will call deg_update_copy_on_write_datablock
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
BEFORE: object_bases_array check...
                     scene frame: 9
  view_layer->object_bases_array: 0
MSF called in layer_eval_view_layer
AFTER: BKE_layer_eval_view_layer_indexed called...
                     scene frame: 9
  view_layer->object_bases_array: 0x7f39a4c7a008
Processing frame 0xa
depsgraph_ensure_view_layer test false, will call deg_update_copy_on_write_datablock
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
BEFORE: object_bases_array check...
                     scene frame: 10
  view_layer->object_bases_array: 0
MSF called in layer_eval_view_layer
AFTER: BKE_layer_eval_view_layer_indexed called...
                     scene frame: 10
  view_layer->object_bases_array: 0x7f39a7e53628
Processing frame 0xb
depsgraph_ensure_view_layer test false, will call deg_update_copy_on_write_datablock
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
BEFORE: object_bases_array check...
                     scene frame: 11
  view_layer->object_bases_array: 0
MSF called in layer_eval_view_layer
AFTER: BKE_layer_eval_view_layer_indexed called...
                     scene frame: 11
  view_layer->object_bases_array: 0x7f39a662efc8
Processing frame 0xc
depsgraph_ensure_view_layer test false, will call deg_update_copy_on_write_datablock
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
BEFORE: object_bases_array check...
                     scene frame: 12
  view_layer->object_bases_array: 0
MSF called in layer_eval_view_layer
AFTER: BKE_layer_eval_view_layer_indexed called...
                     scene frame: 12
  view_layer->object_bases_array: 0x7f39a7e53468
depsgraph_ensure_view_layer test false, will call deg_update_copy_on_write_datablock
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
MSF called in BKE_view_layer_free_ex
BEFORE: object_bases_array check...
                     scene frame: 1
  view_layer->object_bases_array: 0
MSF called in layer_eval_view_layer
AFTER: BKE_layer_eval_view_layer_indexed called...
                     scene frame: 1
  view_layer->object_bases_array: 0x7f39a4c7a0e8
depsgraph_ensure_view_layer test true, returning.
BEFORE: object_bases_array check...
                     scene frame: 1
  view_layer->object_bases_array: 0x7f39a4c7a0e8
I've been gdb'ing this trying to understand what/why this is happening. It is important to note that this is triggered when *both* a bound camera and object keyframes are used, when using the lineart. Neither one on it's own cause the crash, as it is the interaction between the two that is causing the problem. As part of the `lineart_gpencil_bake_startjob`, `BKE_scene_graph_update_for_newframe` is called on each frame in turn. When a camera is bound to a frame, and line art baking is started the following is observed: Up until the frame where the camera changes (frame 6 in my example) the `view_layer->object_bases_array` is not changed. In `depsgraph_ensure_view_layer` the test: ```Cpp (deg_copy_on_write_is_expanded(&scene_cow->id) && (scene_cow->id.recalc & ID_RECALC_COPY_ON_WRITE) == 0) ``` is `true`, and just returns. I don't understand the *why* behind this test, so I may dig a bit to see if I can understand this further. When the camera changes on frame 6, it causes this test to evaluate `false` on the following frame 7, and instead the `depsgraph_ensure_view_layer` code calls `deg_update_copy_on_write_datablock` which ends up at `BKE_view_layer_free_ex` calling ```Cpp MEM_SAFE_FREE(view_layer->object_bases_array) ``` This sets `view_layer->object_bases_array` to be a `nullptr`. Notably it calls this on every frame after, so it keeps resetting this value on every following frame. Only if we *also* have object keyframes does this matter, because then `BKE_object_eval_eval_base_flags` is called which *requires* `view_layer->object_bases_array` to not be a `nullptr`. My previous dumb hack to fix this was to just return from `BKE_object_eval_eval_base_flags` if `view_layer->object_bases_array == nullptr`. I came up with another "fix" that is more useful, by calling `BKE_layer_eval_view_layer_indexed(depsgraph, scene, view_layer_index)` instead, populating `view_layer->object_bases_array` with valid data. This works in as much as the rest of `BKE_object_eval_eval_base_flags` completes without crash/error. The only caveat: Before frame 7 the address of `view_layer->object_bases_array` is constant across frames. Because `deg_update_copy_on_write_datablock` keeps resetting `view_layer->object_bases_array` to be a `nullptr`, the address of `view_layer->object_bases_array` changes every following frame by the call to `BKE_layer_eval_view_layer_indexed`. i.e. This is dumb and not optimal; cached vs. uncached? Ideally the `BKE_layer_eval_view_layer_indexed` would only be called once after the camera changes, but exactly where this should happen is not something my limited skills can figure out. Or maybe some other function needs to be called to prevent the `depsgraph_ensure_view_layer` test from evaluating `false`. Some output from my investigative cerr lines: ``` Processing frame 0x1 depsgraph_ensure_view_layer test true, returning. BEFORE: object_bases_array check... scene frame: 1 view_layer->object_bases_array: 0x7f39a524f388 Processing frame 0x2 depsgraph_ensure_view_layer test true, returning. BEFORE: object_bases_array check... scene frame: 2 view_layer->object_bases_array: 0x7f39a524f388 Processing frame 0x3 depsgraph_ensure_view_layer test true, returning. BEFORE: object_bases_array check... scene frame: 3 view_layer->object_bases_array: 0x7f39a524f388 Processing frame 0x4 depsgraph_ensure_view_layer test true, returning. BEFORE: object_bases_array check... scene frame: 4 view_layer->object_bases_array: 0x7f39a524f388 Processing frame 0x5 depsgraph_ensure_view_layer test true, returning. BEFORE: object_bases_array check... scene frame: 5 view_layer->object_bases_array: 0x7f39a524f388 Processing frame 0x6 depsgraph_ensure_view_layer test true, returning. BEFORE: object_bases_array check... scene frame: 6 view_layer->object_bases_array: 0x7f39a524f388 Processing frame 0x7 depsgraph_ensure_view_layer test false, will call deg_update_copy_on_write_datablock MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex BEFORE: object_bases_array check... scene frame: 7 view_layer->object_bases_array: 0 MSF called in layer_eval_view_layer AFTER: BKE_layer_eval_view_layer_indexed called... scene frame: 7 view_layer->object_bases_array: 0x7f39a662ee08 Processing frame 0x8 depsgraph_ensure_view_layer test false, will call deg_update_copy_on_write_datablock MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex BEFORE: object_bases_array check... scene frame: 8 view_layer->object_bases_array: 0 MSF called in layer_eval_view_layer AFTER: BKE_layer_eval_view_layer_indexed called... scene frame: 8 view_layer->object_bases_array: 0x7f39a662eee8 Processing frame 0x9 depsgraph_ensure_view_layer test false, will call deg_update_copy_on_write_datablock MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex BEFORE: object_bases_array check... scene frame: 9 view_layer->object_bases_array: 0 MSF called in layer_eval_view_layer AFTER: BKE_layer_eval_view_layer_indexed called... scene frame: 9 view_layer->object_bases_array: 0x7f39a4c7a008 Processing frame 0xa depsgraph_ensure_view_layer test false, will call deg_update_copy_on_write_datablock MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex BEFORE: object_bases_array check... scene frame: 10 view_layer->object_bases_array: 0 MSF called in layer_eval_view_layer AFTER: BKE_layer_eval_view_layer_indexed called... scene frame: 10 view_layer->object_bases_array: 0x7f39a7e53628 Processing frame 0xb depsgraph_ensure_view_layer test false, will call deg_update_copy_on_write_datablock MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex BEFORE: object_bases_array check... scene frame: 11 view_layer->object_bases_array: 0 MSF called in layer_eval_view_layer AFTER: BKE_layer_eval_view_layer_indexed called... scene frame: 11 view_layer->object_bases_array: 0x7f39a662efc8 Processing frame 0xc depsgraph_ensure_view_layer test false, will call deg_update_copy_on_write_datablock MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex BEFORE: object_bases_array check... scene frame: 12 view_layer->object_bases_array: 0 MSF called in layer_eval_view_layer AFTER: BKE_layer_eval_view_layer_indexed called... scene frame: 12 view_layer->object_bases_array: 0x7f39a7e53468 depsgraph_ensure_view_layer test false, will call deg_update_copy_on_write_datablock MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex MSF called in BKE_view_layer_free_ex BEFORE: object_bases_array check... scene frame: 1 view_layer->object_bases_array: 0 MSF called in layer_eval_view_layer AFTER: BKE_layer_eval_view_layer_indexed called... scene frame: 1 view_layer->object_bases_array: 0x7f39a4c7a0e8 depsgraph_ensure_view_layer test true, returning. BEFORE: object_bases_array check... scene frame: 1 view_layer->object_bases_array: 0x7f39a4c7a0e8 ```
Author

So the id.recalc the depsgraph_ensure_view_layer expression relies on is being changed by BKE_scene_camera_switch_update, called from MOD_lineart_compute_feature_lines.
The BKE_scene_camera_switch_update happens after the depsgraph_ensure_view_layer, hence why the crash doesn't happen until frame 7, instead of frame 6 where the camera is actually switched.
I'm afraid I'm straining my limited understanding at this point, so I'm reliant on someone with a better understanding taking this forward to a fix.

So the id.recalc the `depsgraph_ensure_view_layer` expression relies on is being changed by `BKE_scene_camera_switch_update`, called from `MOD_lineart_compute_feature_lines`. The `BKE_scene_camera_switch_update` happens *after* the `depsgraph_ensure_view_layer`, hence why the crash doesn't happen until frame 7, instead of frame 6 where the camera is actually switched. I'm afraid I'm straining my limited understanding at this point, so I'm reliant on someone with a better understanding taking this forward to a fix.
Author

So I've been digging away (yes, I have a problem), and I have two "fixes". I don't have the deep insight to understand if these are good, bad, or ugly. Maybe there are better options.

Option 1: source/blender/blenkernel/intern/object_update.cc, BKE_object_eval_eval_base_flags
Add the following before the BLI_assert:

  if (view_layer->object_bases_array == nullptr) {
    BKE_layer_eval_view_layer_indexed(depsgraph, scene, view_layer_index);
  }

Feels a bit like a sticking plaster solution, but it works for me and feels "lighter".

Option 2: source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_ops.cc, lineart_gpencil_bake_startjob
Add the following after the BKE_scene_graph_update_for_newframe(bj->dg); line:

    DEG_graph_build_from_view_layer(bj->dg);

Also works for me, but this feels like using a sledgehammer to crack a nut. It does this build on every frame indiscriminately when baking, and this might be too much overhead.

Additionally there is something which confuses me about MOD_lineart_compute_feature_lines in source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_cpu.cc and it's use of BKE_scene_camera_switch_update in source/blender/blenkernel/intern/scene.cc. In BKE_scene_camera_switch_update the code finds the right camera for the current frame, and sets the scene->camera to this found camera if they don't match. This sets the ID_RECALC_COPY_ON_WRITE flag and frees the view_layer->object_bases_array. Yet on the next frame in the next call of MOD_lineart_compute_feature_lines it appears that scene->camera reverts to the original camera of presumably frame 1. It may be that this is intentional, but it causes any frame where the camera doesn't match the original camera to set the ID_RECALC_COPY_ON_WRITE flag and free view_layer->object_bases_array. I would have expected this to only happen when the camera changes from the previous frame.

So I've been digging away (yes, I have a problem), and I have two "fixes". I don't have the deep insight to understand if these are good, bad, or ugly. Maybe there are better options. Option 1: `source/blender/blenkernel/intern/object_update.cc`, `BKE_object_eval_eval_base_flags` Add the following before the `BLI_assert`: ``` if (view_layer->object_bases_array == nullptr) { BKE_layer_eval_view_layer_indexed(depsgraph, scene, view_layer_index); } ``` Feels a bit like a sticking plaster solution, but it works for me and feels "lighter". Option 2: `source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_ops.cc`, `lineart_gpencil_bake_startjob` Add the following after the `BKE_scene_graph_update_for_newframe(bj->dg);` line: ``` DEG_graph_build_from_view_layer(bj->dg); ``` Also works for me, but this feels like using a sledgehammer to crack a nut. It does this build on every frame indiscriminately when baking, and this might be too much overhead. Additionally there is something which confuses me about `MOD_lineart_compute_feature_lines` in `source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_cpu.cc` and it's use of `BKE_scene_camera_switch_update` in `source/blender/blenkernel/intern/scene.cc`. In `BKE_scene_camera_switch_update` the code finds the right camera for the current frame, and sets the `scene->camera` to this found camera if they don't match. This sets the `ID_RECALC_COPY_ON_WRITE` flag and frees the `view_layer->object_bases_array`. Yet on the next frame in the next call of `MOD_lineart_compute_feature_lines` it appears that `scene->camera` reverts to the original camera of presumably frame 1. It may be that this is intentional, but it causes any frame where the camera doesn't match the original camera to set the `ID_RECALC_COPY_ON_WRITE` flag and free `view_layer->object_bases_array`. I would have expected this to only happen when the camera changes from the previous frame.
Author

Diff files of the fix options for convenience.

Diff files of the fix options for convenience.
Member

Hi, thanks for the investigation. First fix is wrong though.
This assert will be useless then: BLI_assert(view_layer->object_bases_array != nullptr); in BKE_object_eval_eval_base_flags

Not sure about the second fix
@ChengduLittleA , can you check please? :)
object_bases_array is nullptr and crash/assert caused due to this. My knowledge in depsgraph is very less.

Hi, thanks for the investigation. First fix is wrong though. This assert will be useless then: `BLI_assert(view_layer->object_bases_array != nullptr);` in `BKE_object_eval_eval_base_flags` Not sure about the second fix @ChengduLittleA , can you check please? :) `object_bases_array` is nullptr and crash/assert caused due to this. My knowledge in depsgraph is very less.
Member

Hi thanks! Will check.

Hi thanks! Will check.
Member

DEG_graph_build_from_view_layer(bj->dg);

Also works for me, but this feels like using a sledgehammer to crack a nut. It does this build on every frame indiscriminately when baking, and this might be too much overhead.

Yeah this is kind of the problem we have when line art still being a modifier. It's technically still in a depsgraph evaluation, which means you can't guarantee line art gets fully evaluated stuff. Current implementation has been a hack which will be improved in a re-design (for it to be node-based).

It feels to me that the 2nd solution you proposed is a better idea since the hack is restricted in line art code bases and won't affect common utilities. I'll open a PR for you to test if the performance significantly worsened in your cases.

Yet on the next frame in the next call of MOD_lineart_compute_feature_lines it appears that scene->camera reverts to the original camera of presumably frame 1

scene->camera will always be the active camera object that's set in the scene property. The tag-based camera switch acts on top of that property so when there's a new evaluation cycle, the property would revert back.

> ```DEG_graph_build_from_view_layer(bj->dg);``` > > Also works for me, but this feels like using a sledgehammer to crack a nut. It does this build on every frame indiscriminately when baking, and this might be too much overhead. Yeah this is kind of the problem we have when line art still being a modifier. It's technically still in _a_ depsgraph evaluation, which means you can't guarantee line art gets fully evaluated stuff. Current implementation has been a hack which will be improved in a re-design (for it to be node-based). It feels to me that the 2nd solution you proposed is a better idea since the hack is restricted in line art code bases and won't affect common utilities. I'll open a PR for you to test if the performance significantly worsened in your cases. > Yet on the next frame in the next call of `MOD_lineart_compute_feature_lines` it appears that `scene->camera` reverts to the original camera of presumably frame 1 `scene->camera` will always be the active camera object that's set in the scene property. The tag-based camera switch acts on top of that property so when there's a new evaluation cycle, the property would revert back.
Author

I've already built and tested this as correctly working for my usecase. I'll retest with my original heavier file but frankly, even if it is slower, I'll take slow success over a quick crash. It's not like I have a pre-patch benchmark to compare performance against. I can't judge if others will be OK with the extra overhead when baking, as I'm not a "normal" user of GP. I don't have typical files or workflow to test if this makes GP significantly worse for "normal" GP users. I don't even really understand how much internal work the depsgraph evaluation does.

On the scene->camera thing. It is interesting then that when rendering the scene->camera does not appear to revert to the one set in the scene. (I put some debug lines in the camera switch code.) It's off-topic though, and once this fix is in, it is irrelevant from an optimizing/overhead point of view.

Lastly, thanks so much for getting to this before the 4.1 release.

I've already built and tested this as correctly working for _my_ usecase. I'll retest with my original heavier file but frankly, even if it _is_ slower, I'll take slow success over a quick crash. It's not like I have a pre-patch benchmark to compare performance against. I can't judge if others will be OK with the extra overhead when baking, as I'm not a "normal" user of GP. I don't have typical files or workflow to test if this makes GP significantly worse for "normal" GP users. I don't even really understand how much internal work the depsgraph evaluation does. On the scene->camera thing. It is interesting then that when _rendering_ the scene->camera does not appear to revert to the one set in the scene. (I put some debug lines in the camera switch code.) It's off-topic though, and once this fix is in, it is irrelevant from an optimizing/overhead point of view. Lastly, thanks so much for getting to this before the 4.1 release.
Author

Restested with my full scene. It is totally acceptable performance wise for me.

Restested with my full scene. It is totally acceptable performance wise for me.
Blender Bot added
Status
Resolved
and removed
Status
Confirmed
labels 2024-01-25 04:33:50 +01:00
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#104982
No description provided.