diff --git a/packages/core/src/canvas/renderer.ts b/packages/core/src/canvas/renderer.ts index 5cf573424..fc0e990cf 100644 --- a/packages/core/src/canvas/renderer.ts +++ b/packages/core/src/canvas/renderer.ts @@ -131,6 +131,9 @@ export class SkiaRenderer { lastSceneViewport: { panX: number; panY: number; zoom: number } | null = null nodePictureCache = new Map() subtreePictureCache = new Map() + subtreePictureCachePageId: string | null = null + subtreePictureCacheSceneVersion = -1 + subtreePictureCachePositionPreviewVersion = -1 readonly labelCache = new LabelCache() readonly profiler: RenderProfiler diff --git a/packages/core/src/canvas/renderer/retained-backing.ts b/packages/core/src/canvas/renderer/retained-backing.ts index 32eef6aea..9bae9cab6 100644 --- a/packages/core/src/canvas/renderer/retained-backing.ts +++ b/packages/core/src/canvas/renderer/retained-backing.ts @@ -1,6 +1,7 @@ import type { Canvas, Image as CKImage, Surface } from 'canvaskit-wasm' import type { SkiaRenderer } from '#core/canvas/renderer' +import { clearSubtreePictureCache } from '#core/canvas/renderer/state' import { computeDescendantVisualBounds } from '#core/geometry' import type { SceneGraph } from '#core/scene-graph' @@ -163,12 +164,31 @@ function createSceneBackingSurface(r: SkiaRenderer, width: number, height: numbe }) } +function ensureSubtreePictureCacheScope( + r: SkiaRenderer, + graph: SceneGraph, + sceneVersion: number +): void { + if ( + r.subtreePictureCachePageId === r.pageId && + r.subtreePictureCacheSceneVersion === sceneVersion && + r.subtreePictureCachePositionPreviewVersion === graph.positionPreviewVersion + ) { + return + } + clearSubtreePictureCache(r) + r.subtreePictureCachePageId = r.pageId + r.subtreePictureCacheSceneVersion = sceneVersion + r.subtreePictureCachePositionPreviewVersion = graph.positionPreviewVersion +} + function cachedSubtreePicture( r: SkiaRenderer, graph: SceneGraph, childId: string, sceneVersion: number ) { + ensureSubtreePictureCacheScope(r, graph, sceneVersion) const cached = r.subtreePictureCache.get(childId) if ( cached && diff --git a/packages/core/src/canvas/renderer/state.ts b/packages/core/src/canvas/renderer/state.ts index 5512032b1..3b64929e6 100644 --- a/packages/core/src/canvas/renderer/state.ts +++ b/packages/core/src/canvas/renderer/state.ts @@ -13,6 +13,9 @@ export function invalidateScenePicture(r: SkiaRenderer): void { export function clearSubtreePictureCache(r: SkiaRenderer): void { for (const entry of r.subtreePictureCache.values()) entry.picture.delete() r.subtreePictureCache.clear() + r.subtreePictureCachePageId = null + r.subtreePictureCacheSceneVersion = -1 + r.subtreePictureCachePositionPreviewVersion = -1 } export function invalidateAllPictures(r: SkiaRenderer): void {