Re: [whatwg] Canvas 2D memory management

2013-07-19 Thread Ashley Gullen
FWIW, imageBitmap.discard() wouldn't be unprecedented - WebGL allows you to
explicitly release memory with deleteTexture() rather than letting the GC
collect unused textures.

Ashley



On 18 July 2013 17:50, Ian Hickson i...@hixie.ch wrote:

 On Wed, 9 Jan 2013, Ashley Gullen wrote:
 
  Some developers are starting to design large scale games using our HTML5
  game engine, and we're finding we're running in to memory management
  issues.  Consider a device with 50mb of texture memory available.  A
  game might contain 100mb of texture assets, but only use a maximum of
  30mb of them at a time (e.g. if there are three levels each using 30mb
  of different assets, and a menu that uses 10mb of assets).  This game
  ought to fit in memory at all times, but if a user agent is not smart
  about how image loading is handled, it could run out of memory.
 
  [...]
 
  Some ideas:
  1) add new functions to the canvas 2D context, such as:
  ctx.load(image): cache an image in memory so it can be immediately drawn
  when drawImage() is first used
  ctx.unload(image): release the image from memory

 The Web API tries to use garbage collection for this; the idea being that
 you load the images you need when you need them, then discard then when
 you're done, and the memory gets reclaimed when possible.

 We could introduce a mechanism to flush ImageBitmap objects more forcibly,
 e.g. imageBitmap.discard(). This would be a pretty new thing, though. Are
 there any browser vendors who have opinions about this?

 We should probably wait to see if people are able to use ImageBitmap with
 garbage collection first. Note, though, that ImageBitmap doesn't really
 add anything you couldn't do with img before, in the non-Worker case.
 That is, you could just create img elements then lose references to them
 when you wanted them GC'ed; if that isn't working today, I don't see why
 it would start working with ImageBitmap.

 --
 Ian Hickson   U+1047E)\._.,--,'``.fL
 http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [whatwg] Canvas 2D memory management

2013-07-19 Thread Justin Novosad
On Fri, Jul 19, 2013 at 7:09 AM, Ashley Gullen ash...@scirra.com wrote:

 FWIW, imageBitmap.discard() wouldn't be unprecedented - WebGL allows you to
 explicitly release memory with deleteTexture() rather than letting the GC
 collect unused textures.


A related issue we have now is with canvas backing stores. It is common for
web apps to create temporary canvases to do some offscreen rendering. When
the temporary canvas goes out of scope, it continues to consume RAM or GPU
memory until it is garbage collected. Occasionally this results in
memory-leak-like symptoms.  The usual workaround is to use a single
persistent global canvas for offscreen work instead of temporary ones
(yuck).  This could be handled in a cleaner way if there were a .discard()
method on canvases elements too.


 Ashley



 On 18 July 2013 17:50, Ian Hickson i...@hixie.ch wrote:

  On Wed, 9 Jan 2013, Ashley Gullen wrote:
  
   Some developers are starting to design large scale games using our
 HTML5
   game engine, and we're finding we're running in to memory management
   issues.  Consider a device with 50mb of texture memory available.  A
   game might contain 100mb of texture assets, but only use a maximum of
   30mb of them at a time (e.g. if there are three levels each using 30mb
   of different assets, and a menu that uses 10mb of assets).  This game
   ought to fit in memory at all times, but if a user agent is not smart
   about how image loading is handled, it could run out of memory.
  
   [...]
  
   Some ideas:
   1) add new functions to the canvas 2D context, such as:
   ctx.load(image): cache an image in memory so it can be immediately
 drawn
   when drawImage() is first used
   ctx.unload(image): release the image from memory
 
  The Web API tries to use garbage collection for this; the idea being that
  you load the images you need when you need them, then discard then when
  you're done, and the memory gets reclaimed when possible.
 
  We could introduce a mechanism to flush ImageBitmap objects more
 forcibly,
  e.g. imageBitmap.discard(). This would be a pretty new thing, though. Are
  there any browser vendors who have opinions about this?
 
  We should probably wait to see if people are able to use ImageBitmap with
  garbage collection first. Note, though, that ImageBitmap doesn't really
  add anything you couldn't do with img before, in the non-Worker case.
  That is, you could just create img elements then lose references to
 them
  when you wanted them GC'ed; if that isn't working today, I don't see why
  it would start working with ImageBitmap.
 
  --
  Ian Hickson   U+1047E)\._.,--,'``.fL
  http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
  Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
 



