Manage buffers in WebGL map renderer
This commit is contained in:
@@ -132,19 +132,6 @@ ol.renderer.webgl.Layer.prototype.bindFramebuffer =
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.disposeInternal = function() {
|
||||
var mapRenderer = this.getWebGLMapRenderer();
|
||||
var gl = mapRenderer.getGL();
|
||||
if (!gl.isContextLost()) {
|
||||
gl.deleteBuffer(this.arrayBuffer_);
|
||||
}
|
||||
goog.base(this, 'disposeInternal');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.vec.Mat4.Float32} Color matrix.
|
||||
*/
|
||||
|
||||
@@ -22,6 +22,7 @@ goog.require('ol.renderer.webgl.FragmentShader');
|
||||
goog.require('ol.renderer.webgl.ImageLayer');
|
||||
goog.require('ol.renderer.webgl.TileLayer');
|
||||
goog.require('ol.renderer.webgl.VertexShader');
|
||||
goog.require('ol.structs.Buffer');
|
||||
goog.require('ol.structs.LRUCache');
|
||||
goog.require('ol.webgl');
|
||||
goog.require('ol.webgl.WebGLContextEventType');
|
||||
@@ -33,6 +34,12 @@ goog.require('ol.webgl.WebGLContextEventType');
|
||||
ol.WEBGL_TEXTURE_CACHE_HIGH_WATER_MARK = 1024;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{buffer: WebGLBuffer}}
|
||||
*/
|
||||
ol.renderer.webgl.BufferCacheEntry;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{magFilter: number, minFilter: number, texture: WebGLTexture}}
|
||||
*/
|
||||
@@ -170,9 +177,20 @@ ol.renderer.webgl.Map = function(container, map) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {WebGLBuffer}
|
||||
* @type {ol.structs.Buffer}
|
||||
*/
|
||||
this.arrayBuffer_ = null;
|
||||
this.arrayBuffer_ = new ol.structs.Buffer([
|
||||
-1, -1, 0, 0,
|
||||
1, -1, 1, 0,
|
||||
-1, 1, 0, 1,
|
||||
1, 1, 1, 1
|
||||
]);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<number, ol.renderer.webgl.BufferCacheEntry>}
|
||||
*/
|
||||
this.bufferCache_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -216,6 +234,46 @@ ol.renderer.webgl.Map = function(container, map) {
|
||||
goog.inherits(ol.renderer.webgl.Map, ol.renderer.Map);
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} target Target.
|
||||
* @param {ol.structs.Buffer} buf Buffer.
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.bindBuffer = function(target, buf) {
|
||||
var gl = this.getGL();
|
||||
var arr = buf.getArray();
|
||||
// FIXME dirty set should be in buffer cache
|
||||
var dirtySet = buf.getDirtySet();
|
||||
var bufferKey = goog.getUid(buf);
|
||||
if (bufferKey in this.bufferCache_) {
|
||||
var bufferCacheEntry = this.bufferCache_[bufferKey];
|
||||
gl.bindBuffer(target, bufferCacheEntry.buffer);
|
||||
dirtySet.forEachRange(function(start, stop) {
|
||||
// FIXME check if slice is really efficient here
|
||||
var slice = arr.slice(start, stop);
|
||||
gl.bufferSubData(
|
||||
target,
|
||||
start,
|
||||
target == goog.webgl.ARRAY_BUFFER ?
|
||||
new Float32Array(slice) :
|
||||
new Uint16Array(slice));
|
||||
});
|
||||
} else {
|
||||
var buffer = gl.createBuffer();
|
||||
gl.bindBuffer(target, buffer);
|
||||
// FIXME should get STATIC/STREAM from buf
|
||||
gl.bufferData(
|
||||
target,
|
||||
target == goog.webgl.ARRAY_BUFFER ?
|
||||
new Float32Array(arr) : new Uint16Array(arr),
|
||||
goog.webgl.STATIC_DRAW);
|
||||
this.bufferCache_[bufferKey] = {
|
||||
buffer: buffer
|
||||
};
|
||||
}
|
||||
dirtySet.clear();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Tile} tile Tile.
|
||||
* @param {number} magFilter Mag filter.
|
||||
@@ -276,12 +334,31 @@ ol.renderer.webgl.Map.prototype.createLayerRenderer = function(layer) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.structs.Buffer} buf Buffer.
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.deleteBuffer = function(buf) {
|
||||
var gl = this.getGL();
|
||||
var arr = buf.getArray();
|
||||
var bufferKey = goog.getUid(buf);
|
||||
goog.asserts.assert(bufferKey in this.bufferCache_);
|
||||
var bufferCacheEntry = this.bufferCache_[bufferKey];
|
||||
if (!gl.isContextLost()) {
|
||||
gl.deleteBuffer(bufferCacheEntry.buffer);
|
||||
}
|
||||
delete this.bufferCache_[bufferKey];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.disposeInternal = function() {
|
||||
var gl = this.getGL();
|
||||
if (!gl.isContextLost()) {
|
||||
goog.object.forEach(this.bufferCache_, function(bufferCacheEntry) {
|
||||
gl.deleteBuffer(bufferCacheEntry.buffer);
|
||||
});
|
||||
goog.object.forEach(this.programCache_, function(program) {
|
||||
gl.deleteProgram(program);
|
||||
});
|
||||
@@ -409,7 +486,7 @@ ol.renderer.webgl.Map.prototype.handleWebGLContextLost = function(event) {
|
||||
}
|
||||
event.preventDefault();
|
||||
this.locations_ = null;
|
||||
this.arrayBuffer_ = null;
|
||||
this.bufferCache_ = {};
|
||||
this.shaderCache_ = {};
|
||||
this.programCache_ = {};
|
||||
this.textureCache_.clear();
|
||||
@@ -511,19 +588,7 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
|
||||
};
|
||||
}
|
||||
|
||||
if (goog.isNull(this.arrayBuffer_)) {
|
||||
var arrayBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(goog.webgl.ARRAY_BUFFER, arrayBuffer);
|
||||
gl.bufferData(goog.webgl.ARRAY_BUFFER, new Float32Array([
|
||||
-1, -1, 0, 0,
|
||||
1, -1, 1, 0,
|
||||
-1, 1, 0, 1,
|
||||
1, 1, 1, 1
|
||||
]), goog.webgl.STATIC_DRAW);
|
||||
this.arrayBuffer_ = arrayBuffer;
|
||||
} else {
|
||||
gl.bindBuffer(goog.webgl.ARRAY_BUFFER, this.arrayBuffer_);
|
||||
}
|
||||
this.bindBuffer(goog.webgl.ARRAY_BUFFER, this.arrayBuffer_);
|
||||
|
||||
gl.enableVertexAttribArray(this.locations_.a_position);
|
||||
gl.vertexAttribPointer(
|
||||
|
||||
@@ -23,6 +23,7 @@ goog.require('ol.math');
|
||||
goog.require('ol.renderer.webgl.FragmentShader');
|
||||
goog.require('ol.renderer.webgl.Layer');
|
||||
goog.require('ol.renderer.webgl.VertexShader');
|
||||
goog.require('ol.structs.Buffer');
|
||||
|
||||
|
||||
|
||||
@@ -113,9 +114,14 @@ ol.renderer.webgl.TileLayer = function(mapRenderer, tileLayer) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {WebGLBuffer}
|
||||
* @type {ol.structs.Buffer}
|
||||
*/
|
||||
this.arrayBuffer_ = null;
|
||||
this.arrayBuffer_ = new ol.structs.Buffer([
|
||||
0, 0, 0, 1,
|
||||
1, 0, 1, 1,
|
||||
0, 1, 0, 0,
|
||||
1, 1, 1, 0
|
||||
]);
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -150,10 +156,7 @@ goog.inherits(ol.renderer.webgl.TileLayer, ol.renderer.webgl.Layer);
|
||||
*/
|
||||
ol.renderer.webgl.TileLayer.prototype.disposeInternal = function() {
|
||||
var mapRenderer = this.getWebGLMapRenderer();
|
||||
var gl = mapRenderer.getGL();
|
||||
if (!gl.isContextLost()) {
|
||||
gl.deleteBuffer(this.arrayBuffer_);
|
||||
}
|
||||
mapRenderer.deleteBuffer(this.arrayBuffer_);
|
||||
goog.base(this, 'disposeInternal');
|
||||
};
|
||||
|
||||
@@ -188,7 +191,6 @@ ol.renderer.webgl.TileLayer.prototype.getTileLayer = function() {
|
||||
ol.renderer.webgl.TileLayer.prototype.handleWebGLContextLost = function() {
|
||||
goog.base(this, 'handleWebGLContextLost');
|
||||
this.locations_ = null;
|
||||
this.arrayBuffer_ = null;
|
||||
};
|
||||
|
||||
|
||||
@@ -269,20 +271,7 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame =
|
||||
};
|
||||
}
|
||||
|
||||
if (goog.isNull(this.arrayBuffer_)) {
|
||||
var arrayBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(goog.webgl.ARRAY_BUFFER, arrayBuffer);
|
||||
gl.bufferData(goog.webgl.ARRAY_BUFFER, new Float32Array([
|
||||
0, 0, 0, 1,
|
||||
1, 0, 1, 1,
|
||||
0, 1, 0, 0,
|
||||
1, 1, 1, 0
|
||||
]), goog.webgl.STATIC_DRAW);
|
||||
this.arrayBuffer_ = arrayBuffer;
|
||||
} else {
|
||||
gl.bindBuffer(goog.webgl.ARRAY_BUFFER, this.arrayBuffer_);
|
||||
}
|
||||
|
||||
mapRenderer.bindBuffer(goog.webgl.ARRAY_BUFFER, this.arrayBuffer_);
|
||||
gl.enableVertexAttribArray(this.locations_.aPosition);
|
||||
gl.vertexAttribPointer(
|
||||
this.locations_.aPosition, 2, goog.webgl.FLOAT, false, 16, 0);
|
||||
|
||||
Reference in New Issue
Block a user