diff --git a/src/index.js b/src/index.js index 6596b1d..70a2b2d 100644 --- a/src/index.js +++ b/src/index.js @@ -12,6 +12,7 @@ core.particles = require('./particles'); core.accessibility = require('./accessibility'); core.extract = require('./extract'); +core.prepare = require('./prepare'); // export a premade loader instance /** diff --git a/src/index.js b/src/index.js index 6596b1d..70a2b2d 100644 --- a/src/index.js +++ b/src/index.js @@ -12,6 +12,7 @@ core.particles = require('./particles'); core.accessibility = require('./accessibility'); core.extract = require('./extract'); +core.prepare = require('./prepare'); // export a premade loader instance /** diff --git a/src/prepare/index.js b/src/prepare/index.js new file mode 100644 index 0000000..44d9a3f --- /dev/null +++ b/src/prepare/index.js @@ -0,0 +1,4 @@ + +module.exports = { + webGL: require('./webgl/WebGLPrepare') +}; \ No newline at end of file diff --git a/src/index.js b/src/index.js index 6596b1d..70a2b2d 100644 --- a/src/index.js +++ b/src/index.js @@ -12,6 +12,7 @@ core.particles = require('./particles'); core.accessibility = require('./accessibility'); core.extract = require('./extract'); +core.prepare = require('./prepare'); // export a premade loader instance /** diff --git a/src/prepare/index.js b/src/prepare/index.js new file mode 100644 index 0000000..44d9a3f --- /dev/null +++ b/src/prepare/index.js @@ -0,0 +1,4 @@ + +module.exports = { + webGL: require('./webgl/WebGLPrepare') +}; \ No newline at end of file diff --git a/src/prepare/webgl/WebGLPrepare.js b/src/prepare/webgl/WebGLPrepare.js new file mode 100644 index 0000000..37a3aa2 --- /dev/null +++ b/src/prepare/webgl/WebGLPrepare.js @@ -0,0 +1,147 @@ +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} + * @private + */ + this.textures = []; + + /** + * Collection of graphics to do multiple uploads at once. + * @type {Array} + * @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); \ No newline at end of file