Re: [whatwg] Canvas 2D memory management

2013-07-19 Thread K. Gadd
Some of my applications would definitely benefit from this as well. A port
of one client's game managed to hit around 1GB of backing store/bitmap data
combined when preloading all their image assets using img. Even though
browsers then discard the bitmap data, it made it difficult to get things
running without killing a tab due to hitting a memory limit temporarily.
(The assets were not all in use at once, so the actual usage while playing
is fine). Having explicit control over whether bitmaps are resident in
memory would be great for this use case since I can preload the actual file
over the network, then do the actual async forced decode by creating an
ImageBitmap from a Blob, and discard it when the pixel data is no longer
needed (the game already has this information since it uses the C#
IDisposable pattern, where resources are disposed after use)


On Fri, Jul 19, 2013 at 12:34 PM, Justin Novosad ju...@google.com wrote:

 On Fri, Jul 19, 2013 at 7:09 AM, Ashley Gullen ash...@scirra.com wrote:

  FWIW, imageBitmap.discard() wouldn't be unprecedented - WebGL allows you
 to
  explicitly release memory with deleteTexture() rather than letting the GC
  collect unused textures.
 
 
 A related issue we have now is with canvas backing stores. It is common for
 web apps to create temporary canvases to do some offscreen rendering. When
 the temporary canvas goes out of scope, it continues to consume RAM or GPU
 memory until it is garbage collected. Occasionally this results in
 memory-leak-like symptoms.  The usual workaround is to use a single
 persistent global canvas for offscreen work instead of temporary ones
 (yuck).  This could be handled in a cleaner way if there were a .discard()
 method on canvases elements too.


  Ashley
 
 
 
  On 18 July 2013 17:50, Ian Hickson i...@hixie.ch wrote:
 
   On Wed, 9 Jan 2013, Ashley Gullen wrote:
   
Some developers are starting to design large scale games using our
  HTML5
game engine, and we're finding we're running in to memory management
issues.  Consider a device with 50mb of texture memory available.  A
game might contain 100mb of texture assets, but only use a maximum of
30mb of them at a time (e.g. if there are three levels each using
 30mb
of different assets, and a menu that uses 10mb of assets).  This game
ought to fit in memory at all times, but if a user agent is not smart
about how image loading is handled, it could run out of memory.
   
[...]
   
Some ideas:
1) add new functions to the canvas 2D context, such as:
ctx.load(image): cache an image in memory so it can be immediately
  drawn
when drawImage() is first used
ctx.unload(image): release the image from memory
  
   The Web API tries to use garbage collection for this; the idea being
 that
   you load the images you need when you need them, then discard then when
   you're done, and the memory gets reclaimed when possible.
  
   We could introduce a mechanism to flush ImageBitmap objects more
  forcibly,
   e.g. imageBitmap.discard(). This would be a pretty new thing, though.
 Are
   there any browser vendors who have opinions about this?
  
   We should probably wait to see if people are able to use ImageBitmap
 with
   garbage collection first. Note, though, that ImageBitmap doesn't really
   add anything you couldn't do with img before, in the non-Worker case.
   That is, you could just create img elements then lose references to
  them
   when you wanted them GC'ed; if that isn't working today, I don't see
 why
   it would start working with ImageBitmap.
  
   --
   Ian Hickson   U+1047E)\._.,--,'``.
  fL
   http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._
 ,.
   Things that are impossible just take longer.
 `._.-(,_..'--(,_..'`-.;.'
  
 



Re: [whatwg] Canvas 2D memory management

2013-07-18 Thread Ian Hickson
On Wed, 9 Jan 2013, Ashley Gullen wrote:

 Some developers are starting to design large scale games using our HTML5 
 game engine, and we're finding we're running in to memory management 
 issues.  Consider a device with 50mb of texture memory available.  A 
 game might contain 100mb of texture assets, but only use a maximum of 
 30mb of them at a time (e.g. if there are three levels each using 30mb 
 of different assets, and a menu that uses 10mb of assets).  This game 
 ought to fit in memory at all times, but if a user agent is not smart 
 about how image loading is handled, it could run out of memory.

 [...]
 
 Some ideas:
 1) add new functions to the canvas 2D context, such as:
 ctx.load(image): cache an image in memory so it can be immediately drawn
 when drawImage() is first used
 ctx.unload(image): release the image from memory

The Web API tries to use garbage collection for this; the idea being that 
you load the images you need when you need them, then discard then when 
you're done, and the memory gets reclaimed when possible.

