perf(canvas): scope backing subtree cache

This commit is contained in:
Danila Poyarkov 2026-05-20 03:02:01 +03:00
parent 9949a1dd8b
commit ffa0b9d6f8
3 changed files with 26 additions and 0 deletions

View file

@ -131,6 +131,9 @@ export class SkiaRenderer {
lastSceneViewport: { panX: number; panY: number; zoom: number } | null = null
nodePictureCache = new Map<string, SkPicture | null>()
subtreePictureCache = new Map<string, SubtreePictureCacheEntry>()
subtreePictureCachePageId: string | null = null
subtreePictureCacheSceneVersion = -1
subtreePictureCachePositionPreviewVersion = -1
readonly labelCache = new LabelCache()
readonly profiler: RenderProfiler

View file

@ -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 &&

View file

@ -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 {