1
1
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager' ;
2
2
import { CanvasModuleBase } from 'features/controlLayers/konva/CanvasModuleBase' ;
3
+ import type { Transparency } from 'features/controlLayers/konva/util' ;
3
4
import { getPrefixedId } from 'features/controlLayers/konva/util' ;
4
5
import type { GenerationMode } from 'features/controlLayers/store/types' ;
5
6
import { LRUCache } from 'lru-cache' ;
6
7
import type { Logger } from 'roarr' ;
7
8
9
+ type GetCacheEntryWithFallbackArg < T extends NonNullable < unknown > > = {
10
+ cache : LRUCache < string , T > ;
11
+ key : string ;
12
+ getValue : ( ) => Promise < T > ;
13
+ onHit ?: ( value : T ) => void ;
14
+ onMiss ?: ( ) => void ;
15
+ } ;
16
+
8
17
type CanvasCacheModuleConfig = {
9
18
/**
10
19
* The maximum size of the image name cache.
11
20
*/
12
21
imageNameCacheSize : number ;
22
+ /**
23
+ * The maximum size of the image data cache.
24
+ */
25
+ imageDataCacheSize : number ;
26
+ /**
27
+ * The maximum size of the transparency calculation cache.
28
+ */
29
+ transparencyCalculationCacheSize : number ;
13
30
/**
14
31
* The maximum size of the canvas element cache.
15
32
*/
@@ -21,7 +38,9 @@ type CanvasCacheModuleConfig = {
21
38
} ;
22
39
23
40
const DEFAULT_CONFIG : CanvasCacheModuleConfig = {
24
- imageNameCacheSize : 100 ,
41
+ imageNameCacheSize : 1000 ,
42
+ imageDataCacheSize : 32 ,
43
+ transparencyCalculationCacheSize : 1000 ,
25
44
canvasElementCacheSize : 32 ,
26
45
generationModeCacheSize : 100 ,
27
46
} ;
@@ -41,26 +60,38 @@ export class CanvasCacheModule extends CanvasModuleBase {
41
60
config : CanvasCacheModuleConfig = DEFAULT_CONFIG ;
42
61
43
62
/**
44
- * A cache for storing image names. Used as a cache for results of layer/canvas/entity exports. For example, when we
45
- * rasterize a layer and upload it to the server, we store the image name in this cache.
63
+ * A cache for storing image names.
46
64
*
47
- * The cache key is a hash of the exported entity's state and the export rect .
65
+ * For example, the key might be a hash of a composite of entities with the uploaded image name as the value .
48
66
*/
49
67
imageNameCache = new LRUCache < string , string > ( { max : this . config . imageNameCacheSize } ) ;
50
68
51
69
/**
52
- * A cache for storing canvas elements. Similar to the image name cache, but for canvas elements. The primary use is
53
- * for caching composite layers. For example, the canvas compositor module uses this to store the canvas elements for
54
- * individual raster layers when creating a composite of the layers.
70
+ * A cache for storing canvas elements.
55
71
*
56
- * The cache key is a hash of the exported entity's state and the export rect .
72
+ * For example, the key might be a hash of a composite of entities with the canvas element as the value .
57
73
*/
58
74
canvasElementCache = new LRUCache < string , HTMLCanvasElement > ( { max : this . config . canvasElementCacheSize } ) ;
75
+
59
76
/**
60
- * A cache for the generation mode calculation, which is fairly expensive .
77
+ * A cache for image data objects .
61
78
*
62
- * The cache key is a hash of all the objects that contribute to the generation mode calculation (e.g. the composite
63
- * raster layer, the composite inpaint mask, and bounding box), and the value is the generation mode.
79
+ * For example, the key might be a hash of a composite of entities with the image data as the value.
80
+ */
81
+ imageDataCache = new LRUCache < string , ImageData > ( { max : this . config . imageDataCacheSize } ) ;
82
+
83
+ /**
84
+ * A cache for transparency calculation results.
85
+ *
86
+ * For example, the key might be a hash of a composite of entities with the transparency as the value.
87
+ */
88
+ transparencyCalculationCache = new LRUCache < string , Transparency > ( { max : this . config . imageDataCacheSize } ) ;
89
+
90
+ /**
91
+ * A cache for generation mode calculation results.
92
+ *
93
+ * For example, the key might be a hash of a composite of raster and inpaint mask entities with the generation mode
94
+ * as the value.
64
95
*/
65
96
generationModeCache = new LRUCache < string , GenerationMode > ( { max : this . config . generationModeCacheSize } ) ;
66
97
@@ -75,6 +106,33 @@ export class CanvasCacheModule extends CanvasModuleBase {
75
106
this . log . debug ( 'Creating cache module' ) ;
76
107
}
77
108
109
+ /**
110
+ * A helper function for getting a cache entry with a fallback.
111
+ * @param param0.cache The LRUCache to get the entry from.
112
+ * @param param0.key The key to use to retrieve the entry.
113
+ * @param param0.getValue An async function to generate the value if the entry is not in the cache.
114
+ * @param param0.onHit An optional function to call when the entry is in the cache.
115
+ * @param param0.onMiss An optional function to call when the entry is not in the cache.
116
+ * @returns
117
+ */
118
+ static getWithFallback = async < T extends NonNullable < unknown > > ( {
119
+ cache,
120
+ getValue,
121
+ key,
122
+ onHit,
123
+ onMiss,
124
+ } : GetCacheEntryWithFallbackArg < T > ) : Promise < T > => {
125
+ let value = cache . get ( key ) ;
126
+ if ( value === undefined ) {
127
+ onMiss ?.( ) ;
128
+ value = await getValue ( ) ;
129
+ cache . set ( key , value ) ;
130
+ } else {
131
+ onHit ?.( value ) ;
132
+ }
133
+ return value ;
134
+ } ;
135
+
78
136
/**
79
137
* Clears all caches.
80
138
*/
0 commit comments