0

Using rgl in knitr, users can write documents that contain multiple WebGL scenes in separate displays. Each of those is created by creating a canvas, getting a WebGL context associated with it, and then doing a bunch of WebGL plotting.

Users can ask for an arbitrary number of displays in a single HTML page, and eventually they'll run out of contexts, and (in Firefox) the console will show

Exceeded 16 live WebGL contexts for this principal

and I'll get the WebGLcontextlost event. When you scroll the page, all the early displays are blank, only the later ones show up.

How do I ask to restore the ones that are currently showing in the window?

Edited to add: A variant on this question: how do I set a canvas to only attempt to draw itself when it has scrolled into view? In the typical case, only one or two contexts will be visible at a time, so it should be fine to draw both of them. But the code needs to be told when that happens.

user2554330
  • 37,248
  • 4
  • 43
  • 90
  • Some other possible solutions. [Use one canvas and just render viewports](http://stackoverflow.com/questions/30541121/multiple-webgl-models-on-the-same-page). [Using 1 WebGL canvas and multiple non-webgl canvases](http://stackoverflow.com/questions/15824840/display-different-scenes-sharing-resources-on-multiple-canvases). As for only when a context is in view see. As for only rendering when on screen see https://github.com/greggman/requestanimationframe-fix.js – gman Jul 13 '16 at 18:37

1 Answers1

0

I don't know how to trigger the WebGLcontextrestored event, but I can answer the variant on my question:

This web page: http://developer.telerik.com/featured/lazy-loading-images-on-the-web/ describes how to do "lazy loading" of images, i.e. only loading them when they are about to be displayed. The same sort of approach works for lazy loading of WebGL scenes, with the following differences:

  • Since the context may be lost at any time, you don't want to remove the listeners once you've loaded it once.

  • You do want the WebGLcontextlost event to record the fact that the canvas needs to be re-initialized with a new context.

  • You need to draw the scene after re-initializing it.

  • (Optional): I like the illusion that the scene was always there, so my isInBrowserViewport test checks for any part of the scene being visible, rather than the whole scene visible.

Edited to add: The approach above isn't sufficient on Firefox. On that browswer, once you get a WebGL context for a canvas, it appears that it stays there forever. If its context is lost because you have allocated too many others, it never comes back. The only way I've found to allow that canvas to be used again is to delete it and recreate it, then allocate a new context in it. I haven't done as much experimentation in Chrome, but it appears to suffer the same limitation.

user2554330
  • 37,248
  • 4
  • 43
  • 90