Configure cache on the layer instead of the source
This commit is contained in:
@@ -63,6 +63,8 @@ import {assign} from '../obj.js';
|
|||||||
* temporary layers. The standard way to add a layer to a map and have it managed by the map is to
|
* temporary layers. The standard way to add a layer to a map and have it managed by the map is to
|
||||||
* use {@link module:ol/Map#addLayer}.
|
* use {@link module:ol/Map#addLayer}.
|
||||||
* @property {boolean} [useInterimTilesOnError=true] Use interim tiles on error.
|
* @property {boolean} [useInterimTilesOnError=true] Use interim tiles on error.
|
||||||
|
* @property {number} [cacheSize=512] The internal texture cache size. This needs to be large enough to render
|
||||||
|
* two zoom levels worth of tiles.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -265,12 +267,23 @@ class WebGLTileLayer extends BaseTileLayer {
|
|||||||
|
|
||||||
const style = options.style || {};
|
const style = options.style || {};
|
||||||
delete options.style;
|
delete options.style;
|
||||||
|
|
||||||
|
const cacheSize = options.cacheSize;
|
||||||
|
delete options.cacheSize;
|
||||||
|
|
||||||
super(options);
|
super(options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Style}
|
* @type {Style}
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
this.style_ = style;
|
this.style_ = style;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {number}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.cacheSize_ = cacheSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -292,6 +305,7 @@ class WebGLTileLayer extends BaseTileLayer {
|
|||||||
fragmentShader: parsedStyle.fragmentShader,
|
fragmentShader: parsedStyle.fragmentShader,
|
||||||
uniforms: parsedStyle.uniforms,
|
uniforms: parsedStyle.uniforms,
|
||||||
className: this.getClassName(),
|
className: this.getClassName(),
|
||||||
|
cacheSize: this.cacheSize_,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ const attributeDescriptions = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const empty = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform a zoom level into a depth value ranging from -1 to 1.
|
* Transform a zoom level into a depth value ranging from -1 to 1.
|
||||||
* @param {number} z A zoom level.
|
* @param {number} z A zoom level.
|
||||||
@@ -103,6 +105,7 @@ function getRenderExtent(frameState) {
|
|||||||
* @property {Object<string, import("../../webgl/Helper").UniformValue>} [uniforms] Additional uniforms
|
* @property {Object<string, import("../../webgl/Helper").UniformValue>} [uniforms] Additional uniforms
|
||||||
* made available to shaders.
|
* made available to shaders.
|
||||||
* @property {string} [className='ol-layer'] A CSS class name to set to the canvas element.
|
* @property {string} [className='ol-layer'] A CSS class name to set to the canvas element.
|
||||||
|
* @property {number} [cacheSize=512] The texture cache size.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -177,7 +180,8 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
|||||||
this.helper.flushBufferData(indices);
|
this.helper.flushBufferData(indices);
|
||||||
this.indices_ = indices;
|
this.indices_ = indices;
|
||||||
|
|
||||||
this.tileTextureCache_ = new LRUCache(512);
|
const cacheSize = options.cacheSize !== undefined ? options.cacheSize : 512;
|
||||||
|
this.tileTextureCache_ = new LRUCache(cacheSize);
|
||||||
|
|
||||||
this.renderedOpacity_ = NaN;
|
this.renderedOpacity_ = NaN;
|
||||||
}
|
}
|
||||||
@@ -468,23 +472,17 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: let the renderers manage their own cache instead of managing the source cache
|
// TODO: let the renderers manage their own cache instead of managing the source cache
|
||||||
if (tileSource.canExpireCache()) {
|
/**
|
||||||
/**
|
* Here we unconditionally expire the source cache since the renderer maintains
|
||||||
* @param {import("../../PluggableMap.js").default} map Map.
|
* its own cache.
|
||||||
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
|
* @param {import("../../PluggableMap.js").default} map Map.
|
||||||
*/
|
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
|
||||||
const postRenderFunction = function (map, frameState) {
|
*/
|
||||||
const tileSourceKey = getUid(tileSource);
|
const postRenderFunction = function (map, frameState) {
|
||||||
if (tileSourceKey in frameState.usedTiles) {
|
tileSource.expireCache(tileSource.getProjection(), empty);
|
||||||
tileSource.expireCache(
|
};
|
||||||
frameState.viewState.projection,
|
|
||||||
frameState.usedTiles[tileSourceKey]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
frameState.postRenderFunctions.push(postRenderFunction);
|
frameState.postRenderFunctions.push(postRenderFunction);
|
||||||
}
|
|
||||||
|
|
||||||
this.postRender(frameState);
|
this.postRender(frameState);
|
||||||
return canvas;
|
return canvas;
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import {getUid} from '../util.js';
|
|||||||
* @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid.
|
* @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid.
|
||||||
* @property {boolean} [opaque=false] Whether the layer is opaque.
|
* @property {boolean} [opaque=false] Whether the layer is opaque.
|
||||||
* @property {import("./State.js").default} [state] The source state.
|
* @property {import("./State.js").default} [state] The source state.
|
||||||
* @property {number} [cacheSize] Number of tiles to retain in the cache.
|
|
||||||
* @property {number} [tilePixelRatio] Tile pixel ratio.
|
* @property {number} [tilePixelRatio] Tile pixel ratio.
|
||||||
* @property {boolean} [wrapX=true] Render tiles beyond the antimeridian.
|
* @property {boolean} [wrapX=true] Render tiles beyond the antimeridian.
|
||||||
* @property {number} [transition] Transition time when fading in new tiles (in miliseconds).
|
* @property {number} [transition] Transition time when fading in new tiles (in miliseconds).
|
||||||
@@ -56,7 +55,7 @@ class DataTileSource extends TileSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
super({
|
super({
|
||||||
cacheSize: options.cacheSize,
|
cacheSize: 0.1, // don't cache on the source
|
||||||
projection: projection,
|
projection: projection,
|
||||||
tileGrid: tileGrid,
|
tileGrid: tileGrid,
|
||||||
opaque: options.opaque,
|
opaque: options.opaque,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import WebGLHelper from '../../../../../src/ol/webgl/Helper.js';
|
|||||||
import WebGLTileLayer from '../../../../../src/ol/layer/WebGLTile.js';
|
import WebGLTileLayer from '../../../../../src/ol/layer/WebGLTile.js';
|
||||||
import {createCanvasContext2D} from '../../../../../src/ol/dom.js';
|
import {createCanvasContext2D} from '../../../../../src/ol/dom.js';
|
||||||
|
|
||||||
describe('ol.layer.Tile', function () {
|
describe('ol/layer/WebGLTile', function () {
|
||||||
/** @type {WebGLTileLayer} */
|
/** @type {WebGLTileLayer} */
|
||||||
let layer;
|
let layer;
|
||||||
/** @type {Map} */
|
/** @type {Map} */
|
||||||
@@ -120,6 +120,17 @@ describe('ol.layer.Tile', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('tries to expire the source tile cache', (done) => {
|
||||||
|
const source = layer.getSource();
|
||||||
|
const expire = sinon.spy(source, 'expireCache');
|
||||||
|
|
||||||
|
layer.updateStyleVariables({r: 1, g: 2, b: 3});
|
||||||
|
map.once('rendercomplete', () => {
|
||||||
|
expect(expire.called).to.be(true);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('throws on incorrect style configs', function () {
|
it('throws on incorrect style configs', function () {
|
||||||
function incorrectStyle() {
|
function incorrectStyle() {
|
||||||
layer.style_ = {
|
layer.style_ = {
|
||||||
|
|||||||
@@ -54,6 +54,11 @@ describe('ol.renderer.webgl.TileLayer', function () {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('maintains a cache on the renderer instead of the source', function () {
|
||||||
|
expect(tileLayer.getSource().tileCache.highWaterMark).to.be(0.1);
|
||||||
|
expect(renderer.tileTextureCache_.highWaterMark).to.be(512);
|
||||||
|
});
|
||||||
|
|
||||||
it('#prepareFrame()', function () {
|
it('#prepareFrame()', function () {
|
||||||
const source = tileLayer.getSource();
|
const source = tileLayer.getSource();
|
||||||
tileLayer.setSource(null);
|
tileLayer.setSource(null);
|
||||||
@@ -73,7 +78,7 @@ describe('ol.renderer.webgl.TileLayer', function () {
|
|||||||
expect(rendered).to.be.a(HTMLCanvasElement);
|
expect(rendered).to.be.a(HTMLCanvasElement);
|
||||||
expect(frameState.tileQueue.getCount()).to.be(1);
|
expect(frameState.tileQueue.getCount()).to.be(1);
|
||||||
expect(Object.keys(frameState.wantedTiles).length).to.be(1);
|
expect(Object.keys(frameState.wantedTiles).length).to.be(1);
|
||||||
expect(frameState.postRenderFunctions.length).to.be(0); // no tile expired
|
expect(frameState.postRenderFunctions.length).to.be(1); // clear source cache (use renderer cache)
|
||||||
expect(renderer.tileTextureCache_.count_).to.be(1);
|
expect(renderer.tileTextureCache_.count_).to.be(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user