We could introduce a mechanism to flush ImageBitmap objects more forcibly, 
e.g. imageBitmap.discard(). This would be a pretty new thing, though. Are 
there any browser vendors who have opinions about this?

We should probably wait to see if people are able to use ImageBitmap with 
garbage collection first. Note, though, that ImageBitmap doesn't really 
add anything you couldn't do with img before, in the non-Worker case. 
That is, you could just create img elements then lose references to them 
when you wanted them GC'ed; if that isn't working today, I don't see why 
it would start working with ImageBitmap.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] Canvas 2D memory management

2013-07-18 Thread Justin Novosad
On Thu, Jul 18, 2013 at 12:50 PM, Ian Hickson i...@hixie.ch wrote:

 On Wed, 9 Jan 2013, Ashley Gullen wrote:
 
  Some developers are starting to design large scale games using our HTML5
  game engine, and we're finding we're running in to memory management
  issues.  Consider a device with 50mb of texture memory available.  A
  game might contain 100mb of texture assets, but only use a maximum of
  30mb of them at a time (e.g. if there are three levels each using 30mb
  of different assets, and a menu that uses 10mb of assets).  This game
  ought to fit in memory at all times, but if a user agent is not smart
  about how image loading is handled, it could run out of memory.
 
  [...]
 
  Some ideas:
  1) add new functions to the canvas 2D context, such as:
  ctx.load(image): cache an image in memory so it can be immediately drawn
  when drawImage() is first used
  ctx.unload(image): release the image from memory

 The Web API tries to use garbage collection for this; the idea being that
 you load the images you need when you need them, then discard then when
 you're done, and the memory gets reclaimed when possible.

 We could introduce a mechanism to flush ImageBitmap objects more forcibly,
 e.g. imageBitmap.discard(). This would be a pretty new thing, though. Are
 there any browser vendors who have opinions about this?

 We should probably wait to see if people are able to use ImageBitmap with
 garbage collection first. Note, though, that ImageBitmap doesn't really
 add anything you couldn't do with img before, in the non-Worker case.
 That is, you could just create img elements then lose references to them
 when you wanted them GC'ed; if that isn't working today, I don't see why
 it would start working with ImageBitmap.


This is probably an area where most browsers could do a better job.
Browsers should be able to handle the texture memory issues automatically
without any new APIs, if they can't, then file bug reports.  If garbage
collection is not kicking-in at the right time, report it to the vendor.
ImageBitmap should provide the same kind of pinning semantics as the
suggested ctx.load/unload. However, one weakness of the current API is that
upon construction of the ImageBitmap, the browser does not know whether the
asset will be used with a GPU-accelerated rendering context or not. If this
information were available, the asset could be pre-cached on the GPU when
appropriate.  Maybe something like ctx.prefetch(image) would be appropriate
for warming up the caches.


 --
 Ian Hickson   U+1047E)\._.,--,'``.fL
 http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
 Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'



Re: [whatwg] Canvas 2D memory management

2013-07-18 Thread Rik Cabanier
On Thu, Jul 18, 2013 at 2:03 PM, Justin Novosad ju...@google.com wrote:

 On Thu, Jul 18, 2013 at 12:50 PM, Ian Hickson i...@hixie.ch wrote:

  On Wed, 9 Jan 2013, Ashley Gullen wrote:
  
   Some developers are starting to design large scale games using our
 HTML5
   game engine, and we're finding we're running in to memory management
   issues.  Consider a device with 50mb of texture memory available.  A
   game might contain 100mb of texture assets, but only use a maximum of
   30mb of them at a time (e.g. if there are three levels each using 30mb
   of different assets, and a menu that uses 10mb of assets).  This game
   ought to fit in memory at all times, but if a user agent is not smart
   about how image loading is handled, it could run out of memory.
  
   [...]
  
   Some ideas:
   1) add new functions to the canvas 2D context, such as:
   ctx.load(image): cache an image in memory so it can be immediately
 drawn
   when drawImage() is first used
   ctx.unload(image): release the image from memory
 
  The Web API tries to use garbage collection for this; the idea being that
  you load the images you need when you need them, then discard then when
  you're done, and the memory gets reclaimed when possible.
 
  We could introduce a mechanism to flush ImageBitmap objects more
 forcibly,
  e.g. imageBitmap.discard(). This would be a pretty new thing, though. Are
  there any browser vendors who have opinions about this?
 
  We should probably wait to see if people are able to use ImageBitmap with
  garbage collection first. Note, though, that ImageBitmap doesn't really
  add anything you couldn't do with img before, in the non-Worker case.
  That is, you could just create img elements then lose references to
 them
  when you wanted them GC'ed; if that isn't working today, I don't see why
  it would start working with ImageBitmap.
 

 This is probably an area where most browsers could do a better job.
 Browsers should be able to handle the texture memory issues automatically
 without any new APIs, if they can't, then file bug reports.  If garbage
 collection is not kicking-in at the right time, report it to the vendor.


