mirror of
https://github.com/photonstorm/phaser
synced 2024-11-14 00:47:29 +00:00
Improve safety around context loss.
Clarify notes on drawing dynamic textures during context loss. Allow `Shader` to initialize and operate during context loss. Improve resize handling on context loss and recovery.
This commit is contained in:
parent
b762b28575
commit
4353a1e175
3 changed files with 74 additions and 1 deletions
|
@ -35,6 +35,8 @@ A render texture which is redrawn every frame will naturally redraw itself.
|
|||
|
||||
Textures which are drawn once, however, will stay blank. You should listen for the `RESTORE_WEBGL` event to know when to redraw them.
|
||||
|
||||
It is safe to draw while the context is lost, but nothing will be drawn. Snapshots will return blank.
|
||||
|
||||
### WebGL Object Wrappers
|
||||
|
||||
WebGL objects are now wrapped. The wrapper holds the necessary information to automatically recreate the object when context is restored.
|
||||
|
|
|
@ -13,6 +13,7 @@ var SetValue = require('../../utils/object/SetValue');
|
|||
var ShaderRender = require('./ShaderRender');
|
||||
var TransformMatrix = require('../components/TransformMatrix');
|
||||
var ArrayEach = require('../../utils/array/Each');
|
||||
var RenderEvents = require('../../renderer/events');
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
|
@ -166,6 +167,28 @@ var Shader = new Class({
|
|||
*/
|
||||
this.vertexBuffer = renderer.createVertexBuffer(this.vertexData.byteLength, this.gl.STREAM_DRAW);
|
||||
|
||||
/**
|
||||
* Internal property: whether the shader needs to be created,
|
||||
* and if so, the key and textures to use for the shader.
|
||||
*
|
||||
* @name Phaser.GameObjects.Shader#_deferSetShader
|
||||
* @type {?{ key: string, textures: string[]|undefined, textureData: any|undefined }}
|
||||
* @private
|
||||
* @since 3.80.0
|
||||
*/
|
||||
this._deferSetShader = false;
|
||||
|
||||
/**
|
||||
* Internal property: whether the projection matrix needs to be set,
|
||||
* and if so, the data to use for the orthographic projection.
|
||||
*
|
||||
* @name Phaser.GameObjects.Shader#_deferProjOrtho
|
||||
* @type {?{ left: number, right: number, bottom: number, top: number }}
|
||||
* @private
|
||||
* @since 3.80.0
|
||||
*/
|
||||
this._deferProjOrtho = null;
|
||||
|
||||
/**
|
||||
* The WebGL shader program this shader uses.
|
||||
*
|
||||
|
@ -351,6 +374,8 @@ var Shader = new Class({
|
|||
this.setSize(width, height);
|
||||
this.setOrigin(0.5, 0.5);
|
||||
this.setShader(key, textures, textureData);
|
||||
|
||||
this.renderer.on(RenderEvents.RESTORE_WEBGL, this.onContextRestored, this);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -475,6 +500,12 @@ var Shader = new Class({
|
|||
*/
|
||||
setShader: function (key, textures, textureData)
|
||||
{
|
||||
if (this.renderer.contextLost)
|
||||
{
|
||||
this._deferSetShader = { key: key, textures: textures, textureData: textureData };
|
||||
return this;
|
||||
}
|
||||
|
||||
if (textures === undefined) { textures = []; }
|
||||
|
||||
if (typeof key === 'string')
|
||||
|
@ -585,6 +616,12 @@ var Shader = new Class({
|
|||
*/
|
||||
projOrtho: function (left, right, bottom, top)
|
||||
{
|
||||
if (this.renderer.contextLost)
|
||||
{
|
||||
this._deferProjOrtho = { left: left, right: right, bottom: bottom, top: top };
|
||||
return;
|
||||
}
|
||||
|
||||
var near = -1000;
|
||||
var far = 1000;
|
||||
|
||||
|
@ -1207,6 +1244,34 @@ var Shader = new Class({
|
|||
{
|
||||
},
|
||||
|
||||
/**
|
||||
* Run any logic that was deferred during context loss.
|
||||
*
|
||||
* @method Phaser.GameObjects.Shader#onContextRestored
|
||||
* @since 3.80.0
|
||||
*/
|
||||
onContextRestored: function ()
|
||||
{
|
||||
if (this._deferSetShader !== null)
|
||||
{
|
||||
var key = this._deferSetShader.key;
|
||||
var textures = this._deferSetShader.textures;
|
||||
var textureData = this._deferSetShader.textureData;
|
||||
this._deferSetShader = null;
|
||||
this.setShader(key, textures, textureData);
|
||||
}
|
||||
|
||||
if (this._deferProjOrtho !== null)
|
||||
{
|
||||
var left = this._deferProjOrtho.left;
|
||||
var right = this._deferProjOrtho.right;
|
||||
var bottom = this._deferProjOrtho.bottom;
|
||||
var top = this._deferProjOrtho.top;
|
||||
this._deferProjOrtho = null;
|
||||
this.projOrtho(left, right, bottom, top);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Internal destroy handler, called as part of the destroy process.
|
||||
*
|
||||
|
@ -1218,6 +1283,7 @@ var Shader = new Class({
|
|||
{
|
||||
var renderer = this.renderer;
|
||||
|
||||
renderer.off(RenderEvents.RESTORE_WEBGL, this.onContextRestored, this);
|
||||
renderer.deleteProgram(this.program);
|
||||
renderer.deleteBuffer(this.vertexBuffer);
|
||||
|
||||
|
|
|
@ -826,7 +826,7 @@ var WebGLRenderer = new Class({
|
|||
_this.pipelines.restoreContext();
|
||||
|
||||
// Apply resize.
|
||||
_this.resize(_this.width, _this.height);
|
||||
_this.resize(_this.game.scale.width, _this.game.scale.height);
|
||||
|
||||
// Restore GL extensions.
|
||||
setupExtensions();
|
||||
|
@ -1295,6 +1295,11 @@ var WebGLRenderer = new Class({
|
|||
*/
|
||||
resize: function (width, height)
|
||||
{
|
||||
if (this.contextLost)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
var gl = this.gl;
|
||||
|
||||
this.width = width;
|
||||
|
|
Loading…
Reference in a new issue