Closed Bug 1764257 Opened 3 years ago Closed 1 year ago

texImage2D leaks memory with RGBA format from getUserMedia source

Categories

(Core :: Graphics: CanvasWebGL, defect)

Firefox 99
defect

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: spam+bugzilla, Unassigned)

Details

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/99.0

Steps to reproduce:

When using WebGL 2 context, calling the texImage2D method a <video> element with video coming from getUserMedia and with RGBA format seems to leak memory in main Firefox process and in the renderer process in around equal amounts. Using RGB format doesn't seem to have the same problem, albeit is slower.

Tested on Firefox 99.0 and 100.0b (Dev Ed) on macOS and Firefox 99.0 Linux (flatpak).

Demo: https://codepen.io/brainshave/pen/BaJPYqg

Steps to reproduce:

  • acquire MediaSource with navigator.mediaDevices.getUserMedia
  • set the media source as srcObject on a video element
  • create a WebGL 2 context on a canvas element
  • create a texture in the WebGL 2 context
  • call:
gl.texImage2D(
  gl.TEXTURE_2D,
  0,
  gl.RGBA,
  gl.RGBA,
  gl.UNSIGNED_BYTE,
  videoElement
);

Actual results:

Firefox's main process and the renderer process for the particular tab where this is happening accumulate around the same amount of extra RAM every time texImage2D is called. This lead to my computer running out of memory and freezing (on Linux) when I had a call with background replacement feature on https://engoo.com/app/meeting (we since pushed a work-around to use RGB format, we understand that comes with a likely performance hit though)

The demo https://codepen.io/brainshave/pen/BaJPYqg calls texImage2D 1000 times each time the first "textImage2d... RGBA" button is pressed.

After first 1000 calls, a diff from about:memory for main Firefox process shows:

   53,117 ── page-faults-soft
442.95 MB ── resident
  0.39 MB ── resident-unique
 -0.04 MB ── shmem-allocated
441.40 MB ── shmem-mapped
452.07 MB ── vsize

and after another 1000:

  101,135 ── page-faults-soft
884.78 MB ── resident
  0.70 MB ── resident-unique
 -0.04 MB ── shmem-allocated
878.56 MB ── shmem-mapped
878.98 MB ── vsize

So it looks like it grows linearly.

Similarly, the renderer process for codepen.io after 1000 calls shows:

  0.38 MB ── heap-allocated
  113,012 ── page-faults-hard
      748 ── page-faults-soft
443.24 MB ── resident
  0.24 MB ── resident-unique
441.45 MB ── shmem-allocated
441.45 MB ── shmem-mapped
441.45 MB ── vsize

And after another 1000:

  0.67 MB ── heap-allocated
  226,024 ── page-faults-hard
    1,797 ── page-faults-soft
884.81 MB ── resident
299.52 MB ── resident-peak
  0.54 MB ── resident-unique
882.81 MB ── shmem-allocated
882.81 MB ── shmem-mapped
884.81 MB ── vsize

So again, it looks like all measurements grow linearly.

