Weird Cesium rendering exception

I created a custom gridPrimitive that uses cesium polylines to draw a grid with dynamic level of detail.
All works fine, except in one case, our web app has multiple tabs, and if the gridprimitive is rendered on a non-visible/non-selected tab at the startup, I’m getting the following exception:

An error occurred while rendering. Rendering has stopped.
undefined
RangeError: Invalid array length
RangeError: Invalid array length
at updateFrustums (http://localhost:8080/GeoC2/libs/cesium/Cesium.js:139928:36)
at createPotentiallyVisibleSet (http://localhost:8080/GeoC2/libs/cesium/Cesium.js:140079:13)
at render (http://localhost:8080/GeoC2/libs/cesium/Cesium.js:140493:9)
at Scene.render (http://localhost:8080/GeoC2/libs/cesium/Cesium.js:140533:13)
at CesiumWidget.render (http://localhost:8080/GeoC2/libs/cesium/Cesium.js:149935:25)
at Viewer.render (http://localhost:8080/GeoC2/libs/cesium/Cesium.js:155035:28)
at animLoop (http://localhost:8080/GeoC2/app/ui/globe/CesiumGlobe.js?_dc=1433343126082:806:35)

Note as you can see in the callstack, the exception occurs later in Cesium, not in my code.
However adding the following condition to check for the current number of frames rendered to the GridPrimitive update() method makes the problem go away, though I’m not really satisfied with it.

GridPrimitive.prototype.update = function(context, frameState, commandList) {
    if (!this.show) {
        return;
    }

    if (frameState.frameNumber<30) { // This hack fixes the problem, no more exceptions, and the grid displays fine after 30 frames of being invisible
        return;
    }

// more code…
}

``

I guess something in Cesium is not yet ready in the initial frames and thus we get the exception?
The number 30 was just the smallest I tried that worked, for example 10 frames is not enough and I still get the exception.

Ok, after a bit more of investigating I found out that hack actually does not work at all.

In reality, if the tab with the Cesium canvas is not visible when the grid primitive update method is called, the exception always happens.
Now, my question, why is the update() method being called if the Canvas is not visible?
Since only my custom primitive causes the exception, I guess I’m doing something wrong, do I have to check manually if the Canvas is visible or something?

If you’re using the Viewer or CesiumWidget, they don’t call render if the canvas is hidden or size 0x0, does your primitive rely on the size of the canvas at all? It’s practically impossible to debug this type of problem without the code.

Actually yes, it does rely on the size of the canvas, that already gives something to look at, I’ll check whats the canvas size during the exception.

I checked again, it does not use the canvas size, it did in a early version though. The actual code just uses the camera position and frameState.cullingVolume.computeVisibility() to dynamically subdivide the grid.

Does this information give you any idea?

You may not be using the canvas size implicitly, but you could be calling something that does. If you check the widget/height of the canvas and do nothing if there is a 0 somewhere, does that fix the problem?

Are you using a custom render loop?

Yes, there is a custom render loop using Cesium.requestAnimationFrame()

Could that be behind the cause of the problem?

I would bet that’s the problem, there’s lots of little things that need to be taken into account when writing one. I strongly recommend against implementing a custom render loop unless you have a really good reason to do so.