Does the JS VM know about the image bits? It seems not since they live on
the C++ side so the imageBitmap could look like a small object that is
GC'ed later.


 ImageBitmap should provide the same kind of pinning semantics as the
 suggested ctx.load/unload. However, one weakness of the current API is that
 upon construction of the ImageBitmap, the browser does not know whether the
 asset will be used with a GPU-accelerated rendering context or not. If this
 information were available, the asset could be pre-cached on the GPU when
 appropriate.  Maybe something like ctx.prefetch(image) would be appropriate
 for warming up the caches.


That seems too implementation specific.


Re: [whatwg] Canvas 2D memory management

2013-07-18 Thread Boris Zbarsky

On 7/18/13 5:18 PM, Rik Cabanier wrote:

Does the JS VM know about the image bits?


For what it's worth, at least in Firefox it would; we already tell the 
JS VM about all sort of other large C++-side allocations owned by JS 
objects.


-Boris


Re: [whatwg] Canvas 2D memory management

2013-07-18 Thread Justin Novosad
On Thu, Jul 18, 2013 at 5:18 PM, Rik Cabanier caban...@gmail.com wrote:



 On Thu, Jul 18, 2013 at 2:03 PM, Justin Novosad ju...@google.com wrote:

 On Thu, Jul 18, 2013 at 12:50 PM, Ian Hickson i...@hixie.ch wrote:

  On Wed, 9 Jan 2013, Ashley Gullen wrote:
  
   Some developers are starting to design large scale games using our
 HTML5
   game engine, and we're finding we're running in to memory management
   issues.  Consider a device with 50mb of texture memory available.  A
   game might contain 100mb of texture assets, but only use a maximum of
   30mb of them at a time (e.g. if there are three levels each using 30mb
   of different assets, and a menu that uses 10mb of assets).  This game
   ought to fit in memory at all times, but if a user agent is not smart
   about how image loading is handled, it could run out of memory.
  
   [...]
  
   Some ideas:
   1) add new functions to the canvas 2D context, such as:
   ctx.load(image): cache an image in memory so it can be immediately
 drawn
   when drawImage() is first used
   ctx.unload(image): release the image from memory
 
  The Web API tries to use garbage collection for this; the idea being
 that
  you load the images you need when you need them, then discard then when
  you're done, and the memory gets reclaimed when possible.
 
  We could introduce a mechanism to flush ImageBitmap objects more
 forcibly,
  e.g. imageBitmap.discard(). This would be a pretty new thing, though.
 Are
  there any browser vendors who have opinions about this?
 
  We should probably wait to see if people are able to use ImageBitmap
 with
  garbage collection first. Note, though, that ImageBitmap doesn't really
  add anything you couldn't do with img before, in the non-Worker case.
  That is, you could just create img elements then lose references to
 them
  when you wanted them GC'ed; if that isn't working today, I don't see why
  it would start working with ImageBitmap.
 

 This is probably an area where most browsers could do a better job.
 Browsers should be able to handle the texture memory issues automatically
 without any new APIs, if they can't, then file bug reports.  If garbage
 collection is not kicking-in at the right time, report it to the vendor.


 Does the JS VM know about the image bits? It seems not since they live on
 the C++ side so the imageBitmap could look like a small object that is
 GC'ed later.


If there is any memory consumed by the ImageBitmap that is pinned for the
life-time of the object, then that memory needs to be declared to the JS VM
even if the data does not live in the JS heap. I know V8 and JavaScriptCore
have APIs for that and other engines probably do too, so the problem is
manageable.


Re: [whatwg] Canvas 2D memory management

2013-01-14 Thread Paul Bakaus


On 11.01.13 18:41, Rik Cabanier caban...@gmail.com wrote:

On Wed, Jan 9, 2013 at 8:00 AM, Ashley Gullen ash...@scirra.com wrote:

 Some developers are starting to design large scale games using our HTML5
 game engine, and we're finding we're running in to memory management
 issues.  Consider a device with 50mb of texture memory available.  A
