chore: checkpoint web Blender migration source, tools and docs
Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer, web workflow engine and protocol, tooling, docs and task records. Large generated evidence, user-testing archives, build snapshots and imported test assets remain untracked. Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -342,8 +342,10 @@ bool ZstdWriteWrap::open(const char *filepath)
|
||||
}
|
||||
|
||||
/* Leave one thread open for the main writing logic, unless we only have one HW thread. */
|
||||
#if !defined(__EMSCRIPTEN__) || defined(__EMSCRIPTEN_PTHREADS__)
|
||||
int num_threads = max_ii(1, BLI_system_thread_count() - 1);
|
||||
BLI_threadpool_init(&threadpool, ZstdWriteBlockTask::write_task, num_threads);
|
||||
#endif
|
||||
BLI_mutex_init(&mutex);
|
||||
BLI_condition_init(&condition);
|
||||
|
||||
@@ -393,7 +395,9 @@ void ZstdWriteWrap::write_seekable_frames()
|
||||
|
||||
bool ZstdWriteWrap::close()
|
||||
{
|
||||
#if !defined(__EMSCRIPTEN__) || defined(__EMSCRIPTEN_PTHREADS__)
|
||||
BLI_threadpool_end(&threadpool);
|
||||
#endif
|
||||
tasks.free_no_destruct();
|
||||
|
||||
BLI_mutex_end(&mutex);
|
||||
@@ -418,6 +422,11 @@ bool ZstdWriteWrap::write(const void *buf, const size_t buf_len)
|
||||
task->frame_number = num_frames++;
|
||||
task->ww = this;
|
||||
|
||||
#if defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)
|
||||
write_task(task);
|
||||
MEM_delete(task);
|
||||
return !write_error;
|
||||
#endif
|
||||
BLI_mutex_lock(&mutex);
|
||||
BLI_addtail(&tasks, task);
|
||||
|
||||
@@ -1302,7 +1311,7 @@ static void write_id_placeholder(WriteData *wd, ID *id)
|
||||
}
|
||||
|
||||
/** Keep it last of `write_*_data` functions. */
|
||||
static void write_libraries(WriteData *wd, Main *bmain)
|
||||
static void write_libraries(WriteData *wd, Main *bmain, const bool materialize_linked_ids)
|
||||
{
|
||||
const bool is_undo = wd->use_memfile;
|
||||
|
||||
@@ -1327,7 +1336,13 @@ static void write_libraries(WriteData *wd, Main *bmain)
|
||||
|
||||
/* Gather IDs that are somehow directly referenced by data in the current blend file. */
|
||||
Vector<ID *> ids_used_from_library;
|
||||
if (is_undo) {
|
||||
if (materialize_linked_ids) {
|
||||
/* Read-only SceneIR projection of the already loaded Main. Include indirect data too;
|
||||
* Object.data, materials and nested collections must resolve to complete native IDs.
|
||||
* This stream is never used as a saved blend or an undo checkpoint. */
|
||||
ids_used_from_library = ids;
|
||||
}
|
||||
else if (is_undo) {
|
||||
/* Always write placeholders for all linked IDs in undo case. This allows to properly remove
|
||||
* linked data that should not exist on undo/redo. See also #read_undo_move_libmain_data,
|
||||
* #read_libblock_undo_restore_linked and #read_undo_libraries_cleanup_unused_ids. */
|
||||
@@ -1417,7 +1432,7 @@ static void write_libraries(WriteData *wd, Main *bmain)
|
||||
/* Write placeholders for linked data-blocks that are used, and real IDs for the packed linked
|
||||
* ones. */
|
||||
for (ID *id : ids_used_from_library) {
|
||||
if (ID_IS_PACKED(id)) {
|
||||
if (materialize_linked_ids || ID_IS_PACKED(id)) {
|
||||
write_id(wd, id);
|
||||
}
|
||||
else {
|
||||
@@ -1448,7 +1463,11 @@ extern "C" char build_hash[];
|
||||
* - for forward compatibility, `curscreen` has to be saved
|
||||
* - for undo-file, `curscene` needs to be saved.
|
||||
*/
|
||||
static void write_global(WriteData *wd, const int fileflags, Main *mainvar)
|
||||
static void write_global(WriteData *wd,
|
||||
const int fileflags,
|
||||
Main *mainvar,
|
||||
Scene *current_scene,
|
||||
ViewLayer *current_view_layer)
|
||||
{
|
||||
const bool is_undo = wd->use_memfile;
|
||||
FileGlobal fg;
|
||||
@@ -1464,6 +1483,10 @@ static void write_global(WriteData *wd, const int fileflags, Main *mainvar)
|
||||
fg._pad1 = nullptr;
|
||||
|
||||
current_screen_compat(mainvar, is_undo, &screen, &scene, &view_layer);
|
||||
if (!scene && current_scene) {
|
||||
scene = current_scene;
|
||||
view_layer = current_view_layer ? current_view_layer : BKE_view_layer_default_view(scene);
|
||||
}
|
||||
|
||||
/* XXX: still remap `G`. */
|
||||
fg.curscreen = screen;
|
||||
@@ -1564,6 +1587,10 @@ BLO_Write_IDBuffer::BLO_Write_IDBuffer(ID &id, const bool is_undo, const bool is
|
||||
}
|
||||
temp_id->us = 0;
|
||||
temp_id->icon_id = 0;
|
||||
#ifdef WITH_WEB
|
||||
// Dependency evaluation and undo-dirty tags are runtime state in ordinary Web snapshots.
|
||||
if (!is_undo) { temp_id->recalc = 0; temp_id->recalc_after_undo_push = 0; }
|
||||
#endif
|
||||
temp_id->runtime = nullptr;
|
||||
/* Those listbase data change every time we add/remove an ID, and also often when
|
||||
* renaming one (due to re-sorting). This avoids generating a lot of false 'is changed'
|
||||
@@ -1735,7 +1762,10 @@ static bool write_file_handle(Main *mainvar,
|
||||
const int write_flags,
|
||||
const bool use_userdef,
|
||||
const BlendThumbnail *thumb,
|
||||
std::ostream *debug_dst)
|
||||
std::ostream *debug_dst,
|
||||
const bool materialize_linked_ids = false,
|
||||
Scene *current_scene = nullptr,
|
||||
ViewLayer *current_view_layer = nullptr)
|
||||
{
|
||||
WriteData *wd;
|
||||
|
||||
@@ -1758,7 +1788,7 @@ static bool write_file_handle(Main *mainvar,
|
||||
write_blend_file_header(wd);
|
||||
write_renderinfo(wd, mainvar);
|
||||
write_thumb(wd, thumb);
|
||||
write_global(wd, write_flags, mainvar);
|
||||
write_global(wd, write_flags, mainvar, current_scene, current_view_layer);
|
||||
|
||||
/* The window-manager and screen often change,
|
||||
* avoid thumbnail detecting changes because of this. */
|
||||
@@ -1784,7 +1814,7 @@ static bool write_file_handle(Main *mainvar,
|
||||
}
|
||||
|
||||
/* Write libraries about libraries and linked data-blocks. */
|
||||
write_libraries(wd, mainvar);
|
||||
write_libraries(wd, mainvar, materialize_linked_ids);
|
||||
|
||||
/* So changes above don't cause a 'DNA1' to be detected as changed on undo. */
|
||||
mywrite_flush(wd);
|
||||
@@ -2124,14 +2154,36 @@ bool BLO_write_file_mem(Main *mainvar, MemFile *compare, MemFile *current, const
|
||||
bool BLO_write_file_to_callback(Main *mainvar,
|
||||
const int write_flags,
|
||||
BLO_WriteFileCallback callback,
|
||||
void *user_data)
|
||||
void *user_data,
|
||||
const bool materialize_linked_ids_for_snapshot,
|
||||
Scene *current_scene,
|
||||
ViewLayer *current_view_layer)
|
||||
{
|
||||
if (callback == nullptr) {
|
||||
return false;
|
||||
}
|
||||
/* Reject foreign or retired pointers before emitting any bytes. */
|
||||
if (current_scene) {
|
||||
bool scene_found = false;
|
||||
for (Scene &scene : mainvar->scenes) {
|
||||
if (&scene == current_scene) scene_found = true;
|
||||
}
|
||||
if (!scene_found) return false;
|
||||
if (current_view_layer) {
|
||||
bool layer_found = false;
|
||||
for (ViewLayer &view_layer : current_scene->view_layers) {
|
||||
if (&view_layer == current_view_layer) layer_found = true;
|
||||
}
|
||||
if (!layer_found) return false;
|
||||
}
|
||||
}
|
||||
else if (current_view_layer) {
|
||||
return false;
|
||||
}
|
||||
CallbackWriteWrap callback_wrap(callback, user_data);
|
||||
const bool err = write_file_handle(
|
||||
mainvar, &callback_wrap, nullptr, nullptr, write_flags, false, nullptr, nullptr);
|
||||
mainvar, &callback_wrap, nullptr, nullptr, write_flags, false, nullptr, nullptr,
|
||||
materialize_linked_ids_for_snapshot, current_scene, current_view_layer);
|
||||
return (err == 0);
|
||||
}
|
||||
|
||||
@@ -2288,6 +2340,8 @@ void BLO_write_generated_pointer_tag(BlendWriter *writer, const void *data)
|
||||
return;
|
||||
}
|
||||
if (!BLO_write_is_undo(writer)) {
|
||||
/* Generated storage can reuse an earlier ID's temporary allocation. */
|
||||
writer->wd->stable_address_ids.pointer_map.remove(data);
|
||||
return;
|
||||
}
|
||||
const uint64_t address_id = get_address_id_for_undo(*writer->wd);
|
||||
|
||||
Reference in New Issue
Block a user