I know this is an old topic, but Archeia said I should just reply here. xD I was actually looking for the same information, but since I couldn't find it, I went into the code and figured it out on my own. I figured that it would be useful to share this information with everyone.
So the first thing to know is what processes the image goes through before being displayed on the screen.
- read - The image is loaded from a permanent storage medium. This means basically that the file has been read as such into RAM. e.g. If the file is 30kB, the RAM consumption at this point is 30kB.
- decode - The image is decoded into a raw bitmap. This means that e.g. a PNG files has been decompressed and all actual pixels are now in the RAM. If that image is e.g. 1000x1000 pixels with alpha, the size in RAM is now 1000x1000x4 = 4 million Bytes.
- upload to GPU - This means that the GPU now has access to the texture data of the bitmap and can render it. In the previous case from Load it would mean that the texture now also takes 4 million bytes of VRAM.
Keep in mind that Bitmap size information (width and height) will only become available after
decode has been done.
So what do the separate ImageManager functions do?
- Request - Starts the read process asynchronously, but stops after that. So this is useful e.g. if you want to avoid doing HDD operations while the player is actually playing the game.
- Load - Starts the read process asynchronously and will run decode automatically after the file has been read from the permanent storage.
- Reserve - Does the same as the Load, but also marks the bitmap as "keep in memory". I will explain image memory below.
You probably noticed that the
upload to GPU step is missing here and you are correct. The
upload to GPU step is done internally the moment the first render call is used. Incidentally if you alter a bitmap (e.g. with drawText() or fillRect() calls), the bitmap is marked as
dirty and will be reuploaded again the next time it is drawn. This is also why it's not recommended to constantly keep changing bitmaps. Uploading texture data to the GPU is an expensive operation.
The way the
ImageCache system works is that it has a fixed size of pixels (not bytes!) that it's allowed to keep in memory. The variable
ImageCache.limit is set to 10 million pixels by default. This translates to e.g. 10 images of size 1000x1000. If the limit has been surpassed, the ImageCache module will delete the last recently used images until it's under that limit again, but it
keeps all reserved images regardless of that. Most of the images from the
img/system directory are actually reserved like that globally, ie. they are never removed from the cache.
If you intend to use
Reserve with anything other than system images, there are 2 additional things that you have to keep in mind.
- All images reserved are local for the current scene and they will be "released" from reservation after the scene is finished. That means that images can be purged by ImageCache after the scene is finished (unless obviously they are reserved again in another scene).
- Do NOT reserve any images before the create method of the scene has been called. Reservations work via IDs that can be released later and the SceneManager creates that ID for every scene just before calling the scene's create method. My suggestion is to actually call it within the scene's create method. You can even call it before the superclass call to give the ImageManager more time to preload your images.