62 lines
1.6 KiB
Dart
62 lines
1.6 KiB
Dart
|
|
// Double-buffer helper on top of [PageTileCache] to kill zoom white-flash:
|
||
|
|
// keep painting the last good tile while a higher-DPI raster is in flight.
|
||
|
|
|
||
|
|
import 'dart:ui' as ui;
|
||
|
|
|
||
|
|
import 'package:flutter/widgets.dart';
|
||
|
|
|
||
|
|
import 'page_tile_cache.dart';
|
||
|
|
|
||
|
|
/// Holds the "last good" page image for the currently visible page so a zoom
|
||
|
|
/// settle never exposes an empty frame (plan W2 / R11).
|
||
|
|
class PageTileLayer extends ChangeNotifier {
|
||
|
|
PageTileLayer({PageTileCache? cache}) : _cache = cache ?? PageTileCache();
|
||
|
|
|
||
|
|
final PageTileCache _cache;
|
||
|
|
ui.Image? _lastGood;
|
||
|
|
TileKey? _lastKey;
|
||
|
|
|
||
|
|
PageTileCache get cache => _cache;
|
||
|
|
ui.Image? get lastGood => _lastGood;
|
||
|
|
TileKey? get lastKey => _lastKey;
|
||
|
|
|
||
|
|
/// Snap continuous zoom to a coarse DPI bucket (avoids a tile per frame).
|
||
|
|
static int dpiBucketFor(double zoom, {double baseDpi = 96, double step = 0.5}) {
|
||
|
|
final raw = zoom / step;
|
||
|
|
final snapped = raw.round().clamp(1, 16);
|
||
|
|
return (snapped * step * baseDpi).round();
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Promote [image] as the last-good tile for [key].
|
||
|
|
void put(TileKey key, ui.Image image) {
|
||
|
|
_cache.put(key, image);
|
||
|
|
_lastGood = image;
|
||
|
|
_lastKey = key;
|
||
|
|
notifyListeners();
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Prefer exact bucket; else fall back to last-good so zoom never blanks.
|
||
|
|
ui.Image? resolve(TileKey key) {
|
||
|
|
final hit = _cache.get(key);
|
||
|
|
if (hit != null) {
|
||
|
|
_lastGood = hit;
|
||
|
|
_lastKey = key;
|
||
|
|
return hit;
|
||
|
|
}
|
||
|
|
return _lastGood;
|
||
|
|
}
|
||
|
|
|
||
|
|
void clear() {
|
||
|
|
_lastGood = null;
|
||
|
|
_lastKey = null;
|
||
|
|
_cache.dispose();
|
||
|
|
notifyListeners();
|
||
|
|
}
|
||
|
|
|
||
|
|
@override
|
||
|
|
void dispose() {
|
||
|
|
clear();
|
||
|
|
super.dispose();
|
||
|
|
}
|
||
|
|
}
|