Pixi.js: When resize canvas , there is a white background flickering

Created on 3 Dec 2016  ·  7Comments  ·  Source: pixijs/pixi.js

I resize canvas with a simple standalone function , like this :

function resizeCanvas(width, height) {
    game.canvas.width = width;
    game.canvas.height = height;
    game.canvas.style.width = width / game.resolution + 'px';
    game.canvas.style.height = height / game.resolution + 'px';
}

And when game bootup , I do something like this :

game.renderer = new PIXI.WebGLRenderer(
    game.canvas.width,
    game.canvas.height,
    {
         view: game.canvas,
         backgroundColor: 0x000000,
     }
);

// recompute viewport size & canvas size with  browser window size 
game.scaler.update();  

// resize  renderer with new size.
game.renderer.resize(game.viewportWidth, game.viewportHeight);

the test case is very simple : draw a small png image.

Browser: Chrome 55 for macOS 10.12

Safari is OK.

I know maybe this is a issues of Chrome , but I hop there is a hack way for fix it.

Thanks

💾 v4.x (Legacy)

Most helpful comment

Aw, thanks! @mickdekkers that's awesome, calling render immediately makes it work with the ResizeObserver callbacks.

All 7 comments

I use the code like this for fixing this bug :

    game.renderer.resize(game.viewportWidth - 1, game.viewportHeight);
    setTimeout(function() {
        game.renderer.resize(game.viewportWidth, game.viewportHeight);
    }, 1);

It's so ugly , Who could give me a better suggestion ?

Certainly ,The best way is report it to Chrome team.
Who could do it ? My english is too weak to describe this bug。

new Chrome no this issue.

I'd like to confirm that this still happens on desktop Safari (latest) and Edge. Pixi v4.3.0.

Edit: in pseudocode, we were doing something like

handleWindowDimensionChange(function() {
renderer.resize(window.innerWidth, window.innerHeight)
});

Resizing the window causes ugly flickering in both the mentioned browsers. Not chrome or Firefox.

Does anyone have an idea what can potentially cause the flicker on resize? I have the same problem in Electron (tested with different versions, but basically, Chromium 56, 58 and 59) and Pixi 4.5.5 (tested on Linux and macOS) but only in a bizarre scenario:

I'm resizing the renderer (webgl) based on a container element in the DOM: the container element can change size if the window is resized or triggered by a resizable widget implemented in Javascript. Now, if I resize the renderer in the window's resize and the widget's custom resize handler (based on mousemove events), all is fine, but if I use the new ResizeObserver API on the container element instead, I get pretty bad flickering.

A couple of observations:

  • The flickering is caused by the entire canvas being cleared (like the OP mentions, in my case it's not white but transparent): this is clearly visible when I do a performance recording with screenshots in the dev-tools: the canvas is blank for about 100ms during resizing.
  • I assumed that this is a performance / timing issue in that ResizeObserver fires more frequently, but that is not the case: I get comparable frequency in both scenarios.
  • What's more, I'm throttling the resize itself, so the frequency of the actual call to renderer.resize is identical in both cases; also the call does not happen in either of the event handlers but is delayed, so it looks unlikely to me that timing is to blame.
  • My next guess was that the values reported by the ResizeObserver are different; it reports the container's content box not the bounding box, but since there is no border or padding involved the values are the same. Furthermore, I'm rounding the dimensions to full pixels in both scenarios. Really, both the dimensions being set and the frequency are very similar in both cases.
  • The flickering stops if I increase the throttle timeout to about 500ms or higher
  • Using the window/widget event handlers I need to measure the container using getBoundingClientRect() -- to save this call (causing a re-paint) is actually a big reason for using ResizeObserver but I figured the lack of the extra-repaint may be causing the flickering for some reason. So I added an unnecessary call to getBoundingClientRect() before the resize, but to no avail.

I'm not too concerned, because there is a viable workaround (using the two separate handlers, instead of ResizeObserver), but I'd really like to know what's causing this. I also turned off autoResize and antialias but that made no difference. Any ideas what else I could try?

@inukshuk in my case the solution turned out to be really simple: just call render after resizing.

app.renderer.resize(width, height)
// Immediately render because resizing clears the canvas
app.render()

This fixed the flickering issue for me. Keep in mind that if you have animations running, it will just display the last frame until your next update loop and this might give a "freezing" effect. If you want to keep it running smoothly, you'll want to call your update function before calling render.

Aw, thanks! @mickdekkers that's awesome, calling render immediately makes it work with the ResizeObserver callbacks.

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.

Was this page helpful?
0 / 5 - 0 ratings