Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #528 from AnalyticalGraphicsInc/contextObjectCache

Context object cache
  • Loading branch information...
commit 1c9e463a32423d9adc3ba799dd4c325772a1f28c 2 parents 884fadc + 6c26cec
Patrick Cozzi pjcozzi authored
23 Source/Renderer/Context.js
View
@@ -254,6 +254,18 @@ define([
this._defaultTexture = undefined;
this._defaultCubeMap = undefined;
+
+ /**
+ * A cache of objects tied to this context. Just before the Context is destroyed,
+ * <code>destroy</code> will be invoked on each object in this object literal that has
+ * such a method. This is useful for caching any objects that might otherwise
+ * be stored globally, except they're tied to a particular context, and to manage
+ * their lifetime.
+ *
+ * @private
+ * @type {Object}
+ */
+ this.cache = {};
};
Context.prototype._enableOrDisable = function(glEnum, enable) {
@@ -2794,6 +2806,17 @@ define([
};
Context.prototype.destroy = function() {
+ // Destroy all objects in the cache that have a destroy method.
+ var cache = this.cache;
+ for (var property in cache) {
+ if (cache.hasOwnProperty(property)) {
+ var propertyValue = cache[property];
+ if (typeof propertyValue.destroy !== 'undefined') {
+ propertyValue.destroy();
+ }
+ }
+ }
+
this._shaderCache = this._shaderCache.destroy();
this._defaultTexture = this._defaultTexture && this._defaultTexture.destroy();
this._defaultCubeMap = this._defaultCubeMap && this._defaultCubeMap.destroy();
38 Source/Scene/BillboardCollection.js
View
@@ -551,18 +551,11 @@ define([
function getDirectionsVertexBuffer(context) {
var sixteenK = 16 * 1024;
- // Per-context cache for billboard collections
- context._primitivesCache = context._primitivesCache || {};
- var primitivesCache = context._primitivesCache;
- primitivesCache._billboardCollection = primitivesCache._billboardCollection || {};
- var c = primitivesCache._billboardCollection;
-
- if (c.directionsVertexBuffer) {
- return c.directionsVertexBuffer;
+ var directionsVertexBuffer = context.cache.billboardCollection_directionsVertexBuffer;
+ if (typeof directionsVertexBuffer !== 'undefined') {
+ return directionsVertexBuffer;
}
- c.directionsVertexBuffer = c.directionsVertexBuffer && c.directionsVertexBuffer.destroy();
-
var directions = new Uint8Array(sixteenK * 4 * 2);
for (var i = 0, j = 0; i < sixteenK; ++i) {
directions[j++] = 0;
@@ -580,22 +573,18 @@ define([
// PERFORMANCE_IDEA: Should we reference count billboard collections, and eventually delete this?
// Is this too much memory to allocate up front? Should we dynamically grow it?
- c.directionsVertexBuffer = context.createVertexBuffer(directions, BufferUsage.STATIC_DRAW);
- c.directionsVertexBuffer.setVertexArrayDestroyable(false);
- return c.directionsVertexBuffer;
+ directionsVertexBuffer = context.createVertexBuffer(directions, BufferUsage.STATIC_DRAW);
+ directionsVertexBuffer.setVertexArrayDestroyable(false);
+ context.cache.billboardCollection_directionsVertexBuffer = directionsVertexBuffer;
+ return directionsVertexBuffer;
}
function getIndexBuffer(context) {
var sixteenK = 16 * 1024;
- // Per-context cache for billboard collections
- context._primitivesCache = context._primitivesCache || {};
- var primitivesCache = context._primitivesCache;
- primitivesCache._billboardCollection = primitivesCache._billboardCollection || {};
- var c = primitivesCache._billboardCollection;
-
- if (c.indexBuffer) {
- return c.indexBuffer;
+ var indexBuffer = context.cache.billboardCollection_indexBuffer;
+ if (typeof indexBuffer !== 'undefined') {
+ return indexBuffer;
}
var length = sixteenK * 6;
@@ -612,9 +601,10 @@ define([
// PERFORMANCE_IDEA: Should we reference count billboard collections, and eventually delete this?
// Is this too much memory to allocate up front? Should we dynamically grow it?
- c.indexBuffer = context.createIndexBuffer(indices, BufferUsage.STATIC_DRAW, IndexDatatype.UNSIGNED_SHORT);
- c.indexBuffer.setVertexArrayDestroyable(false);
- return c.indexBuffer;
+ indexBuffer = context.createIndexBuffer(indices, BufferUsage.STATIC_DRAW, IndexDatatype.UNSIGNED_SHORT);
+ indexBuffer.setVertexArrayDestroyable(false);
+ context.cache.billboardCollection_indexBuffer = indexBuffer;
+ return indexBuffer;
}
BillboardCollection.prototype.computeNewBuffersUsage = function() {
39 Source/Scene/EllipsoidPrimitive.js
View
@@ -190,47 +190,25 @@ define([
};
};
- // Per-context cache for ellipsoids
- var vertexArrayCache = {};
-
function getVertexArray(context) {
- var c = vertexArrayCache[context.getId()];
-
- if (typeof c !== 'undefined' &&
- typeof c.vertexArray !== 'undefined') {
+ var vertexArray = context.cache.ellipsoidPrimitive_vertexArray;
- ++c.referenceCount;
- return c;
+ if (typeof vertexArray !== 'undefined') {
+ return vertexArray;
}
var mesh = BoxTessellator.compute({
dimensions : new Cartesian3(2.0, 2.0, 2.0)
});
- var va = context.createVertexArrayFromMesh({
+ vertexArray = context.createVertexArrayFromMesh({
mesh: mesh,
attributeIndices: attributeIndices,
bufferUsage: BufferUsage.STATIC_DRAW
});
- var cachedVA = {
- vertexArray : va,
- referenceCount : 1,
-
- release : function() {
- if (typeof this.vertexArray !== 'undefined' &&
- --this.referenceCount === 0) {
-
- // PERFORMANCE_IDEA: Schedule this for a few hundred frames later so we don't thrash the cache
- this.vertexArray = this.vertexArray.destroy();
- }
-
- return undefined;
- }
- };
-
- vertexArrayCache[context.getId()] = cachedVA;
- return cachedVA;
+ context.cache.ellipsoidPrimitive_vertexArray = vertexArray;
+ return vertexArray;
}
/**
@@ -314,7 +292,7 @@ define([
this._sp = context.getShaderCache().getShaderProgram(EllipsoidVS, fsSource, attributeIndices);
colorCommand.primitiveType = PrimitiveType.TRIANGLES;
- colorCommand.vertexArray = this._va.vertexArray;
+ colorCommand.vertexArray = this._va;
colorCommand.renderState = this._rs;
colorCommand.shaderProgram = this._sp;
colorCommand.uniformMap = combine([this._uniforms, this._material._uniforms], false, false);
@@ -349,7 +327,7 @@ define([
this._pickSP = context.getShaderCache().getShaderProgram(EllipsoidVS, pickFS, attributeIndices);
pickCommand.primitiveType = PrimitiveType.TRIANGLES;
- pickCommand.vertexArray = this._va.vertexArray;
+ pickCommand.vertexArray = this._va;
pickCommand.renderState = this._rs;
pickCommand.shaderProgram = this._pickSP;
pickCommand.uniformMap = combine([this._uniforms, pickMaterial._uniforms], false, false);
@@ -402,7 +380,6 @@ define([
*/
EllipsoidPrimitive.prototype.destroy = function() {
this._sp = this._sp && this._sp.release();
- this._va = this._va && this._va.release();
this._pickSP = this._pickSP && this._pickSP.release();
this._pickId = this._pickId && this._pickId.destroy();
return destroyObject(this);
17 Source/Scene/Tile.js
View
@@ -652,18 +652,23 @@ define([
return parent.terrainData.isChildAvailable(parent.x, parent.y, tile.x, tile.y);
}
- var waterMaskDataByContext = {};
-
function createWaterMaskTexture(context, waterMask) {
var result;
- var contextID = context.getId();
- var waterMaskData = waterMaskDataByContext[contextID];
+ var waterMaskData = context.cache.tile_waterMaskData;
if (typeof waterMaskData === 'undefined') {
- waterMaskData = waterMaskDataByContext[contextID] = {
+ waterMaskData = context.cache.tile_waterMaskData = {
allWaterTexture : undefined,
allLandTexture : undefined,
- sampler : undefined
+ sampler : undefined,
+ destroy : function() {
+ if (typeof this.allWaterTexture !== 'undefined') {
+ this.allWaterTexture.destroy();
+ }
+ if (typeof this.allLandTexture !== 'undefined') {
+ this.allLandTexture.destroy();
+ }
+ }
};
}
36 Source/Scene/ViewportQuad.js
View
@@ -105,17 +105,12 @@ define([
textureCoordinates : 1
};
- var vertexArrayCache = {};
-
function getVertexArray(context) {
// Per-context cache for viewport quads
- var c = vertexArrayCache[context.getId()];
-
- if (typeof c !== 'undefined' &&
- typeof c.vertexArray !== 'undefined') {
+ var vertexArray = context.cache.viewportQuad_vertexArray;
- ++c.referenceCount;
- return c;
+ if (typeof vertexArray !== 'undefined') {
+ return vertexArray;
}
var mesh = {
@@ -144,30 +139,14 @@ define([
}
};
- var va = context.createVertexArrayFromMesh({
+ vertexArray = context.createVertexArrayFromMesh({
mesh : mesh,
attributeIndices : attributeIndices,
bufferUsage : BufferUsage.STATIC_DRAW
});
- var cachedVA = {
- vertexArray : va,
- referenceCount : 1,
-
- release : function() {
- if (typeof this.vertexArray !== 'undefined' &&
- --this.referenceCount === 0) {
-
- // TODO: Schedule this for a few hundred frames later so we don't thrash the cache
- this.vertexArray = this.vertexArray.destroy();
- }
-
- return undefined;
- }
- };
-
- vertexArrayCache[context.getId()] = cachedVA;
- return cachedVA;
+ context.cache.viewportQuad_vertexArray = vertexArray;
+ return vertexArray;
}
/**
@@ -194,7 +173,7 @@ define([
if (typeof this._va === 'undefined') {
this._va = getVertexArray(context);
- this._overlayCommand.vertexArray = this._va.vertexArray;
+ this._overlayCommand.vertexArray = this._va;
this._overlayCommand.renderState = context.createRenderState({
blending : BlendingState.ALPHA_BLEND
});
@@ -260,7 +239,6 @@ define([
* quad = quad && quad.destroy();
*/
ViewportQuad.prototype.destroy = function() {
- this._va = this._va && this._va.release();
this._overlayCommand.shaderProgram = this._overlayCommand.shaderProgram && this._overlayCommand.shaderProgram.release();
return destroyObject(this);
15 Specs/Renderer/ContextSpec.js
View
@@ -226,4 +226,19 @@ defineSuite([
c.destroy();
expect(c.isDestroyed()).toEqual(true);
});
+
+ it('destroying Context destroys objects in cache', function() {
+ var c = createContext();
+ var destroyableObject = jasmine.createSpyObj('destroyableObject', ['destroy']);
+ c.cache.foo = destroyableObject;
+ c.destroy();
+ expect(destroyableObject.destroy).toHaveBeenCalled();
+ });
+
+ it('non-destroyable objects are allowed in the cache', function() {
+ var c = createContext();
+ var nonDestroyableObject = {};
+ c.cache.foo = nonDestroyableObject;
+ c.destroy();
+ });
}, 'WebGL');
Please sign in to comment.
Something went wrong with that request. Please try again.