WebGL slower (?) than canvas in html5 target and other problems with canvas

Among our tests with OpenFL we are porting a framework that allows us a quick workflow based on assets swf created in the Animate CC environment. Among other things it allows screen transitions (specified in the Animate library with their class names).

We have a very simple test with two screens (1280x720). In both there is a button to move to the other by a slide from right to left, both are moving at the same time. What we do internally is to convert both 1280x720 screens to bitmap at runtime (bitmapdata.draw), we hide the original movieclips (with some text and “vectors”) of the animate library, and then we move both “bitmap screens” to obtain the smoothest possible sliding movement. This technique works perfect in Adobe AIR applications (desktop & Android) and also in any OpenFL output that is not html5 (windows, android app, etc, in all those other versions it’s all super smooth)

However, if we compile the OpenFL project in html5 with WebGL (by default), in some “low” powered devices (motog5 as an example), we have realized that this mode is slower than if we compile it with <window hardware = "false “if =” html5 "/>
The movement of the two screen bitmaps (only 1280x720 each) is rough (stutters…). It does not do it at 60fps, in fact we have checked it and the fps oscillate (go down) much more in the webGL version every time there is a screen transition …

Keep in mind that on that mobile, any other version is perfect. Totally smooth, so it’s not a matter of hardware. And as far as I know, it perfectly supports webGL.

Is it possible that webGL can be slower than canvas in some situations? Is there any reason for something so simple can seem to stutter in webGL and not in “normal” canvas?

And another question: Has anyone had problems with flickering in moving canvas elements on some devices? (including artifacts on the screen when you are entering the web). It’s happening to us in Chrome Android (from 63 or 64 onwards), just in a somewhat old low-performance tablet with a Mali 450 gpu (I do not know if this can give any clue).

We have not yet found a solution and we have seen that it also happens in other frameworks based on html5 canvas …

More data…

I do not know the internals of OpenFL, but I get the impression that somehow, according to certain parameters in the project.xml, it could be that webGL is enabled or disabled at runtime … (without specifying hardware = “false”)

I have a computer with an Intel Xeon 3.0Ghz, but the graphics card is a very low end Nvidia G210. Without framework, without any extra code nor swf with assets, running the most basic possible project “DisplayingABitmap”, moving the bitmap horizontally with Actuate, and simply playing with the line if I leave it as it is, it visually looks smooth and gives the impression of 60fps.

Now, if I change the resolution to something higher (1280x720 or more), the movement shows stuttering … It’s like if webGL was disabled… And that’s the impression it gives me on the motog5 in chrome. Not only on this computer with a very low performance graphics card.

The problem that I find is that I need to specify a high output resolution (1920x1080) so that all text and other elements look good quality. Maybe there is another way to specify more “quality” but that seemed valid for a series of projects … except that the only way I have achieved a certain fluidity, has been leaving an output configured to “normal canvas” (hardware = "false ") and converting vectors and texts to bitmaps, but not with webGL (even with only bitmaps on screen).

Does anyone know anything about this topic?

Ok. to begin with and since you are targetting high resolutions add this to your project.xml

<window allow-high-dpi="true" />

That will probably sink your performance even more, but you will get full quality in your assets.

Now, for the Canvas vs WebGL dilema.
For what I have tested (So take this as hearsay)

  • WebGL feeds off your GPU and canvas off your CPU.
  • WebGL is WAAAAAY better than canvas renderer.
  • Your computer might have a GPU so bad that canvas runs better than webgl
  • Canvas is laggy but consistently laggy while webgl can be the most smooth thing ever or die at 1fps.
  • anything that has “draw” in the function name is baaaaaaaad. “.drawRect”, “.drawCircle”, “.drawTriangles”, etc. (important note, the new “drawQuads” on webgl is apparently good)
    • That means vectors are REALLY BAAAAAD!
  • Importing SWF, while possible it always ends up killing performance. No matter what we do. We resorted to using spritesheets.
  • I don’t think the “hardware” flag works on html5 target

Hope you get some help from all this and if you find a crazy trick to get better performance on canvas let me know <3

You might want to check which renderer is selected by OpenFL at startup :
Because it can switch to CANVAS if the hardware doesn’t support WEBGL.

