| 1 |
- {"version":3,"file":"mixin-cache-as-bitmap.min.mjs","sources":["../../src/index.ts"],"sourcesContent":["import type { Renderer, MaskData, AbstractRenderer } from '@pixi/core';\nimport { Texture, BaseTexture, RenderTexture } from '@pixi/core';\nimport { Sprite } from '@pixi/sprite';\nimport type { Container, IDestroyOptions } from '@pixi/display';\nimport { DisplayObject } from '@pixi/display';\nimport type { IPointData, Rectangle } from '@pixi/math';\nimport { Matrix } from '@pixi/math';\nimport { uid } from '@pixi/utils';\nimport { settings } from '@pixi/settings';\nimport { MSAA_QUALITY } from '@pixi/constants';\n\n// Don't import CanvasRender to remove dependency on this optional package\n// this type should satisify these requirements for cacheAsBitmap types\ninterface CanvasRenderer extends AbstractRenderer\n{\n context: CanvasRenderingContext2D;\n}\n\nconst _tempMatrix = new Matrix();\n\nDisplayObject.prototype._cacheAsBitmap = false;\nDisplayObject.prototype._cacheData = null;\nDisplayObject.prototype._cacheAsBitmapResolution = null;\nDisplayObject.prototype._cacheAsBitmapMultisample = MSAA_QUALITY.NONE;\n\n// figured there's no point adding ALL the extra variables to prototype.\n// this model can hold the information needed. This can also be generated on demand as\n// most objects are not cached as bitmaps.\n/**\n * @class\n * @ignore\n * @private\n */\nexport class CacheData\n{\n public textureCacheId: string;\n public originalRender: (renderer: Renderer) => void;\n public originalRenderCanvas: (renderer: AbstractRenderer) => void;\n public originalCalculateBounds: () => void;\n public originalGetLocalBounds: (rect?: Rectangle) => Rectangle;\n public originalUpdateTransform: () => void;\n public originalDestroy: (options?: IDestroyOptions | boolean) => void;\n public originalMask: Container | MaskData;\n public originalFilterArea: Rectangle;\n public originalContainsPoint: (point: IPointData) => boolean;\n public sprite: Sprite;\n\n constructor()\n {\n this.textureCacheId = null;\n\n this.originalRender = null;\n this.originalRenderCanvas = null;\n this.originalCalculateBounds = null;\n this.originalGetLocalBounds = null;\n\n this.originalUpdateTransform = null;\n this.originalDestroy = null;\n this.originalMask = null;\n this.originalFilterArea = null;\n this.originalContainsPoint = null;\n this.sprite = null;\n }\n}\n\nObject.defineProperties(DisplayObject.prototype, {\n /**\n * The resolution to use for cacheAsBitmap. By default this will use the renderer's resolution\n * but can be overriden for performance. Lower values will reduce memory usage at the expense\n * of render quality. A falsey value of `null` or `0` will default to the renderer's resolution.\n * If `cacheAsBitmap` is set to `true`, this will re-render with the new resolution.\n * @member {number} cacheAsBitmapResolution\n * @memberof PIXI.DisplayObject#\n * @default null\n */\n cacheAsBitmapResolution: {\n get(): number\n {\n return this._cacheAsBitmapResolution;\n },\n set(resolution: number): void\n {\n if (resolution === this._cacheAsBitmapResolution)\n {\n return;\n }\n\n this._cacheAsBitmapResolution = resolution;\n\n if (this.cacheAsBitmap)\n {\n // Toggle to re-render at the new resolution\n this.cacheAsBitmap = false;\n this.cacheAsBitmap = true;\n }\n },\n },\n\n /**\n * The number of samples to use for cacheAsBitmap. If set to `null`, the renderer's\n * sample count is used.\n * If `cacheAsBitmap` is set to `true`, this will re-render with the new number of samples.\n * @member {number} cacheAsBitmapMultisample\n * @memberof PIXI.DisplayObject#\n * @default PIXI.MSAA_QUALITY.NONE\n */\n cacheAsBitmapMultisample: {\n get(): MSAA_QUALITY\n {\n return this._cacheAsBitmapMultisample;\n },\n set(multisample: MSAA_QUALITY): void\n {\n if (multisample === this._cacheAsBitmapMultisample)\n {\n return;\n }\n\n this._cacheAsBitmapMultisample = multisample;\n\n if (this.cacheAsBitmap)\n {\n // Toggle to re-render with new multisample\n this.cacheAsBitmap = false;\n this.cacheAsBitmap = true;\n }\n },\n },\n\n /**\n * Set this to true if you want this display object to be cached as a bitmap.\n * This basically takes a snap shot of the display object as it is at that moment. It can\n * provide a performance benefit for complex static displayObjects.\n * To remove simply set this property to `false`\n *\n * IMPORTANT GOTCHA - Make sure that all your textures are preloaded BEFORE setting this property to true\n * as it will take a snapshot of what is currently there. If the textures have not loaded then they will not appear.\n * @member {boolean}\n * @memberof PIXI.DisplayObject#\n */\n cacheAsBitmap: {\n get(): CacheData\n {\n return this._cacheAsBitmap;\n },\n set(value: CacheData): void\n {\n if (this._cacheAsBitmap === value)\n {\n return;\n }\n\n this._cacheAsBitmap = value;\n\n let data: CacheData;\n\n if (value)\n {\n if (!this._cacheData)\n {\n this._cacheData = new CacheData();\n }\n\n data = this._cacheData;\n\n data.originalRender = this.render;\n data.originalRenderCanvas = this.renderCanvas;\n\n data.originalUpdateTransform = this.updateTransform;\n data.originalCalculateBounds = this.calculateBounds;\n data.originalGetLocalBounds = this.getLocalBounds;\n\n data.originalDestroy = this.destroy;\n\n data.originalContainsPoint = this.containsPoint;\n\n data.originalMask = this._mask;\n data.originalFilterArea = this.filterArea;\n\n this.render = this._renderCached;\n this.renderCanvas = this._renderCachedCanvas;\n\n this.destroy = this._cacheAsBitmapDestroy;\n }\n else\n {\n data = this._cacheData;\n\n if (data.sprite)\n {\n this._destroyCachedDisplayObject();\n }\n\n this.render = data.originalRender;\n this.renderCanvas = data.originalRenderCanvas;\n this.calculateBounds = data.originalCalculateBounds;\n this.getLocalBounds = data.originalGetLocalBounds;\n\n this.destroy = data.originalDestroy;\n\n this.updateTransform = data.originalUpdateTransform;\n this.containsPoint = data.originalContainsPoint;\n\n this._mask = data.originalMask;\n this.filterArea = data.originalFilterArea;\n }\n },\n },\n});\n\n/**\n * Renders a cached version of the sprite with WebGL\n * @private\n * @method _renderCached\n * @memberof PIXI.DisplayObject#\n * @param {PIXI.Renderer} renderer - the WebGL renderer\n */\nDisplayObject.prototype._renderCached = function _renderCached(renderer: Renderer): void\n{\n if (!this.visible || this.worldAlpha <= 0 || !this.renderable)\n {\n return;\n }\n\n this._initCachedDisplayObject(renderer);\n\n this._cacheData.sprite.transform._worldID = this.transform._worldID;\n this._cacheData.sprite.worldAlpha = this.worldAlpha;\n (this._cacheData.sprite as any)._render(renderer);\n};\n\n/**\n * Prepares the WebGL renderer to cache the sprite\n * @private\n * @method _initCachedDisplayObject\n * @memberof PIXI.DisplayObject#\n * @param {PIXI.Renderer} renderer - the WebGL renderer\n */\nDisplayObject.prototype._initCachedDisplayObject = function _initCachedDisplayObject(renderer: Renderer): void\n{\n if (this._cacheData && this._cacheData.sprite)\n {\n return;\n }\n\n // make sure alpha is set to 1 otherwise it will get rendered as invisible!\n const cacheAlpha = this.alpha;\n\n this.alpha = 1;\n\n // first we flush anything left in the renderer (otherwise it would get rendered to the cached texture)\n renderer.batch.flush();\n // this.filters= [];\n\n // next we find the dimensions of the untransformed object\n // this function also calls updatetransform on all its children as part of the measuring.\n // This means we don't need to update the transform again in this function\n // TODO pass an object to clone too? saves having to create a new one each time!\n const bounds = (this as Container).getLocalBounds(null, true).clone();\n\n // add some padding!\n if (this.filters && this.filters.length)\n {\n const padding = this.filters[0].padding;\n\n bounds.pad(padding);\n }\n\n bounds.ceil(settings.RESOLUTION);\n\n // for now we cache the current renderTarget that the WebGL renderer is currently using.\n // this could be more elegant..\n const cachedRenderTexture = renderer.renderTexture.current;\n const cachedSourceFrame = renderer.renderTexture.sourceFrame.clone();\n const cachedDestinationFrame = renderer.renderTexture.destinationFrame.clone();\n const cachedProjectionTransform = renderer.projection.transform;\n\n // We also store the filter stack - I will definitely look to change how this works a little later down the line.\n // const stack = renderer.filterManager.filterStack;\n\n // this renderTexture will be used to store the cached DisplayObject\n const renderTexture = RenderTexture.create({\n width: bounds.width,\n height: bounds.height,\n resolution: this.cacheAsBitmapResolution || renderer.resolution,\n multisample: this.cacheAsBitmapMultisample ?? renderer.multisample,\n });\n\n const textureCacheId = `cacheAsBitmap_${uid()}`;\n\n this._cacheData.textureCacheId = textureCacheId;\n\n BaseTexture.addToCache(renderTexture.baseTexture, textureCacheId);\n Texture.addToCache(renderTexture, textureCacheId);\n\n // need to set //\n const m = this.transform.localTransform.copyTo(_tempMatrix).invert().translate(-bounds.x, -bounds.y);\n\n // set all properties to there original so we can render to a texture\n this.render = this._cacheData.originalRender;\n\n renderer.render(this, { renderTexture, clear: true, transform: m, skipUpdateTransform: false });\n renderer.framebuffer.blit();\n\n // now restore the state be setting the new properties\n renderer.projection.transform = cachedProjectionTransform;\n renderer.renderTexture.bind(cachedRenderTexture, cachedSourceFrame, cachedDestinationFrame);\n\n // renderer.filterManager.filterStack = stack;\n\n this.render = this._renderCached;\n // the rest is the same as for Canvas\n this.updateTransform = this.displayObjectUpdateTransform;\n this.calculateBounds = this._calculateCachedBounds;\n this.getLocalBounds = this._getCachedLocalBounds;\n\n this._mask = null;\n this.filterArea = null;\n this.alpha = cacheAlpha;\n\n // create our cached sprite\n const cachedSprite = new Sprite(renderTexture);\n\n cachedSprite.transform.worldTransform = this.transform.worldTransform;\n cachedSprite.anchor.x = -(bounds.x / bounds.width);\n cachedSprite.anchor.y = -(bounds.y / bounds.height);\n cachedSprite.alpha = cacheAlpha;\n cachedSprite._bounds = this._bounds;\n\n this._cacheData.sprite = cachedSprite;\n\n this.transform._parentID = -1;\n // restore the transform of the cached sprite to avoid the nasty flicker..\n if (!this.parent)\n {\n this.enableTempParent();\n this.updateTransform();\n this.disableTempParent(null);\n }\n else\n {\n this.updateTransform();\n }\n\n // map the hit test..\n (this as Sprite).containsPoint = cachedSprite.containsPoint.bind(cachedSprite);\n};\n\n/**\n * Renders a cached version of the sprite with canvas\n * @private\n * @method _renderCachedCanvas\n * @memberof PIXI.DisplayObject#\n * @param {PIXI.CanvasRenderer} renderer - The canvas renderer\n */\nDisplayObject.prototype._renderCachedCanvas = function _renderCachedCanvas(renderer: AbstractRenderer): void\n{\n if (!this.visible || this.worldAlpha <= 0 || !this.renderable)\n {\n return;\n }\n\n this._initCachedDisplayObjectCanvas(renderer);\n\n this._cacheData.sprite.worldAlpha = this.worldAlpha;\n (this._cacheData.sprite as any)._renderCanvas(renderer);\n};\n\n// TODO this can be the same as the WebGL version.. will need to do a little tweaking first though..\n/**\n * Prepares the Canvas renderer to cache the sprite\n * @private\n * @method _initCachedDisplayObjectCanvas\n * @memberof PIXI.DisplayObject#\n * @param {PIXI.CanvasRenderer} renderer - The canvas renderer\n */\nDisplayObject.prototype._initCachedDisplayObjectCanvas = function _initCachedDisplayObjectCanvas(\n renderer: CanvasRenderer\n): void\n{\n if (this._cacheData && this._cacheData.sprite)\n {\n return;\n }\n\n // get bounds actually transforms the object for us already!\n const bounds = (this as Container).getLocalBounds(null, true);\n\n const cacheAlpha = this.alpha;\n\n this.alpha = 1;\n\n const cachedRenderTarget = renderer.context;\n const cachedProjectionTransform = (renderer as any)._projTransform;\n\n bounds.ceil(settings.RESOLUTION);\n\n const renderTexture = RenderTexture.create({ width: bounds.width, height: bounds.height });\n\n const textureCacheId = `cacheAsBitmap_${uid()}`;\n\n this._cacheData.textureCacheId = textureCacheId;\n\n BaseTexture.addToCache(renderTexture.baseTexture, textureCacheId);\n Texture.addToCache(renderTexture, textureCacheId);\n\n // need to set //\n const m = _tempMatrix;\n\n this.transform.localTransform.copyTo(m);\n m.invert();\n\n m.tx -= bounds.x;\n m.ty -= bounds.y;\n\n // m.append(this.transform.worldTransform.)\n // set all properties to there original so we can render to a texture\n this.renderCanvas = this._cacheData.originalRenderCanvas;\n\n renderer.render(this, { renderTexture, clear: true, transform: m, skipUpdateTransform: false });\n // now restore the state be setting the new properties\n renderer.context = cachedRenderTarget;\n (renderer as any)._projTransform = cachedProjectionTransform;\n\n this.renderCanvas = this._renderCachedCanvas;\n // the rest is the same as for WebGL\n this.updateTransform = this.displayObjectUpdateTransform;\n this.calculateBounds = this._calculateCachedBounds;\n this.getLocalBounds = this._getCachedLocalBounds;\n\n this._mask = null;\n this.filterArea = null;\n this.alpha = cacheAlpha;\n\n // create our cached sprite\n const cachedSprite = new Sprite(renderTexture);\n\n cachedSprite.transform.worldTransform = this.transform.worldTransform;\n cachedSprite.anchor.x = -(bounds.x / bounds.width);\n cachedSprite.anchor.y = -(bounds.y / bounds.height);\n cachedSprite.alpha = cacheAlpha;\n cachedSprite._bounds = this._bounds;\n\n this._cacheData.sprite = cachedSprite;\n\n this.transform._parentID = -1;\n // restore the transform of the cached sprite to avoid the nasty flicker..\n if (!this.parent)\n {\n this.parent = (renderer as any)._tempDisplayObjectParent;\n this.updateTransform();\n this.parent = null;\n }\n else\n {\n this.updateTransform();\n }\n\n // map the hit test..\n (this as Sprite).containsPoint = cachedSprite.containsPoint.bind(cachedSprite);\n};\n\n/**\n * Calculates the bounds of the cached sprite\n * @private\n * @method\n */\nDisplayObject.prototype._calculateCachedBounds = function _calculateCachedBounds(): void\n{\n this._bounds.clear();\n this._cacheData.sprite.transform._worldID = this.transform._worldID;\n (this._cacheData.sprite as any)._calculateBounds();\n this._bounds.updateID = (this as any)._boundsID;\n};\n\n/**\n * Gets the bounds of the cached sprite.\n * @private\n * @method\n * @returns {Rectangle} The local bounds.\n */\nDisplayObject.prototype._getCachedLocalBounds = function _getCachedLocalBounds(): Rectangle\n{\n return this._cacheData.sprite.getLocalBounds(null);\n};\n\n/**\n * Destroys the cached sprite.\n * @private\n * @method\n */\nDisplayObject.prototype._destroyCachedDisplayObject = function _destroyCachedDisplayObject(): void\n{\n this._cacheData.sprite._texture.destroy(true);\n this._cacheData.sprite = null;\n\n BaseTexture.removeFromCache(this._cacheData.textureCacheId);\n Texture.removeFromCache(this._cacheData.textureCacheId);\n\n this._cacheData.textureCacheId = null;\n};\n\n/**\n * Destroys the cached object.\n * @private\n * @method\n * @param {object|boolean} [options] - Options parameter. A boolean will act as if all options\n * have been set to that value.\n * Used when destroying containers, see the Container.destroy method.\n */\nDisplayObject.prototype._cacheAsBitmapDestroy = function _cacheAsBitmapDestroy(options?: IDestroyOptions | boolean): void\n{\n this.cacheAsBitmap = false;\n this.destroy(options);\n};\n"],"names":["_tempMatrix","Matrix","DisplayObject","prototype","_cacheAsBitmap","_cacheData","_cacheAsBitmapResolution","_cacheAsBitmapMultisample","MSAA_QUALITY","NONE","CacheData","this","textureCacheId","originalRender","originalRenderCanvas","originalCalculateBounds","originalGetLocalBounds","originalUpdateTransform","originalDestroy","originalMask","originalFilterArea","originalContainsPoint","sprite","Object","defineProperties","cacheAsBitmapResolution","get","set","resolution","cacheAsBitmap","cacheAsBitmapMultisample","multisample","value","data","render","renderCanvas","updateTransform","calculateBounds","getLocalBounds","destroy","containsPoint","_mask","filterArea","_renderCached","_renderCachedCanvas","_cacheAsBitmapDestroy","_destroyCachedDisplayObject","renderer","visible","worldAlpha","renderable","_initCachedDisplayObject","transform","_worldID","_render","cacheAlpha","alpha","batch","flush","bounds","clone","filters","length","padding","pad","ceil","settings","RESOLUTION","cachedRenderTexture","renderTexture","current","cachedSourceFrame","sourceFrame","cachedDestinationFrame","destinationFrame","cachedProjectionTransform","projection","RenderTexture","create","width","height","_a","uid","BaseTexture","addToCache","baseTexture","Texture","m","localTransform","copyTo","invert","translate","x","y","clear","skipUpdateTransform","framebuffer","blit","bind","displayObjectUpdateTransform","_calculateCachedBounds","_getCachedLocalBounds","cachedSprite","Sprite","worldTransform","anchor","_bounds","_parentID","parent","enableTempParent","disableTempParent","_initCachedDisplayObjectCanvas","_renderCanvas","cachedRenderTarget","context","_projTransform","tx","ty","_tempDisplayObjectParent","_calculateBounds","updateID","_boundsID","_texture","removeFromCache","options"],"mappings":"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"}
|