Skip to content

Commit 58865f2

Browse files
committed
The WebGL Lost and Restored Context callbacks were never removed, which could cause them to hold onto stale references. Fix phaserjs#3610
1 parent 53076e0 commit 58865f2

1 file changed

Lines changed: 49 additions & 56 deletions

File tree

src/renderer/webgl/WebGLRenderer.js

Lines changed: 49 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ var BaseCamera = require('../../cameras/2d/BaseCamera');
99
var CameraEvents = require('../../cameras/2d/events');
1010
var Class = require('../../utils/Class');
1111
var CONST = require('../../const');
12+
var GameEvents = require('../../core/events');
1213
var IsSizePowerOfTwo = require('../../math/pow2/IsSizePowerOfTwo');
14+
var NOOP = require('../../utils/NOOP');
1315
var ScaleEvents = require('../../scale/events');
1416
var SpliceOne = require('../../utils/array/SpliceOne');
1517
var TextureEvents = require('../../textures/events');
@@ -51,9 +53,6 @@ var WebGLRenderer = new Class({
5153

5254
function WebGLRenderer (game)
5355
{
54-
// eslint-disable-next-line consistent-this
55-
var renderer = this;
56-
5756
var gameConfig = game.config;
5857

5958
var contextCreationConfig = {
@@ -134,24 +133,6 @@ var WebGLRenderer = new Class({
134133
*/
135134
this.canvas = game.canvas;
136135

137-
/**
138-
* An array of functions to invoke if the WebGL context is lost.
139-
*
140-
* @name Phaser.Renderer.WebGL.WebGLRenderer#lostContextCallbacks
141-
* @type {WebGLContextCallback[]}
142-
* @since 3.0.0
143-
*/
144-
this.lostContextCallbacks = [];
145-
146-
/**
147-
* An array of functions to invoke if the WebGL context is restored.
148-
*
149-
* @name Phaser.Renderer.WebGL.WebGLRenderer#restoredContextCallbacks
150-
* @type {WebGLContextCallback[]}
151-
* @since 3.0.0
152-
*/
153-
this.restoredContextCallbacks = [];
154-
155136
/**
156137
* An array of blend modes supported by the WebGL Renderer.
157138
*
@@ -175,7 +156,7 @@ var WebGLRenderer = new Class({
175156
this.nativeTextures = [];
176157

177158
/**
178-
* Set to `true` if the WebGL context of the renderer is lost.
159+
* This property is set to `true` if the WebGL context of the renderer is lost.
179160
*
180161
* @name Phaser.Renderer.WebGL.WebGLRenderer#contextLost
181162
* @type {boolean}
@@ -313,7 +294,6 @@ var WebGLRenderer = new Class({
313294
* @type {Uint32Array}
314295
* @since 3.0.0
315296
*/
316-
// this.currentScissor = new Uint32Array([ 0, 0, this.width, this.height ]);
317297
this.currentScissor = null;
318298

319299
/**
@@ -325,30 +305,8 @@ var WebGLRenderer = new Class({
325305
*/
326306
this.scissorStack = [];
327307

328-
// Setup context lost and restore event listeners
329-
330-
this.canvas.addEventListener('webglcontextlost', function (event)
331-
{
332-
renderer.contextLost = true;
333-
event.preventDefault();
334-
335-
for (var index = 0; index < renderer.lostContextCallbacks.length; ++index)
336-
{
337-
var callback = renderer.lostContextCallbacks[index];
338-
callback[0].call(callback[1], renderer);
339-
}
340-
}, false);
341-
342-
this.canvas.addEventListener('webglcontextrestored', function ()
343-
{
344-
renderer.contextLost = false;
345-
renderer.init(renderer.config);
346-
for (var index = 0; index < renderer.restoredContextCallbacks.length; ++index)
347-
{
348-
var callback = renderer.restoredContextCallbacks[index];
349-
callback[0].call(callback[1], renderer);
350-
}
351-
}, false);
308+
this.contextLostHandler = NOOP;
309+
this.contextRestoredHandler = NOOP;
352310

353311
// These are initialized post context creation
354312

@@ -560,6 +518,31 @@ var WebGLRenderer = new Class({
560518

561519
this.gl = gl;
562520

521+
var _this = this;
522+
523+
this.contextLostHandler = function (event)
524+
{
525+
console.log('ctx lost handler');
526+
527+
_this.contextLost = true;
528+
529+
_this.game.events.emit(GameEvents.CONTEXT_LOST, _this);
530+
531+
event.preventDefault();
532+
};
533+
534+
this.contextRestoredHandler = function ()
535+
{
536+
_this.contextLost = false;
537+
538+
_this.init(_this.config);
539+
540+
_this.game.events.emit(GameEvents.CONTEXT_RESTORED, _this);
541+
};
542+
543+
canvas.addEventListener('webglcontextlost', this.contextLostHandler, false);
544+
canvas.addEventListener('webglcontextrestored', this.contextRestoredHandler, false);
545+
563546
// Set it back into the Game, so developers can access it from there too
564547
game.context = gl;
565548

@@ -2701,28 +2684,38 @@ var WebGLRenderer = new Class({
27012684
destroy: function ()
27022685
{
27032686
// Clear-up anything that should be cleared :)
2687+
2688+
for (var i = 0; i < this.nativeTextures.length; i++)
2689+
{
2690+
this.gl.deleteTexture(this.nativeTextures[i]);
2691+
}
2692+
2693+
this.nativeTextures = [];
2694+
27042695
for (var key in this.pipelines)
27052696
{
27062697
this.pipelines[key].destroy();
27072698

27082699
delete this.pipelines[key];
27092700
}
27102701

2711-
for (var index = 0; index < this.nativeTextures.length; index++)
2712-
{
2713-
this.deleteTexture(this.nativeTextures[index]);
2702+
this.defaultCamera.destroy();
27142703

2715-
delete this.nativeTextures[index];
2716-
}
2704+
this.currentMask = null;
2705+
this.currentCameraMask = null;
27172706

2718-
delete this.gl;
2719-
delete this.game;
2707+
this.canvas.removeEventListener('webglcontextlost', this.contextLostHandler, false);
2708+
this.canvas.removeEventListener('webglcontextrestored', this.contextRestoredHandler, false);
27202709

2721-
this.maskStack.length = 0;
2710+
this.game = null;
2711+
this.gl = null;
2712+
this.canvas = null;
2713+
2714+
this.maskStack = [];
27222715

27232716
this.contextLost = true;
2717+
27242718
this.extensions = {};
2725-
this.nativeTextures.length = 0;
27262719
}
27272720

27282721
});

0 commit comments

Comments
 (0)