game
 might contain 100mb of texture assets, but only use a maximum of 30mb of
 them at a time (e.g. if there are three levels each using 30mb of
different
 assets, and a menu that uses 10mb of assets).  This game ought to fit in
 memory at all times, but if a user agent is not smart about how image
 loading is handled, it could run out of memory.

 We have a WebGL renderer which solves this by explicitly creating and
 deleting textures as necessary when switching levels, which guarantees
that
 memory is managed efficiently.  It also has the additional benefit that
all
 necessary textures are pre-loaded, so there's no janking during the
game as
 the first drawImage() of a particular asset in the level uploads a
texture.

 I would like to suggest memory management features for the canvas 2D
 rendering context.  By explicitly pre-loading images and releasing them
at
 the end of the level we can guarantee that devices will not run out of
 memory, as well as making gameplay smoother.

 Some ideas:
 1) add new functions to the canvas 2D context, such as:
 ctx.load(image): cache an image in memory so it can be immediately drawn
 when drawImage() is first used


Is this what you're looking for:
http://www.whatwg.org/specs/web-apps/current-work/#imagebitmap

Very interesting! I wasn't aware of this part of the spec. Sounds like
this could become extremely useful. Looking forward to play with an
implementation to see if it fixes our issues.



 ctx.unload(image): release the image from memory


Releasing all reference to ImageBitmap should release it from memory. Are
you looking for a scheme that does not involve garbage collection?

Some of you concerns with memory management could be addressed with
WeakMaps.
Basically, you can put all your images in a WeakMap and during the draw
cycle, you pull them out and use them. If they're no longer there, it
meant
that the garbage collector has kicked in to free up memory and you need to
reload (which will unfortunately cause a jank). I'm unsure how smart the
garbage collector is because you probably want the items in the WeakMaps
to
be deleted last.



 2) we can drawImage() every image on startup to force lazy-loading
browsers
 to load everything that will be used, but there's still no way to
indicate
 which images should be released at the end of a level.  This could be
left
 for the browser to determine (perhaps releasing by least-recently-used),
 but perhaps this should be required in the specification?

 3) leave current behavior as it is and suggest WebGL for this type of
 application

 My preference is option 1, but I don't know if this works for all use
cases
 and will work nicely with implementations.  Any thoughts?

 Ashley Gullen
 Scirra.com




Re: [whatwg] Canvas 2D memory management

2013-01-12 Thread Ashley Gullen
I'd be curious to learn more about how IE handles it.  Does it use
least-recently-used or some other heuristics?  I think letting the browser
guess could result in sub-optimal load times.  Consider a game with two
levels:
Level 1: uses texture set A and B
Level 2: uses texture set A and C
When switching from level 1 to level 2, we want to release texture set B
then load texture set C, leaving set A in memory.  If the browser guesses
about releasing textures, it may release textures from set A while loading
set C, when it would be more appropriate to release textures from set B.
 Since level 2 still needs set A, it will load them again.  This means
either the game still janks during level 2, or when loading textures from
set A are needlessly released and loaded again, increasing the load time.

I hadn't heard of ImageBitmap before, and it looks like it could solve the
problem, assuming the existence of an ImageBitmap implies the texture is
already loaded in memory (which it looks like the intent is).  If set A's
ImageBitmap objects are still referenced, and set B are unreferenced and
collected when loading set C if the device runs out of memory, that appears
to be optimal behavior.  What's the implementation status of ImageBitmap?
 Do any browsers support it yet?

Ashley Gullen
Scirra.com



On 11 January 2013 22:56, Rik Cabanier caban...@gmail.com wrote:



 On Fri, Jan 11, 2013 at 2:36 PM, Robert O'Callahan 
 rob...@ocallahan.orgwrote:

 On Sat, Jan 12, 2013 at 6:41 AM, Rik Cabanier caban...@gmail.com wrote:

 Some of you concerns with memory management could be addressed with
 WeakMaps.
 Basically, you can put all your images in a WeakMap and during the draw
 cycle, you pull them out and use them. If they're no longer there, it
 meant
 that the garbage collector has kicked in to free up memory and you need
 to
 reload (which will unfortunately cause a jank). I'm unsure how smart the
 garbage collector is because you probably want the items in the WeakMaps
 to
 be deleted last.


 WeakMaps don't work like that. You can only test whether something is in
 a WeakMap by looking it up with a key object. If the key object stays alive
 and the WeakMap stays alive, then the value must also stay alive. On other
 hand, if the key object or the WeakMap have been collected, obviously you
 can't do the lookup. So you can't observe whether GC has happened using a
 WeakMap. (This is by design.)

 Sorry about that!
 yes, you are correct that you can't use it that way.

 Someone told me that WeakMaps work the same way as Flash's dictionary with
 weak keys, but that is not the case.

 FWIW, flash game developers use dictionaries with 'weak keys' as I
 described earlier. If the memory runs low, the garbage collector will
 delete objects from that cache.



