Core: remove support for writing MemFile undo steps as .blend files
In many modes, Blender uses the `MemFile` undo step, which serializes all DNA data in RAM almost as if writing a .blend file. For auto-save, Blender used to write the last `MemFile` undo step to disk because that was faster serializing all of DNA again. Furthermore, saving the `quit.blend` file when closing Blender also used this. This functionality is now removed in preparate for supporting implicit sharing in the undo system (#106903). Auto-save and saving the quit.blend file now use regular file saving. The removal of this feature and its implications have also been discussed here: https://devtalk.blender.org/t/remove-support-for-saving-memfile-undo-steps-as-blend-files-proposal/33544
This commit is contained in:
@@ -94,11 +94,5 @@ void BLO_memfile_clear_future(MemFile *memfile);
|
|||||||
/* Utilities. */
|
/* Utilities. */
|
||||||
|
|
||||||
Main *BLO_memfile_main_get(MemFile *memfile, Main *bmain, Scene **r_scene);
|
Main *BLO_memfile_main_get(MemFile *memfile, Main *bmain, Scene **r_scene);
|
||||||
/**
|
|
||||||
* Saves .blend using undo buffer.
|
|
||||||
*
|
|
||||||
* \return success.
|
|
||||||
*/
|
|
||||||
bool BLO_memfile_write_file(MemFile *memfile, const char *filepath);
|
|
||||||
|
|
||||||
FileReader *BLO_memfile_new_filereader(MemFile *memfile, int undo_direction);
|
FileReader *BLO_memfile_new_filereader(MemFile *memfile, int undo_direction);
|
||||||
|
|||||||
@@ -175,61 +175,6 @@ Main *BLO_memfile_main_get(MemFile *memfile, Main *bmain, Scene **r_scene)
|
|||||||
return bmain_undo;
|
return bmain_undo;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BLO_memfile_write_file(MemFile *memfile, const char *filepath)
|
|
||||||
{
|
|
||||||
MemFileChunk *chunk;
|
|
||||||
int file, oflags;
|
|
||||||
|
|
||||||
/* NOTE: This is currently used for auto-save and `quit.blend`,
|
|
||||||
* where _not_ following symbolic-links is OK,
|
|
||||||
* however if this is ever executed explicitly by the user,
|
|
||||||
* we may want to allow writing to symbolic-links. */
|
|
||||||
|
|
||||||
oflags = O_BINARY | O_WRONLY | O_CREAT | O_TRUNC;
|
|
||||||
#ifdef O_NOFOLLOW
|
|
||||||
/* use O_NOFOLLOW to avoid writing to a symlink - use 'O_EXCL' (CVE-2008-1103) */
|
|
||||||
oflags |= O_NOFOLLOW;
|
|
||||||
#else
|
|
||||||
/* TODO(sergey): How to deal with symlinks on windows? */
|
|
||||||
# ifndef _MSC_VER
|
|
||||||
# warning "Symbolic links will be followed on undo save, possibly causing CVE-2008-1103"
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
file = BLI_open(filepath, oflags, 0666);
|
|
||||||
|
|
||||||
if (file == -1) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Unable to save '%s': %s\n",
|
|
||||||
filepath,
|
|
||||||
errno ? strerror(errno) : "Unknown error opening file");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (chunk = static_cast<MemFileChunk *>(memfile->chunks.first); chunk;
|
|
||||||
chunk = static_cast<MemFileChunk *>(chunk->next))
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (size_t(write(file, chunk->buf, uint(chunk->size))) != chunk->size)
|
|
||||||
#else
|
|
||||||
if (size_t(write(file, chunk->buf, chunk->size)) != chunk->size)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
close(file);
|
|
||||||
|
|
||||||
if (chunk) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Unable to save '%s': %s\n",
|
|
||||||
filepath,
|
|
||||||
errno ? strerror(errno) : "Unknown error writing file");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int64_t undo_read(FileReader *reader, void *buffer, size_t size)
|
static int64_t undo_read(FileReader *reader, void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
UndoReader *undo = (UndoReader *)reader;
|
UndoReader *undo = (UndoReader *)reader;
|
||||||
|
|||||||
@@ -2115,9 +2115,12 @@ static bool wm_autosave_write_try(Main *bmain, wmWindowManager *wm)
|
|||||||
|
|
||||||
wm_autosave_location(filepath);
|
wm_autosave_location(filepath);
|
||||||
|
|
||||||
if (MemFile *memfile = ED_undosys_stack_memfile_get_if_active(wm->undo_stack)) {
|
/* Technically, we could always just save here, but that would cause performance regressions
|
||||||
/* Fast save of last undo-buffer, now with UI. */
|
* compared to when the #MemFile undo step was used for saving undo-steps. So for now just skip
|
||||||
BLO_memfile_write_file(memfile, filepath);
|
* auto-save when we are in a mode where auto-save wouldn't have worked previously anyway. This
|
||||||
|
* check can be removed once the performance regressions have been solved. */
|
||||||
|
if (ED_undosys_stack_memfile_get_if_active(wm->undo_stack) != nullptr) {
|
||||||
|
WM_autosave_write(wm, bmain);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((U.uiflag & USER_GLOBALUNDO) == 0) {
|
if ((U.uiflag & USER_GLOBALUNDO) == 0) {
|
||||||
|
|||||||
@@ -471,26 +471,19 @@ void WM_exit_ex(bContext *C, const bool do_python_exit, const bool do_user_exit_
|
|||||||
/* NOTE: same code copied in `wm_files.cc`. */
|
/* NOTE: same code copied in `wm_files.cc`. */
|
||||||
if (C && wm) {
|
if (C && wm) {
|
||||||
if (do_user_exit_actions) {
|
if (do_user_exit_actions) {
|
||||||
/* save the undo state as quit.blend */
|
/* Save quit.blend. */
|
||||||
Main *bmain = CTX_data_main(C);
|
Main *bmain = CTX_data_main(C);
|
||||||
char filepath[FILE_MAX];
|
char filepath[FILE_MAX];
|
||||||
BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_base(), BLENDER_QUIT_FILE);
|
const int fileflags = G.fileflags & ~G_FILE_COMPRESS;
|
||||||
MemFile *undo_memfile = wm->undo_stack ?
|
|
||||||
ED_undosys_stack_memfile_get_if_active(wm->undo_stack) :
|
|
||||||
nullptr;
|
|
||||||
/* When true, the `undo_memfile` doesn't contain all information necessary
|
|
||||||
* for writing and up to date blend file. */
|
|
||||||
const bool is_memfile_outdated = ED_editors_flush_edits(bmain);
|
|
||||||
|
|
||||||
if (undo_memfile && !is_memfile_outdated) {
|
BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_base(), BLENDER_QUIT_FILE);
|
||||||
BLO_memfile_write_file(undo_memfile, filepath);
|
|
||||||
|
ED_editors_flush_edits(bmain);
|
||||||
|
|
||||||
|
BlendFileWriteParams blend_file_write_params{};
|
||||||
|
if (BLO_write_file(bmain, filepath, fileflags, &blend_file_write_params, nullptr)) {
|
||||||
|
printf("Saved session recovery to \"%s\"\n", filepath);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
const int fileflags = G.fileflags & ~G_FILE_COMPRESS;
|
|
||||||
BlendFileWriteParams blend_file_write_params{};
|
|
||||||
BLO_write_file(bmain, filepath, fileflags, &blend_file_write_params, nullptr);
|
|
||||||
}
|
|
||||||
printf("Saved session recovery to \"%s\"\n", filepath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WM_jobs_kill_all(wm);
|
WM_jobs_kill_all(wm);
|
||||||
|
|||||||
Reference in New Issue
Block a user