Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Array length invalid due to hidden canvas #2662

Closed
emackey opened this issue Apr 24, 2015 · 3 comments · Fixed by #2668
Closed

Array length invalid due to hidden canvas #2662

emackey opened this issue Apr 24, 2015 · 3 comments · Fixed by #2668

Comments

@emackey
Copy link
Contributor

emackey commented Apr 24, 2015

Here's a familiar old error, with a brand new root cause.

An error occurred while rendering. Rendering has stopped.
RangeError: Invalid array length
RangeError: Invalid array length
    at Q (http://cesiumjs.org/Cesium/Build/Apps/CesiumViewer/CesiumViewerStartup.js:459:10263)
    at et (http://cesiumjs.org/Cesium/Build/Apps/CesiumViewer/CesiumViewerStartup.js:459:12101)
    at ht (http://cesiumjs.org/Cesium/Build/Apps/CesiumViewer/CesiumViewerStartup.js:459:17072)
    at vt.render (http://cesiumjs.org/Cesium/Build/Apps/CesiumViewer/CesiumViewerStartup.js:459:22867)
    at P.render (http://cesiumjs.org/Cesium/Build/Apps/CesiumViewer/CesiumViewerStartup.js:460:30833)
    at t (http://cesiumjs.org/Cesium/Build/Apps/CesiumViewer/CesiumViewerStartup.js:460:13504)

Steps to reproduce the new way:

  1. Launch Cesium Viewer
  2. Open DevTools.
  3. Find & select the DOM element with id="cesiumContainer".
  4. Put a temporary element-specific style rule: width: 0. The globe will disappear, that's OK.
  5. Un-check your new temporary rule, and the globe reappears.
  6. This next step requires some dexterity. Spin the globe, applying mouse inertia to it, and then re-check your temporary rule while the globe is spinning. The globe disappears again.
  7. Take a breath, then un-check your temporary rule, revealing... the error.

What's happening? When the width is zero, CesiumWidget sets a flag called _canRender to false. With this flag set, Scene.initializeFrame continues to fire at full speed, but Scene.render is never called. If mouse inertia is running, it will run off the rails here. Camera.positionWC becomes equal to { x: NaN, y: NaN, z: NaN } during this time. When _canRender becomes true again, the render loop chokes on the invalid camera position.

This was found by Anne and Sunny, who are using a Bootstrap tab to hide and reveal a Cesium Viewer. If you tab away (via Bootstrap tab, not browser tab) while the globe is spinning, when you tab back there will be an exception.

@emackey
Copy link
Contributor Author

emackey commented Apr 24, 2015

Take a look at CesiumWidget.js#L647-L651, where initializeFrame continues to be called while render is skipped. Should we just skip both when _canRender is false?

@mramato
Copy link
Contributor

mramato commented Apr 28, 2015

Should we just skip both when _canRender is false?

In the short term, this is probably the best option. Longer term, may need better checks inside functions that require a non-zero canvas to work. Because fixing the default render loop does nothing if a user calls into some camera function while the canvas is hidden. Adding checks all over the place may affect performance, so more research would be needed. Since it's such an edge case, I'm not sure it's worth worrying about anytime soon.

A workaround to this bug until 1.9 is out is to disable the render loop before hiding and renable it on show.

mramato added a commit that referenced this issue Apr 28, 2015
Having the default render loop call `scene.initializeFrame` when the canvas
height or width is 0 causes issues in camera code which expects these
values to be non-zero.  As far as I can tell, similar to `render`, there's
no reason we should be calling `initializeFrame` in this case anyway.

Fixes #2662 (some additional discussion there as well)
@emackey
Copy link
Contributor Author

emackey commented Apr 28, 2015

I'm not too concerned for users who manually call render on a zero-size canvas. PR looks good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants