Bitmaps Being Cached As Bitmaps - actionscript-3

I have a slideshow type portion of an AIR Mobile for iOS I am working on. There are four pages that the user can scroll through. Each page contains a PNG (as large as 1MB, even after compression) loaded in using the Bitmap class and two TextFields. As I am scrolling through them (using a custom scroll framework that works without any issues throughout the app), the app is caching each of the PNG images as a Bitmap as they come onto the screen and unloading them when they leave the screen after a period (most likely the next GC, though it seems to be less random than GC).
The act of caching the PNGs is incredibly slow on iOS, especially when it is happening while another action (such as scrolling) is happening. This produces a ~1 sec delay while scrolling, which is obviously unacceptable. Is there a way to either a) prevent the caching or b) keep them cached longer/indefinitely until the images themselves are eligible for GC?
I've triple checked my code and nothing is set to cacheAsBitmap. Additionally, I've been using Adobe Scout to pinpoint what was causing that momentary freeze and it is definitely from caching the images. I've also eliminated any transforms or scales or filters or anything that might turn cacheAsBitmap on in order to operate and the results remain the same.

It turns out that bitmap caching wasn't really the problem afterall. After much more examination, I found that it was actually PNG decompression. Basically, Flash was decompressing PNGs as they were coming on screen (which is even more expensive than caching), adding those to memory, and undoing the process after they had been off the screen for a period of time, meaning I would have to decompress all over again after that period of time for each image.
To get around this, you simply need to access the BitmapData object in some way. I used getPixel( 0, 0 ) in my constructors and the images were decompressed and loaded into BitmapData permanently upon doing so. It will add a bit of time to the startup, but preloading in this fashion results in better performance.

To avoid this decompressing on the run (on demand) you can instead request flash to decompress it on load. This will increase the load time but improve the perceived performance of the app since a separate thread takes care of the decompressing. This of course means no jitter or skip when the image hits the screen.
var loaderContext:LoaderContext = new LoaderContext();
loaderContext.imageDecodingPolicy = ImageDecodingPolicy.ON_LOAD
var loader:Loader = new Loader();
loader.load(new URLRequest("http://www.adobe.com/myimage.png"), loaderContext);
See: http://help.adobe.com/en_US/as3/dev/WS52621785137562065a8e668112d98c8c4df-8000.html
And
http://www.bytearray.org/?p=2931
Embedded images (via code) are not supposed to be compressed, so this problem shouldn't occur with applications that do so. However, if you are like me, and you use the Flash Pro IDE to import PNGs or other bitmap assets, Flash Pro compresses them as JPG by default, using the setting provided by the image itself.
To fix this and avoid these decompression issues, simply go to your Flash Pro asset library, right click on the image you want to change, click on properties and select "lossless / PNG/GIF" as compression. This will increase largely the load time but you will have the much better perceived performance discussed here. This should be done in addition to implementing the code above, or it will make no difference.
In my experience the frame rate average dropped only by one frame per second, but it's much more consistent without any skips or lags which is essential for games.
Since Flash Player will free the decompressed bitmap memory of a BitmapData, here's a solution if decompression still occurs after this: Keeping Bitmaps Decompressed.

Related

Spritestage and multiple spritesheets

My team is currently working on a rather large Web application. We have switched from the flash platform to Html5 in hope for a one size fits all platform.
The UI, is mainly based on createjs, which I by the way really enjoy working with.
However we have now reached the maturity phase and started optimizing some of the animations, that doesn't run smoothly in especially IE.
The thing is that we have a around 1500 sprites (pngs & jpgs) which is drawn onto a stage. We only draw around 60 of them per frame.
They are rather large (up to 800x800 pixels), and the application engine can choose which 60 to show more or less randomly.
The images are packed in a zip file and unpacked in the browser and Html images are constructed by converting the binary data to a base64 encoded string, which is passed to the src property of an image.
So in each frame render a set of around
60 images are drawn to the stage. And this is for some reason slow.
I have therefore used some time to experiment with the Spritestage of createjs to take advantage of Webgl, but with only small improvements.
So now I'm considering to pack our sprites in a spritesheet, which results in many sheets because of the large amount of data.
My question is therefore:
Would spritestage gain any improvements if my sprites are spread across multiple sheets? According to the documentation only spritesheets with a single image are supported.
Best regards
/Mikkel Rasmussen
In general, spritesheets speed up rendering by decrease the number of draw call required by frame. Instead of say, using a different texture and render for every sprite, spritesheet implementations can draw multiple sprites with one render call, provided that the sprite sheet contains all the different individual sprite images. So to answer your question, you are unlikely to see performance gains if the sprites you want to draw are scattered on different sprite sheets.
Draw calls have significant overhead and it is generally a good idea to minimize them. 1500 individual draw calls would be pretty slow.
I dont know if it this is applicable to your situation but it is possible your bottleneck is not the number of draw calls you dispatch to GPU but you are doing too much overdraw since you mention your sprites are 800x800 each. If that is the case, try to render front to back with the depth test or stencil test turned on.

Canvas performance in Dart