Re: [whatwg] Canvas 2D memory management

2013-01-12 Thread Rik Cabanier
On Sat, Jan 12, 2013 at 11:52 AM, Ashley Gullen ash...@scirra.com wrote:

 I'd be curious to learn more about how IE handles it.  Does it use
 least-recently-used or some other heuristics?  I think letting the browser
 guess could result in sub-optimal load times.  Consider a game with two
 levels:
 Level 1: uses texture set A and B
 Level 2: uses texture set A and C
 When switching from level 1 to level 2, we want to release texture set B
 then load texture set C, leaving set A in memory.  If the browser guesses
 about releasing textures, it may release textures from set A while loading
 set C, when it would be more appropriate to release textures from set B.
  Since level 2 still needs set A, it will load them again.  This means
 either the game still janks during level 2, or when loading textures from
 set A are needlessly released and loaded again, increasing the load time.

 I hadn't heard of ImageBitmap before, and it looks like it could solve the
 problem, assuming the existence of an ImageBitmap implies the texture is
 already loaded in memory (which it looks like the intent is).  If set A's
 ImageBitmap objects are still referenced, and set B are unreferenced and
 collected when loading set C if the device runs out of memory, that appears
 to be optimal behavior.


Well, it would be the optimal behavior if you knew for sure that A and (B
or c) would fit in the browser's memory without having to resort to paging.
Since you don't, you might still get worse janking (or outright failure)
than if you could give hints to the JS engine that certain things are OK to
be destroyed first. (This is probably a discussion for a JavaScript mailing
list and not whatwg.)


 What's the implementation status of ImageBitmap?  Do any browsers support
 it yet?


I believe noone has implemented it yet. I scanned the WebKit and Mozilla
code bases and didn't find any references.




 On 11 January 2013 22:56, Rik Cabanier caban...@gmail.com wrote:



 On Fri, Jan 11, 2013 at 2:36 PM, Robert O'Callahan 
 rob...@ocallahan.orgwrote:

 On Sat, Jan 12, 2013 at 6:41 AM, Rik Cabanier caban...@gmail.comwrote:

 Some of you concerns with memory management could be addressed with
 WeakMaps.
 Basically, you can put all your images in a WeakMap and during the draw
 cycle, you pull them out and use them. If they're no longer there, it
 meant
 that the garbage collector has kicked in to free up memory and you need
 to
 reload (which will unfortunately cause a jank). I'm unsure how smart the
 garbage collector is because you probably want the items in the
 WeakMaps to
 be deleted last.


 WeakMaps don't work like that. You can only test whether something is in
 a WeakMap by looking it up with a key object. If the key object stays alive
 and the WeakMap stays alive, then the value must also stay alive. On other
 hand, if the key object or the WeakMap have been collected, obviously you
 can't do the lookup. So you can't observe whether GC has happened using a
 WeakMap. (This is by design.)

 Sorry about that!
 yes, you are correct that you can't use it that way.

 Someone told me that WeakMaps work the same way as Flash's dictionary
 with weak keys, but that is not the case.

 FWIW, flash game developers use dictionaries with 'weak keys' as I
 described earlier. If the memory runs low, the garbage collector will
 delete objects from that cache.





Re: [whatwg] Canvas 2D memory management

2013-01-11 Thread Paul Bakaus
Hi Ashley,

I brought this very topic up in the latest W3C performance workgroup
meeting but pretty much all of my ideas were cut off due to a number of
parties believing that these are ultimately UA-specific (browser specific)
concerns, and should be dealt with at the browser level.

