getOrBuildWithReport method
Implementation
PictureCacheResult getOrBuildWithReport(
String key,
ui.Size size,
void Function(ui.Canvas canvas, ui.Size size) builder,
) {
final safeSize = _safeCacheSize(size);
if (_isEmptySize(safeSize)) {
invalidate(key);
_misses++;
_skippedWrites++;
return PictureCacheResult(
picture: _recordEmptyPicture(),
cacheHit: false,
retained: false,
skippedWrite: true,
);
}
final cached = _cache.remove(key);
if (cached != null && cached.size == safeSize) {
_hits++;
_cache[key] = cached; // Move to end (MRU)
return PictureCacheResult(
picture: cached.picture,
cacheHit: true,
retained: true,
skippedWrite: false,
);
}
if (cached != null) {
// The same logical layer at a different size must be re-recorded.
cached.picture.dispose();
_currentMemory = (_currentMemory - cached.memoryBytes)
.clamp(0, _maxTrackedMemoryBytes)
.toInt();
}
_misses++;
final recorder = ui.PictureRecorder();
final canvas = ui.Canvas(recorder);
builder(canvas, safeSize);
final picture = recorder.endRecording();
// Estimate memory (RGBA pixels + ~2KB overhead).
final estimatedBytes = estimateMemoryBytes(safeSize);
if (!_canRetain(estimatedBytes)) {
_skippedWrites++;
return PictureCacheResult(
picture: picture,
cacheHit: false,
retained: false,
skippedWrite: true,
);
}
_evictIfNeeded(estimatedBytes);
_cache[key] = _CachedPicture(picture, estimatedBytes, safeSize);
_currentMemory += estimatedBytes;
return PictureCacheResult(
picture: picture,
cacheHit: false,
retained: true,
skippedWrite: false,
);
}