play-co / timestep

GNU General Public License v3.0
16 stars 27 forks source link

Optimized context of onscreen canvas #124

Closed bchevalier closed 7 years ago

bchevalier commented 7 years ago

Why

Some settings of the WebGL contexts implied implicit GPU operations that were unnecessary. These operations are: antialiasing and creating of a depth buffer for the onscreen canvas.

Anti-aliasing

Anti-aliasing can be an expensive operation, its complexity probably is O(n+m) where n is the number of polygons on screen and m is the total length (in canvas coordinates) of the polygon edges. 2d games usually do not benefit from this kind of anti-aliasing (polygon edge anti-aliasing) and disabling it would not affect visual quality since most edges are either transparent, not visible on screen or axis-aligned.

It is particularly heavy when the number of sprites displayed is high (for instance, benchmarks on a macbook showed that the famous PIXI bunny mark achieves only 1/3 of its performance when anti-aliasing is not disabled).

Anti-aliasing is disabled by default on older devices but enabled by default on newer devices/browsers (enabled from iOS 10 for instance, old Xperia phones have it disabled while newer models have it enabled).

Depth buffer allocation

Allocating memory for the depth buffer is done only at context-creation time but consumes some RAM unnecessarily for 2d games. Disabling the depth buffer should save up some memory in theory but it will be hard to test as this memory cannot be profiled by the dev tools that cannot access GPU memory usage.

Note: The depth buffer and anti-aliasing are WebGL features only.

How

Simply by explicitly disabling those operations when creating the context of the on-screen canvas.

Result

The depth buffer optimization is hard to measure for the moment but I do not think it can hurt to include this change.

In order to measure noticeably any FPS change when testing the effect of the anti-aliasing feature I had to virtually increase the pixel ratio to 8. The result on my machine is the following: With anti-aliasing

screen shot 2017-06-13 at 6 09 28 pm

Without anti-aliasing

screen shot 2017-06-13 at 6 08 47 pm

Of course, turning it off has no noticeable effect on quality.

Note: Concretely the benefit might translate only into battery savings and fewer heat dissipation since the performance bottleneck appears to be the CPU on all the devices I have hands on.

Additional information

I initially had included a change to disable alpha-blending of the on-screen canvas and the html body but it seems that, counter-intuitively, performance gets worse when it is turned off:

With alpha

screen shot 2017-06-13 at 6 46 05 pm

Without alpha

screen shot 2017-06-13 at 6 45 41 pm

(Tested on mac by rendering a 4k on-screen canvas)