This patch is by no mean considered ready for production, it's rather a proof-of-concept demoing current idea to speed up undo's in Blender.
As such, if you try it, expect crashes, .blend files corruptions, etc.
The intent of this patch is to get early reviews/advices/comments from other devs knowing well the affected areas: Undo system (based on memfile, i.e. undo in object/pose modes mostly), read/write code of .blend files, and depsgraph.
Related design task: T60695.
Here is a quick demo video of the same set of actions, followed by complete undo's, performed on a 'worst case' file (we are editing simple objects, with a very heavily modified mesh one that remain unchanged). Left side is current patch, right one is current master.
One can notice some of the glitches/limitations still present in the patch (the very first undo step does not currently benefit from any speed-up, due to some annoying detail, switching in/out of Edit modes will also enfore a full re-evaluated undo step, etc.).
Also, if your edit affects in any way a heavy-to-evaluate object, there will be limited to no improvements, as currently this requires rebuilding all the caches.
General idea of the project is to detect unchanged data-blocks, and only re-read and re-evaluate those who need it. This implies re-using existing depsgraphes, such that caches and general internal relations data in them remain valid for unchanged IDs, since their memory addresses will remain the same.
Here are the main changes for each area:
Modifications to the undo system itself are quite minimal. We need to store a 'future' unchanged flag in memory chunks (in addition to the regular 'unchanged compared to past' one), needed when doing undo's (as we need to know which IDs changed between step n and n - 1, and not between step n and n + 1 like for redo's).
And we also need to extract and restore depsgraphes around the actual undo step 'reading', as by default depsgraphes are completely lost during this process.
The heaviest changes are done in reading code, to enable re-using unchanged data-blocks from existiong ('old') bmain, instead of using their newly-read versions. This requires some careful remapping of the old pointers to new ones (either new from newly read data-blocks, or from re-used data-blocks).
After quiet a few trials and errors, using idnames as 'uid' was chosen as the only viable solution, having too many 'memory realms' at play during undo history makes using pointers values themselves close to impossible. This implies that renaming of IDs has to enforce a complete undo step (in most of the cases this would not be needed, but some corner-cases could generate bad naming collisions, completely breaking the remapping process). This has some cost over the readfile part of the undo, but it remains neglectable compared to the undo process as a whole.
Write part of the code was mainly changed to ensure we do have a write flush for every ID, so that each ID has at least one 'own' memory chunk, to make detecting unchanged IDs easy and simple.
There is no changes to the behavior of the depsgraph itself, but some APIs were added to allow extraction/storage of the depsgraphes into a temp ghash (using scenes' and viewlayers' names as keys). 'Extraction' means that those depsgraph are fully removed from current scenes, hences said scenes can be freed without loosing any evaluation data.
Restoration of the depsgraphes simply searches for stored ones in the ghash, and restore them when found. A way to change their Main reference was also needed, to point it to the newly created Main after the undo.