mirror of
https://github.com/photonstorm/phaser
synced 2024-11-10 07:04:31 +00:00
Working through start of gl texture management for context-loss recovery
This commit is contained in:
parent
059ff984a2
commit
b4b364f183
7 changed files with 179 additions and 27 deletions
|
@ -136,7 +136,7 @@ var Plane = new Class({
|
|||
this.setViewHeight();
|
||||
},
|
||||
|
||||
/**
|
||||
/**
|
||||
* Do not change this value. It has no effect other than to break things.
|
||||
*
|
||||
* @name Phaser.GameObjects.Plane#originX
|
||||
|
@ -154,7 +154,7 @@ var Plane = new Class({
|
|||
|
||||
},
|
||||
|
||||
/**
|
||||
/**
|
||||
* Do not change this value. It has no effect other than to break things.
|
||||
*
|
||||
* @name Phaser.GameObjects.Plane#originY
|
||||
|
@ -385,7 +385,8 @@ var Plane = new Class({
|
|||
if (alpha2 === undefined) { alpha2 = 255; }
|
||||
if (height === undefined) { height = 128; }
|
||||
|
||||
var gl = this.scene.sys.renderer.gl;
|
||||
var renderer = this.scene.sys.renderer;
|
||||
var gl = renderer.gl;
|
||||
|
||||
var glTexture = gl.createTexture();
|
||||
|
||||
|
@ -420,10 +421,12 @@ var Plane = new Class({
|
|||
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(colors));
|
||||
|
||||
glTexture.isAlphaPremultiplied = true;
|
||||
glTexture.isRenderTexture = false;
|
||||
glTexture.width = 16;
|
||||
glTexture.height = 16;
|
||||
renderer.addToTextureCache(glTexture, 16, 16, 'Plane');
|
||||
|
||||
// glTexture.isAlphaPremultiplied = true;
|
||||
// glTexture.isRenderTexture = false;
|
||||
// glTexture.width = 16;
|
||||
// glTexture.height = 16;
|
||||
|
||||
var texture = this.scene.sys.textures.addGLTexture(UUID(), glTexture, 16, 16);
|
||||
|
||||
|
|
|
@ -225,12 +225,14 @@ var RenderTarget = new Class({
|
|||
|
||||
if (this.autoResize && (scaledWidth !== this.width || scaledHeight !== this.height))
|
||||
{
|
||||
console.log('RenderTarget.resize', width, height);
|
||||
|
||||
var renderer = this.renderer;
|
||||
|
||||
renderer.deleteFramebuffer(this.framebuffer);
|
||||
|
||||
renderer.deleteTexture(this.texture);
|
||||
|
||||
renderer.deleteFramebuffer(this.framebuffer);
|
||||
|
||||
width *= this.scale;
|
||||
height *= this.scale;
|
||||
|
||||
|
@ -386,9 +388,12 @@ var RenderTarget = new Class({
|
|||
|
||||
renderer.off(Events.RESIZE, this.resize, this);
|
||||
|
||||
renderer.deleteFramebuffer(this.framebuffer);
|
||||
console.log('RT.destroy');
|
||||
|
||||
renderer.deleteTexture(this.texture);
|
||||
|
||||
renderer.deleteFramebuffer(this.framebuffer);
|
||||
|
||||
this.renderer = null;
|
||||
this.framebuffer = null;
|
||||
this.texture = null;
|
||||
|
|
|
@ -636,6 +636,9 @@ var WebGLRenderer = new Class({
|
|||
*/
|
||||
this._debugCapture = false;
|
||||
|
||||
this.textureCache = [];
|
||||
this.framebufferCache = [];
|
||||
|
||||
this.init(this.config);
|
||||
},
|
||||
|
||||
|
@ -807,6 +810,8 @@ var WebGLRenderer = new Class({
|
|||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([ 0, 0, 255, 255 ]));
|
||||
|
||||
this.textureIndexes.push(index);
|
||||
|
||||
this.addToTextureCache(tempTexture, 1, 1, 'MacFix' + index);
|
||||
}
|
||||
|
||||
this.pipelines = new PipelineManager(this);
|
||||
|
@ -1864,6 +1869,40 @@ var WebGLRenderer = new Class({
|
|||
return this;
|
||||
},
|
||||
|
||||
addToTextureCache: function (texture, width, height, source, isAlphaPremultiplied, isRenderTexture)
|
||||
{
|
||||
if (source === undefined) { source = 'Unknown'; }
|
||||
if (isAlphaPremultiplied === undefined) { isAlphaPremultiplied = true; }
|
||||
if (isRenderTexture === undefined) { isRenderTexture = false; }
|
||||
|
||||
this.textureCache.push({
|
||||
texture: texture,
|
||||
source: source,
|
||||
width: width,
|
||||
height: height,
|
||||
isAlphaPremultiplied: isAlphaPremultiplied,
|
||||
isRenderTexture: isRenderTexture
|
||||
});
|
||||
|
||||
console.log('addToTextureCache', width, height, source, this.textureCache.length);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
getTextureCacheEntry: function (texture)
|
||||
{
|
||||
// Find the entry in the textureCache
|
||||
var index = this.textureCache.findIndex(function (element)
|
||||
{
|
||||
return (element.texture === texture);
|
||||
});
|
||||
|
||||
if (index !== -1)
|
||||
{
|
||||
return this.textureCache[index];
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a texture from an image source. If the source is not valid it creates an empty texture.
|
||||
*
|
||||
|
@ -2013,10 +2052,14 @@ var WebGLRenderer = new Class({
|
|||
gl.bindTexture(gl.TEXTURE_2D, currentTexture);
|
||||
}
|
||||
|
||||
texture.isAlphaPremultiplied = pma;
|
||||
texture.isRenderTexture = false;
|
||||
texture.width = width;
|
||||
texture.height = height;
|
||||
this.addToTextureCache(texture, width, height, 'Unknown', pma, false);
|
||||
|
||||
// These properties used to be directly on the WebGLTexture, but now they're stored in the cache:
|
||||
|
||||
// texture.isAlphaPremultiplied = pma;
|
||||
// texture.isRenderTexture = false;
|
||||
// texture.width = width;
|
||||
// texture.height = height;
|
||||
|
||||
return texture;
|
||||
},
|
||||
|
@ -2044,8 +2087,10 @@ var WebGLRenderer = new Class({
|
|||
|
||||
this.setFramebuffer(framebuffer);
|
||||
|
||||
renderTexture.isRenderTexture = true;
|
||||
renderTexture.isAlphaPremultiplied = false;
|
||||
var entry = this.getTextureCacheEntry(renderTexture);
|
||||
|
||||
entry.isRenderTexture = true;
|
||||
entry.isAlphaPremultiplied = false;
|
||||
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, renderTexture, 0);
|
||||
|
||||
|
@ -2063,6 +2108,7 @@ var WebGLRenderer = new Class({
|
|||
throw new Error('Framebuffer status: ' + (errors[complete] || complete));
|
||||
}
|
||||
|
||||
// TODO - REMOVE THIS
|
||||
framebuffer.renderTexture = renderTexture;
|
||||
|
||||
if (addDepthStencilBuffer)
|
||||
|
@ -2265,15 +2311,34 @@ var WebGLRenderer = new Class({
|
|||
* @method Phaser.Renderer.WebGL.WebGLRenderer#deleteTexture
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param {WebGLTexture} texture - The WebGL Texture to be deleted.
|
||||
* @param {WebGLTexture} glTexture - The WebGL Texture to be deleted.
|
||||
*
|
||||
* @return {this} This WebGLRenderer instance.
|
||||
*/
|
||||
deleteTexture: function (texture)
|
||||
deleteTexture: function (glTexture)
|
||||
{
|
||||
if (texture)
|
||||
if (glTexture)
|
||||
{
|
||||
this.gl.deleteTexture(texture);
|
||||
// Find the entry in the textureCache
|
||||
var index = this.textureCache.findIndex(function (element)
|
||||
{
|
||||
return (element.texture === glTexture);
|
||||
});
|
||||
|
||||
if (index !== -1)
|
||||
{
|
||||
var entry = this.textureCache[index];
|
||||
|
||||
this.textureCache.splice(index, 1);
|
||||
|
||||
this.gl.deleteTexture(entry.texture);
|
||||
|
||||
console.log('Texture Deleted from index', index);
|
||||
}
|
||||
else
|
||||
{
|
||||
console.warn('Texture not found in cache', glTexture);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
|
@ -2296,6 +2361,8 @@ var WebGLRenderer = new Class({
|
|||
return this;
|
||||
}
|
||||
|
||||
console.log('deleteFramebuffer', framebuffer);
|
||||
|
||||
var gl = this.gl;
|
||||
|
||||
if (this.currentFramebuffer === framebuffer)
|
||||
|
@ -2307,6 +2374,8 @@ var WebGLRenderer = new Class({
|
|||
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
||||
|
||||
framebuffer.renderTexture = undefined;
|
||||
|
||||
// Check for a color attachment and remove it
|
||||
var colorAttachment = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
|
||||
|
||||
|
@ -2314,8 +2383,14 @@ var WebGLRenderer = new Class({
|
|||
{
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
|
||||
|
||||
// TODO: Check if this texture is used elsewhere. If not, delete it:
|
||||
gl.deleteTexture(colorAttachment);
|
||||
var colorEntry = this.getTextureCacheEntry(colorAttachment);
|
||||
|
||||
if (colorEntry)
|
||||
{
|
||||
this.deleteTexture(colorAttachment);
|
||||
}
|
||||
|
||||
// gl.deleteTexture(colorAttachment);
|
||||
}
|
||||
|
||||
// Check for a depth-stencil attachment and delete it
|
||||
|
@ -2324,6 +2399,8 @@ var WebGLRenderer = new Class({
|
|||
if (depthStencilAttachment !== null)
|
||||
{
|
||||
gl.deleteRenderbuffer(depthStencilAttachment);
|
||||
|
||||
console.log('deleteFramebuffer - delete render buffer', depthStencilAttachment);
|
||||
}
|
||||
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
|
|
|
@ -168,6 +168,8 @@ var LightPipeline = new Class({
|
|||
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([ 127, 127, 255, 255 ]));
|
||||
|
||||
this.renderer.addToTextureCache(tempTexture, 1, 1, 'LightPipeline');
|
||||
|
||||
this.defaultNormalMap = { glTexture: tempTexture };
|
||||
},
|
||||
|
||||
|
|
|
@ -224,16 +224,20 @@ var PostFXPipeline = new Class({
|
|||
*/
|
||||
this.halfFrame2;
|
||||
|
||||
if (this.renderer.isBooted)
|
||||
{
|
||||
this.manager = this.renderer.pipelines;
|
||||
this.pendingBoot = true;
|
||||
|
||||
this.boot();
|
||||
}
|
||||
// if (this.renderer.isBooted)
|
||||
// {
|
||||
// this.manager = this.renderer.pipelines;
|
||||
|
||||
// this.boot();
|
||||
// }
|
||||
},
|
||||
|
||||
boot: function ()
|
||||
{
|
||||
this.manager = this.renderer.pipelines;
|
||||
|
||||
WebGLPipeline.prototype.boot.call(this);
|
||||
|
||||
var utility = this.manager.UTILITY_PIPELINE;
|
||||
|
@ -251,6 +255,34 @@ var PostFXPipeline = new Class({
|
|||
{
|
||||
targets[i].autoResize = true;
|
||||
}
|
||||
|
||||
this.pendingBoot = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* This method is called every time the Pipeline Manager makes this pipeline the currently active one.
|
||||
*
|
||||
* It binds the resources and shader needed for this pipeline, including setting the vertex buffer
|
||||
* and attribute pointers.
|
||||
*
|
||||
* @method Phaser.Renderer.WebGL.WebGLPipeline#bind
|
||||
* @fires Phaser.Renderer.WebGL.Pipelines.Events#BIND
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current.
|
||||
*
|
||||
* @return {this} This WebGLPipeline instance.
|
||||
*/
|
||||
bind: function (currentShader)
|
||||
{
|
||||
if (this.pendingBoot)
|
||||
{
|
||||
console.log('PostFXPipeline booting');
|
||||
|
||||
this.boot();
|
||||
}
|
||||
|
||||
WebGLPipeline.prototype.bind.call(this, currentShader);
|
||||
},
|
||||
|
||||
onDraw: function (renderTarget)
|
||||
|
|
|
@ -99,6 +99,28 @@ var DynamicTexture = new Class({
|
|||
*/
|
||||
this.renderer = renderer;
|
||||
|
||||
/**
|
||||
* The width of this Dynamic Texture.
|
||||
*
|
||||
* Treat this property as read-only. Use the `setSize` method to change the size.
|
||||
*
|
||||
* @name Phaser.Textures.DynamicTexture#width
|
||||
* @type {number}
|
||||
* @since 3.60.0
|
||||
*/
|
||||
this.width = width;
|
||||
|
||||
/**
|
||||
* The height of this Dynamic Texture.
|
||||
*
|
||||
* Treat this property as read-only. Use the `setSize` method to change the size.
|
||||
*
|
||||
* @name Phaser.Textures.DynamicTexture#height
|
||||
* @type {number}
|
||||
* @since 3.60.0
|
||||
*/
|
||||
this.height = height;
|
||||
|
||||
/**
|
||||
* This flag is set to 'true' during `beginDraw` and reset to 'false` in `endDraw`,
|
||||
* allowing you to determine if this Dynamic Texture is batch drawing, or not.
|
||||
|
@ -232,6 +254,8 @@ var DynamicTexture = new Class({
|
|||
var frame = this.get();
|
||||
var source = frame.source;
|
||||
|
||||
console.log('DT.setSize >>>', width, height, 'from', this.width, this.height);
|
||||
|
||||
if (width !== this.width || height !== this.height)
|
||||
{
|
||||
if (this.canvas)
|
||||
|
@ -246,10 +270,17 @@ var DynamicTexture = new Class({
|
|||
{
|
||||
renderTarget.resize(width, height);
|
||||
|
||||
var e = this.renderer.getTextureCacheEntry(frame.glTexture);
|
||||
|
||||
console.log('DT.setSize e', e);
|
||||
console.log('DT.setSize rt', frame, frame.glTexture);
|
||||
console.log('DT.setSize 2', frame.glTexture === renderTarget.texture);
|
||||
|
||||
frame.glTexture = renderTarget.texture;
|
||||
|
||||
source.isRenderTexture = true;
|
||||
source.isGLTexture = true;
|
||||
|
||||
source.glTexture = renderTarget.texture;
|
||||
source.glTexture.flipY = true;
|
||||
}
|
||||
|
|
|
@ -224,6 +224,8 @@ var TextureSource = new Class({
|
|||
var height = this.height;
|
||||
var scaleMode = this.scaleMode;
|
||||
|
||||
console.log('TextureSource', this.texture.key);
|
||||
|
||||
if (this.isCanvas)
|
||||
{
|
||||
this.glTexture = renderer.createCanvasTexture(image, false, flipY);
|
||||
|
|
Loading…
Reference in a new issue