Jason Weber of the IE team (cc'ed), in particular, was confident that IE
handling it sufficiently already. To his credits, I simply didn't try to
come up with a test case that proves otherwise, so I think that would be
the next step needed to convince vendors that this is a generic issue.
Maybe you can help?

In any case, here [1] are my slides from the meeting and here [2] is the
report from the workshop.

[1] 
https://docs.google.com/presentation/d/1a1NfQmRtuQYtBgfPVVHQBwWzDgmPaHASsyM
FWLwWMbI/edit#slide=id.p
[2] http://www.w3.org/2012/11/performance-workshop/report.html#i10

Thanks!
Paul

On 09.01.13 17:00, Ashley Gullen ash...@scirra.com wrote:

Some developers are starting to design large scale games using our HTML5
game engine, and we're finding we're running in to memory management
issues.  Consider a device with 50mb of texture memory available.  A game
might contain 100mb of texture assets, but only use a maximum of 30mb of
them at a time (e.g. if there are three levels each using 30mb of
different
assets, and a menu that uses 10mb of assets).  This game ought to fit in
memory at all times, but if a user agent is not smart about how image
loading is handled, it could run out of memory.

We have a WebGL renderer which solves this by explicitly creating and
deleting textures as necessary when switching levels, which guarantees
that
memory is managed efficiently.  It also has the additional benefit that
all
necessary textures are pre-loaded, so there's no janking during the game
as
the first drawImage() of a particular asset in the level uploads a
texture.

I would like to suggest memory management features for the canvas 2D
rendering context.  By explicitly pre-loading images and releasing them at
the end of the level we can guarantee that devices will not run out of
memory, as well as making gameplay smoother.

Some ideas:
1) add new functions to the canvas 2D context, such as:
ctx.load(image): cache an image in memory so it can be immediately drawn
when drawImage() is first used
ctx.unload(image): release the image from memory

2) we can drawImage() every image on startup to force lazy-loading
browsers
to load everything that will be used, but there's still no way to indicate
which images should be released at the end of a level.  This could be left
for the browser to determine (perhaps releasing by least-recently-used),
but perhaps this should be required in the specification?

3) leave current behavior as it is and suggest WebGL for this type of
application

My preference is option 1, but I don't know if this works for all use
cases
and will work nicely with implementations.  Any thoughts?

Ashley Gullen
Scirra.com



Re: [whatwg] Canvas 2D memory management

2013-01-11 Thread Rik Cabanier
On Wed, Jan 9, 2013 at 8:00 AM, Ashley Gullen ash...@scirra.com wrote:

 Some developers are starting to design large scale games using our HTML5
 game engine, and we're finding we're running in to memory management
 issues.  Consider a device with 50mb of texture memory available.  A game
 might contain 100mb of texture assets, but only use a maximum of 30mb of
 them at a time (e.g. if there are three levels each using 30mb of different
 assets, and a menu that uses 10mb of assets).  This game ought to fit in
 memory at all times, but if a user agent is not smart about how image
 loading is handled, it could run out of memory.

 We have a WebGL renderer which solves this by explicitly creating and
 deleting textures as necessary when switching levels, which guarantees that
 memory is managed efficiently.  It also has the additional benefit that all
 necessary textures are pre-loaded, so there's no janking during the game as
 the first drawImage() of a particular asset in the level uploads a texture.

 I would like to suggest memory management features for the canvas 2D
 rendering context.  By explicitly pre-loading images and releasing them at
 the end of the level we can guarantee that devices will not run out of
 memory, as well as making gameplay smoother.

 Some ideas:
 1) add new functions to the canvas 2D context, such as:
 ctx.load(image): cache an image in memory so it can be immediately drawn
 when drawImage() is first used


Is this what you're looking for:
http://www.whatwg.org/specs/web-apps/current-work/#imagebitmap


 ctx.unload(image): release the image from memory


Releasing all reference to ImageBitmap should release it from memory. Are
you looking for a scheme that does not involve garbage collection?

Some of you concerns with memory management could be addressed with
WeakMaps.
Basically, you can put all your images in a WeakMap and during the draw
cycle, you pull them out and use them. If they're no longer there, it meant
that the garbage collector has kicked in to free up memory and you need to
reload (which will unfortunately cause a jank). I'm unsure how smart the
garbage collector is because you probably want the items in the WeakMaps to
be deleted last.



 2) we can drawImage() every image on startup to force lazy-loading browsers
 to load everything that will be used, but there's still no way to indicate
 which images should be released at the end of a level.  This could be left
 for the browser to determine (perhaps releasing by least-recently-used),
 but perhaps this should be required in the specification?

 3) leave current behavior as it is and suggest WebGL for this type of
 application

 My preference is option 1, but I don't know if this works for all use cases
 and will work nicely with implementations.  Any thoughts?

 Ashley Gullen
 Scirra.com



