Skip to content

Instantly share code, notes, and snippets.

@liply

liply/liply_GC.js

Created Oct 24, 2016
Embed
What would you like to do?
memory patch
(function () {
'use strict';
Graphics._bitmapPool = [];
Graphics.MEMORY_THRESHOLD = 100 * 1024 * 1024;
//
// Scene_Base
//
var Scene_Base_prototype_initialize = Scene_Base.prototype.initialize;
Scene_Base.prototype.initialize = function() {
Scene_Base_prototype_initialize.call(this);
this.__liply_sceneId = SceneManager._generateId();
};
//
// Bitmap
//
Bitmap.snap = function(stage) {
var width = Graphics.width;
var height = Graphics.height;
var bitmap = new Bitmap(width, height);
var context = bitmap._context;
var renderTexture = PIXI.RenderTexture.create(width, height);
if (stage) {
Graphics._renderer.render(stage, renderTexture);
stage.worldTransform.identity();
var canvas = null;
if (Graphics.isWebGL()) {
canvas = Graphics._renderer.extract.canvas(renderTexture);
} else {
canvas = renderTexture.baseTexture._canvasRenderTarget.canvas;
}
context.drawImage(canvas, 0, 0);
} else {
//TODO: Ivan: what if stage is not present?
}
bitmap._setDirty();
renderTexture.destroy();
if(Graphics.isWebGL()){
var textures = Graphics._renderer.textureManager._managedTextures;
if(textures.indexOf(renderTexture) !== -1)
textures.splice(textures.indexOf(renderTexture), 1);
}
return bitmap;
};
Bitmap.prototype.retain = function(){
if(this.__liply_count === undefined){
this.__liply_count = 1;
}else{
this.__liply_count++;
}
};
Bitmap.prototype.release = function(){
this.__liply_count--;
};
Bitmap.prototype.count = function(){
return this.__liply_count || 0;
};
var Bitmap_prototype_initialize = Bitmap.prototype.initialize;
Bitmap.prototype.initialize = function(width, height){
Bitmap_prototype_initialize.call(this, width, height);
this.__liply_sceneId = SceneManager._scene.__liply_sceneId;
if(Graphics.getUsedMemory() > Graphics.MEMORY_THRESHOLD){
Graphics.reserveGc(true);
}
Graphics._registerBitmap(this);
};
Bitmap.prototype.free = function(){
ImageManager.detachFromCache(this);
this.baseTexture.destroy();
this.baseTexture.hasLoaded = false;
this.canvas.width = 0;
this.__liply_broken = true;
};
/**
* Plugin creator MUST CALL this method if created Bitmap is not directly attached to Scene.
* Otherwise, the bitmap will be released when emergent gc is invoked, so your plugin rendering may be broken.
*/
Bitmap.prototype.using = function(){
this.__liply_attachedToScene = true;
};
//
// ImageManager
//
var ImageManager_loadSystem = ImageManager.loadSystem;
ImageManager.loadSystem = function(filename, hue) {
var bitmap = ImageManager_loadSystem.call(this, filename, hue);
bitmap.retain();
return bitmap;
};
var ImageManager_loadEmptyBitmap = ImageManager.loadEmptyBitmap;
ImageManager.loadEmptyBitmap = function(){
var bitmap = ImageManager_loadEmptyBitmap.call(this);
bitmap.retain();
return bitmap;
};
ImageManager.detachFromCache = function(bitmap){
var cacheData = this.cache._inner;
for(var key in cacheData){
if(cacheData.hasOwnProperty(key)){
var item = cacheData[key].item;
if(bitmap === item){
delete cacheData[key];
break;
}
}
}
};
//
// Graphics
//
Graphics._registerBitmap = function(bitmap){
this._bitmapPool.push(bitmap);
};
Graphics._miniMark = function(target, emergency){
var this$1 = this;
if (emergency) {
this._bitmapPool.forEach(function (b){
if (b.__liply_sceneId == target.__liply_sceneId && b.__liply_attachedToScene) {
b.__liply_mark = true;
}
});
} else {
this._bitmapPool.forEach(function (b){
if (b.__liply_sceneId == target.__liply_sceneId) {
b.__liply_mark = true;
}
});
}
if(target && target.children) {
target.children.forEach(function (s){
if (s.bitmap) {
s.bitmap.__liply_mark = true;
}
if(s.bitmaps){
for(var n = 0; n < s.bitmaps.length; ++n){
s.bitmaps[n].__liply_mark = true;
}
}
this$1._miniMark(s);
});
}
};
Graphics.cleanupTinter = function(target){
var this$1 = this;
if(target && target.children) {
target.children.forEach(function (s){
if(s._tintTexture) s._tintTexture.destroy();
this$1.cleanupTinter(s);
});
}
};
Graphics._sweep = function(){
var pool = this._bitmapPool;
var alive = [];
for(var n = 0, l = pool.length; n < l; ++n){
var bitmap = pool[n];
if(bitmap.__liply_mark || bitmap.count() > 0){
alive.push(bitmap);
}else{
bitmap.free();
}
bitmap.__liply_mark = false;
}
return alive;
};
Graphics.getUsedMemory = function(){
var pool = this._bitmapPool;
var size = 0;
for(var key in pool){
if(pool.hasOwnProperty(key)){
var bitmap = pool[key];
size += bitmap.canvas.width * bitmap.canvas.height * 4;
}
}
return size;
};
Graphics.getBitmapCount = function(){
return this._bitmapPool.length;
};
Graphics.gc = function(emergency){
var this$1 = this;
var stack = SceneManager.getSceneStack();
for(var n = 0; n < stack; ++n)
this$1._miniMark(stack[n], emergency);
this._miniMark(SceneManager.getCurrentScene(), emergency);
this._bitmapPool = this._sweep();
};
Graphics.reserveGc = function(emergency){
this._reserveGcFlag = true;
this._emergencyFlag = emergency;
};
Graphics.isEmergency = function(){
return this._emergencyFlag;
};
Graphics.performReservedGc = function(){
if(this._reserveGcFlag){
this._reserveGcFlag = false;
this.gc(this._emergencyFlag);
}
};
//
// SceneManager
//
SceneManager._generateId = (function(){
var id = 1;
return function (){ return id++; };
})();
SceneManager.isSceneStable = function(){
return !this.isSceneChanging() && this.isCurrentSceneStarted();
};
SceneManager.performCleanupIfChanged = function(){
var newScene = this._scene;
if(this._beforeScene !== newScene){
if(this._beforeScene) Graphics.cleanupTinter(this._beforeScene);
this._beforeScene = newScene;
}
};
SceneManager.getSceneStack = function(){
return this._stack;
};
SceneManager.getCurrentScene = function(){
return this._scene;
};
var SceneManager_goto = SceneManager.goto;
SceneManager.goto = function () {
SceneManager_goto.apply(this, arguments);
Graphics.reserveGc();
};
var SceneManager_push = SceneManager.push;
SceneManager.push = function () {
SceneManager_push.apply(this, arguments);
Graphics.reserveGc();
};
var SceneManager_pop = SceneManager.pop;
SceneManager.pop = function () {
SceneManager_pop.apply(this, arguments);
Graphics.reserveGc();
};
var SceneManager_updateScene = SceneManager.updateScene;
SceneManager.updateScene = function(){
SceneManager_updateScene.call(this);
this.performCleanupIfChanged();
if(this.isSceneStable())Graphics.performReservedGc(this._scene);
};
var SceneManager_snapForBackground = SceneManager.snapForBackground;
SceneManager.snapForBackground = function() {
if(this._backgroundBitmap){
this._backgroundBitmap.free();
this._backgroundBitmap = null;
}
SceneManager_snapForBackground.call(this);
};
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment