Optimize and robustify asset prefetching and material loading.
- Parallelize asset prefetching (max 4 workers) with retry logic and on-screen error banner, replacing silent failures and cryptic WASM out-of-bounds crashes with explicit missing-file errors. - Support binary Uint8Array/ArrayBuffer in C++ asset registry via typed_memory_view, preventing Embind string coercion from corrupting binary shader packages into ASCII text. - Automatically glob .mat files in CMake instead of maintaining a manual list. - Add missing reflection materials to prefetch arrays. - Disable caching for index.html in web server so template/script updates apply on normal page reload without stale cache issues, the file is small so caching had a negligible upside. - Add null resource and payload validation in ObjectManager::LoadMaterial before constructing Filament materials. PiperOrigin-RevId: 963364509 Change-Id: I7de79df6a5cede4e54683415ee193f1c5a665286
This commit is contained in:
committed by
Copybara-Service
parent
fb03be0e4f
commit
fca913b4f5
@@ -214,13 +214,15 @@ limitations under the License.
|
||||
}
|
||||
return prefix + path;
|
||||
},
|
||||
onRuntimeInitialized: () => {
|
||||
onRuntimeInitialized: async () => {
|
||||
const assetsToPrefetch = [
|
||||
"AtkinsonHyperlegibleNext[wght].ttf",
|
||||
"AtkinsonHyperlegibleMono-Regular.ttf",
|
||||
"fontawesome-webfont.ttf",
|
||||
"ibl.ktx",
|
||||
"pbr.filamat",
|
||||
"pbr_reflect.filamat",
|
||||
"pbr_packed_reflect.filamat",
|
||||
"pbr_transparent.filamat",
|
||||
"pbr_packed.filamat",
|
||||
"pbr_packed_transparent.filamat",
|
||||
@@ -245,28 +247,55 @@ limitations under the License.
|
||||
"unlit_ui.filamat",
|
||||
];
|
||||
|
||||
const assetPromises = assetsToPrefetch.map(async (filename) => {
|
||||
for (let attempt = 0; attempt < 3; attempt++) {
|
||||
try {
|
||||
if (attempt > 0) {
|
||||
await new Promise((r) => setTimeout(r, 500 * attempt));
|
||||
const PARALLEL = 4;
|
||||
const failedAssets = [];
|
||||
let nextIndex = 0;
|
||||
|
||||
async function prefetchWorker() {
|
||||
while (nextIndex < assetsToPrefetch.length) {
|
||||
const filename = assetsToPrefetch[nextIndex++];
|
||||
let loaded = false;
|
||||
for (let attempt = 0; attempt < 3; attempt++) {
|
||||
try {
|
||||
if (attempt > 0) {
|
||||
await new Promise((r) => setTimeout(r, 500 * attempt));
|
||||
}
|
||||
const response = await fetch("assets/" + filename);
|
||||
if (!response.ok) continue;
|
||||
const buffer = await response.arrayBuffer();
|
||||
Module.registerAsset(filename, new Uint8Array(buffer));
|
||||
loaded = true;
|
||||
break;
|
||||
} catch (error) {
|
||||
console.warn(`Attempt ${attempt + 1} failed for ${filename}:`, error);
|
||||
}
|
||||
const response = await fetch("assets/" + filename);
|
||||
if (!response.ok) continue;
|
||||
const buffer = await response.arrayBuffer();
|
||||
Module.registerAsset(filename, new Uint8Array(buffer));
|
||||
return;
|
||||
} catch (error) {
|
||||
console.warn(`Attempt ${attempt + 1} failed for ${filename}:`, error);
|
||||
}
|
||||
if (!loaded) {
|
||||
console.error(`Error prefetching asset ${filename} after 3 attempts`);
|
||||
failedAssets.push(filename);
|
||||
}
|
||||
}
|
||||
console.error(`Error prefetching asset ${filename} after 3 attempts`);
|
||||
});
|
||||
}
|
||||
|
||||
Promise.all(assetPromises).then(() => {
|
||||
Module.startApp();
|
||||
reloadModel();
|
||||
});
|
||||
const workers = [];
|
||||
for (let i = 0; i < Math.min(PARALLEL, assetsToPrefetch.length); i++) {
|
||||
workers.push(prefetchWorker());
|
||||
}
|
||||
await Promise.all(workers);
|
||||
|
||||
if (failedAssets.length > 0) {
|
||||
const msg = `Failed to load required assets (${failedAssets.join(", ")}). Please check server runfiles or connection and reload.`;
|
||||
console.error(msg);
|
||||
const errDiv = document.createElement("div");
|
||||
errDiv.style.cssText =
|
||||
"position:absolute;top:20px;left:20px;right:20px;padding:16px;background:#7a1a1a;color:#fff;font-family:sans-serif;font-size:14px;border-radius:8px;z-index:9999;box-shadow:0 4px 12px rgba(0,0,0,0.5);";
|
||||
errDiv.textContent = msg;
|
||||
document.body.appendChild(errDiv);
|
||||
return;
|
||||
}
|
||||
|
||||
Module.startApp();
|
||||
reloadModel();
|
||||
},
|
||||
};
|
||||
// Set only the CSS size; SDL owns canvas.width/height. Use whole
|
||||
|
||||
Reference in New Issue
Block a user