Re: [whatwg] Canvas 2D memory management

2013-01-11 Thread Robert O'Callahan
On Sat, Jan 12, 2013 at 6:41 AM, Rik Cabanier caban...@gmail.com wrote:

 Some of you concerns with memory management could be addressed with
 WeakMaps.
 Basically, you can put all your images in a WeakMap and during the draw
 cycle, you pull them out and use them. If they're no longer there, it meant
 that the garbage collector has kicked in to free up memory and you need to
 reload (which will unfortunately cause a jank). I'm unsure how smart the
 garbage collector is because you probably want the items in the WeakMaps to
 be deleted last.


WeakMaps don't work like that. You can only test whether something is in a
WeakMap by looking it up with a key object. If the key object stays alive
and the WeakMap stays alive, then the value must also stay alive. On other
hand, if the key object or the WeakMap have been collected, obviously you
can't do the lookup. So you can't observe whether GC has happened using a
WeakMap. (This is by design.)

Rob
-- 
Jesus called them together and said, “You know that the rulers of the
Gentiles lord it over them, and their high officials exercise authority
over them. Not so with you. Instead, whoever wants to become great among
you must be your servant, and whoever wants to be first must be your
slave — just
as the Son of Man did not come to be served, but to serve, and to give his
life as a ransom for many.” [Matthew 20:25-28]


Re: [whatwg] Canvas 2D memory management

2013-01-11 Thread Rik Cabanier
On Fri, Jan 11, 2013 at 2:36 PM, Robert O'Callahan rob...@ocallahan.orgwrote:

 On Sat, Jan 12, 2013 at 6:41 AM, Rik Cabanier caban...@gmail.com wrote:

 Some of you concerns with memory management could be addressed with
 WeakMaps.
 Basically, you can put all your images in a WeakMap and during the draw
 cycle, you pull them out and use them. If they're no longer there, it
 meant
 that the garbage collector has kicked in to free up memory and you need to
 reload (which will unfortunately cause a jank). I'm unsure how smart the
 garbage collector is because you probably want the items in the WeakMaps
 to
 be deleted last.


 WeakMaps don't work like that. You can only test whether something is in a
 WeakMap by looking it up with a key object. If the key object stays alive
 and the WeakMap stays alive, then the value must also stay alive. On other
 hand, if the key object or the WeakMap have been collected, obviously you
 can't do the lookup. So you can't observe whether GC has happened using a
 WeakMap. (This is by design.)

 Sorry about that!
yes, you are correct that you can't use it that way.

Someone told me that WeakMaps work the same way as Flash's dictionary with
weak keys, but that is not the case.

FWIW, flash game developers use dictionaries with 'weak keys' as I
described earlier. If the memory runs low, the garbage collector will
delete objects from that cache.


[whatwg] Canvas 2D memory management

2013-01-09 Thread Ashley Gullen
Some developers are starting to design large scale games using our HTML5
game engine, and we're finding we're running in to memory management
issues.  Consider a device with 50mb of texture memory available.  A game
might contain 100mb of texture assets, but only use a maximum of 30mb of
them at a time (e.g. if there are three levels each using 30mb of different
assets, and a menu that uses 10mb of assets).  This game ought to fit in
memory at all times, but if a user agent is not smart about how image
loading is handled, it could run out of memory.

We have a WebGL renderer which solves this by explicitly creating and
deleting textures as necessary when switching levels, which guarantees that
memory is managed efficiently.  It also has the additional benefit that all
necessary textures are pre-loaded, so there's no janking during the game as
the first drawImage() of a particular asset in the level uploads a texture.

I would like to suggest memory management features for the canvas 2D
rendering context.  By explicitly pre-loading images and releasing them at
the end of the level we can guarantee that devices will not run out of
memory, as well as making gameplay smoother.

Some ideas:
1) add new functions to the canvas 2D context, such as:
ctx.load(image): cache an image in memory so it can be immediately drawn
when drawImage() is first used
ctx.unload(image): release the image from memory

2) we can drawImage() every image on startup to force lazy-loading browsers
to load everything that will be used, but there's still no way to indicate
which images should be released at the end of a level.  This could be left
for the browser to determine (perhaps releasing by least-recently-used),
but perhaps this should be required in the specification?

3) leave current behavior as it is and suggest WebGL for this type of
application

My preference is option 1, but I don't know if this works for all use cases
and will work nicely with implementations.  Any thoughts?

Ashley Gullen
Scirra.com