CocoonJS, the advanced survival guide.

CocoonJS now offers out-of-the-box integration with many major HTML5 gaming platforms and frameworks like Scirra Play Construct 2, Impact or CAAT among others.
Integration is direct, and no code changes must be made to your source code beyond the tips we already talked about in the post CocoonJS a survival guide.

But we can’t forget that CocoonJS is a hardware accelerated environment, with deep OpenGL bridge integration, and sometimes, that is not at zero cost. This post unveils some advanced concepts you probably won’t have to be dealing with, but just in case, we must warn you about them.

These topics are not CocoonJS specific, but generally applicable to any OpenGL backed development.

Be aware of your images’ size.

Regular HTML Image objects are backed by OpenGL Textures. These textures must be 2^n sized, that means that valid texture sizes will be 64×64, 64×128, 256×512, etc., which in the end, could lead to wasting texture space. For example, if you have an Image that is 33×65 pixels, it will take 64x128x4 bytes in memory instead of the expected 33x65x4 (multiply by 4 because each pixel is RGBA packed).
Whenever possible, an atlas image is better than many arbitrary images.

Images’ size can’t be huge.

In addition to the two square size restrictions, textures can’t exceed a given size. While we’ve found that normally a GL Texture object could be 4096 pixels width and/or height, certain medium-high end Android devices will limit that size to 2048.
While it seems to be enough size for an Image, to make sure, limit your Image’s width to 2048 pixels.

Be aware of your Canvas objects.

Regular Canvas objects are backed by OpenGL FrameBuffers. This means amongst other things, that the same size restrictions apply as to Image objects. Despite the fact that a regular game is not supposed to keep many canvas objects at the same time, you should keep their number tight.
Additionally, if clipping operations are performed on a Canva’s Rendering context object, the canvas needs to allocate extra resources, like an stencil buffer.
Keep in mind that Canvas objects can take twice as much as a regular Image.

Clipping.

In addition to the size constraint when clipping is enabled, clipping should be used sparingly. CocoonJS implementation allows you to nest as much clipping areas as needed, but at the cost of some performance loss.
This is due to the fact that clipping areas must first of all be tesselated, but reconstructed when the context is saved/restored.
If your game does not perform as expected and you’re doing heavy clipping operations, try disabling them and compare.

FillText.

Despite what it may seem, filling text is not that straightforward operation. Filling text means: allocating a new GL Texture to hold drawn text, uploading pixels to that texture, and then destroy the texture to probably repeat that procedure in the next frame.
CocoonJS caches text, but is not heuristically intelligent. So if your game makes extensive use of drawn text, our advice is to cache the text to an offscreen canvas and manage it yourself, or even better, draw text with an sprited font.

To assist you with all this memory management nightmare, CocoonJS will issue some warnings with debug information regarding the allocated amount of memory in addition to the allocated number of images and canvas’s.

2 Comments CocoonJS, the advanced survival guide.

Leave a Reply

Your email address will not be published. Required fields are marked *