Merge pull request #9592 from fredj/f9587_layerIndex

Remove `layerState` param from `prepareFrame` and `renderFrame` function
This commit is contained in:
Frédéric Junod
2019-05-29 09:27:38 +02:00
committed by GitHub
17 changed files with 87 additions and 40 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -0,0 +1,30 @@
import Map from '../../../src/ol/Map.js';
import View from '../../../src/ol/View.js';
import {Group as LayerGroup, Tile as TileLayer} from '../../../src/ol/layer.js';
import XYZ from '../../../src/ol/source/XYZ.js';
new Map({
target: 'map',
view: new View({
center: [0, 0],
zoom: 3
}),
layers: new LayerGroup({
opacity: 0.75,
layers: [
new TileLayer({
opacity: 0.25,
source: new XYZ({
url: '/data/tiles/satellite/{z}/{x}/{y}.jpg'
})
}),
new TileLayer({
source: new XYZ({
url: '/data/tiles/stamen-labels/{z}/{x}/{y}.png'
})
})
]
})
});
render();

View File

@@ -43,6 +43,7 @@ import {create as createTransform, apply as applyTransform} from './transform.js
* @property {import("./coordinate.js").Coordinate} focus * @property {import("./coordinate.js").Coordinate} focus
* @property {number} index * @property {number} index
* @property {Array<import("./layer/Layer.js").State>} layerStatesArray * @property {Array<import("./layer/Layer.js").State>} layerStatesArray
* @property {number} layerIndex
* @property {import("./transform.js").Transform} pixelToCoordinateTransform * @property {import("./transform.js").Transform} pixelToCoordinateTransform
* @property {Array<PostRenderFunction>} postRenderFunctions * @property {Array<PostRenderFunction>} postRenderFunctions
* @property {import("./size.js").Size} size * @property {import("./size.js").Size} size
@@ -1231,13 +1232,14 @@ class PluggableMap extends BaseObject {
if (size !== undefined && hasArea(size) && view && view.isDef()) { if (size !== undefined && hasArea(size) && view && view.isDef()) {
const viewHints = view.getHints(this.frameState_ ? this.frameState_.viewHints : undefined); const viewHints = view.getHints(this.frameState_ ? this.frameState_.viewHints : undefined);
viewState = view.getState(this.pixelRatio_); viewState = view.getState(this.pixelRatio_);
frameState = /** @type {FrameState} */ ({ frameState = {
animate: false, animate: false,
coordinateToPixelTransform: this.coordinateToPixelTransform_, coordinateToPixelTransform: this.coordinateToPixelTransform_,
declutterItems: previousFrameState ? previousFrameState.declutterItems : [], declutterItems: previousFrameState ? previousFrameState.declutterItems : [],
extent: extent, extent: extent,
focus: this.focus_ ? this.focus_ : viewState.center, focus: this.focus_ ? this.focus_ : viewState.center,
index: this.frameIndex_++, index: this.frameIndex_++,
layerIndex: 0,
layerStatesArray: this.getLayerGroup().getLayerStatesArray(), layerStatesArray: this.getLayerGroup().getLayerStatesArray(),
pixelRatio: this.pixelRatio_, pixelRatio: this.pixelRatio_,
pixelToCoordinateTransform: this.pixelToCoordinateTransform_, pixelToCoordinateTransform: this.pixelToCoordinateTransform_,
@@ -1250,7 +1252,7 @@ class PluggableMap extends BaseObject {
viewState: viewState, viewState: viewState,
viewHints: viewHints, viewHints: viewHints,
wantedTiles: {} wantedTiles: {}
}); };
} }
if (frameState) { if (frameState) {

View File

@@ -83,6 +83,9 @@ class BaseLayer extends BaseObject {
} }
/** /**
* This method is not meant to be called by layers or layer renderers because the state
* is incorrect if the layer is included in a layer group.
*
* @param {boolean=} opt_managed Layer is managed. * @param {boolean=} opt_managed Layer is managed.
* @return {import("./Layer.js").State} Layer state. * @return {import("./Layer.js").State} Layer state.
*/ */

View File

@@ -195,9 +195,9 @@ class Layer extends BaseLayer {
*/ */
render(frameState, target) { render(frameState, target) {
const layerRenderer = this.getRenderer(); const layerRenderer = this.getRenderer();
const layerState = this.getLayerState();
if (layerRenderer.prepareFrame(frameState, layerState)) { if (layerRenderer.prepareFrame(frameState)) {
return layerRenderer.renderFrame(frameState, layerState, target); return layerRenderer.renderFrame(frameState, target);
} }
} }

View File

@@ -90,6 +90,7 @@ class CompositeMapRenderer extends MapRenderer {
let previousElement = null; let previousElement = null;
for (let i = 0, ii = layerStatesArray.length; i < ii; ++i) { for (let i = 0, ii = layerStatesArray.length; i < ii; ++i) {
const layerState = layerStatesArray[i]; const layerState = layerStatesArray[i];
frameState.layerIndex = i;
if (!visibleAtResolution(layerState, viewResolution) || if (!visibleAtResolution(layerState, viewResolution) ||
(layerState.sourceState != SourceState.READY && layerState.sourceState != SourceState.UNDEFINED)) { (layerState.sourceState != SourceState.READY && layerState.sourceState != SourceState.UNDEFINED)) {
continue; continue;

View File

@@ -29,10 +29,9 @@ class LayerRenderer extends Observable {
* Determine whether render should be called. * Determine whether render should be called.
* @abstract * @abstract
* @param {import("../PluggableMap.js").FrameState} frameState Frame state. * @param {import("../PluggableMap.js").FrameState} frameState Frame state.
* @param {import("../layer/Layer.js").State} layerState Layer state.
* @return {boolean} Layer is ready to be rendered. * @return {boolean} Layer is ready to be rendered.
*/ */
prepareFrame(frameState, layerState) { prepareFrame(frameState) {
return abstract(); return abstract();
} }
@@ -40,11 +39,10 @@ class LayerRenderer extends Observable {
* Render the layer. * Render the layer.
* @abstract * @abstract
* @param {import("../PluggableMap.js").FrameState} frameState Frame state. * @param {import("../PluggableMap.js").FrameState} frameState Frame state.
* @param {import("../layer/Layer.js").State} layerState Layer state.
* @param {HTMLElement} target Target that may be used to render content to. * @param {HTMLElement} target Target that may be used to render content to.
* @return {HTMLElement} The rendered element. * @return {HTMLElement} The rendered element.
*/ */
renderFrame(frameState, layerState, target) { renderFrame(frameState, target) {
return abstract(); return abstract();
} }

View File

@@ -38,7 +38,8 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
/** /**
* @inheritDoc * @inheritDoc
*/ */
prepareFrame(frameState, layerState) { prepareFrame(frameState) {
const layerState = frameState.layerStatesArray[frameState.layerIndex];
const pixelRatio = frameState.pixelRatio; const pixelRatio = frameState.pixelRatio;
const viewState = frameState.viewState; const viewState = frameState.viewState;
const viewResolution = viewState.resolution; const viewResolution = viewState.resolution;
@@ -72,11 +73,12 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
/** /**
* @inheritDoc * @inheritDoc
*/ */
renderFrame(frameState, layerState, target) { renderFrame(frameState, target) {
const image = this.image_; const image = this.image_;
const imageExtent = image.getExtent(); const imageExtent = image.getExtent();
const imageResolution = image.getResolution(); const imageResolution = image.getResolution();
const imagePixelRatio = image.getPixelRatio(); const imagePixelRatio = image.getPixelRatio();
const layerState = frameState.layerStatesArray[frameState.layerIndex];
const pixelRatio = frameState.pixelRatio; const pixelRatio = frameState.pixelRatio;
const viewState = frameState.viewState; const viewState = frameState.viewState;
const viewCenter = viewState.center; const viewCenter = viewState.center;

View File

@@ -125,7 +125,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
/** /**
* @inheritDoc * @inheritDoc
*/ */
prepareFrame(frameState, layerState) { prepareFrame(frameState) {
return true; return true;
} }
@@ -137,7 +137,8 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
* @inheritDoc * @inheritDoc
* @returns {HTMLElement} The rendered element. * @returns {HTMLElement} The rendered element.
*/ */
renderFrame(frameState, layerState, target) { renderFrame(frameState, target) {
const layerState = frameState.layerStatesArray[frameState.layerIndex];
const viewState = frameState.viewState; const viewState = frameState.viewState;
const projection = viewState.projection; const projection = viewState.projection;
const viewResolution = viewState.resolution; const viewResolution = viewState.resolution;

View File

@@ -63,7 +63,7 @@ class CanvasVectorImageLayerRenderer extends CanvasImageLayerRenderer {
/** /**
* @inheritDoc * @inheritDoc
*/ */
prepareFrame(frameState, layerState) { prepareFrame(frameState) {
const pixelRatio = frameState.pixelRatio; const pixelRatio = frameState.pixelRatio;
const viewState = frameState.viewState; const viewState = frameState.viewState;
const viewResolution = viewState.resolution; const viewResolution = viewState.resolution;
@@ -92,10 +92,10 @@ class CanvasVectorImageLayerRenderer extends CanvasImageLayerRenderer {
})); }));
const newSkippedFeatures = Object.keys(imageFrameState.skippedFeatureUids).sort(); const newSkippedFeatures = Object.keys(imageFrameState.skippedFeatureUids).sort();
const image = new ImageCanvas(renderedExtent, viewResolution, pixelRatio, context.canvas, function(callback) { const image = new ImageCanvas(renderedExtent, viewResolution, pixelRatio, context.canvas, function(callback) {
if (vectorRenderer.prepareFrame(imageFrameState, layerState) && if (vectorRenderer.prepareFrame(imageFrameState) &&
(vectorRenderer.replayGroupChanged || (vectorRenderer.replayGroupChanged ||
!equals(skippedFeatures, newSkippedFeatures))) { !equals(skippedFeatures, newSkippedFeatures))) {
vectorRenderer.renderFrame(imageFrameState, layerState, null); vectorRenderer.renderFrame(imageFrameState, null);
renderDeclutterItems(imageFrameState, null); renderDeclutterItems(imageFrameState, null);
skippedFeatures = newSkippedFeatures; skippedFeatures = newSkippedFeatures;
callback(); callback();

View File

@@ -80,9 +80,10 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
/** /**
* @inheritDoc * @inheritDoc
*/ */
renderFrame(frameState, layerState, target) { renderFrame(frameState, target) {
const pixelRatio = frameState.pixelRatio; const pixelRatio = frameState.pixelRatio;
const layerState = frameState.layerStatesArray[frameState.layerIndex];
// set forward and inverse pixel transforms // set forward and inverse pixel transforms
makeScale(this.pixelTransform_, 1 / pixelRatio, 1 / pixelRatio); makeScale(this.pixelTransform_, 1 / pixelRatio, 1 / pixelRatio);
@@ -232,7 +233,7 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
/** /**
* @inheritDoc * @inheritDoc
*/ */
prepareFrame(frameState, layerState) { prepareFrame(frameState) {
const vectorLayer = /** @type {import("../../layer/Vector.js").default} */ (this.getLayer()); const vectorLayer = /** @type {import("../../layer/Vector.js").default} */ (this.getLayer());
const vectorSource = vectorLayer.getSource(); const vectorSource = vectorLayer.getSource();

View File

@@ -218,13 +218,13 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
/** /**
* @inheritDoc * @inheritDoc
*/ */
prepareFrame(frameState, layerState) { prepareFrame(frameState) {
const layerRevision = this.getLayer().getRevision(); const layerRevision = this.getLayer().getRevision();
if (this.renderedLayerRevision_ != layerRevision) { if (this.renderedLayerRevision_ != layerRevision) {
this.renderedTiles.length = 0; this.renderedTiles.length = 0;
} }
this.renderedLayerRevision_ = layerRevision; this.renderedLayerRevision_ = layerRevision;
return super.prepareFrame(frameState, layerState); return super.prepareFrame(frameState);
} }
/** /**
@@ -390,12 +390,12 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
/** /**
* @inheritDoc * @inheritDoc
*/ */
renderFrame(frameState, layerState, target) { renderFrame(frameState, target) {
const viewHints = frameState.viewHints; const viewHints = frameState.viewHints;
const hifi = !(viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING]); const hifi = !(viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING]);
this.renderQueuedTileImages_(hifi, frameState); this.renderQueuedTileImages_(hifi, frameState);
super.renderFrame(frameState, layerState, target); super.renderFrame(frameState, target);
const layer = /** @type {import("../../layer/VectorTile.js").default} */ (this.getLayer()); const layer = /** @type {import("../../layer/VectorTile.js").default} */ (this.getLayer());
const renderMode = layer.getRenderMode(); const renderMode = layer.getRenderMode();
@@ -495,6 +495,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
} }
} }
if (declutterReplays) { if (declutterReplays) {
const layerState = frameState.layerStatesArray[frameState.layerIndex];
replayDeclutter(declutterReplays, context, rotation, layerState.opacity, hifi, frameState.declutterItems); replayDeclutter(declutterReplays, context, rotation, layerState.opacity, hifi, frameState.declutterItems);
} }

View File

@@ -284,7 +284,8 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
/** /**
* @inheritDoc * @inheritDoc
*/ */
renderFrame(frameState, layerState) { renderFrame(frameState) {
const layerState = frameState.layerStatesArray[frameState.layerIndex];
this.helper_.drawElements(0, this.indicesBuffer_.getArray().length); this.helper_.drawElements(0, this.indicesBuffer_.getArray().length);
this.helper_.finalizeDraw(frameState); this.helper_.finalizeDraw(frameState);
const canvas = this.helper_.getCanvas(); const canvas = this.helper_.getCanvas();

View File

@@ -214,6 +214,7 @@ class RasterSource extends ImageSource {
extent: null, extent: null,
focus: null, focus: null,
index: 0, index: 0,
layerIndex: 0,
layerStatesArray: getLayerStatesArray(this.layers_), layerStatesArray: getLayerStatesArray(this.layers_),
pixelRatio: 1, pixelRatio: 1,
pixelToCoordinateTransform: createTransform(), pixelToCoordinateTransform: createTransform(),
@@ -358,7 +359,8 @@ class RasterSource extends ImageSource {
const len = this.layers_.length; const len = this.layers_.length;
const imageDatas = new Array(len); const imageDatas = new Array(len);
for (let i = 0; i < len; ++i) { for (let i = 0; i < len; ++i) {
const imageData = getImageData(this.layers_[i], frameState, frameState.layerStatesArray[i]); frameState.layerIndex = i;
const imageData = getImageData(this.layers_[i], frameState);
if (imageData) { if (imageData) {
imageDatas[i] = imageData; imageDatas[i] = imageData;
} else { } else {
@@ -430,21 +432,20 @@ let sharedContext = null;
* Get image data from a layer. * Get image data from a layer.
* @param {import("../layer/Layer.js").default} layer Layer to render. * @param {import("../layer/Layer.js").default} layer Layer to render.
* @param {import("../PluggableMap.js").FrameState} frameState The frame state. * @param {import("../PluggableMap.js").FrameState} frameState The frame state.
* @param {import("../layer/Layer.js").State} layerState The layer state.
* @return {ImageData} The image data. * @return {ImageData} The image data.
*/ */
function getImageData(layer, frameState, layerState) { function getImageData(layer, frameState) {
const renderer = layer.getRenderer(); const renderer = layer.getRenderer();
if (!renderer) { if (!renderer) {
throw new Error('Unsupported layer type: ' + layer); throw new Error('Unsupported layer type: ' + layer);
} }
if (!renderer.prepareFrame(frameState, layerState)) { if (!renderer.prepareFrame(frameState)) {
return null; return null;
} }
const width = frameState.size[0]; const width = frameState.size[0];
const height = frameState.size[1]; const height = frameState.size[1];
const container = renderer.renderFrame(frameState, layerState, null); const container = renderer.renderFrame(frameState, null);
let element; let element;
if (container) { if (container) {
element = container.firstElementChild; element = container.firstElementChild;

View File

@@ -35,6 +35,8 @@ describe('ol/renderer/canvas/VectorImageLayer', function() {
projExtent[0] - 10000, -10000, projExtent[0] + 10000, 10000 projExtent[0] - 10000, -10000, projExtent[0] + 10000, 10000
]; ];
const frameState = { const frameState = {
layerStatesArray: [layer.getLayerState()],
layerIndex: 0,
extent: extent, extent: extent,
skippedFeatureUids: {}, skippedFeatureUids: {},
viewHints: [], viewHints: [],
@@ -44,7 +46,7 @@ describe('ol/renderer/canvas/VectorImageLayer', function() {
rotation: 0 rotation: 0
} }
}; };
renderer.prepareFrame(frameState, {}); renderer.prepareFrame(frameState);
const expected = renderer.image_.getExtent(); const expected = renderer.image_.getExtent();
scaleFromCenter(extent, 2); scaleFromCenter(extent, 2);

View File

@@ -243,7 +243,7 @@ describe('ol.renderer.canvas.VectorLayer', function() {
frameState.extent = frameState.extent =
[projExtent[0] - 10000, -10000, projExtent[0] + 10000, 10000]; [projExtent[0] - 10000, -10000, projExtent[0] + 10000, 10000];
renderer.prepareFrame(frameState, {}); renderer.prepareFrame(frameState);
expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([ expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([
projExtent[0] - worldWidth + buffer, projExtent[0] - worldWidth + buffer,
-10000, projExtent[2] + worldWidth - buffer, 10000 -10000, projExtent[2] + worldWidth - buffer, 10000
@@ -255,7 +255,7 @@ describe('ol.renderer.canvas.VectorLayer', function() {
frameState.extent = frameState.extent =
[projExtent[0] - 10000, -10000, projExtent[1] - 10000, 10000]; [projExtent[0] - 10000, -10000, projExtent[1] - 10000, 10000];
renderer.prepareFrame(frameState, {}); renderer.prepareFrame(frameState);
expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([ expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([
projExtent[0] - worldWidth + buffer, projExtent[0] - worldWidth + buffer,
-10000, projExtent[2] + worldWidth - buffer, 10000 -10000, projExtent[2] + worldWidth - buffer, 10000
@@ -266,7 +266,7 @@ describe('ol.renderer.canvas.VectorLayer', function() {
frameState.extent = frameState.extent =
[2 * projExtent[0] - 10000, -10000, 2 * projExtent[1] + 10000, 10000]; [2 * projExtent[0] - 10000, -10000, 2 * projExtent[1] + 10000, 10000];
renderer.prepareFrame(frameState, {}); renderer.prepareFrame(frameState);
expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([ expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([
projExtent[0] - worldWidth + buffer, projExtent[0] - worldWidth + buffer,
-10000, projExtent[2] + worldWidth - buffer, 10000 -10000, projExtent[2] + worldWidth - buffer, 10000
@@ -279,7 +279,7 @@ describe('ol.renderer.canvas.VectorLayer', function() {
projExtent[0] - 2 * worldWidth - 10000, projExtent[0] - 2 * worldWidth - 10000,
-10000, projExtent[1] + 2 * worldWidth + 10000, 10000 -10000, projExtent[1] + 2 * worldWidth + 10000, 10000
]; ];
renderer.prepareFrame(frameState, {}); renderer.prepareFrame(frameState);
expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([ expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([
projExtent[0] - 2 * worldWidth - 10000, projExtent[0] - 2 * worldWidth - 10000,
-10000, projExtent[2] + 2 * worldWidth + 10000, 10000 -10000, projExtent[2] + 2 * worldWidth + 10000, 10000
@@ -288,9 +288,9 @@ describe('ol.renderer.canvas.VectorLayer', function() {
it('sets replayGroupChanged correctly', function() { it('sets replayGroupChanged correctly', function() {
frameState.extent = [-10000, -10000, 10000, 10000]; frameState.extent = [-10000, -10000, 10000, 10000];
renderer.prepareFrame(frameState, {}); renderer.prepareFrame(frameState);
expect(renderer.replayGroupChanged).to.be(true); expect(renderer.replayGroupChanged).to.be(true);
renderer.prepareFrame(frameState, {}); renderer.prepareFrame(frameState);
expect(renderer.replayGroupChanged).to.be(false); expect(renderer.replayGroupChanged).to.be(false);
}); });
@@ -301,13 +301,15 @@ describe('ol.renderer.canvas.VectorLayer', function() {
expect(true); expect(true);
done(); done();
}); });
frameState.layerStatesArray = [layer.getLayerState()];
frameState.layerIndex = 0;
frameState.extent = [-10000, -10000, 10000, 10000]; frameState.extent = [-10000, -10000, 10000, 10000];
frameState.size = [100, 100]; frameState.size = [100, 100];
frameState.viewState.center = [0, 0]; frameState.viewState.center = [0, 0];
let rendered = false; let rendered = false;
if (renderer.prepareFrame(frameState, {})) { if (renderer.prepareFrame(frameState)) {
rendered = true; rendered = true;
renderer.renderFrame(frameState, layer.getLayerState(), null); renderer.renderFrame(frameState, null);
} }
expect(rendered).to.be(true); expect(rendered).to.be(true);
}); });

View File

@@ -234,6 +234,8 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
}; };
const proj = getProjection('EPSG:3857'); const proj = getProjection('EPSG:3857');
const frameState = { const frameState = {
layerStatesArray: [layer.getLayerState()],
layerIndex: 0,
extent: proj.getExtent(), extent: proj.getExtent(),
pixelRatio: 1, pixelRatio: 1,
time: Date.now(), time: Date.now(),
@@ -247,13 +249,13 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
usedTiles: {}, usedTiles: {},
wantedTiles: {} wantedTiles: {}
}; };
renderer.renderFrame(frameState, {}); renderer.renderFrame(frameState);
const replayState = renderer.renderedTiles[0].getReplayState(layer); const replayState = renderer.renderedTiles[0].getReplayState(layer);
const revision = replayState.renderedTileRevision; const revision = replayState.renderedTileRevision;
renderer.renderFrame(frameState, {}, null); renderer.renderFrame(frameState, null);
expect(replayState.renderedTileRevision).to.be(revision); expect(replayState.renderedTileRevision).to.be(revision);
layer.changed(); layer.changed();
renderer.renderFrame(frameState, {}, null); renderer.renderFrame(frameState, null);
expect(replayState.renderedTileRevision).to.be(revision + 1); expect(replayState.renderedTileRevision).to.be(revision + 1);
expect(Object.keys(renderer.tileListenerKeys_).length).to.be(0); expect(Object.keys(renderer.tileListenerKeys_).length).to.be(0);
}); });