Closed Bug 820217 Opened 12 years ago Closed 5 years ago

SpaceBlaster app crashes

Categories

(Core :: Graphics: CanvasWebGL, defect)

ARM
Gonk (Firefox OS)
defect
Not set
critical

Tracking

()

RESOLVED WONTFIX

People

(Reporter: eviljeff, Assigned: bjacob)

References

(Depends on 1 open bug, Blocks 1 open bug, )

Details

(Keywords: crash, reproducible, Whiteboard: [games:p?])

Attachments

(3 files)

SpaceBlaster app crashes after pressing the Start graphic on the loading screen.  App loads (but doesn't work particularly well) on Android.

manifest:
http://www.scirra.com/labs/sbopenwebapp/manifest.webapp

direct url to app content
http://www.scirra.com/labs/sbopenwebapp/
Confirmed. Consistently reproducible as well.
Severity: normal → critical
Keywords: crash, reproducible
blocking-basecamp: --- → ?
App developer here: we make Construct 2, a HTML5 game editor (www.scirra.com).  I submitted this as a test to see how our game engine holds up on Firefox Marketplace.

I was disappointed to see the app rejected on Android due to poor performance; this is Firefox's fault.  We use WebGL for rendering wherever available, and I believe Firefox has very poor WebGL performance on Android.  It would be nice if this was fixed soon, since no games made with Construct 2 will run fast enough to be accepted otherwise.

As for the crash, we've seen lots of other implementations crash at the same point due to WebGL bugs or graphics driver issues.
Component: General → Canvas: WebGL
Product: Boot2Gecko → Core
Version: unspecified → Trunk
Joe and Benoit - Any thoughts on what's going on here? Why is this WebGL game failing on the phone? Why is the perf on the Android equivalent running into issues?
WebGL perf is likely worse than other browsers due to bug 716859, which we're very actively working on.

Can you show us a crash stack or crash report?
Yep, our WebGL perf is gated by that bug currently on Android; it should provide a significant speed improvement.  (Which other browsers support WebGL on Android?)

I can't reproduce a crash with Firefox 17 on a HTC One X (though I did run into bug 745174 after closing the app -- seems unrelated to webgl though).
(In reply to Vladimir Vukicevic [:vlad] [:vladv] from comment #5)
> I can't reproduce a crash with Firefox 17 on a HTC One X

the crash is just on FirefoxOS
David kindly offered to get a stack.
Flags: needinfo?(dclarke)
QA Contact: dclarke
Attached file Logcat output (deleted) —
This is the logcat output, looks like we are running out of memory. 

I know we have an issue where we don't clean up memory when images leave the view, same for webGL ? 

could this make it so that graphically intensive games are generally doomed ?
Flags: needinfo?(dclarke)
Is this game rendering at device resolution or oversampling?
Chris i am unsure if we are oversampling, how would one detect this, and what is the optimal value.
The game should be rendering to a canvas that's sized to window bounds, and the assets used by the game should be sized (or upsampled/downsampled) appropriate for that resolution.
The game is resolution independent.  It's designed for 720x960 but creates the canvas at a size that proportionally fills the window (black bars will appear at the side if the aspect ratio is different).  Then it scales the canvas so the sprites scale accordingly.  The game renders with WebGL if available, but falls back to canvas 2D if WebGL is not available.

I estimate all the images used by the game, when decompressed, should take about 45mb of memory.  I think if a device runs out of memory with this game it probably has underpowered hardware and is unlikely to be able to run many games at all.  This game only has one level!
Benoit is looking at this.
Assignee: nobody → bgirard
Flags: needinfo?(bgirard)
Sorry, mixed up two bugs.  bjacob, can you just double check that we're not leaking memory somewhere or holding on to what we don't need to.  We've sorted out that we start with <90mb free to start, so I can see a 45mb game causing us to run out of memory, but let's confirm.
Assignee: bgirard → bjacob
Flags: needinfo?(bgirard) → needinfo?(bjacob)
I have looked a bit into this.

What I know for sure is:

1. this is an out-of-memory crash: we get a SIGKILL in the browser process, and just before that, the main process receives a low-memory event.

2. the WebGL context is initially being created with size 720x960 and only later is downscaled to size 273x365 (my screen is 320x480). You would get faster load times, and you would stress the drivers' video memory allocator less, if you created the canvas right away with the smaller size. You want to set the right width and height on your canvas element before calling getContext.

3. (THE MAIN ISSUE) This applications is creating *many* *large* *uncompressed* *32 bpp* textures. There is nothing that we can do about that and I have near certainty that this is the only thing to blame for the out-of-memory crash. I'm attaching a log I recorded by running in a debugger, with breakpoints set on key WebGL functions. What I know for sure is:

  a. No compressed textures are used at all. This application does not take advantage of this hardware capability which we consider essential to running any sizeable WebGL content on a phone with limited memory. We support ATC (supported on Adreno GPUs), PVRTC (supported on PowerVR GPUs) and S3TC (supported on Tegra and desktop GPUs). For typicaly B2G hardware, ATC is going to be the most important format (current B2G phones have Adreno GPUs).

  b. No 16 bpp textures used at all. If for some reason you can't use compressed textures, you should at least use 16 bpp textures, allowing you to halve memory usage with generally acceptable quality impact (especially on a phone screen). DITHER may futher help if rendering to FBOs.

  b. By the time we crash, we have created 68 uncompressed WebGL textures, all of which are uncompressed 32 bpp, including 4 textures of size 1024x1024 (4 M each, total 16 M) and 40 textures of size 512x512 (1 M each, total 40 M). That is already 56 M of texture memory usage and I didn't even finish counting all textures --- and I don't know how many more textures would be loaded if it didn't run out-of-memory.

In conclusion, let's continue this conversation once this applications's texture memory usage is optimized.
Flags: needinfo?(bjacob)
(In the current state of this application, I suggest RESOLVED INVALID, but maybe people want to do something more here such as make a note of this issue for developer evangelism).
Are games supposed to run on devices which can't spare 64MB of memory?  I thought devices were past that these days - 1 GB of shared memory in the iPad 4 etc.

I'll look in to texture compression, but the game runs on a wide range of Android and iOS devices as it is.
You're targeting Firefox OS right?

The total amount of RAM in current prototype Firefox OS phones is 256 M. Video memory goes in there.

For the time being, targeting Firefox OS means targeting low-end hardware. We're not competing with the iPad 4.
Also, your games will run faster everywhere with texture compression or generally anything lowering texture sizes (reasons: texture memory bandwidth, texture caches). So it's something that you should do anyway, regardless of the issue of low-memory devices.
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → INVALID
OK, we'll see what we can do, but a brief look makes it look like texture compression isn't straightforward to use.  As an engine developer and not just developing one specific game, it's hard to do things like enable lossy compression everywhere - especially for 2D games where there's no distance to hide artefacts - and it looks like we'll need either a texture compressor written in javascript (which may have patent issues surrounding), or separate compressed-texture assets (which could increase the download size).  One of our options is just to wait for devices to get better.  I'm not sure what the best thing for us to do is, but I do hope we can figure out some way to support early Firefox OS devices.  Please let me know if you have any advice on how to handle this or if there are any good libraries out there we could use.
Compressed textures are essential to a high quality game experience on any device from phone to high-end desktop. Every serious desktop game uses it to achieve high performance. It's been so for a long time; it's not changing. For it to change, you would not only need devices to get more RAM; you would also need them to evolve in such a way that texture memory bandwidth and texture caches are large enough that they don't matter anymore. There is no indication of this happening on any device form factor (mobile or not).

So yes, you should probably try to find a way to offer a texture compression tool at some point in your tool-chain. There are plenty of nontrivial problems to solve there, but the good news is all your competitors have the same problems to solve.

Meanwhile, some easy steps you could take are:
 - use 16 bpp formats instead of 32 bpp. This is a 1-line change (just change the type/format parameters you pass to webgl.texImage2D, and the browser will automatically do the texture format conversion for you; you are paying for a texture conversion anyway as your assets are DOM elements decoded into BGRA format and your are uploading to RGBA, so this won't significantly slow down startup times).
 - use smaller textures when targeting low-end devices. For example, for your Firefox OS port, you can assume low-end device with a low screen resolution like 320x480. Do you need 4 1024x1024 textures + 40 512x512 textures to run a game on a device with a 320x480 screen? probably not.
(In reply to ashley from comment #21)
> especially for 2D games where there's no distance
> to hide artefacts

That's a good point. In my above replies I had 3D games in mind.

I don't know if commercial-grade 2D games use texture compression carefully (maybe avoid using it for certain images; also, certain formats are worse than others), or don't use it. If you can't use it, the other tips in my previous comment could still allow you to divide memory usage by 8x (2x from using a 16bpp format and 4x from halving texture dimensions)
Another thing that games do is that instead of loading all of their textures upfront when launching the game, they continuously load and un-load textures as required. Do you need all of these textures to be loaded simultaneously at the beginning of the game?
(In reply to Milan Sreckovic from comment #14)
> Sorry, mixed up two bugs.  bjacob, can you just double check that we're not
> leaking memory somewhere or holding on to what we don't need to.  We've
> sorted out that we start with <90mb free to start, so I can see a 45mb game
> causing us to run out of memory, but let's confirm.

Not following too closely, but FFOS has improved memory usage to the point where web apps can allocate 115MB (directly, through TypedArray, not counting the gecko memory).

100MB+ is a lot of memory, but it's not enough for everything.  Probably a good cut-off line for an up-front decision about support.
For what it's worth, I wanted to get a about:memory dump from jlebar's tool, but ran into a snag: only the main process gets the low-memory even, and it's the browser process that crashes. To generate that dump at the right time, we'd need to have the main process signal the browser process immediately when it gets the low-memory event. Should file a bug about allowing doing that.
Until we have the about:memory dump we can only make conjectures, but one thing that we know for sure is that this app has about 60 M of textures alone. These textures are uploaded from image elements decoded to BGRA8 so that if they are still all present in memory in decoded form, which is likely, that's another 60 M of image memory usage, so we'd get at 120 M, enough to OOM.

This makes me think that an important memory optimization we should make is immediately discard decoded images that have been uploaded as WebGL textures. The rationale is that 1) an image that's been uploaded as a WebGL texture will typically never be used again in other ways, and 2) WebGL textures are a leading cause of OOMs. Need to file a bug.
|python tools/get_about_memory.py| collects dumps for all processes.
Yes, but the problem is that I don't easily get to know when to run it. What I know is that just before the crash, the main process gets a low-memory pressure event. I can break there, but that doesn't prevent the browser process from continuing and crashing. Whence the idea to have the main process signal other processes when it receives low-memory.
I'll echo bjacob's statements above regarding compressed textures -- even on devices with 1-2GB memory (iPad, Nexus 10, etc.) any game that's going for performance uses compressed textures.  The visual quality loss is usually negligible, and you end up with not only a significant memory usage savings, but memory *bandwidth* savings, which is often much more important.  It makes the entire pipeline, from upload to sampling, more efficient.  Unfortunately, there isn't a good supported-everywhere texture compression format on mobile devices; one is coming soon, but it's not here available in hardware yet.  Most engines end up dealing with multiple compressed versions of assets, and selecting which one to load/download at runtime.

(In reply to Benoit Jacob [:bjacob] from comment #27)
> This makes me think that an important memory optimization we should make is
> immediately discard decoded images that have been uploaded as WebGL
> textures. The rationale is that 1) an image that's been uploaded as a WebGL
> texture will typically never be used again in other ways, and 2) WebGL
> textures are a leading cause of OOMs. Need to file a bug.

This is a good idea -- it's easy enough for us to see if an image has any observers at upload time too (e.g. happens to be used on the page elsewhere, etc).
Thanks for the discussion, very englightening - but as a developer having to deal with this, I have to say it's difficult.  I can't see that the tradeoff of a significantly bigger download size for lower memory use is worth it on desktop - I think the hardware is powerful enough just to deal with it (especially since these are 2D games and not too taxing).  A 4x longer download time could also lose potential players, especially for a 2D web game.  Maybe it's worth it on mobile, but then the connection is likely to be slower, exacerbating the download time problem.  I definitely don't think it's worth it on desktop, but given our engine is also commercial we'd also hesitate to get involved with any encoders that need licensing.

A good open ubiquitous compressed format that can be encoded from Javascript (so we can still serve PNGs and JPEGs) sounds like the best solution.  Anyone got more information on that?  In the mean time we can use 16-bit formats where possible, and allow engine users to opt in to these formats as well.

For the record our engine does unload unnecessary textures, but only level-by-level.  Since there's only one level here, basically everything is loaded.  Streaming during a level can cause annoying jankiness as rendering is held up by texture uploads.  Also the textures are too large for the resolution described here, but it's because it's a direct port from other platforms.  People want to write-once, run-everywhere, and I suppose that means you'll have cases like this one when developers have not specifically optimised for low-res devices (especially when Android and iOS have a lot of mindshare).
As you point out, using a raw compressed texture format as transmission format is not great, because of the lower compression ration compared to JPEG/PNG.

So yes, a common solution is certainly to keep tranmitting your images as JPEG/PNG and compress them on the client; another solution I've heard of are to use a compression algorithm specialized for the compressed texture format at hand; and finally you could see how far along you can get by just applying a generic compression algorithm (gzip...) to your raw compressed texture format.

I don't know specifics (not a game dev myself, just chatting with game devs) but these things exist in nature, maybe googling will find them.

> A good open ubiquitous compressed format

As Vlad said, such a format won't exist for some time yet. In a few years from now, ETC2 will hopefully be this format.

> For the record our engine does unload unnecessary textures, but only
> level-by-level.  Since there's only one level here, basically everything is
> loaded.  Streaming during a level can cause annoying jankiness as rendering
> is held up by texture uploads.

We hear you on this. Async texture uploads have been under discussion in the WG for a while. Until they happen, you could try distributing your texture uploads so you do, say, at most one during each frame. If each texture upload doesn't take more than, say, 1 millisecond, you could still have a smooth framerate.

>  Also the textures are too large for the
> resolution described here, but it's because it's a direct port from other
> platforms.  People want to write-once, run-everywhere, and I suppose that
> means you'll have cases like this one when developers have not specifically
> optimised for low-res devices (especially when Android and iOS have a lot of
> mindshare).

Right. So, some games just won't run on a Firefox OS phone with 256 M RAM. That's why I marked this bug is INVALID --- it's not a bug, it's a reality. That said, there are some fairly simple things that you could do that might allow your game to run there, as described above. Having half-size, 16bpp versions of your textures around wouldn't be very costly for you (files would be much smaller than the original image files) and your could then easily detecting the client's screen resolution, and if it's smaller than, say, 700 in the largest dimension, decide to serve the low-res images; that would cost you little and allow you to serve 8x smaller textures to low-spec devices.

If you question the importance of low-spec devices on the market, consider why Mozilla based its whole Firefox OS strategy on them ;-) We think that a billion people in developing countries will come online over the next few years and that many of them will use low-spec devices. The Firefox OS prototype phones (256 M, 320x480 screen) reflect what we think is going to be very relevant hardware there.
Wooooah so here's some new data. I just ran the game on my desktop, and went to about:memory.

        269 ── webgl-texture-count
  283.08 MB ── webgl-texture-memory

That's right. So the above mentioned 60 M texture memory usage figure was just what we got at the time of the crash; the application is really trying to allocate 283 M of texture memory.

That confirms the INVALID status of this bug: no trick we can possibly do will allow to run this application as-is on target Firefox OS hardware.

But, if the application is modified to use 16bpp half-size textures, dividing mem usage by 8x, that would become 35 M of memory usage, so we could hope to run it.
Filed bug 822011 about discarding decoded image data after uploading to WebGL textures.
The total pixel area of all the images used by the app is about 11.4 megapixels, almost all of which are power-of-two size, which assuming 4 bytes per pixel should be around 45MB... perhaps we should also turn off mipmap generation on mobile too?  I suppose if that pushes the texture size up to the next square power-of-two size that could be 4x as much memory.

If Firefox OS doesn't crash and reports an error of OUT_OF_MEMORY, perhaps we could then try freeing everything and re-uploading all textures with a lossy smaller format or automatically stretch the images down... maybe that could get us best of both worlds?  Then as Firefox OS devices get more powerful it will start using better quality textures if they can fit in memory.
(In reply to ashley from comment #35)
> The total pixel area of all the images used by the app is about 11.4
> megapixels, almost all of which are power-of-two size, which assuming 4
> bytes per pixel should be around 45MB... perhaps we should also turn off
> mipmap generation on mobile too?  I suppose if that pushes the texture size
> up to the next square power-of-two size that could be 4x as much memory.

Mipmap generation only results in a +33% increase in texture memory usage

 (because 1.33 == 4/3 == 1 + 2^-2 + 2^-4 + 2^-6 + 2^-8 + ...)

Mipmapped texturing would also fail (and you would get WebGL warnings) if applied to non-power-of-two textures.

At least when run on a desktop the data in comment 33 clearly shows that texture memory usage is 280 M, unless we have a bug in our accounting, but that is not very likely. The 45 M figure can't be true anyway as on B2G I measured stricly > 56 M before the crash occured. Also, yes, I confirm that the textures use 4 bytes per pixel (you are passing format=RGBA and type=UNSIGNED_BYTE to texImage2D).

> 
> If Firefox OS doesn't crash and reports an error of OUT_OF_MEMORY,

Unfortunately, with the present testcase, the content process gets killed without any texImage2D call generating OUT_OF_MEMORY. I suppose that it gets killed as something else is also trying to allocate memory at the wrong time.

> perhaps
> we could then try freeing everything and re-uploading all textures with a
> lossy smaller format or automatically stretch the images down...

Trying first to load the high-quality assets, and only if that fails loading low-quality assets, would give a poor user experience (long startup times if nothing else).

Why not just determine which set of assets to load based on the client's screen resolution?

> maybe that
> could get us best of both worlds?  Then as Firefox OS devices get more
> powerful it will start using better quality textures if they can fit in
> memory.

More powerful devices with more memory will also have a higher-res screen, so detecting screen res would still give you that; also, the screen res is actually exactly what determines whether it is useful to use high-res textures; and in practice, in actual devices, screen res is very correlated to the amount of memory and the power of the GPU.
blocking-basecamp: ? → ---
We've updated the original URL (www.scirra.com/labs/sbopenwebapp) to reduce the texture memory used by the app using some of the techniques described here.  Can someone with a real Firefox OS device with limited memory verify if it works or still doesn't have enough memory?
Out of memory again.

If you could make a version that tries to use less memory also when run on a desktop, you could then load it in your desktop browser and go to about:memory and see how much it uses. Currently it still uses 280 M of textures when run on my desktop, but I suppose that that's because it detected a desktop.
That doesn't sound right, Nightly definitely said 51 M for me on that URL.  We used the same URL but also use App Cache so maybe there's some issue with that, double-refreshing might help or ctrl+shift+del and clear offline data.
I just checked on a nightly, and indeed I now get 51.5MB webgl-texture-memory with that latest build.  bjacob, sounds like you're getting some caching somewhere?
That is really weird: in my main Firefox profile, I force-reloaded a few times and am still getting 280M of textures.

But in a different profile, I do get 51M of textures!
Attached file new B2G GDB log (deleted) —
Still crashing on B2G; here is a new GDB log with a breakpoint in TexImage2D_base.

Some analysis:

First, let's see what 'type' argument you are now passing to texImage2D:

$ grep type= b2glog | sed 's/.*\(type=[0-9]\+\).*/\1/g' | sort | uniq -c | sort -rn
     39 type=5121      # UNSIGNED_BYTE
      8 type=32819     # UNSIGNED_SHORT_4_4_4_4
      1 type=32820     # UNSIGNED_SHORT_5_5_5_1

So out of 48 textures, only 9 are using 16bpp formats. 39 are still using 8 bits per channel formats.

Let's break them down:

$ grep type=5121 b2glog -B1 | grep [^l]format | sed 's/.*\([^l]format=[0-9]\+\).*/\1/g' | sort | uniq -c | sort -rn
     33  format=6408   # RGBA
      6  format=6407   # RGB

So out of these 39 8-bit-per-channel textures, 33 are still 32bpp RGBA and 6 are 24bpp RGB.

Breaking down sizes, there are indeed fewer 512x512 textures at the time of the crash (20 instead of 40) but there still are the 4 1024x1024 textures:

$ grep width b2glog | sed 's/.*\([^l]width=[0-9]\+\,\ height=[0-9]\+\).*/\1/g' | sort | uniq -c | sort -rn
     20  width=512, height=512
      8  width=256, height=256
      4  width=1024, height=1024
      2  width=36, height=37
      2  width=207, height=135
      2  width=205, height=22
      2  width=149, height=22
      2  width=128, height=128
      2  width=108, height=12
      1  width=52, height=27
      1  width=52, height=26
      1  width=449, height=231
      1  width=32, height=32
Reopening this bug because the game was fixed to a point where it should run on B2G. (51 M of textures instead of 280M).

We should fix bug 822011 which would considerably help here.
Status: RESOLVED → REOPENED
Resolution: INVALID → ---
So I was lucky enough to manage to get a run where it hit the beginning of the game before crashing (and crashed OOM a few seconds later) which means that we are very close to getting this to run on B2G hardware.

Was also lucky enough to get a good run of ./get_about_memory.py from it:

Browser (pid 2812)

Explicit Allocations
25.73 MB (100.0%) -- explicit
├───8.24 MB (32.02%) -- window-objects/top(http://www.scirra.com/labs/sbopenwebapp/, id=1)/active/window(http://www.scirra.com/labs/sbopenwebapp/)
│   ├──8.06 MB (31.31%) -- js/compartment(http://www.scirra.com/labs/sbopenwebapp/)
│   │  ├──4.28 MB (16.65%) -- type-inference
│   │  │  ├──3.22 MB (12.51%) ── analysis-pool
│   │  │  ├──0.66 MB (02.55%) ── type-pool
│   │  │  ├──0.32 MB (01.23%) ── type-scripts
│   │  │  └──0.09 MB (00.36%) ── allocation-site-tables
│   │  ├──1.97 MB (07.67%) -- gc-heap
│   │  │  ├──1.05 MB (04.10%) -- objects
│   │  │  │  ├──0.47 MB (01.82%) ── ordinary
│   │  │  │  ├──0.33 MB (01.28%) ── dense-array
│   │  │  │  └──0.26 MB (00.99%) ── function
│   │  │  ├──0.36 MB (01.40%) ++ shapes
│   │  │  ├──0.31 MB (01.19%) ── unused-gc-things
│   │  │  └──0.25 MB (00.99%) ++ (5 tiny)
│   │  ├──0.62 MB (02.40%) ── script-data
│   │  ├──0.55 MB (02.12%) -- objects-extra
│   │  │  ├──0.29 MB (01.11%) ── elements
│   │  │  └──0.26 MB (01.01%) ── slots
│   │  ├──0.32 MB (01.23%) ++ shapes-extra
│   │  ├──0.27 MB (01.07%) ── jaeger-data
│   │  └──0.05 MB (00.18%) ++ (3 tiny)
│   └──0.18 MB (00.70%) ++ (4 tiny)
├───5.76 MB (22.37%) -- images
│   ├──5.76 MB (22.37%) -- content
│   │  ├──5.76 MB (22.37%) -- used
│   │  │  ├──4.01 MB (15.60%) ── uncompressed-heap
│   │  │  ├──1.74 MB (06.77%) ── raw
│   │  │  └──0.00 MB (00.00%) ── uncompressed-nonheap
│   │  └──0.00 MB (00.00%) ++ unused
│   └──0.00 MB (00.00%) ++ chrome
├───5.26 MB (20.43%) -- js-non-window
│   ├──2.72 MB (10.58%) -- runtime
│   │  ├──1.91 MB (07.41%) ── jaeger-code
│   │  └──0.81 MB (03.17%) ++ (13 tiny)
│   ├──1.41 MB (05.48%) -- gc-heap
│   │  ├──1.35 MB (05.24%) ── decommitted-arenas
│   │  └──0.06 MB (00.24%) ++ (3 tiny)
│   └──1.12 MB (04.37%) -- compartments
│      ├──0.74 MB (02.86%) -- non-window-global
│      │  ├──0.65 MB (02.52%) -- compartment([System Principal])
│      │  │  ├──0.33 MB (01.28%) ++ gc-heap
│      │  │  └──0.32 MB (01.24%) ++ (6 tiny)
│      │  └──0.09 MB (00.34%) ++ (2 tiny)
│      └──0.39 MB (01.51%) ++ no-global/compartment(atoms)
├───4.03 MB (15.66%) ── heap-unclassified
├───1.18 MB (04.59%) ++ (12 tiny)
├───0.98 MB (03.83%) ── xpti-working-set
└───0.29 MB (01.11%) -- media
    ├──0.29 MB (01.11%) ── decoded-audio
    └──0.00 MB (00.00%) ── decoded-video

Resident Set Size (RSS) Breakdown
71.91 MB (100.0%) ++ rss

Proportional Set Size (PSS) Breakdown
69.98 MB (100.0%) ++ pss

Virtual Size Breakdown
150.05 MB (100.0%) ++ size

Swap Breakdown
0.00 MB (100.0%) ++ swap

Other Measurements
6 (100.0%) -- js-compartments
├──3 (50.00%) ── system
└──3 (50.00%) ── user

13.31 MB (100.0%) -- js-main-runtime
├───9.18 MB (68.96%) -- compartments
│   ├──4.38 MB (32.90%) -- type-inference
│   │  ├──3.31 MB (24.88%) ── analysis-pool
│   │  ├──0.66 MB (04.93%) ── type-pool
│   │  ├──0.32 MB (02.38%) ── type-scripts
│   │  └──0.09 MB (00.70%) ── allocation-site-tables
│   ├──2.59 MB (19.46%) -- gc-heap
│   │  ├──1.14 MB (08.54%) -- objects
│   │  │  ├──0.49 MB (03.71%) ── ordinary
│   │  │  ├──0.33 MB (02.49%) ── dense-array
│   │  │  └──0.31 MB (02.34%) ── function
│   │  ├──0.49 MB (03.71%) ── unused-gc-things
│   │  ├──0.43 MB (03.22%) -- shapes
│   │  │  ├──0.26 MB (01.93%) ++ (2 tiny)
│   │  │  └──0.17 MB (01.29%) -- tree
│   │  │     ├──0.16 MB (01.22%) ── global-parented
│   │  │     └──0.01 MB (00.06%) ── non-global-parented
│   │  ├──0.26 MB (01.94%) -- strings
│   │  │  ├──0.15 MB (01.14%) ── normal
│   │  │  └──0.11 MB (00.80%) ── short
│   │  ├──0.19 MB (01.40%) ── scripts
│   │  └──0.09 MB (00.66%) ++ (3 tiny)
│   ├──0.75 MB (05.62%) ── script-data
│   ├──0.58 MB (04.36%) -- objects-extra
│   │  ├──0.29 MB (02.21%) ── slots
│   │  └──0.29 MB (02.15%) ── elements
│   ├──0.37 MB (02.74%) -- shapes-extra
│   │  ├──0.17 MB (01.24%) ── compartment-tables
│   │  ├──0.13 MB (01.01%) ── tree-tables
│   │  └──0.07 MB (00.49%) ++ (2 tiny)
│   ├──0.27 MB (02.06%) ── jaeger-data
│   ├──0.20 MB (01.54%) ── string-chars/non-huge
│   └──0.04 MB (00.29%) ++ (2 tiny)
├───2.72 MB (20.45%) ── runtime
└───1.41 MB (10.59%) -- gc-heap
    ├──1.35 MB (10.12%) ── decommitted-arenas
    └──0.06 MB (00.47%) ++ (3 tiny)

2.65 MB (100.0%) -- js-main-runtime-gc-heap-committed
├──2.16 MB (81.40%) -- used
│  ├──2.08 MB (78.36%) ── gc-things
│  ├──0.06 MB (02.36%) ── chunk-admin
│  └──0.02 MB (00.68%) ── arena-admin
└──0.49 MB (18.60%) -- unused
   ├──0.49 MB (18.60%) ── gc-things
   └──0.00 MB (00.00%) ++ (2 tiny)

0.18 MB (100.0%) -- window-objects
├──0.15 MB (83.72%) -- layout
│  ├──0.10 MB (55.34%) ── style-sets
│  ├──0.03 MB (18.32%) ── pres-shell
│  ├──0.01 MB (03.21%) ── frames
│  ├──0.01 MB (03.16%) ── rule-nodes
│  ├──0.00 MB (02.27%) ── style-contexts
│  └──0.00 MB (01.42%) ++ (3 tiny)
├──0.03 MB (15.24%) -- dom
│  ├──0.01 MB (06.73%) ── orphan-nodes
│  ├──0.01 MB (03.70%) ── element-nodes
│  ├──0.00 MB (02.47%) ── other
│  ├──0.00 MB (01.63%) ── text-nodes
│  └──0.00 MB (00.70%) ++ (2 tiny)
└──0.00 MB (01.04%) ++ (2 tiny)

  0.04 MB ── canvas-2d-pixel-bytes
 25.73 MB ── explicit
  4.43 MB ── gfx-surface-image
        0 ── ghost-windows
  0.00 MB ── gralloc
 19.72 MB ── heap-allocated
 20.80 MB ── heap-committed
  1.08 MB ── heap-committed-unused
    5.48% ── heap-committed-unused-ratio
  0.54 MB ── heap-dirty
  7.28 MB ── heap-unused
  4.01 MB ── images-content-used-uncompressed
  4.00 MB ── js-gc-heap
    3,112 ── page-faults-hard
   75,247 ── page-faults-soft
 71.58 MB ── resident
 67.90 MB ── resident-unique
150.05 MB ── vsize
       10 ── webgl-buffer-count
  0.02 MB ── webgl-buffer-memory
        1 ── webgl-context-count
        0 ── webgl-renderbuffer-count
  0.00 MB ── webgl-renderbuffer-memory
        4 ── webgl-shader-count
       50 ── webgl-texture-count
 51.54 MB ── webgl-texture-memory
So this:

├───5.76 MB (22.37%) -- images
│   ├──5.76 MB (22.37%) -- content
│   │  ├──5.76 MB (22.37%) -- used
│   │  │  ├──4.01 MB (15.60%) ── uncompressed-heap

Means that we can hope to shave 4M off from bug 822011.

I am also running without the patch in bug 822404 which would save up to 4 M too.
A PSS of 70MB is peanuts.  We can handle >110MB.

Are you sure this is OOM and not a crash?
(In reply to Chris Jones [:cjones] [:warhammer] from comment #46)
> A PSS of 70MB is peanuts.  We can handle >110MB.

Sorry, >120MB.
Depends on: 822404
Depends on: 822011
(In reply to Chris Jones [:cjones] [:warhammer] from comment #46)
> A PSS of 70MB is peanuts.  We can handle >110MB.
> 
> Are you sure this is OOM and not a crash?

It is a sigkill so I assumed it was still OOM.

We have 51 M of WebGL textures here which are in principle not in our address space (although I don't know what the driver does internally). In my limited understanding (correct me if I'm missing something) that is not accounted for by PSS. This would fit well with the numbers you mention:

   70 M PSS  +  51 M textures  == 121 M total == when we OOM
... and these 51 M of WebGL textures are not the entirety of OpenGL resources we have, that could live outside of our address space: there also are some other OpenGL resources such as the primary framebuffer of this WebGL context, etc.
SIGKILL usually indicates oom, but the b2g process will deliver it in some circumstances.

My assumption about texture-memory accounting was the opposite as you guessed, but if it's not being accounted that way then this makes sense.
(Looked at logcat with cjones off-bug, agreed it's likely an OOM)
Ashley: I also see these errors when running on the B2G phone, which I don't get when running on my desktop:

E/GeckoConsole( 3121): [JavaScript Warning: "Error: WebGL: texImage2D: not enough data for operation (need 56158, have 55890)" {file: "http://www.scirra.com/labs/sbopenwebapp/c2runtime.js" line: 1134}]
E/GeckoConsole( 3121): [JavaScript Warning: "Error: WebGL: texImage2D: not enough data for operation (need 9062, have 9020)" {file: "http://www.scirra.com/labs/sbopenwebapp/c2runtime.js" line: 1134}]
E/GeckoConsole( 3121): [JavaScript Warning: "Error: WebGL: texImage2D: not enough data for operation (need 6598, have 6556)" {file: "http://www.scirra.com/labs/sbopenwebapp/c2runtime.js" line: 1134}]

This indicates passing a too small array to texImage2D.

My guess is that you might need to call webgl.pixelStorei to set the UNPACK_ALIGNMENT to fit the way that your arrays are packed (likely webgl.pixelStorei(webgl.UNPACK_ALIGNMENT, 1)).
Benoit: thanks for the heads up, we're just passing an array of zeroes to create textures for rendering to, so it shouldn't matter.  I've replaced the arrays with null, since the spec says the browser will pass a zero initialised buffer of sufficient size in that case (which is what we were trying to do).
(In reply to ashley from comment #53)
> Benoit: thanks for the heads up, we're just passing an array of zeroes to
> create textures for rendering to, so it shouldn't matter.

It probably matters because this error was in principle causing this texImage2D call to be a no-operation.

>  I've replaced the
> arrays with null, since the spec says the browser will pass a zero
> initialised buffer of sufficient size in that case (which is what we were
> trying to do).

Yes, that is the right way to achieve this. It's more efficient, too.
Whiteboard: [games:p?]
Blocks: 830390
Whiteboard: [games:p?] → [games:p2]
AAsa I know, to use compressed texture you have to only change one enum in texImage calls. Check this:
http://www.opengl.org/registry/specs/ARB/texture_compression.txt

The driver will compress the image on-the-fly and store the compressed form into its texture memory. Base on the hardware you can choose many different compress format. I think s3tc is the most popular one for modern games, since it support alpha-channel properly. And I think its defaultly dsupported in DirexteX.
(In reply to Chiajung Hung [:chiajung] from comment #55)
> AAsa I know, to use compressed texture you have to only change one enum in
> texImage calls. Check this:
> http://www.opengl.org/registry/specs/ARB/texture_compression.txt
> 
> The driver will compress the image on-the-fly and store the compressed form
> into its texture memory. Base on the hardware you can choose many different
> compress format. I think s3tc is the most popular one for modern games,
> since it support alpha-channel properly. And I think its defaultly
> dsupported in DirexteX.

That is how OpenGL works, but not how WebGL works. WebGL does not support any texture formats conversions. So in WebGL, in order to use a certain textures format (compressed or not), the application developer must provide texture image data already encoded in that format.
(In reply to Benoit Jacob [:bjacob] from comment #56)
> (In reply to Chiajung Hung [:chiajung] from comment #55)
> > AAsa I know, to use compressed texture you have to only change one enum in
> > texImage calls. Check this:
> > http://www.opengl.org/registry/specs/ARB/texture_compression.txt
> > 
> > The driver will compress the image on-the-fly and store the compressed form
> > into its texture memory. Base on the hardware you can choose many different
> > compress format. I think s3tc is the most popular one for modern games,
> > since it support alpha-channel properly. And I think its defaultly
> > dsupported in DirexteX.
> 
> That is how OpenGL works, but not how WebGL works. WebGL does not support
> any texture formats conversions.

Well, let me clarify this a little bit: WebGL does not support texture formats conversions in the entry points that take a Typed Array. In particular, no conversions on compressed texture data.
Regardless, GPU compressed texture formats are not lossless, so we can't automatically try to compress otherwise lossless textures anyways. GLES doesn't support mismatched `format` and `internalFormat` parameters, either. (format conversions are disallowed)
Blocks: gecko-games
Whiteboard: [games:p2] → [games:p?]

B2G is WONTFIX.

Status: REOPENED → RESOLVED
Closed: 12 years ago5 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: