theia-trace-extension icon indicating copy to clipboard operation
theia-trace-extension copied to clipboard

timegraph views lose some content if many are opened

Open marcdumais-work opened this issue 5 months ago • 1 comments

Bug Description:

It might be more precise to talk about PIXI-created canvas objects getting lost - not all of them are timegraph views.

When opening a few traces that have a couple of timegraph views, or several traces with some views opened, one will notice the following warning in the devtools console:

time-graph-container.ts:39 WARNING: Too many active WebGL contexts. Oldest context will be lost.

Some BG info I quickly gathered:

  • WebGL contexts are managed by the browser and are limited to a certain number (per browser tab?) (max 16 for Chrome?). There seems to be no generic way to increase that number, across various browsers. However, there's a way (that I have not tested) to do so in Chromium-based browser (and Electron) using a CLI argument "--max-active-webgl-contexts=n". However, doing so brings risks (instability, crashes, ...) that may in big part depend on the specific GPU HW and driver:
    • https://groups.google.com/a/chromium.org/g/graphics-dev/c/fmNedEEAYpA/m/3KOxDY4IAAAJ
    • https://issues.chromium.org/issues/40543269#comment2
  • There seems to be no API to determine how many WebGL contexts are used and how many may be available.
    • https://stackoverflow.com/questions/61277222/how-to-determine-number-of-active-webgl-contexts

The affected code is from timeline-chart, file time-graph-container.ts::

export class TimeGraphContainer {
[...]
   constructor(protected config: TimeGraphContainerOptions, [...]
      let canvas: HTMLCanvasElement
      if (!extCanvas) {
          canvas = document.createElement('canvas');
      [...]
      const noWebgl2 = !PIXI.utils.isWebGLSupported() || !canvas.getContext('webgl2');
      [...]

There, timeline-chart, is creating a PIXI canvas, using if available a webgl2 context from the browser. So long WebGL is supported and the browser is able to provide such a context, it's good - it should make canvas operations faster by using hardware acceleration.

Such a canvas seems to be created when:

  • a timeline view is opened for a given trace. This triggers 2 canvas being created: one focusContainer and one for the timeline char itself
  • when a trace is opened and any graphical view is opened other than the default "Overview". This allocates 2 PIXI canvas (when creating elements timegraph-axis and time-navigator). These are garbage-collected if all views other than "Overview" are closed for that trace.

But there seems to be a couple of problems with this, in situations where WebGL is supported:

  • canvas.getContext('webgl2') always succeeds (at least on Chrome/Electron?):
    • if the browser has run out of WebGL contexts (as per its limit), it will "free" an "old" so it can allocate the new requested one. The code above then does not work as intended, apparently expecting that the call to canvas.getContext('webgl2') would return e.g. an undefined value when no WebGL context is available, permitting it to fallback to an un-accelerated canvas. Instead, a WebGL context, previously allocated to another trace viewer canvas, was freed under-the-table by the browser, resulting in a DOM element that can't be found (a couple of them in this screenshot): Image

This stackoverflow contains some suggestions that may be interesting to investigate (not sure if they would be practical in our case): https://stackoverflow.com/questions/59140439/allowing-more-webgl-contexts

Another way might be to count the number of canvas we allocate (and decrement when they get de-allocated) and after a past a certain number, we do not request a WebGL context for a new canvas.

Some related material here, though not exactly the suggestion above: https://stackoverflow.com/questions/61277222/how-to-determine-number-of-active-webgl-contexts

Steps to Reproduce:

  1. Open a trace, then open a couple of views related to timeline (resources status, IRQ Analisis - scenarios, ...)
  2. Open the devtools and watch for a warning in the console: "WARNING: Too many active WebGL contexts. Oldest context will be lost."
  3. Repeat 1,2 until you see the warning
  4. Once the warning is displayed, go back to the first opened trace and confirm that one or more of its canvas is not an empty element (white with sad face icon in upper left corner)

Additional Information

  • Operating System:
  • Theia Version:

marcdumais-work avatar Jun 09 '25 14:06 marcdumais-work