Dispatch pre-render before rendering

This commit is contained in:
Tim Schaub
2018-11-14 18:47:34 +01:00
parent 8eb48604e9
commit c137b68938
+59 -78
View File
@@ -4,7 +4,7 @@
import {getUid} from '../../util.js'; import {getUid} from '../../util.js';
import TileRange from '../../TileRange.js'; import TileRange from '../../TileRange.js';
import TileState from '../../TileState.js'; import TileState from '../../TileState.js';
import {createEmpty, equals, getIntersection, isEmpty} from '../../extent.js'; import {createEmpty, getIntersection} from '../../extent.js';
import {createCanvasContext2D} from '../../dom.js'; import {createCanvasContext2D} from '../../dom.js';
import CanvasLayerRenderer from './Layer.js'; import CanvasLayerRenderer from './Layer.js';
import {create as createTransform, compose as composeTransform} from '../../transform.js'; import {create as createTransform, compose as composeTransform} from '../../transform.js';
@@ -49,12 +49,6 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
*/ */
this.renderedExtent_ = null; this.renderedExtent_ = null;
/**
* @private
* @type {number}
*/
this.renderedPixelRatio_ = 1;
/** /**
* @protected * @protected
* @type {number} * @type {number}
@@ -144,6 +138,14 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
* @inheritDoc * @inheritDoc
*/ */
prepareFrame(frameState, layerState) { prepareFrame(frameState, layerState) {
return true;
}
/**
* @inheritDoc
*/
renderFrame(frameState, layerState) {
const context = this.context;
const size = frameState.size; const size = frameState.size;
const viewState = frameState.viewState; const viewState = frameState.viewState;
const projection = viewState.projection; const projection = viewState.projection;
@@ -163,10 +165,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
if (layerState.extent !== undefined) { if (layerState.extent !== undefined) {
extent = getIntersection(extent, layerState.extent); extent = getIntersection(extent, layerState.extent);
} }
if (isEmpty(extent)) {
// Return false to prevent the rendering of the layer.
return false;
}
// TODO: clip by layer extent // TODO: clip by layer extent
const tilePixelRatio = tileSource.getTilePixelRatio(pixelRatio); const tilePixelRatio = tileSource.getTilePixelRatio(pixelRatio);
@@ -238,59 +237,57 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
} }
} }
if (this.newTiles_ || !this.renderedExtent_ || !equals(canvasExtent, this.renderedExtent_)) { const canvas = context.canvas;
if (canvas.width != width || canvas.height != height) {
const context = this.context; canvas.width = width;
const canvas = context.canvas; canvas.height = height;
if (canvas.width != width || canvas.height != height) { } else {
canvas.width = width; context.clearRect(0, 0, width, height);
canvas.height = height;
} else {
context.clearRect(0, 0, width, height);
}
this.renderedTiles.length = 0;
/** @type {Array<number>} */
const zs = Object.keys(tilesToDrawByZ).map(Number);
zs.sort(function(a, b) {
if (a === z) {
return 1;
} else if (b === z) {
return -1;
} else {
return a > b ? 1 : a < b ? -1 : 0;
}
});
for (let i = 0, ii = zs.length; i < ii; ++i) {
const currentZ = zs[i];
const currentTilePixelSize = tileSource.getTilePixelSize(currentZ, pixelRatio, projection);
const currentResolution = tileGrid.getResolution(currentZ);
const currentScale = currentResolution / tileResolution;
const w = currentTilePixelSize[0] * currentScale;
const h = currentTilePixelSize[1] * currentScale;
const tileGutter = tilePixelRatio * tileSource.getGutterForProjection(projection);
const tilesToDraw = tilesToDrawByZ[currentZ];
for (const tileCoordKey in tilesToDraw) {
const tile = tilesToDraw[tileCoordKey];
const tileExtent = tileGrid.getTileCoordExtent(tile.getTileCoord(), tmpExtent);
const x = Math.round(tilePixelRatio * (tileExtent[0] - canvasExtent[0]) / tileResolution);
const y = Math.round(tilePixelRatio * (canvasExtent[3] - tileExtent[3]) / tileResolution);
this.drawTileImage(tile, frameState, layerState, x, y, w, h, tileGutter, z === currentZ);
this.renderedTiles.push(tile);
}
}
this.renderedRevision = sourceRevision;
this.renderedResolution = tileResolution;
this.renderedPixelRatio_ = tilePixelRatio;
this.renderedExtent_ = canvasExtent;
} }
this.preRender(context, frameState);
this.renderedTiles.length = 0;
/** @type {Array<number>} */
const zs = Object.keys(tilesToDrawByZ).map(Number);
zs.sort(function(a, b) {
if (a === z) {
return 1;
} else if (b === z) {
return -1;
} else {
return a > b ? 1 : a < b ? -1 : 0;
}
});
for (let i = 0, ii = zs.length; i < ii; ++i) {
const currentZ = zs[i];
const currentTilePixelSize = tileSource.getTilePixelSize(currentZ, pixelRatio, projection);
const currentResolution = tileGrid.getResolution(currentZ);
const currentScale = currentResolution / tileResolution;
const w = currentTilePixelSize[0] * currentScale;
const h = currentTilePixelSize[1] * currentScale;
const tileGutter = tilePixelRatio * tileSource.getGutterForProjection(projection);
const tilesToDraw = tilesToDrawByZ[currentZ];
for (const tileCoordKey in tilesToDraw) {
const tile = tilesToDraw[tileCoordKey];
const tileExtent = tileGrid.getTileCoordExtent(tile.getTileCoord(), tmpExtent);
const x = Math.round(tilePixelRatio * (tileExtent[0] - canvasExtent[0]) / tileResolution);
const y = Math.round(tilePixelRatio * (canvasExtent[3] - tileExtent[3]) / tileResolution);
this.drawTileImage(tile, frameState, layerState, x, y, w, h, tileGutter, z === currentZ);
this.renderedTiles.push(tile);
}
}
this.renderedRevision = sourceRevision;
this.renderedResolution = tileResolution;
this.renderedExtent_ = canvasExtent;
const scale = this.renderedResolution / frameState.viewState.resolution; const scale = this.renderedResolution / frameState.viewState.resolution;
const halfWidth = width / 2; const halfWidth = width / 2;
const halfHeight = height / 2; const halfHeight = height / 2;
// TODO: check where these are used and confirm they are correct
const transform = composeTransform( const transform = composeTransform(
this.imageTransform_, this.imageTransform_,
halfWidth, halfHeight, halfWidth, halfHeight,
@@ -305,39 +302,23 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
0, 0,
-viewCenter[0], -viewCenter[1]); -viewCenter[0], -viewCenter[1]);
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange); this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
this.manageTilePyramid(frameState, tileSource, tileGrid, pixelRatio, this.manageTilePyramid(frameState, tileSource, tileGrid, pixelRatio,
projection, extent, z, tileLayer.getPreload()); projection, extent, z, tileLayer.getPreload());
this.scheduleExpireCache(frameState, tileSource); this.scheduleExpireCache(frameState, tileSource);
return this.renderedTiles.length > 0;
}
/**
* @inheritDoc
*/
renderFrame(frameState, layerState) {
const context = this.context;
this.preRender(context, frameState);
// consider moving work from prepareFrame to here
this.postRender(context, frameState, layerState); this.postRender(context, frameState, layerState);
const canvas = context.canvas;
const opacity = layerState.opacity; const opacity = layerState.opacity;
if (opacity !== canvas.style.opacity) { if (opacity !== canvas.style.opacity) {
canvas.style.opacity = opacity; canvas.style.opacity = opacity;
} }
const rotation = frameState.viewState.rotation; const canvasScale = this.renderedResolution / frameState.viewState.resolution / tilePixelRatio;
const scale = this.renderedResolution / frameState.viewState.resolution / this.renderedPixelRatio_;
const transform = 'rotate(' + rotation + 'rad) scale(' + scale + ')'; const canvasTransform = 'rotate(' + rotation + 'rad) scale(' + canvasScale + ')';
if (transform !== canvas.style.transform) { if (canvasTransform !== canvas.style.transform) {
canvas.style.transform = transform; canvas.style.transform = canvasTransform;
} }
return canvas; return canvas;