Webgl / clarified the buffer binding/flushing logic
The Webgl points layer renderer has also been optimized accordingly, giving out much better performance.
This commit is contained in:
@@ -323,6 +323,9 @@ class WebGLPointsLayerRenderer extends LayerRenderer {
|
|||||||
baseIndex + 1, baseIndex + 2, baseIndex + 3
|
baseIndex + 1, baseIndex + 2, baseIndex + 3
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.helper_.flushBufferData(ARRAY_BUFFER, this.verticesBuffer_);
|
||||||
|
this.helper_.flushBufferData(ELEMENT_ARRAY_BUFFER, this.indicesBuffer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// write new data
|
// write new data
|
||||||
|
|||||||
+36
-16
@@ -23,8 +23,8 @@ import {getContext} from '../webgl';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} BufferCacheEntry
|
* @typedef {Object} BufferCacheEntry
|
||||||
* @property {import("./Buffer.js").default} buf
|
* @property {import("./Buffer.js").default} buffer
|
||||||
* @property {WebGLBuffer} buffer
|
* @property {WebGLBuffer} webGlBuffer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -153,15 +153,24 @@ export const DefaultAttrib = {
|
|||||||
* ### Binding WebGL buffers and flushing data into them:
|
* ### Binding WebGL buffers and flushing data into them:
|
||||||
*
|
*
|
||||||
* Data that must be passed to the GPU has to be transferred using `WebGLArrayBuffer` objects.
|
* Data that must be passed to the GPU has to be transferred using `WebGLArrayBuffer` objects.
|
||||||
* A buffer has to be created only once, but must be bound everytime the data it holds is changed. Using `WebGLHelper.bindBuffer`
|
* A buffer has to be created only once, but must be bound everytime the buffer content should be used for rendering.
|
||||||
* will bind the buffer and flush the new data to the GPU.
|
* This is done using `WebGLHelper.bindBuffer`.
|
||||||
|
* When the buffer's array content has changed, the new data has to be flushed to the GPU memory; this is done using
|
||||||
|
* `WebGLHelper.flushBufferData`. Note: this operation is expensive and should be done as infrequently as possible.
|
||||||
*
|
*
|
||||||
* For now, the `WebGLHelper` class expects {@link module:ol/webgl/Buffer~WebGLArrayBuffer} objects.
|
* When binding a `WebGLArrayBuffer`, a `target` parameter must be given: it should be either {@link module:ol/webgl~ARRAY_BUFFER}
|
||||||
|
* (if the buffer contains vertices data) or {@link module:ol/webgl~ELEMENT_ARRAY_BUFFER} (if the buffer contains indices data).
|
||||||
|
*
|
||||||
|
* Examples below:
|
||||||
* ```js
|
* ```js
|
||||||
* // at initialization phase
|
* // at initialization phase
|
||||||
* this.verticesBuffer = new WebGLArrayBuffer([], DYNAMIC_DRAW);
|
* this.verticesBuffer = new WebGLArrayBuffer([], DYNAMIC_DRAW);
|
||||||
* this.indicesBuffer = new WebGLArrayBuffer([], DYNAMIC_DRAW);
|
* this.indicesBuffer = new WebGLArrayBuffer([], DYNAMIC_DRAW);
|
||||||
*
|
*
|
||||||
|
* // when array values have changed
|
||||||
|
* this.context.flushBufferData(ARRAY_BUFFER, this.verticesBuffer);
|
||||||
|
* this.context.flushBufferData(ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
|
||||||
|
*
|
||||||
* // at rendering phase
|
* // at rendering phase
|
||||||
* this.context.bindBuffer(ARRAY_BUFFER, this.verticesBuffer);
|
* this.context.bindBuffer(ARRAY_BUFFER, this.verticesBuffer);
|
||||||
* this.context.bindBuffer(ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
|
* this.context.bindBuffer(ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
|
||||||
@@ -342,24 +351,35 @@ class WebGLHelper extends Disposable {
|
|||||||
* Just bind the buffer if it's in the cache. Otherwise create
|
* Just bind the buffer if it's in the cache. Otherwise create
|
||||||
* the WebGL buffer, bind it, populate it, and add an entry to
|
* the WebGL buffer, bind it, populate it, and add an entry to
|
||||||
* the cache.
|
* the cache.
|
||||||
* TODO: improve this, the logic is unclear: we want A/ to bind a buffer and B/ to flush data in it
|
* @param {number} target Target, either ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER.
|
||||||
* @param {number} target Target.
|
* @param {import("./Buffer").default} buffer Buffer.
|
||||||
* @param {import("./Buffer").default} buf Buffer.
|
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
bindBuffer(target, buf) {
|
bindBuffer(target, buffer) {
|
||||||
const gl = this.getGL();
|
const gl = this.getGL();
|
||||||
const arr = buf.getArray();
|
const bufferKey = getUid(buffer);
|
||||||
const bufferKey = getUid(buf);
|
|
||||||
let bufferCache = this.bufferCache_[bufferKey];
|
let bufferCache = this.bufferCache_[bufferKey];
|
||||||
if (!bufferCache) {
|
if (!bufferCache) {
|
||||||
const buffer = gl.createBuffer();
|
const webGlBuffer = gl.createBuffer();
|
||||||
bufferCache = this.bufferCache_[bufferKey] = {
|
bufferCache = this.bufferCache_[bufferKey] = {
|
||||||
buf: buf,
|
buffer: buffer,
|
||||||
buffer: buffer
|
webGlBuffer: webGlBuffer
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
gl.bindBuffer(target, bufferCache.buffer);
|
gl.bindBuffer(target, bufferCache.webGlBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the data contained in the buffer array; this is required for the
|
||||||
|
* new data to be rendered
|
||||||
|
* @param {number} target Target, either ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER.
|
||||||
|
* @param {import("./Buffer").default} buffer Buffer.
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
flushBufferData(target, buffer) {
|
||||||
|
const gl = this.getGL();
|
||||||
|
const arr = buffer.getArray();
|
||||||
|
this.bindBuffer(target, buffer);
|
||||||
let /** @type {ArrayBufferView} */ arrayBuffer;
|
let /** @type {ArrayBufferView} */ arrayBuffer;
|
||||||
if (target == ARRAY_BUFFER) {
|
if (target == ARRAY_BUFFER) {
|
||||||
arrayBuffer = new Float32Array(arr);
|
arrayBuffer = new Float32Array(arr);
|
||||||
@@ -367,7 +387,7 @@ class WebGLHelper extends Disposable {
|
|||||||
arrayBuffer = this.hasOESElementIndexUint ?
|
arrayBuffer = this.hasOESElementIndexUint ?
|
||||||
new Uint32Array(arr) : new Uint16Array(arr);
|
new Uint32Array(arr) : new Uint16Array(arr);
|
||||||
}
|
}
|
||||||
gl.bufferData(target, arrayBuffer, buf.getUsage());
|
gl.bufferData(target, arrayBuffer, buffer.getUsage());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user