Note : you can force OpenFL to use CANVAS renderer with the -Dcanvas compiler flag, without changing the project.xml file.

Specifying allow-high-dpi only change something on devices but not on a computer. For the time being I will continue to do tests with this matter.

As for canvas vs webgl, as I remember it is not exactly like that. Canvas without webgl has 2d acceleration by default in browsers for years. This works “automatically” when you work with bitmaps. Without this acceleration it is impossible to achieve maximum softness (60fps sustained) even with a single bitmap on the screen, especially if you have a scarce CPU.

I have done more tests, and now I am sure of what I say. As I commented in my second post, in a very simple example, moving a single bitmap (not vectors) with Actuate from one side of the screen to the other, the movement is very smooth on canvas (without webgl). But if I deactivate the acceleration 2d of canvas in chrome in the mobile of tests (motog5), the movement is abrupt (stuttering). Therefore, the gpu itself is acting to be able to “move” sprites / bitmaps smoothly.

(hardware = false does work in html5 and from what I understand it acts as “canvas without webgl”, which as I say, does not mean it is not accelerated)

This is very similar to the gpu mode of Flash / AIR. And for that reason we use in our framework the technique that we have commented.

What happens, is that with WebGL in certain cases you can optimize better (have more control of the gpu), move more things at once, and has another set of advantages. But this is mainly in powerful hardware.

I have achieved “smoothness” in a more complex project with normal canvas (swf with bitmaps inside) - because it is actually accelerated - . What I need to know is why I can not get the same with webgl on the same hardware …

I’m trying to figure out … if I have a test project configured in webgl, on the computer I said (with very low gpu), with the “webgl mode” activated (I have verified that this computer supports it), why OpenFL is so “slow”.

However, if I run the webgl examples of pixijs in the same hardware, they are executed perfectly smooth? … is what I do not quite understand …

Maybe it surprises me more than in the motog5 (with a sufficiently powerful gpu and webgl well supported), in webgl mode is not completely smooth when making a “transition” of two screens (bitmap) and yet the “canvas normal mode” is perfect. There is something that escapes us.

Something works differently in the “webgl” of OpenFL. And it would be good to know why, as it would solve a number of things. That’s why I was talking about the OpenFL “internals”, in case someone closer to the creators can throw a little light on the matter.

I just found that from Lime 7.0+ (I think) the instruction has changed to: trace (stage.window.context.type);

Both the computer and the motog5 return WebGL, so it’s not deactivated …

Does anyone know anything about the other problem? Maybe it went unnoticed:

A single bitmap should certainly animate smoothly in WebGL, if not, there’s a problem.

Does openfl test html5 -Dwebgl1 make a difference? We default to trying WebGL 2 if available, perhaps the G5 has poor WebGL 2 support, but good WebGL 1 support?

You can check this at runtime by checking the stage.window.context.version for newer versions of Lime.

You said this device runs WebGL smoothly using pixi?

Testing hardware:

  • Intel Xeon E31240 3.3Ghz computer + low performance gpu Nvidia G210. Webgl enabled (shows 2.0)
  • Mobile device motog5 (not plus). Webgl enabled (shows 2.0)

Browser: Chrome


<window width = “1920” height = “1080” />
<window fps = “60” vsync = “true” />

Test 1. DisplayingABitmap example with OpenFL bitmap logo and a simple horizontal slide movement with Actuate from one side of the screen to the other.

WebGL: Stuttering all time
Canvas (hard accel 2d on): Perfect smooth
Canvas (hard accel 2d off): Some stuttering
(openfl test html5 -Dwebgl1 makes no difference)

WebGL: Perfect smooth
Canvas (hard accel 2d on): Perfect smooth
Canvas (hard accel 2d off): Some stuttering
(openfl test html5 -Dwebgl1 makes no difference)

(if I specify allow-high-dpi = true, stutters all time on both)

In both, even in the computer with a gpu of such low specification, the pixijs examples are perfect.

EDIT on next post.

I found the problem The resolution that I select (1920x1080) is problematic for less powerful devices and computers. It is what is slowing it down the most.

Modifying this in project.xml
<window width = “1280” height = “720” unless = “mobile” />
<window width = “0” height = “0” if = “html5” />

