mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-22 05:06:09 +03:00
In webgl drawer, fall back to canvas drawer for tiled images with tainted data
This commit is contained in:
parent
f7d86ac244
commit
0a154a3b21
@ -166,6 +166,7 @@ $.TiledImage = function( options ) {
|
|||||||
_lastDrawn: [], // array of tiles that were last fetched by the drawer
|
_lastDrawn: [], // array of tiles that were last fetched by the drawer
|
||||||
_isBlending: false, // Are any tiles still being blended?
|
_isBlending: false, // Are any tiles still being blended?
|
||||||
_wasBlending: false, // Were any tiles blending before the last draw?
|
_wasBlending: false, // Were any tiles blending before the last draw?
|
||||||
|
_isTainted: false, // Has a Tile been found with tainted data?
|
||||||
//configurable settings
|
//configurable settings
|
||||||
springStiffness: $.DEFAULT_SETTINGS.springStiffness,
|
springStiffness: $.DEFAULT_SETTINGS.springStiffness,
|
||||||
animationTime: $.DEFAULT_SETTINGS.animationTime,
|
animationTime: $.DEFAULT_SETTINGS.animationTime,
|
||||||
@ -326,6 +327,25 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
return this._needsDraw;
|
return this._needsDraw;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the internal _isTainted flag for this TiledImage. Lazy loaded - not
|
||||||
|
* checked each time a Tile is loaded, but can be set if a consumer of the
|
||||||
|
* tiles (e.g. a Drawer) discovers a Tile to have tainted data so that further
|
||||||
|
* checks are not needed and alternative rendering strategies can be used.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
setTainted(isTainted){
|
||||||
|
this._isTainted = isTainted;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @returns {Boolean} whether the TiledImage has been marked as tainted
|
||||||
|
*/
|
||||||
|
isTainted(){
|
||||||
|
return this._isTainted;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy the TiledImage (unload current loaded tiles).
|
* Destroy the TiledImage (unload current loaded tiles).
|
||||||
*/
|
*/
|
||||||
|
@ -90,6 +90,7 @@
|
|||||||
this._clippingCanvas = null;
|
this._clippingCanvas = null;
|
||||||
this._clippingContext = null;
|
this._clippingContext = null;
|
||||||
this._renderingCanvas = null;
|
this._renderingCanvas = null;
|
||||||
|
this._backupCanvasDrawer = null;
|
||||||
|
|
||||||
// Add listeners for events that require modifying the scene or camera
|
// Add listeners for events that require modifying the scene or camera
|
||||||
this.viewer.addHandler("tile-ready", ev => this._tileReadyHandler(ev));
|
this.viewer.addHandler("tile-ready", ev => this._tileReadyHandler(ev));
|
||||||
@ -206,6 +207,25 @@
|
|||||||
return canvas;
|
return canvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the backup renderer (CanvasDrawer) to use if data cannot be used by webgl
|
||||||
|
* Lazy loaded
|
||||||
|
* @private
|
||||||
|
* @returns {CanvasDrawer}
|
||||||
|
*/
|
||||||
|
_getBackupCanvasDrawer(){
|
||||||
|
if(!this._backupCanvasDrawer){
|
||||||
|
this._backupCanvasDrawer = new $.CanvasDrawer({
|
||||||
|
viewer: this.viewer,
|
||||||
|
viewport: this.viewport,
|
||||||
|
element: this.container,
|
||||||
|
});
|
||||||
|
this._backupCanvasDrawer.canvas.style.setProperty('visibility', 'hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._backupCanvasDrawer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {Array} tiledImages Array of TiledImage objects to draw
|
* @param {Array} tiledImages Array of TiledImage objects to draw
|
||||||
@ -237,6 +257,22 @@
|
|||||||
//iterate over tiled images and draw each one using a two-pass rendering pipeline if needed
|
//iterate over tiled images and draw each one using a two-pass rendering pipeline if needed
|
||||||
tiledImages.forEach( (tiledImage, tiledImageIndex) => {
|
tiledImages.forEach( (tiledImage, tiledImageIndex) => {
|
||||||
|
|
||||||
|
if(tiledImage.isTainted()){
|
||||||
|
// first, draw any data left in the rendering buffer onto the output canvas
|
||||||
|
if(renderingBufferHasImageData){
|
||||||
|
this._outputContext.drawImage(this._renderingCanvas, 0, 0);
|
||||||
|
// clear the buffer
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||||
|
gl.clear(gl.COLOR_BUFFER_BIT); // clear the back buffer
|
||||||
|
renderingBufferHasImageData = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// next, use the backup canvas drawer to draw this tainted image
|
||||||
|
const canvasDrawer = this._getBackupCanvasDrawer();
|
||||||
|
canvasDrawer.draw([tiledImage]);
|
||||||
|
this._outputContext.drawImage(canvasDrawer.canvas, 0, 0);
|
||||||
|
|
||||||
|
} else {
|
||||||
let tilesToDraw = tiledImage.getTilesToDraw();
|
let tilesToDraw = tiledImage.getTilesToDraw();
|
||||||
|
|
||||||
if(tilesToDraw.length === 0 || tiledImage.getOpacity() === 0){
|
if(tilesToDraw.length === 0 || tiledImage.getOpacity() === 0){
|
||||||
@ -399,6 +435,9 @@
|
|||||||
if(tiledImageIndex === 0){
|
if(tiledImageIndex === 0){
|
||||||
this._raiseTiledImageDrawnEvent(tiledImage, tilesToDraw.map(info=>info.tile));
|
this._raiseTiledImageDrawnEvent(tiledImage, tilesToDraw.map(info=>info.tile));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -802,7 +841,19 @@
|
|||||||
let tile = event.tile;
|
let tile = event.tile;
|
||||||
let tiledImage = event.tiledImage;
|
let tiledImage = event.tiledImage;
|
||||||
let tileContext = tile.getCanvasContext();
|
let tileContext = tile.getCanvasContext();
|
||||||
let canvas = tileContext.canvas;
|
let canvas = tileContext && tileContext.canvas;
|
||||||
|
// if the tile doesn't provide a canvas, or is tainted by cross-origin
|
||||||
|
// data, marked the TiledImage as tainted so the canvas drawer can be
|
||||||
|
// used instead, and return immediately - data cannot be uploaded to webgl
|
||||||
|
if(!canvas || $.isCanvasTainted(canvas)){
|
||||||
|
const wasTainted = tiledImage.isTainted();
|
||||||
|
if(!wasTainted){
|
||||||
|
tiledImage.setTainted(true);
|
||||||
|
$.console.warn('WebGL cannot be used to draw this TiledImage because it has tainted data. Does crossOriginPolicy need to be set?');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let textureInfo = this._TextureMap.get(canvas);
|
let textureInfo = this._TextureMap.get(canvas);
|
||||||
|
|
||||||
// if this is a new image for us, create a texture
|
// if this is a new image for us, create a texture
|
||||||
|
Loading…
Reference in New Issue
Block a user