var core = require('../../core'), SharedTicker = core.ticker.shared; /** * The prepare manager provides functionality to upload content to the GPU * @class * @memberof PIXI * @param renderer {PIXI.WebGLRenderer} A reference to the current renderer */ function Prepare(renderer) { /** * Reference to the renderer. * @type {PIXI.WebGLRenderer} * @private */ this.renderer = renderer; /** * Collection of textures to do multiple uploads at once. * @type {Array<PIXI.Texture>} * @private */ this.textures = []; /** * Collection of graphics to do multiple uploads at once. * @type {Array<PIXI.Graphics>} * @private */ this.graphics = []; /** * Callback to call after completed. * @type {Function} * @private */ this.complete = null; } /** * The number of graphics or textures to upload to the GPU * @property {int} UPLOADS_PER_FRAME * @static * @default 4 */ Prepare.UPLOADS_PER_FRAME = 4; Prepare.prototype.constructor = Prepare; module.exports = Prepare; /** * Upload all the textures and graphics to the GPU. * @method upload * @static * @param {PIXI.WebGLRenderer} renderer Render to upload to * @param {PIXI.DisplayObject|PIXI.Container} clip MovieClip to upload * @param {Function} done When completed */ Prepare.prototype.upload = function(displayObject, done) { // Get the items for upload from the display if (this.find(displayObject)) { this.numLeft = Prepare.UPLOADS_PER_FRAME; this.complete = done; SharedTicker.add(this.tick, this); } else { done(); } }; /** * Handle tick update * @method tick * @private */ Prepare.prototype.tick = function() { // Upload the graphics while(this.graphics.length && this.numLeft) { this.renderer.plugins.graphics.updateGraphics(this.graphics.pop()); this.numLeft--; } // Upload the textures while(this.textures.length && this.numLeft) { this.renderer.textureManager.updateTexture(this.textures.pop()); this.numLeft--; } // We're finished if (this.textures.length || this.graphics.length) { this.numLeft = Prepare.UPLOADS_PER_FRAME; } else { SharedTicker.remove(this.tick, this); var done = this.complete; this.complete = null; done(); } }; /** * Scan for uploadable items. * @method uploadable * @private * @param {PIXI.DisplayObject|PIXI.Container} displayObject * @return {Boolean} `true` if items were found and we should proceed. */ Prepare.prototype.find = function(displayObject) { // Objects with textures, like Sprites/Text if (displayObject._texture && displayObject._texture instanceof core.Texture) { var texture = displayObject._texture.baseTexture; if (this.textures.indexOf(texture) === -1) { this.textures.push(texture); } } else if (displayObject instanceof core.Graphics) { this.graphics.push(displayObject); } // Get childen recursively if (displayObject instanceof core.Container) { for (var i = displayObject.children.length - 1; i >= 0; i--) { this.find(displayObject.children[i]); } } return this.textures.length + this.graphics.length; }; core.WebGLRenderer.registerPlugin('prepare', Prepare);