Running in WebGL with this params seems to work correctly in the motog5. Although the computer does not improve much, so the solution is partial … and I keep wondering why in pixijs everything is always smooth even on this computer…

However, the performance when moving (a few) sprites per screen is similar in both canvas and webgl (reasonably smooth). So I do not know if WebGL in our case is worth it.

We will continue to do tests in any way.

About the ocassional flickering problem, does anyone know anything? Some similar problem in some device?

Never had a problem there and have done some crazy things with canvas (have 2 sprites rendering a game and doing a crazy non rectangular mask on one of them and having A METRIC TON of assets in a large open world )
both games are running on canvas, the first one is with an openfl version 4,8,1 and the second one is 8,6,4

Be careful that <window width = “0” height = “0” if = “html5” /> means “fill the screen”. I am using that now for a responsive web game where we listen the RESIZE event and shift elements arround.

However, the performance when moving (a few) sprites per screen is similar in both canvas and webgl (reasonably smooth). So I do not know if WebGL in our case is worth it.

If for some reason you need to keep canvas compatibility (in our case, some clients ask for the game to run on older internet explorer versions), force yourself to canvas.

If you can choose what to use, I would go for the default WebGL and fallback to canvas. Try to make it work on both but wouldn’t stress too much if canvas is not as fluid as webgl.

Has anyone tried forcing WebGL 1? I’m curious if that would make the difference

In my case openfl test html5 -Dwebgl1 makes no difference in speed. I’ve tried in the example above.

What version of Lime/OpenFL are you using? The define might not have worked correctly in other versions. You may have to modify the source directly to make sure it calls for “webgl” and not “webgl2” when Lime initializes the context

Haxe 3.4.4
OpenFL 8.7.0
Lime 7.2.0

I am super confused on how webgl works after these tests

Bunnymark made with openfl create bunnymark, changed width and height to zero and resizable to true so that it will fill the viewport, set the viewport to 4k on chrome.

No bunnies were added. This is the initial batch of 100

  • openfl test html5 -clean -Dcanvas: 60fps screenshot
  • openfl test html5 -clean -Dwebgl1 15fps screenshot
  • openfl test html5 -clean -Dwebgl2 15fps screenshot

fps measured with chrome tool as the incorporated fps was resized and couldn’t be read. movement fluidity correlates with the fps notated.

openfl 8.8.0
lime 7.2.1
openfl-samples 8.7.0 (reference for bunnymark)

So it seems that the bigger the viewport, the worse webgl performance we get :frowning:

On a bold note: this only happens when you refresh the window with the big resolution simulation on. If you refresh the window with a smaller resolution and then make it bigger, the fps take a hit but not as big as depicted in the screenshots and the bunnies still cover the new surface area. ¿could there be something wrong with the initialization?

I wonder if the FPS meter is partially to blame:

Having timers in my code and performing non-hardware accelerated css animations in my game managed to block the thread and therefore cause the render to be scheduled for later.

On the flickering problem, we think that it is a generalized problem of rendering (only in html5 canvas target), but that it happens according to a combination of hardware and software factors (chrome version) in only some devices of the market.

It happens to us in a BQ Edison 3 tablet if we have a chrome version higher than 60. It probably has to do with a driver conflict problem and what chrome does internally. But that tablet is no longer going to have updates, so the problem has little solution …

Be careful that <window width = “0” height = “0” if = “html5” /> means “fill the screen”. I am using that now for a responsive web game where we listen the RESIZE event and shift elements arround.

I know. But it’s the only way I have that everything goes fast enough and at the same time it looks good on any device. What we do with our framework, is to resize the interactive content to the size of the viewport without problems.

The problem with webgl, as I was saying, is that it is only fast in a sufficiently powerful hardware (and if you develop things in a very specific way).

Canvas (default hw accelerated) is faster / smoother on a larger number of devices and computers, by default. On the other hand, the difference between default canvas and webgl for certain developments is minimal. All this, as I said, as long as we always work with bitmaps (from swf or in other ways).

What I do not think there is an easy way to know if a device that a priori supports webgl, will go faster or slower in default canvas or in webgl …