(Side note/guess: Since big chunk of that looks like shared memory, perhaps the total amount of system RAM consumed isn't the sum of numbers between main process and the renderer)

These are the only numbers that seemed significantly different. Might be due to https://bugzilla.mozilla.org/show_bug.cgi?id=1350292 but there was nothing really WebGL 2 specific showing. I can upload full reports if it helps but will have to probably redo them to only include the data from the demo.

Refreshing the page seems to not have any consequences, RAM is still taken. But closing the tab with the demo will release the system memory it seems.

Expected results:

After creating the texture memory usage should remain about constant.

Repeating the same steps with gl.RGB instead of gl.RGBA doesn't seem to have this symptom. The demo includes a button for that (the last one) that doesn't seem to cause the issue.

The Bugbug bot thinks this bug should belong to the 'Core::Performance' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → Performance
Product: Firefox → Core
Component: Performance → Canvas: WebGL

We have also tried using DMD in scan mode on FF Nightly to locate the leak.
It revealed an interesting location that seems to grow after using the RGBA upload button and remains the same when using RGB.

Here's an excerpt, comparing initial page state vs after 6 leaking invocations:

Live {
  6,000 blocks in heap block record 2 of 2,012
  384,000 bytes (336,000 requested / 48,000 slop)
  Individual block sizes: 64 x 6,000
  21.24% of the heap (47.52% cumulative)
  Allocated at {
    #01: replace_malloc(unsigned long)[/Applications/Firefox Nightly.app/Contents/MacOS/libmozglue.dylib +0x86ad4]
    #02: moz_xmalloc[/Applications/Firefox Nightly.app/Contents/MacOS/libmozglue.dylib +0x4da10]
    #03: mozilla::ipc::Shmem::Alloc(mozilla::ipc::Shmem::PrivateIPDLCaller, unsigned long, mozilla::ipc::SharedMemory::SharedMemoryType, bool, bool)[/Applications/Firefox Nightly.app/Contents/MacOS/XUL +0x6a70f8]
    #04: mozilla::ipc::IToplevelProtocol::CreateSharedMemory(unsigned long, mozilla::ipc::SharedMemory::SharedMemoryType, bool, int*)[/Applications/Firefox Nightly.app/Contents/MacOS/XUL +0x69e47c]
    #05: mozilla::ipc::IProtocol::AllocShmem(unsigned long, mozilla::ipc::SharedMemory::SharedMemoryType, mozilla::ipc::Shmem*)[/Applications/Firefox Nightly.app/Contents/MacOS/XUL +0x33666d0]
    #06: mozilla::ClientWebGLContext::TexImage(unsigned char, unsigned int, int, unsigned int, mozilla::avec3<int> const&, mozilla::Maybe<mozilla::avec3<int> > const&, int, mozilla::webgl::PackingInfo const&, mozilla::TexImageSource const&) const[/Applications/Firefox Nightly.app/Contents/MacOS/XUL +0xd223c8]
    #07: void mozilla::ClientWebGLContext::TexImage2D<mozilla::dom::HTMLVideoElement>(unsigned int, int, unsigned int, unsigned int, unsigned int, mozilla::dom::HTMLVideoElement const&, mozilla::ErrorResult&) const[/Applications/Firefox Nightly.app/Contents/MacOS/XUL +0x3c1986c]
    #08: mozilla::dom::WebGL2RenderingContext_Binding::texImage2D(JSContext*, JS::Handle<JSObject*>, void*, JSJitMethodCallArgs const&)[/Applications/Firefox Nightly.app/Contents/MacOS/XUL +0x3c18e5c]
  }
}

Looks like this is pointing to somewhere around https://searchfox.org/mozilla-central/source/dom/canvas/ClientWebGLContext.cpp#4271 ?

First time using DMD, so not sure if I've done this correctly, but hopefully this helps.

The severity field is not set for this bug.
:jgilbert, could you have a look please?

For more information, please visit auto_nag documentation.

Flags: needinfo?(jgilbert)

I guess it still exsited in Firefox 102.0.1.
Any progress about it?

I don't see this on Windows today, at least.
@bradwerth can you try to repro on Mac?

Flags: needinfo?(jgilbert) → needinfo?(bwerth)

(In reply to Kelsey Gilbert [:jgilbert] from comment #5)

I don't see this on Windows today, at least.
@bradwerth can you try to repro on Mac?

I don't think this is replicating on macOS. I'm no expert at interpreting memory report diffs, but the diff in resident amounts stayed small even after clicking the RGBA button about 15 times. And the macOS Activity Monitor did not show any increase in memory usage.

Flags: needinfo?(bwerth)

Ok, thanks!

Setting as WORKSFORME, but happy to reopen this if it's still happening for someone!

Status: UNCONFIRMED → RESOLVED
Closed: 1 year ago
Flags: needinfo?(spam+bugzilla)
Resolution: --- → WORKSFORME

Apologies for late response but I also cannot reproduce this any more on Firefox 128 on macOS 14.6

Thank you for looking into it!

Flags: needinfo?(spam+bugzilla)
You need to log in before you can comment on or make changes to this bug.