question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

cacheAsBitmap causing issues in Canvas mode

See original GitHub issue

HI all,

First of all, thank you for building this wonderful library. Really makes life so much easier!

While PIXI seems to work without any issues in Webgl mode, I see problems when I am trying to load the same code in Canvas mode. Our setup has thousand of sprites but I tried with only few components as well and if cacheAsBitmap is turned on, it’s the same issue. We are doing panning-zooming on the canvas so probably can be an issue but below code which I forked from cacheAsBitmap function in the webglRenderer seems to do the trick…

I have been diagnosing the issue and found the culprit to be cacheAsBitmap functionality.

I thought cacheAsBitmap would be same for Webgl and canvas and pretty much would work in similar fashion. Also looking at the main function, , it says ‘// TODO this can be the same as the webGL verison… will need to do a little tweaking first though…’. Looks like author realizes that and therefore has added it to the todo list.

Since I needed this fix quickly for what I am doing, I decided to copy Webgl code for similar function and use that after making few necessary changes.

Is it possible to merge that for your next release and even better, look at the code changes I did.

Added

/**
     * Changes the current renderer to the one given in parameter
     *
     * @param {PIXI.ObjectRenderer} objectRenderer - The object renderer to use.
     */


    CanvasRenderer.prototype.setObjectRenderer = function setObjectRenderer(objectRenderer) {
        if (this.currentRenderer === objectRenderer) {
            return;
        }

        this.currentRenderer.stop();
        this.currentRenderer = objectRenderer;
        this.currentRenderer.start();
    };

    /**
     * This should be called if you wish to do some custom rendering
     * It will basically render anything that may be batched up such as sprites
     *
     */


    CanvasRenderer.prototype.flush = function flush() {
        this.setObjectRenderer(this.emptyRenderer);
    };

and then modified function _initCachedDisplayObjectCanvas as below

DisplayObject.prototype._initCachedDisplayObjectCanvas = function _initCachedDisplayObjectCanvas(renderer) {
    if (this._cacheData && this._cacheData.sprite) {
        return;
    }

    var cacheAlpha = this.alpha;

    this.alpha = 1;

    // first we flush anything left in the renderer (otherwise it would get rendered to the cached texture)
    renderer.plugins.sprite.renderer.flush();
    // this.filters= [];

    // get bounds actually transforms the object for us already!
    var bounds = this.getLocalBounds();

    // next we find the dimensions of the untransformed object
    // this function also calls updatetransform on all its children as part of the measuring.
    // This means we don't need to update the transform again in this function
    // TODO pass an object to clone too? saves having to create a new one each time!
    var bounds = this.getLocalBounds().clone();

    // add some padding!
    if (this._filters) {
        var padding = this._filters[0].padding;

        bounds.pad(padding);
    }

    // for now we cache the current renderTarget that the webGL renderer is currently using.
    // this could be more elegent..
    var cachedRenderTarget = renderer.context;
    // We also store the filter stack - I will definitely look to change how this works a little later down the line.
    // var stack = renderer.filterManager.filterStack;

    // this renderTexture will be used to store the cached DisplayObject

    var renderTexture = core.RenderTexture.create(bounds.width | 0, bounds.height | 0);

    var textureCacheId = 'cacheAsBitmap_' + (0, _utils.uid)();

    this._cacheData.textureCacheId = textureCacheId;

    _BaseTexture2.default.addToCache(renderTexture.baseTexture, textureCacheId);
    _Texture2.default.addToCache(renderTexture, textureCacheId);

    // need to set //
    var m = _tempMatrix;

    m.tx = -bounds.x;
    m.ty = -bounds.y;

    // m.tx -= bounds.x;
    // m.ty -= bounds.y;

    // m.append(this.transform.worldTransform.)
    // set all properties to there original so we can render to a texture
    this.renderCanvas = this._cacheData.originalRenderCanvas;

    renderer.render(this, renderTexture, true, m, true);
    // now restore the state be setting the new properties
    renderer.context = cachedRenderTarget;

    this.renderCanvas = this._renderCachedCanvas;
    this._calculateBounds = this._calculateCachedBounds;

    this._mask = null;
    this.filterArea = null;

    // create our cached sprite
    var cachedSprite = new core.Sprite(renderTexture);

    cachedSprite.transform.worldTransform = this.transform.worldTransform;
    cachedSprite.anchor.x = -(bounds.x / bounds.width);
    cachedSprite.anchor.y = -(bounds.y / bounds.height);
    cachedSprite._bounds = this._bounds;
    cachedSprite.alpha = cacheAlpha;

    // easy bounds..
    this._calculateBounds = this._calculateCachedBounds;
    this.getLocalBounds = this._getCachedLocalBounds;

    this._cacheData.sprite = cachedSprite;

    this.transform._parentID = -1;
    // restore the transform of the cached sprite to avoid the nasty flicker..
    if (!this.parent) {
        this.parent = renderer._tempDisplayObjectParent;
        this.updateTransform();
        this.parent = null;
    } else {
        this.updateTransform();
    }

    this.updateTransform = this.displayObjectUpdateTransform;

    this.containsPoint = cachedSprite.containsPoint.bind(cachedSprite);
};

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:1
  • Comments:8 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
SaleRisecommented, Jan 23, 2018

Hi @bigtimebuddy, Where it is causing the issues is file with thousands of line of codes. I will soon have something simpler prepared for you.

Thanks

0reactions
lock[bot]commented, Apr 15, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Read more comments on GitHub >

github_iconTop Results From Across the Web

cacheAsBitmap causing issues in Canvas mode #4626 - GitHub
I have been diagnosing the issue and found the culprit to be cacheAsBitmap functionality. I thought cacheAsBitmap would be same for Webgl and ......
Read more >
pixijs/pixi.js - Gitter
cacheAsBitmap - Causes the bounds of my elements to be incorrect, removes interaction support from the stage. Still need to experiment more with...
Read more >
PIXI.Container - PixiJS API Documentation
Renders the object using the Canvas renderer ... In fact, recalculating inside a render() call may cause corruption in certain cases.
Read more >
Textures - PixiJS
Doing this for a large number of source images can be slow and cause lag spikes ... to let you use canvas's drawing...
Read more >
openfl (6.2.2) - Haxelib
setStencilActions on OpenGL; Fixed minor build issues when using Haxe 4 prerelease ... Fixed rendering issue on Chrome when resizing canvas in -Ddom...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found