When an operator, file loading or the dependency graph take a long time, Blender currently just hangs and will appear as if it’s crashing even if it isn’t going to. This looks bad and is not helpful to the user in any way.
Ideally we should make Blender’s UI should always interactive to some degree by moving the computations to a separate worker thread. However, making our existing drawing code work while operators are modifying data or the depsgraph is not fully evaluated seems impractical currently.
This document proposes an alternative approach that is more useful than not doing anything about it and should be more straightforward to implement.
Proposal
The proposal is to have a progress dialog like in the following video. Note the UI is obviously very work-in-progress but functionality wise it is working already (slightly adapted from this PR).
This dialog should automatically pop up after Blender is blocked for a couple of seconds. The exact time needs to be chosen so that it’s not too short that it pops up unnecessarily and not too long so that Blender does not appear like it’s crashing.
Information in Dialog
The dialog itself can contain some useful information like:
- Processing time: Showing the time the current operation is running already makes it obvious that Blender is not yet crashed. Also if people build operators or node groups which take a long but consistent amount of time, this is almost like a progress bar. While Blender does not know how long the operation will take, the user might know.
- Status message: We could show status messages like
Evaluating: <object name>, <modifier name>
. - RAM and CPU usage: This can help the user to make an educated guess whether they should attempt to kill the process before it e.g. uses up all RAM slowing the entire system down. Not sure if we can easily access this information on all platforms, but it would be good to include on the platforms where we can access this info from the OS.
Recovery
Limited forms of interactivity can be supported in the dialog as well. Buttons and shortcuts can work to some degree. It’s not entirely clear if we can reuse much of our existing ui code for this though.
A “Close Blender” button would be especially useful. It essentially kills Blender when there is no hope that Blender will finish the computation, either because it would run out of memory or because it would take an eternity.
For extra usefulness, we could also attempt to perform an undo step and then save a recovery file. This might not work in all cases reliably, especially if the blocking operation is modifying DNA data. However, it probably succeeds in a large number of cases and avoids losing work. The undo step is necessary because otherwise one would usually have the same blocking operation when attempting to open the recovery file again. I’ve tested this recovery mechanism before and it appears to be working surprisingly well in many cases.
It’s probably a bit out of scope for the initial implementation, but ideally we’d also have a “Cancel” button that attempts to stop the current operation. I say it’s out of scope, because cancelling arbitrary computations is very hard. Also it’s not obvious what should happen when cancelling a depsgraph evaluation, because we need an evaluated depsgraph in the end regardless. For operators, this might be a bit simpler to implement, but can also be done separately.
Implementation
To achieve all of this, we still have to move the work off the main thread. That’s necessary because the main thread is the only one that can reliably get events from the OS currently. That was the limiting factor in my initial attempt at solving this.
The key non-obvious aspect is that while we use a separate worker thread, the main thread will still be blocked semantically, e.g. it does not proceed to redraw the 3D view while the depsgraph is still evaluating. Instead, the main thread is running a mini event loop and just draws on top of the previously rendered Blender UI.
This patch can be used as reference for the implementation.
If we decide to implement this dialog, it would be very useful to have some good mockups for how it should look like.