This problem is related to my framework VilTAGE (https://github.com/ViliX64/VilTAGE). It's an ASCII web game framework, that renders to Canvas. The problem is, that the drawing time is twice as long as the computation time.
The way the rendering works now is that there is a HashMap of each CharNode (an object, with a text character, color, etc..) and CanvasElement, that has the text drawn onto it. When the loop wants to draw a CharNode (15-30x a second), it goes through the HashMap, find required CanvasElement and renders it to the main CanvasElement. (See https://github.com/ViliX64/VilTAGE/blob/master/lib/etc/utility.dart).
The individual CanvasElement snaps are small (usually about 10x10). They are drawn using drawImage(..);
The problem is, that in a game with 70x40 CharNodes, the game runs (unsuprisingly) very slow and even more, when compiled to JavaScript.
Is there any obvious mistake I am making or could you please give me any tips of improving the performance?
EDIT 1: It runs the slowest on Firefox and IE. Performance on Google Chrome is better.
If it works like it does in javascript, your issue is probably with the fact that you're cacheing a CanvasElement and that the drawImage have to retrieve the bitmapData from it each time it is called. This is a really expensive operation.
You could try to cache the imageData with getImageData and draw it with putImageData (both are CanvasRenderingContext2D methods)

Speeding up the image loading process

How can we speed up the process of loading hundred's of images in as3? it seams to be taking a very long time to load 100's of images.
If you don't have the ability to change the image quality or sizes, then there isn't a lot you can do to speed up such a large load, as you are limited by connection speed and simultaneous browser connections.
You may be benefitted by using a loading manager, like Greensock's LoaderMax. LoaderMax will help make sure you are loading several assets simultaneously - check out the maxConnections parameter.
Also, I suggest not loading everything up front with one preloader. Instead, have placeholders with a spinning loader for each image that then gets replaced by the final image once loaded. This will provide a much smoother user experience and create the illusion of the overall load taking less time.
100s of requests can take quite a long time even if the total size of the images isn't prohibitively large. If you know which images you need in advance, you could embed the images in another swf which you load at runtime.
By the way, what is the reason that you need to load 100s of images right away. Is there any reason you can't load them in the background a little more slowly?
A few suggestions:
Reduce the filesize of your images (obvious but most important).
Don't run all the requests at once - queue the images and load them one at a time (most relevant to least relevant).
There were lots of good advices already. But here a re my 2 cents. One day I had to load about 1000 of really small images. It was taking too long so I used FZip AS3 library. Worked like a charm.
The question does not provide a lot of specifics, so here are some general guidelines.
If the images are large JPEGs, you might be able to sacrifice some quality and recompress the images to make them smaller.
If the images are PNGs and represent, e.g., lots of small, individual tiles for a game, you could try combining many of them into a single image and then parsing them out into images on the client side after loading the image over the network.
Implement download queue, for example simple loader
https://github.com/hydrotik/QueueLoader
Do not load images that
currently out of stage (you can load them in background)
Use texture packer if you have plenty of small images
Optimize pics
quality (i.e. size, type)
Use cache, for instance Local Shared
Object, so for next time you'll get your pics ultimately fast from
LSO.
Is there any way to get thumbnails of the images made? If so, you could use the thumbnails while the larger versions load. Load all the thumbnails first (since they'd load really fast), then load the larger versions in prioritized order.
It sounds like you don't have a lot of control over the images, though. If you don't have any control there, there's very little you can do to speed up the process besides using a loading optimizer as others have suggested.

sprite vs individual images

Ok - for a web SITE that loads over and over again this is an obvious question. One sprite sheet (that will probably be cached on the users system) and some fancy css background-position trickery, and you're saving yourself a ton of server requests.
But for a web APP, that loads once, and never again. Is a sprite really the way to go. Yes, breaking it up into individual pngs means that many more requests up front, but in the long run, how does this fair?
I'm guessing it depends entirely on the rendering engine and how the memory management works, but it seems like having a 200k sprite sheet duplicated all over the place might be more costly to performance in the long run...
Normally you will use sprite for change states of particular element, e.g. for the button, not for all the images at once. Benefit of using sprites in that case is not just to save a request, but also to make state changes (say on mouse over) instant.

how big is too big for a swf file

I am making a flash game. And I want to know how big is too big for a swf file. Also, Ive been looking at my swf file and right now its at 38.2k. Is the swf file that gets created during debugging, is this the correct size for the file that will eventually be placed on the web.
thanks
Kilobytes is small stuff.
Anything less than a couple of megabytes is fine - once you get above that you might start worrying about loading times and keeping users interested during the preloader, but most portals accept files up to 10MB or so.
Yes, the file is the same. A game of 38.2 kb is pretty small, if you go on Flash game sites they regularly run in the multiple of megabytes.
The SWF is slightly smaller in release mode. The size difference is essentially nothing.
As for a guideline size, this depends on who you are expecting to play your game.
if you want your game to reach a very wide audience keep it as small as you possibly can.
a game without any heavy animation , embedded assets like png files or sound will usually be small.
a good discussion regarding Optimal swf size for flash games here at
http://board.flashkit.com/board/showthread.php?t=788271
The difference between debug and release builds is, according to my experience, some 30-40% in file size (debug version being bigger, of course), which is not insignificant.
Anyways, I think you're safe to assume that anything below 100kb is small enough to be considered an instant download, with no need to use preloaders. However, adding graphical and sound assets to the game will quickly push it up in size, at which point the preloader will probably be a good idea.