Add WebGL page cache and runtime checks

This commit is contained in:
2026-06-08 14:39:42 +02:00
parent 119cefd4bd
commit a73dc5725f
11 changed files with 891 additions and 32 deletions
+30 -1
View File
@@ -7,10 +7,11 @@ import { BaseModule } from './base-module.js';
class BookTextureRendererModule extends BaseModule {
constructor() {
super('book-texture-renderer', 'Book Texture Renderer');
this.dependencies = ['book-page-format', 'book-pagination', 'localization'];
this.dependencies = ['book-page-format', 'book-pagination', 'localization', 'webgl-page-cache'];
this.pageFormat = null;
this.pagination = null;
this.localization = null;
this.pageCache = null;
this.metrics = null;
this.canvases = {
left: null,
@@ -70,6 +71,7 @@ class BookTextureRendererModule extends BaseModule {
'buildLineSegments',
'startRevealAnimation',
'prepareRevealBlock',
'hasPreparedRevealBlock',
'createAnimationState',
'publishPreparedReveal',
'startPreparedRevealAnimation',
@@ -81,6 +83,8 @@ class BookTextureRendererModule extends BaseModule {
'requestAnimationFrame',
'tickAnimations',
'publishSpread',
'cachePublishedPages',
'schedulePageCacheWrite',
'getPageCanvas',
'getHitMap',
'handlePageCountChanged'
@@ -91,6 +95,7 @@ class BookTextureRendererModule extends BaseModule {
this.pageFormat = this.getModule('book-page-format');
this.pagination = this.getModule('book-pagination');
this.localization = this.getModule('localization');
this.pageCache = this.getModule('webgl-page-cache');
window.BookTextureRendererDebug = {
pipelineTimings: this.pipelineTimings
};
@@ -704,6 +709,11 @@ class BookTextureRendererModule extends BaseModule {
});
}
hasPreparedRevealBlock(blockId) {
const id = String(blockId ?? '');
return Boolean(id && this.preparedRevealCache.has(id));
}
publishPreparedReveal(prepared) {
if (!prepared) return;
this.markPipelineTiming('publishPreparedReveal', {
@@ -884,6 +894,7 @@ class BookTextureRendererModule extends BaseModule {
};
});
if (Object.keys(reveal).length) detail.reveal = reveal;
this.cachePublishedPages(sidesToPublish, detail);
this.markPipelineTiming('publishSpread', {
sides: sidesToPublish,
hasReveal: Object.keys(reveal).length > 0,
@@ -896,6 +907,24 @@ class BookTextureRendererModule extends BaseModule {
return detail;
}
cachePublishedPages(sides = [], detail = {}) {
if (!this.pageCache || typeof this.pageCache.cachePageCanvas !== 'function') return;
sides.forEach((side) => {
const canvas = detail[side];
const pageMeta = detail.pageMeta?.[side] || null;
if (!canvas || !pageMeta || !Number.isFinite(Number(pageMeta.pageIndex))) return;
this.schedulePageCacheWrite(pageMeta, canvas);
});
}
schedulePageCacheWrite(pageMeta, canvas) {
const frozenCanvas = this.cloneCanvas(canvas);
const scheduler = window.requestIdleCallback || ((callback) => window.setTimeout(callback, 16));
scheduler(() => {
this.pageCache?.cachePageCanvas?.(pageMeta, frozenCanvas);
}, { timeout: 250 });
}
getPageCanvas(side) {
return this.canvases[side] || null;
}