Force prototype extension on inlined tile source. Ensure zombies are processed with invalidation before restored in the system. WebGL drawer can use canvas drawer. Add changelog updates.

This commit is contained in:
Aiosa 2024-11-30 09:52:27 +01:00
parent 85e8b381b8
commit 271f437568
5 changed files with 63 additions and 5 deletions

View File

@ -1,6 +1,30 @@
OPENSEADRAGON CHANGELOG
=======================
6.0.0: (draft)
* NEW BEHAVIOR: OpenSeadragon Data Pipeline Overhaul
* DEPRECATION: Properties on tile that manage drawer data, or store data to draw: Tile.[element|imgElement|style|context2D|getImage|getCanvasContext] and transitively Tile.getScaleForEdgeSmoothing
* DEPRECATION: TileSource data lifecycle handlers: system manages these automatically: TileSource.[createTileCache|destroyTileCache|getTileCacheData|getTileCacheDataAsImage|getTileCacheDataAsContext2D]
* Tiles data is driven by caches: tiles can have multiple caches and cache can reference multiple tiles.
* Data types & conversion pipeline: caches support automated conversion between types, and call optionally destructors. These are asynchronous.
* Data conversion reasoning: the system keeps costs of convertors and seeks the cheapest conversion to a target format (using Dijkstra).
* Async support: events can now await handlers. Added OpenSeadragon.Promise proxy object. This object supports also synchronous mode.
* Drawers define what data they are able to work with, and receive automatically data from one of the declared types.
* Drawers now store data only inside cache, and provide optional type convertors to move data into a format they can work with.
* TileSource equality operator. TileSource destructor support. TileSources now must output type of the data they download [context.finish].
* Zombies: data can outlive tiles, and be kept in the system to wait if they are not suddenly needed. Turned on automatically with TiledImage addition with `replace: true` and equality test success.
* ImagesLoadedPerFrame is boosted 10 times when system is fresh (reset / open) and then declines back to original value.
* CacheRecord supports 'internal cache' of 'SimpleCache' type. This cache can be used by drawers to hide complex types used for rendering. Such caches are stored internally on CacheRecord objects.
* CacheRecord drives asynchronous data management and ensures correct behavior through awaiting Promises.
* TileCache adds new methods for cache modification: renameCache, cloneCache, injectCache, replaceCache, restoreTilesThatShareOriginalCache, safeUnloadCache, unloadCacheForTile and more. Used internally within invalidation events
* Tiles have up to two 'originalCacheKey' and 'cacheKey' caches, which keep original data and target drawn data (if modified).
* Invalidation Pipeline: New event 'tile-invalidated' and requestInvalidate methods on World and TiledImage. Tiles get methods to modify data to draw, system prepares data for drawing and swaps them with the current main tile cache.
* New test suites for the new cache system, conversion pipeline and invalidation events.
* New testing/demo utilities (MockSeadragon, DrawerSwitcher for switching drawers in demos, getBuiltInDrawersForTest for testing all drawers), serialization guard in tests to remove circular references.
* New demos, demonstrating the new pipeline. New demos for older plugins to show how compatible new version is.
* Misc: updated CSS for dev server, new dev & test commands.
5.0.1: (in progress...)
* Improved overlay handling so it plays better with other libraries (#2582 @BeebBenjamin)

View File

@ -516,8 +516,16 @@ $.Tile.prototype = {
},
/**
* Create tile cache for given data object. NOTE: if the existing cache already exists,
* Create tile cache for given data object.
*
* Using `setAsMain` updates also main tile cache key - the main cache key used to draw this tile.
* In that case, the cache should be ready to be rendered immediatelly (converted to one of the supported formats
* of the currently employed drawer).
*
* NOTE: if the existing cache already exists,
* data parameter is ignored and inherited from the existing cache object.
* WARNING: if you override main tile cache key to point to a different cache, the invalidation routine
* will no longer work. If you need to modify tile main data, prefer to use invalidation routine instead.
*
* @param {string} key cache key, if unique, new cache object is created, else existing cache attached
* @param {*} data this data will be IGNORED if cache already exists; therefore if
@ -758,6 +766,14 @@ $.Tile.prototype = {
delete this._caches[oldKey];
},
/**
* Check if two tiles are data-equal
* @param {OpenSeadragon.Tile} tile
*/
equals(tile) {
return this._ocKey === this._ocKey;
},
/**
* Removes tile from the system: it will still be present in the
* OSD memory, but marked as loaded=false, and its data will be erased.

View File

@ -176,7 +176,7 @@
* Returns undefined if the data is not ready for rendering.
* @private
*/
getDataForRendering(drawer, tileToDraw ) {
getDataForRendering(drawer, tileToDraw) {
const supportedTypes = drawer.getSupportedDataFormats(),
keepInternalCopy = drawer.options.usePrivateCache;
if (this.loaded && supportedTypes.includes(this.type)) {
@ -823,9 +823,14 @@
if (cacheRecord) {
// zombies should not be (yet) destroyed, but if we encounter one...
if (cacheRecord._destroyed) {
// if destroyed, invalidation routine will get triggered for us automatically
cacheRecord.revive();
} else {
// if zombie ready, do not overwrite its data
// if zombie ready, do not overwrite its data, in that case try to call
// we need to trigger invalidation routine, data was not part of the system!
if (typeof data === 'function') {
options.data();
}
delete options.data;
}
delete this._zombiesLoaded[cacheKey];

View File

@ -2732,7 +2732,8 @@ function getTileSourceImplementation( viewer, tileSource, imgOptions, successCal
waitUntilReady(new $TileSource(options), tileSource);
}
} else {
//can assume it's already a tile source implementation
//can assume it's already a tile source implementation, force inheritance
tileSource = $.extend({}, $.TileSource.prototype, tileSource);
waitUntilReady(tileSource, tileSource);
}
});

View File

@ -240,6 +240,17 @@
if(!this._backupCanvasDrawer){
this._backupCanvasDrawer = this.viewer.requestDrawer('canvas', {mainDrawer: false});
this._backupCanvasDrawer.canvas.style.setProperty('visibility', 'hidden');
this._backupCanvasDrawer.getSupportedDataFormats = () => this._supportedFormats;
this._backupCanvasDrawer.getDataToDraw = (tile) => {
const cache = tile.getCache(tile.cacheKey);
if (!cache) {
$.console.warn("Attempt to draw tile %s when not cached!", tile);
return undefined;
}
const dataCache = cache.getDataForRendering(this, tile);
// Use CPU Data for the drawer instead
return dataCache && dataCache.cpuData;
};
}
return this._backupCanvasDrawer;
@ -926,7 +937,8 @@
// TextureInfo stored in the cache
return {
texture: texture,
position: position
position: position,
cpuData: data // Reference to the outer cache data, used to draw if webgl canont be used
};
};
const tex2DCompatibleDestructor = textureInfo => {