From 207bc88aabfd388d5bf8f2157977be91cf647c81 Mon Sep 17 00:00:00 2001 From: Aiosa <469130@mail.muni.cz> Date: Wed, 23 Oct 2024 14:37:43 +0200 Subject: [PATCH] Fix demo further: _queuedInvalidateTiles was not being used, simplify how tile cache updates are being called (but without priorities). --- src/tile.js | 2 +- src/tilecache.js | 8 +++--- src/tiledimage.js | 10 ++----- src/viewer.js | 4 +-- src/world.js | 71 ++++++++++++++++++++++------------------------- 5 files changed, 43 insertions(+), 52 deletions(-) diff --git a/src/tile.js b/src/tile.js index 6e03affb..c24dcddc 100644 --- a/src/tile.js +++ b/src/tile.js @@ -264,7 +264,7 @@ $.Tile = function(level, x, y, bounds, exists, url, context2D, loadWithAjax, aja this._wcKey = `w${_workingCacheIdDealer++}://` + this.originalCacheKey; /** * Processing flag, exempt the tile from removal when there are ongoing updates - * @member {Boolean} + * @member {Boolean|Number} * @private */ this.processing = false; diff --git a/src/tilecache.js b/src/tilecache.js index 9bd1e076..288cc0c1 100644 --- a/src/tilecache.js +++ b/src/tilecache.js @@ -230,8 +230,7 @@ prepareForRendering(drawerId, supportedTypes, keepInternalCopy = true, _shareTileUpdateStamp = null) { const fin = () => { - // Locked update of render target, - console.log("FINISH CACHE PREPARE", this._tRef); + // Locked update of render target to the tile that initiated processing if (_shareTileUpdateStamp) { for (let tile of this._tiles) { if (tile.processing === _shareTileUpdateStamp) { @@ -1088,10 +1087,11 @@ /** * Returns reference to all tiles loaded by a particular * tiled image item - * @param {OpenSeadragon.TiledImage|Boolean} tiledImage true for all, reference for selection + * @param {OpenSeadragon.TiledImage|null} tiledImage if null, gets all tiles, else filters out tiles + * that belong to a specific image */ getLoadedTilesFor(tiledImage) { - if (tiledImage === true) { + if (!tiledImage) { return [...this._tilesLoaded]; } return this._tilesLoaded.filter(tile => tile.tiledImage === tiledImage); diff --git a/src/tiledimage.js b/src/tiledimage.js index cbb95246..0421cb97 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -284,12 +284,11 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag * as outdated, and fire tile update event on relevant tiles * Detailed description is available within the 'tile-invalidated' * event. + * @param {Boolean} [restoreTiles=true] if true, tile processing starts from the tile original data * @param {boolean} [viewportOnly=false] optionally invalidate only viewport-visible tiles if true * @param {number} [tStamp=OpenSeadragon.now()] optionally provide tStamp of the update event - * @param {Boolean} [restoreTiles=true] if true, tile processing starts from the tile original data */ - requestInvalidate: function (viewportOnly, tStamp, restoreTiles = true) { - tStamp = tStamp || $.now(); + requestInvalidate: function (restoreTiles = true, viewportOnly = false, tStamp = $.now()) { const tiles = viewportOnly ? this._lastDrawn.map(x => x.tile) : this._tileCache.getLoadedTilesFor(this); return this.viewer.world.requestTileInvalidateEvent(tiles, tStamp, restoreTiles); }, @@ -2118,10 +2117,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag eventFinished = false; const _this = this, finishPromise = new $.Promise(r => { - resolver = () => { - console.log("TILE READY", tile); - r(); - }; + resolver = r; }); function completionCallback() { diff --git a/src/viewer.js b/src/viewer.js index 43cc05d0..558d2cc4 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -778,11 +778,11 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, } const tStamp = $.now(); - const worldPromise = this.world.requestInvalidate(tStamp, restoreTiles); + const worldPromise = this.world.requestInvalidate(restoreTiles, tStamp); if (!this.navigator) { return worldPromise; } - const navigatorPromise = this.navigator.world.requestInvalidate(tStamp, restoreTiles); + const navigatorPromise = this.navigator.world.requestInvalidate(restoreTiles, tStamp); return $.Promise.all([worldPromise, navigatorPromise]); }, diff --git a/src/world.js b/src/world.js index 33b85f78..f903b322 100644 --- a/src/world.js +++ b/src/world.js @@ -54,7 +54,6 @@ $.World = function( options ) { this._needsDraw = false; this._autoRefigureSizes = true; this._needsSizesFigured = false; - this._queuedInvalidateTiles = []; this._delegatedFigureSizes = function(event) { if (_this._autoRefigureSizes) { _this._figureSizes(); @@ -238,40 +237,59 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W * as outdated, and fire tile update event on relevant tiles * Detailed description is available within the 'tile-invalidated' * event. - * @param {number} [tStamp=OpenSeadragon.now()] optionally provide tStamp of the update event * @param {Boolean} [restoreTiles=true] if true, tile processing starts from the tile original data + * @param {number} [tStamp=OpenSeadragon.now()] optionally provide tStamp of the update event * @function * @fires OpenSeadragon.Viewer.event:tile-invalidated * @return {OpenSeadragon.Promise} */ - requestInvalidate: function (tStamp, restoreTiles = true) { - $.__updated = tStamp = tStamp || $.now(); + requestInvalidate: function (restoreTiles = true, tStamp = $.now()) { + $.__updated = tStamp; + // const priorityTiles = this._items.map(item => item._lastDrawn.map(x => x.tile)).flat(); + // const promise = this.requestTileInvalidateEvent(priorityTiles, tStamp, restoreTiles); + // return promise.then(() => this.requestTileInvalidateEvent(this.viewer.tileCache.getLoadedTilesFor(null), tStamp, restoreTiles)); - const promises = this._items.map(item => item.requestInvalidate(true, tStamp, restoreTiles)); + // + //return this.requestTileInvalidateEvent(this.viewer.tileCache.getLoadedTilesFor(null), tStamp, restoreTiles); - const tiles = this.viewer.tileCache.getLoadedTilesFor(true); - promises.push(this.requestTileInvalidateEvent(tiles, tStamp, restoreTiles)); - return $.Promise.all(promises); + // Try go cache-first order, ensuring all tiles that do have cache entry get processed + return this.requestTileInvalidateEvent(new Set(Object.values(this.viewer.tileCache._cachesLoaded).map(c => !c._destroyed && c._tiles[0])), tStamp, restoreTiles); }, /** * Requests tile data update. * @function OpenSeadragon.Viewer.prototype._updateSequenceButtons * @private - * @param {Array} tileList tiles to update + * @param {Iterable} tilesToProcess tiles to update * @param {Number} tStamp timestamp in milliseconds, if active timestamp of the same value is executing, * changes are added to the cycle, else they await next iteration * @param {Boolean} [restoreTiles=true] if true, tile processing starts from the tile original data * @fires OpenSeadragon.Viewer.event:tile-invalidated * @return {OpenSeadragon.Promise} */ - requestTileInvalidateEvent: function(tileList, tStamp, restoreTiles = true) { - if (tileList.length < 1) { - return $.Promise.resolve(); + requestTileInvalidateEvent: function(tilesToProcess, tStamp, restoreTiles = true) { + const tileList = []; + for (const tile of tilesToProcess) { + //todo if tiles are processing then it does not update them to the latest stage + // but if we do allow it, then a collision on processing occurs - swap in middle of rendering, we need + // to check what is the latest processing stamp and if it is bigger than current process finish we need to abort + if (!tile || !tile.loaded || tile.processing) { /* || tile.processing*/ + continue; + } + const tileCache = tile.getCache(); + if (tileCache._updateStamp >= tStamp) { + continue; + } + tileCache._updateStamp = tStamp; + + for (let t of tileCache._tiles) { + // Mark all as processing + t.processing = tStamp; + } + tileList.push(tile); } - if (this._queuedInvalidateTiles.length) { - this._queuedInvalidateTiles.push(tileList); + if (!tileList.length) { return $.Promise.resolve(); } @@ -281,23 +299,6 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W const keepInternalCacheCopy = eventTarget.drawer.options.usePrivateCache; const drawerId = eventTarget.drawer.getId(); - tileList = tileList.filter(tile => { - if (!tile.loaded || tile.processing) { - return false; - } - const tileCache = tile.getCache(); - if (tileCache._updateStamp >= tStamp) { - return false; - } - tileCache._updateStamp = tStamp; - - for (let t of tileCache._tiles) { - // Mark all as processing - t.processing = true; - } - return true; - }); - const jobList = tileList.map(tile => { if (restoreTiles) { tile.restore(); @@ -323,13 +324,7 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W } } - if (this._queuedInvalidateTiles.length) { - // Make space for other logics execution before we continue in processing - let list = this._queuedInvalidateTiles.splice(0, 1)[0]; - this.requestTileInvalidateEvent(list, tStamp, restoreTiles); - } else { - this.draw(); - } + this.draw(); }); },