The Cocoon accelerated canvas (Canvas+ from now on) for 2D and WebGL is a highly optimized JavaScript Virtual Machine for iOS and Android that implements a subset of the HTML5 standard. Actually, this is one of the first things that has to be noticed: The Canvas+ environment is not a full browser, it’s a very specialized environment for canvas 2D and WebGL based web apps/games. This guide provides a comprehensive overlook of what can and can’t be done in this execution environment.

Only canvas related content will be rendered

Although the Canvas+ execution environment supports the parsing of an HTML file and understands the following tags: <html>, <head>, <body>, <meta>, <script>, <img>, <canvas>, <audio>, <div>, it only renders elements inside a canvas using its 2D and WebGL contexts. Even a simple text inside an HTML document won’t be renderer, so if your app/game is not using just plain canvas for the main content, it won’t be able to show anything on screen.

Support for other important HTML APIs

Although anything that needs to be rendered needs to be drawn inside a canvas, Canvas+ includes several other web APIs for non graphic related tasks, all of them based on the HTML5 standard and that are important for any app/game.

    • Script injection: The Canvas+ environment supports script object creation and addition/injection to the DOM.
    • Audio: There is support for the HTML5 Audio objects, not full WebAudio API.
    • LocalStorage: There is support for LocalStorage with a ciphered binary file implementation underneath.
    • XMLHTTPRequest and EventSource: There is full support for XHR and EventSource.
    • WebSockets: There is full support for both text and binary websockets.
    • Gamepad, Vibration, DeviceOrientation, Geolocation: There is full support for the HTML5 gamepad, vibration, device orientation and geolocation standard APIs.

 

  • DOMParser
  • Document handling: getElementsById, getElementsByTagName, querySelector and querySelectorAll (but a bit limited).

 

The Cocoon Developer App

The easiest way to test the Canvas+ accelerated canvas environment is using the Cocoon Developer App for iOS and Android. You can download the latest version from the official stores.

Inside the YOUR APP section, after registering, you can introduce a URL (both manually or using a QRCode) to your web server where your app/game is hosted and execute it in the accelerated canvas environment. The FPS counter you will see is also a button that gives access to a console where you are able to check some possible error messages or even show your own console logs. If there is some HTML component the Cocoon accelerated canvas (Canvas+) execution environment does not support, it will pop up in this console, so please, check out the log from time to time. This debugging console also allows you to reload the page so iterating over an app/game is very efficient: change you code, save it, reload and check the changes on the device.

For more information on the Cocoon Developer App check out the Cocoon documentation at http://docs.cocoon.io/article/developer-app/

Letting your code know that it is being executed inside the Canvas+ execution environment

Your code can know if it’s being executed inside the Canvas+ execution environment by using the navigator.isCocoonJS property. This can come very handy while changing the code of your existing game/engine to make it compatible/run inside this specialized environment while still being able to provide a fallback for a regular browser.

Boost performance using ScreenCanvas

ScreenCanvas is a CocoonJS exclusive feature that allows a performance boost for canvas based apps and games, specially on Android. Although it is not mandatory to be used, it is highly recommended in order to take advantage of the full potential of the accelerated canvas environment. Screencanvas is a canvas that maps directly to the main screen framebuffer so it is suitable for apps/games that use a main canvas where all the content is rendered (very common in all the mobile games). Activating screencanvas is easy because there is a property inside every canvas to indicate that it should be the main canvas (the screencanvas).

This approach is completely compatible with regular browsers thanks to the nature of JavaScript where new properties can be added anytime.

Screencanvas has some constraints by it’s nature:

  • It has to be the main canvas of the scene, where you draw everything (other canvases, images, webgl shaders/geometry, …).
  • It has to be fullscreen on mobile devices.
  • As it is the screen framebuffer, it has to be redrawn in every frame.

If your app/game meets these requirements, we highly recommend that you activate screencanvas on your main canvas element.

For more information about screencanvas: http://docs.cocoon.io/article/screencanvas/  

Efficient memory management: Free image, canvas, audio and XHR objects from memory synchronously anytime

JavaScript is quite lazy when it comes to garbage collection. If you already know that you no longer need an image, canvas, audio or XHR instance you have created, there is a CocoonJS specific function called “dispose” that you can use to synchronously free the underlying memory. It is really easy to use and still be compatible with other browsers.

The WebView

Cocoon is a complete set of technologies. Apart from the accelerated canvas execution environment, very suitable for games, Ludei has also included an extension to be able to have content executed in a system webview. Of course, this environment is the stock webview in the system and it has no acceleration and some drawbacks like fragmentation, but it could come very handy for supporting elements the accelerated canvas environment does not support. The interesting thing to know is that the webview can be displayed on top of the accelerated canvas and provide a unified look and feel to the user (they will never know there are two layers). This way, you can lay a web form or complex text on top of a canvas running your game or animation. It is important to notice that these are two separate environments and thus, they run different code, but Ludei provides mechanisms to communicate both environments very easily. Another interesting feature is that this combination, is fully emulated in a regular browser, so your application will run exactly the same with no code changes on a browser.

For more information on the webview: http://docs.cocoon.io/article/canvas-internal-webview/

Tips to improve memory efficiency

Mobile devices are very scarce in both computing power and memory. The Canvas+ execution environment uses OpenGLES and having a good understanding of what is happening under the hood could be very useful when dealing with memory efficiency.

  • Power of two friendly images: OpenGL forces to generate textures in memory that are power of two in size. They do not have to be square like in the old days, but the width and the height must be POT. Whenever an image that is not POT in size is loaded, the system generates a texture in memory of the closest bigger POT value. For example, an image of 120×40 pixels in size, will be creating a texture of 128×64 pixels in memory. In this case, the memory “loss” is not significant but if you have a texture of 270×580 the texture that will be created will be 512×1024 and that is quite a significant loss (the same as having a useless additional image of 242×444 pixels). So, the tip is to be as power of two friendly as possible whenever possible having image sizes that are close but equal or lower that a power of two value (2, 4, 8, 16, 32, 64, 128, 512, 1024, 20148). Talk to your designer/graphics artist so they are aware of this when they develop the resources.
  • Another good practice for both memory efficiency and reducing loading times (specially for apps that are loaded on demand over the internet) is texture packaging. It usually requires some modifications to your engine/technology to be able to read both the image and the atlas file that describes the images inside it, but it is definitively worth the effort.
  • Finally, remember that the maximum size of an image is dependant of the underlying graphics hardware and driver. Although there are ways to know this using the WebGL context of a canvas

a simpler solution could be to try to keep the images lower than 2048×2048 (even low end devices allow this size of textures). You can also have two sets of images for HD and SD and detect the size of your canvas/window and then decide which one to load (hardware that supports HD resolutions, always allows loading images bigger than 2048, like 4096).

NOTE: There is an advanced document on memory management that explains some of these techniques (and others) in much more detail. Please, request this document if you are interested.