Factor out ol.webgl.Context
This commit is contained in:
@@ -25,12 +25,11 @@ goog.require('ol.renderer.webgl.map.shader.Color');
|
|||||||
goog.require('ol.renderer.webgl.map.shader.Default');
|
goog.require('ol.renderer.webgl.map.shader.Default');
|
||||||
goog.require('ol.source.State');
|
goog.require('ol.source.State');
|
||||||
goog.require('ol.structs.Buffer');
|
goog.require('ol.structs.Buffer');
|
||||||
goog.require('ol.structs.IntegerSet');
|
|
||||||
goog.require('ol.structs.LRUCache');
|
goog.require('ol.structs.LRUCache');
|
||||||
goog.require('ol.structs.PriorityQueue');
|
goog.require('ol.structs.PriorityQueue');
|
||||||
goog.require('ol.webgl');
|
goog.require('ol.webgl');
|
||||||
|
goog.require('ol.webgl.Context');
|
||||||
goog.require('ol.webgl.WebGLContextEventType');
|
goog.require('ol.webgl.WebGLContextEventType');
|
||||||
goog.require('ol.webgl.shader');
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,14 +38,6 @@ goog.require('ol.webgl.shader');
|
|||||||
ol.WEBGL_TEXTURE_CACHE_HIGH_WATER_MARK = 1024;
|
ol.WEBGL_TEXTURE_CACHE_HIGH_WATER_MARK = 1024;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {{buf: ol.structs.Buffer,
|
|
||||||
* buffer: WebGLBuffer,
|
|
||||||
* dirtySet: ol.structs.IntegerSet}}
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.BufferCacheEntry;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {{magFilter: number, minFilter: number, texture: WebGLTexture}}
|
* @typedef {{magFilter: number, minFilter: number, texture: WebGLTexture}}
|
||||||
*/
|
*/
|
||||||
@@ -91,6 +82,12 @@ ol.renderer.webgl.Map = function(container, map) {
|
|||||||
});
|
});
|
||||||
goog.asserts.assert(!goog.isNull(this.gl_));
|
goog.asserts.assert(!goog.isNull(this.gl_));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {ol.webgl.Context}
|
||||||
|
*/
|
||||||
|
this.context_ = new ol.webgl.Context(this.canvas_, this.gl_);
|
||||||
|
|
||||||
goog.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.LOST,
|
goog.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.LOST,
|
||||||
this.handleWebGLContextLost, false, this);
|
this.handleWebGLContextLost, false, this);
|
||||||
goog.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.RESTORED,
|
goog.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.RESTORED,
|
||||||
@@ -119,24 +116,6 @@ ol.renderer.webgl.Map = function(container, map) {
|
|||||||
1, 1, 1, 1
|
1, 1, 1, 1
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Object.<number, ol.renderer.webgl.BufferCacheEntry>}
|
|
||||||
*/
|
|
||||||
this.bufferCache_ = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Object.<number, WebGLShader>}
|
|
||||||
*/
|
|
||||||
this.shaderCache_ = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Object.<string, WebGLProgram>}
|
|
||||||
*/
|
|
||||||
this.programCache_ = {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {ol.structs.LRUCache}
|
* @type {ol.structs.LRUCache}
|
||||||
@@ -200,47 +179,6 @@ ol.renderer.webgl.Map = function(container, map) {
|
|||||||
goog.inherits(ol.renderer.webgl.Map, ol.renderer.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();
|
|
||||||
var bufferKey = goog.getUid(buf);
|
|
||||||
if (bufferKey in this.bufferCache_) {
|
|
||||||
var bufferCacheEntry = this.bufferCache_[bufferKey];
|
|
||||||
gl.bindBuffer(target, bufferCacheEntry.buffer);
|
|
||||||
bufferCacheEntry.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));
|
|
||||||
});
|
|
||||||
bufferCacheEntry.dirtySet.clear();
|
|
||||||
} else {
|
|
||||||
var buffer = gl.createBuffer();
|
|
||||||
gl.bindBuffer(target, buffer);
|
|
||||||
gl.bufferData(
|
|
||||||
target,
|
|
||||||
target == goog.webgl.ARRAY_BUFFER ?
|
|
||||||
new Float32Array(arr) : new Uint16Array(arr),
|
|
||||||
buf.getUsage());
|
|
||||||
var dirtySet = new ol.structs.IntegerSet();
|
|
||||||
buf.addDirtySet(dirtySet);
|
|
||||||
this.bufferCache_[bufferKey] = {
|
|
||||||
buf: buf,
|
|
||||||
buffer: buffer,
|
|
||||||
dirtySet: dirtySet
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ol.Tile} tile Tile.
|
* @param {ol.Tile} tile Tile.
|
||||||
* @param {number} magFilter Mag filter.
|
* @param {number} magFilter Mag filter.
|
||||||
@@ -300,46 +238,19 @@ 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 bufferKey = goog.getUid(buf);
|
|
||||||
goog.asserts.assert(bufferKey in this.bufferCache_);
|
|
||||||
var bufferCacheEntry = this.bufferCache_[bufferKey];
|
|
||||||
bufferCacheEntry.buf.removeDirtySet(bufferCacheEntry.dirtySet);
|
|
||||||
if (!gl.isContextLost()) {
|
|
||||||
gl.deleteBuffer(bufferCacheEntry.buffer);
|
|
||||||
}
|
|
||||||
delete this.bufferCache_[bufferKey];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.Map.prototype.disposeInternal = function() {
|
ol.renderer.webgl.Map.prototype.disposeInternal = function() {
|
||||||
var gl = this.getGL();
|
var gl = this.getGL();
|
||||||
goog.object.forEach(this.bufferCache_, function(bufferCacheEntry) {
|
|
||||||
bufferCacheEntry.buf.removeDirtySet(bufferCacheEntry.dirtySet);
|
|
||||||
});
|
|
||||||
if (!gl.isContextLost()) {
|
if (!gl.isContextLost()) {
|
||||||
goog.object.forEach(this.bufferCache_, function(bufferCacheEntry) {
|
|
||||||
gl.deleteBuffer(bufferCacheEntry.buffer);
|
|
||||||
});
|
|
||||||
goog.object.forEach(this.programCache_, function(program) {
|
|
||||||
gl.deleteProgram(program);
|
|
||||||
});
|
|
||||||
goog.object.forEach(this.shaderCache_, function(shader) {
|
|
||||||
gl.deleteShader(shader);
|
|
||||||
});
|
|
||||||
this.textureCache_.forEach(function(textureCacheEntry) {
|
this.textureCache_.forEach(function(textureCacheEntry) {
|
||||||
if (!goog.isNull(textureCacheEntry)) {
|
if (!goog.isNull(textureCacheEntry)) {
|
||||||
gl.deleteTexture(textureCacheEntry.texture);
|
gl.deleteTexture(textureCacheEntry.texture);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
goog.dispose(this.context_);
|
||||||
goog.base(this, 'disposeInternal');
|
goog.base(this, 'disposeInternal');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -378,6 +289,14 @@ ol.renderer.webgl.Map.prototype.getCanvas = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {ol.webgl.Context}
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.Map.prototype.getContext = function() {
|
||||||
|
return this.context_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {WebGLRenderingContext} GL.
|
* @return {WebGLRenderingContext} GL.
|
||||||
*/
|
*/
|
||||||
@@ -386,66 +305,6 @@ ol.renderer.webgl.Map.prototype.getGL = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.webgl.shader.Fragment} fragmentShaderObject Fragment shader.
|
|
||||||
* @param {ol.webgl.shader.Vertex} vertexShaderObject Vertex shader.
|
|
||||||
* @return {WebGLProgram} Program.
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.Map.prototype.getProgram = function(
|
|
||||||
fragmentShaderObject, vertexShaderObject) {
|
|
||||||
var programKey =
|
|
||||||
goog.getUid(fragmentShaderObject) + '/' + goog.getUid(vertexShaderObject);
|
|
||||||
if (programKey in this.programCache_) {
|
|
||||||
return this.programCache_[programKey];
|
|
||||||
} else {
|
|
||||||
var gl = this.getGL();
|
|
||||||
var program = gl.createProgram();
|
|
||||||
gl.attachShader(program, this.getShader(fragmentShaderObject));
|
|
||||||
gl.attachShader(program, this.getShader(vertexShaderObject));
|
|
||||||
gl.linkProgram(program);
|
|
||||||
if (goog.DEBUG) {
|
|
||||||
if (!gl.getProgramParameter(program, goog.webgl.LINK_STATUS) &&
|
|
||||||
!gl.isContextLost()) {
|
|
||||||
goog.log.error(this.logger_, gl.getProgramInfoLog(program));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goog.asserts.assert(
|
|
||||||
gl.getProgramParameter(program, goog.webgl.LINK_STATUS) ||
|
|
||||||
gl.isContextLost());
|
|
||||||
this.programCache_[programKey] = program;
|
|
||||||
return program;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.webgl.Shader} shaderObject Shader object.
|
|
||||||
* @return {WebGLShader} Shader.
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.Map.prototype.getShader = function(shaderObject) {
|
|
||||||
var shaderKey = goog.getUid(shaderObject);
|
|
||||||
if (shaderKey in this.shaderCache_) {
|
|
||||||
return this.shaderCache_[shaderKey];
|
|
||||||
} else {
|
|
||||||
var gl = this.getGL();
|
|
||||||
var shader = gl.createShader(shaderObject.getType());
|
|
||||||
gl.shaderSource(shader, shaderObject.getSource());
|
|
||||||
gl.compileShader(shader);
|
|
||||||
if (goog.DEBUG) {
|
|
||||||
if (!gl.getShaderParameter(shader, goog.webgl.COMPILE_STATUS) &&
|
|
||||||
!gl.isContextLost()) {
|
|
||||||
goog.log.error(this.logger_, gl.getShaderInfoLog(shader));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goog.asserts.assert(
|
|
||||||
gl.getShaderParameter(shader, goog.webgl.COMPILE_STATUS) ||
|
|
||||||
gl.isContextLost());
|
|
||||||
this.shaderCache_[shaderKey] = shader;
|
|
||||||
return shader;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {ol.structs.PriorityQueue} Tile texture queue.
|
* @return {ol.structs.PriorityQueue} Tile texture queue.
|
||||||
*/
|
*/
|
||||||
@@ -462,9 +321,6 @@ ol.renderer.webgl.Map.prototype.handleWebGLContextLost = function(event) {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.colorLocations_ = null;
|
this.colorLocations_ = null;
|
||||||
this.defaultLocations_ = null;
|
this.defaultLocations_ = null;
|
||||||
this.bufferCache_ = {};
|
|
||||||
this.shaderCache_ = {};
|
|
||||||
this.programCache_ = {};
|
|
||||||
this.textureCache_.clear();
|
this.textureCache_.clear();
|
||||||
this.textureCacheFrameMarkerCount_ = 0;
|
this.textureCacheFrameMarkerCount_ = 0;
|
||||||
goog.object.forEach(this.getLayerRenderers(), function(layerRenderer) {
|
goog.object.forEach(this.getLayerRenderers(), function(layerRenderer) {
|
||||||
@@ -519,6 +375,7 @@ ol.renderer.webgl.Map.prototype.logger_ =
|
|||||||
*/
|
*/
|
||||||
ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
|
ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
|
||||||
|
|
||||||
|
var context = this.getContext();
|
||||||
var gl = this.getGL();
|
var gl = this.getGL();
|
||||||
|
|
||||||
if (gl.isContextLost()) {
|
if (gl.isContextLost()) {
|
||||||
@@ -566,7 +423,7 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
|
|||||||
gl.enable(goog.webgl.BLEND);
|
gl.enable(goog.webgl.BLEND);
|
||||||
gl.viewport(0, 0, size[0], size[1]);
|
gl.viewport(0, 0, size[0], size[1]);
|
||||||
|
|
||||||
this.bindBuffer(goog.webgl.ARRAY_BUFFER, this.arrayBuffer_);
|
context.bindBuffer(goog.webgl.ARRAY_BUFFER, this.arrayBuffer_);
|
||||||
|
|
||||||
var currentProgram = null;
|
var currentProgram = null;
|
||||||
var locations;
|
var locations;
|
||||||
@@ -595,7 +452,7 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
|
|||||||
vertexShader = ol.renderer.webgl.map.shader.DefaultVertex.getInstance();
|
vertexShader = ol.renderer.webgl.map.shader.DefaultVertex.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
var program = this.getProgram(fragmentShader, vertexShader);
|
var program = context.getProgram(fragmentShader, vertexShader);
|
||||||
if (program != currentProgram) {
|
if (program != currentProgram) {
|
||||||
|
|
||||||
gl.useProgram(program);
|
gl.useProgram(program);
|
||||||
|
|||||||
@@ -87,7 +87,8 @@ goog.inherits(ol.renderer.webgl.TileLayer, ol.renderer.webgl.Layer);
|
|||||||
*/
|
*/
|
||||||
ol.renderer.webgl.TileLayer.prototype.disposeInternal = function() {
|
ol.renderer.webgl.TileLayer.prototype.disposeInternal = function() {
|
||||||
var mapRenderer = this.getWebGLMapRenderer();
|
var mapRenderer = this.getWebGLMapRenderer();
|
||||||
mapRenderer.deleteBuffer(this.arrayBuffer_);
|
var context = mapRenderer.getContext();
|
||||||
|
context.deleteBuffer(this.arrayBuffer_);
|
||||||
goog.base(this, 'disposeInternal');
|
goog.base(this, 'disposeInternal');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -117,6 +118,7 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame =
|
|||||||
function(frameState, layerState) {
|
function(frameState, layerState) {
|
||||||
|
|
||||||
var mapRenderer = this.getWebGLMapRenderer();
|
var mapRenderer = this.getWebGLMapRenderer();
|
||||||
|
var context = mapRenderer.getContext();
|
||||||
var gl = mapRenderer.getGL();
|
var gl = mapRenderer.getGL();
|
||||||
|
|
||||||
var view2DState = frameState.view2DState;
|
var view2DState = frameState.view2DState;
|
||||||
@@ -172,15 +174,14 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame =
|
|||||||
gl.clear(goog.webgl.COLOR_BUFFER_BIT);
|
gl.clear(goog.webgl.COLOR_BUFFER_BIT);
|
||||||
gl.disable(goog.webgl.BLEND);
|
gl.disable(goog.webgl.BLEND);
|
||||||
|
|
||||||
var program = mapRenderer.getProgram(
|
var program = context.getProgram(this.fragmentShader_, this.vertexShader_);
|
||||||
this.fragmentShader_, this.vertexShader_);
|
|
||||||
gl.useProgram(program);
|
gl.useProgram(program);
|
||||||
if (goog.isNull(this.locations_)) {
|
if (goog.isNull(this.locations_)) {
|
||||||
this.locations_ =
|
this.locations_ =
|
||||||
new ol.renderer.webgl.tilelayer.shader.Locations(gl, program);
|
new ol.renderer.webgl.tilelayer.shader.Locations(gl, program);
|
||||||
}
|
}
|
||||||
|
|
||||||
mapRenderer.bindBuffer(goog.webgl.ARRAY_BUFFER, this.arrayBuffer_);
|
context.bindBuffer(goog.webgl.ARRAY_BUFFER, this.arrayBuffer_);
|
||||||
gl.enableVertexAttribArray(this.locations_.a_position);
|
gl.enableVertexAttribArray(this.locations_.a_position);
|
||||||
gl.vertexAttribPointer(
|
gl.vertexAttribPointer(
|
||||||
this.locations_.a_position, 2, goog.webgl.FLOAT, false, 16, 0);
|
this.locations_.a_position, 2, goog.webgl.FLOAT, false, 16, 0);
|
||||||
|
|||||||
@@ -0,0 +1,243 @@
|
|||||||
|
goog.provide('ol.webgl.Context');
|
||||||
|
|
||||||
|
goog.require('goog.asserts');
|
||||||
|
goog.require('goog.events');
|
||||||
|
goog.require('goog.log');
|
||||||
|
goog.require('goog.object');
|
||||||
|
goog.require('ol.structs.Buffer');
|
||||||
|
goog.require('ol.structs.IntegerSet');
|
||||||
|
goog.require('ol.webgl.WebGLContextEventType');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{buf: ol.structs.Buffer,
|
||||||
|
* buffer: WebGLBuffer,
|
||||||
|
* dirtySet: ol.structs.IntegerSet}}
|
||||||
|
*/
|
||||||
|
ol.webgl.BufferCacheEntry;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {goog.events.EventTarget}
|
||||||
|
* @param {HTMLCanvasElement} canvas Canvas.
|
||||||
|
* @param {WebGLRenderingContext} gl GL.
|
||||||
|
*/
|
||||||
|
ol.webgl.Context = function(canvas, gl) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {HTMLCanvasElement}
|
||||||
|
*/
|
||||||
|
this.canvas_ = canvas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {WebGLRenderingContext}
|
||||||
|
*/
|
||||||
|
this.gl_ = gl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {Object.<number, ol.webgl.BufferCacheEntry>}
|
||||||
|
*/
|
||||||
|
this.bufferCache_ = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {Object.<number, WebGLShader>}
|
||||||
|
*/
|
||||||
|
this.shaderCache_ = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {Object.<string, WebGLProgram>}
|
||||||
|
*/
|
||||||
|
this.programCache_ = {};
|
||||||
|
|
||||||
|
goog.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.LOST,
|
||||||
|
this.handleWebGLContextLost, false, this);
|
||||||
|
goog.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.RESTORED,
|
||||||
|
this.handleWebGLContextRestored, false, this);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} target Target.
|
||||||
|
* @param {ol.structs.Buffer} buf Buffer.
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.bindBuffer = function(target, buf) {
|
||||||
|
var gl = this.getGL();
|
||||||
|
var arr = buf.getArray();
|
||||||
|
var bufferKey = goog.getUid(buf);
|
||||||
|
if (bufferKey in this.bufferCache_) {
|
||||||
|
var bufferCacheEntry = this.bufferCache_[bufferKey];
|
||||||
|
gl.bindBuffer(target, bufferCacheEntry.buffer);
|
||||||
|
bufferCacheEntry.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));
|
||||||
|
});
|
||||||
|
bufferCacheEntry.dirtySet.clear();
|
||||||
|
} else {
|
||||||
|
var buffer = gl.createBuffer();
|
||||||
|
gl.bindBuffer(target, buffer);
|
||||||
|
gl.bufferData(
|
||||||
|
target,
|
||||||
|
target == goog.webgl.ARRAY_BUFFER ?
|
||||||
|
new Float32Array(arr) : new Uint16Array(arr),
|
||||||
|
buf.getUsage());
|
||||||
|
var dirtySet = new ol.structs.IntegerSet();
|
||||||
|
buf.addDirtySet(dirtySet);
|
||||||
|
this.bufferCache_[bufferKey] = {
|
||||||
|
buf: buf,
|
||||||
|
buffer: buffer,
|
||||||
|
dirtySet: dirtySet
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.structs.Buffer} buf Buffer.
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.deleteBuffer = function(buf) {
|
||||||
|
var gl = this.getGL();
|
||||||
|
var bufferKey = goog.getUid(buf);
|
||||||
|
goog.asserts.assert(bufferKey in this.bufferCache_);
|
||||||
|
var bufferCacheEntry = this.bufferCache_[bufferKey];
|
||||||
|
bufferCacheEntry.buf.removeDirtySet(bufferCacheEntry.dirtySet);
|
||||||
|
if (!gl.isContextLost()) {
|
||||||
|
gl.deleteBuffer(bufferCacheEntry.buffer);
|
||||||
|
}
|
||||||
|
delete this.bufferCache_[bufferKey];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.disposeInternal = function() {
|
||||||
|
goog.object.forEach(this.bufferCache_, function(bufferCacheEntry) {
|
||||||
|
bufferCacheEntry.buf.removeDirtySet(bufferCacheEntry.dirtySet);
|
||||||
|
});
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
goog.object.forEach(this.shaderCache_, function(shader) {
|
||||||
|
gl.deleteShader(shader);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {HTMLCanvasElement} Canvas.
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.getCanvas = function() {
|
||||||
|
return this.canvas_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {WebGLRenderingContext} GL.
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.getGL = function() {
|
||||||
|
return this.gl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.webgl.Shader} shaderObject Shader object.
|
||||||
|
* @return {WebGLShader} Shader.
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.getShader = function(shaderObject) {
|
||||||
|
var shaderKey = goog.getUid(shaderObject);
|
||||||
|
if (shaderKey in this.shaderCache_) {
|
||||||
|
return this.shaderCache_[shaderKey];
|
||||||
|
} else {
|
||||||
|
var gl = this.getGL();
|
||||||
|
var shader = gl.createShader(shaderObject.getType());
|
||||||
|
gl.shaderSource(shader, shaderObject.getSource());
|
||||||
|
gl.compileShader(shader);
|
||||||
|
if (goog.DEBUG) {
|
||||||
|
if (!gl.getShaderParameter(shader, goog.webgl.COMPILE_STATUS) &&
|
||||||
|
!gl.isContextLost()) {
|
||||||
|
goog.log.error(this.logger_, gl.getShaderInfoLog(shader));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goog.asserts.assert(
|
||||||
|
gl.getShaderParameter(shader, goog.webgl.COMPILE_STATUS) ||
|
||||||
|
gl.isContextLost());
|
||||||
|
this.shaderCache_[shaderKey] = shader;
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.webgl.shader.Fragment} fragmentShaderObject Fragment shader.
|
||||||
|
* @param {ol.webgl.shader.Vertex} vertexShaderObject Vertex shader.
|
||||||
|
* @return {WebGLProgram} Program.
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.getProgram = function(
|
||||||
|
fragmentShaderObject, vertexShaderObject) {
|
||||||
|
var programKey =
|
||||||
|
goog.getUid(fragmentShaderObject) + '/' + goog.getUid(vertexShaderObject);
|
||||||
|
if (programKey in this.programCache_) {
|
||||||
|
return this.programCache_[programKey];
|
||||||
|
} else {
|
||||||
|
var gl = this.getGL();
|
||||||
|
var program = gl.createProgram();
|
||||||
|
gl.attachShader(program, this.getShader(fragmentShaderObject));
|
||||||
|
gl.attachShader(program, this.getShader(vertexShaderObject));
|
||||||
|
gl.linkProgram(program);
|
||||||
|
if (goog.DEBUG) {
|
||||||
|
if (!gl.getProgramParameter(program, goog.webgl.LINK_STATUS) &&
|
||||||
|
!gl.isContextLost()) {
|
||||||
|
goog.log.error(this.logger_, gl.getProgramInfoLog(program));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goog.asserts.assert(
|
||||||
|
gl.getProgramParameter(program, goog.webgl.LINK_STATUS) ||
|
||||||
|
gl.isContextLost());
|
||||||
|
this.programCache_[programKey] = program;
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME empy description for jsdoc
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.handleWebGLContextLost = function() {
|
||||||
|
goog.object.clear(this.bufferCache_);
|
||||||
|
goog.object.clear(this.shaderCache_);
|
||||||
|
goog.object.clear(this.programCache_);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME empy description for jsdoc
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.handleWebGLContextRestored = function() {
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {goog.log.Logger}
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.logger_ = goog.log.getLogger('ol.webgl.Context');
|
||||||
Reference in New Issue
Block a user