Fix WebGL page cache and flip sequencing

This commit is contained in:
2026-06-08 23:08:13 +02:00
parent a73dc5725f
commit 419691000c
7 changed files with 364 additions and 60 deletions
+27 -4
View File
@@ -15,9 +15,9 @@ class WebGLPageCacheModule extends BaseModule {
this.db = null;
this.cacheStatus = 'uninitialized';
this.currentCacheSize = 0;
this.maxCacheSizeBytes = 180 * 1024 * 1024;
this.maxCacheSizeBytes = 5 * 1024 * 1024 * 1024;
this.memoryCanvasCache = new Map();
this.maxMemoryCanvasCount = 12;
this.maxMemoryCanvasCount = 256;
this.bindMethods([
'initialize',
@@ -27,6 +27,7 @@ class WebGLPageCacheModule extends BaseModule {
'makePageKey',
'canvasToBlob',
'blobToCanvas',
'isOlderPageEntry',
'manageCacheSize',
'calculateTotalCacheSize',
'deleteEntry',
@@ -45,7 +46,7 @@ class WebGLPageCacheModule extends BaseModule {
this.reportProgress(100, 'WebGL page texture cache ready');
return true;
} catch (error) {
console.warn('WebGLPageCache: IndexedDB unavailable, continuing without persistent page cache', error);
console.error('WebGLPageCache: IndexedDB unavailable; persistent page caching is in a problem state', error);
this.cacheStatus = 'error';
this.reportProgress(100, 'WebGL page texture cache unavailable');
return true;
@@ -100,7 +101,6 @@ class WebGLPageCacheModule extends BaseModule {
height: canvas.height,
cacheKey: pageMeta.cacheKey
});
if (this.memoryCanvasCache.has(key)) return true;
try {
const blob = await this.canvasToBlob(canvas);
if (!blob) return false;
@@ -109,6 +109,7 @@ class WebGLPageCacheModule extends BaseModule {
request.onsuccess = () => resolve(request.result || null);
request.onerror = () => reject(request.error);
});
if (this.isOlderPageEntry(pageMeta, oldEntry)) return true;
await this.manageCacheSize(blob.size);
await new Promise((resolve, reject) => {
const request = this.tx('readwrite').put({
@@ -116,6 +117,10 @@ class WebGLPageCacheModule extends BaseModule {
pageIndex,
width: canvas.width,
height: canvas.height,
contentVersion: Math.max(0, Number(pageMeta.contentVersion || 0)),
completenessScore: Math.max(0, Number(pageMeta.completenessScore || 0)),
maxBlockId: Math.max(0, Number(pageMeta.maxBlockId || 0)),
lineCount: Math.max(0, Number(pageMeta.lineCount || 0)),
blob,
size: blob.size,
lastAccessed: Date.now()
@@ -161,6 +166,13 @@ class WebGLPageCacheModule extends BaseModule {
});
if (!entry?.blob) return null;
const canvas = await this.blobToCanvas(entry.blob, entry.width, entry.height);
if (canvas) canvas.__webglPageCacheMeta = {
pageIndex: entry.pageIndex,
contentVersion: entry.contentVersion,
completenessScore: entry.completenessScore,
maxBlockId: entry.maxBlockId,
lineCount: entry.lineCount
};
if (canvas) this.rememberCanvas(key, canvas);
return canvas;
} catch (error) {
@@ -169,6 +181,17 @@ class WebGLPageCacheModule extends BaseModule {
}
}
isOlderPageEntry(pageMeta = {}, oldEntry = null) {
if (!oldEntry) return false;
const incomingCompleteness = Math.max(0, Number(pageMeta.completenessScore || 0));
const existingCompleteness = Math.max(0, Number(oldEntry.completenessScore || 0));
if (incomingCompleteness < existingCompleteness) return true;
if (incomingCompleteness > existingCompleteness) return false;
const incomingVersion = Math.max(0, Number(pageMeta.contentVersion || 0));
const existingVersion = Math.max(0, Number(oldEntry.contentVersion || 0));
return incomingVersion > 0 && existingVersion > incomingVersion;
}
canvasToBlob(canvas) {
return new Promise((resolve) => {
if (typeof canvas.toBlob !== 'function') {