Low fps even on empty canvas.

Hi!

I create an empty 1680?1050px canvas with gl.clear only. It shows ~30 fps in Chrome on E8400@3000Ghz & 8800 GTS.
Where I am wrong?

Here is the code:


<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=UTF-8">
		<title>webgl test</title>
	</head>
	<body>
		<canvas id="canvas" width="1680" height="1050"></canvas>
		<div id="log">log here</div>
	</body>
	<script type="text/javascript">
		var log = document.getElementById('log');
		
		var canvas = document.getElementById('canvas');
		
		var gl;
		try
		{ 
			if(!gl)
				gl = canvas.getContext('moz-webgl');
		}
		catch(e){ }
		
		try
		{ 
			if(!gl)
				gl = canvas.getContext('webkit-3d');
		}
		catch (e) { }
		
		if(!gl)
			alert('no webgl');
		
		gl.clearColor(0.2, 0.2, 0.2, 1.0);
		gl.clearDepth(1.0);
		
		var fps = 0;
		function render()
		{
			gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
			gl.flush();
			
			fps++;
		}
		
		function getFps()
		{
			log.innerHTML = fps;
			fps = 0;
		}
		
		window.setInterval(render, 10);
		window.setInterval(getFps, 1000);
	</script>
</html>

Maybe this does happen because you are calling flush() explicitly? You don’t need to call this.

Same result without flush().
I`ve tested it on 2 different configs – slow on both.

nope seems like minefield has the same problem

I guess the framerate won’t stay in the high 60’s when you go over 700px x 700px canvas so try using a smaller canvas or use it with that framerate

This reminds me to something:
I’m not 100% sure, but this might have something to do with scaling of the canvas element. It’s possible that the scaling is done using software, not hardware. However, I had similar problems when I applied width 100% and height 100% to the canvas using CSS. Then I read the element size using JavaScript and set width and height attributes of the canvas element to that size. For some reason Minefield showed scrollbars and was incredible slow. I’m not sure, but I think an CSS-style “overflow:hidden;” solved the problem.

2Coolcat: Ive tried several canvas size definitions with the same result. Its really looks like software processing.
Did you fix it? How many fps do you have now?

Did you fix it?

Yes, but I don’t know how :wink:
It might also have something to do with restarting Minefield.

How many fps do you have now?

I’m rendering a full scene (*) at 72 fps.

(*) my current project: UltimateConquest
http://www-users.rwth-aachen.de/martin. … quest.html
http://www.youtube.com/watch?v=JDTiq3RWfTc

I thought, an empty canvas or scene like this should show a thousands fps :expressionless:

I thought, an empty canvas or scene like this should show a thousands fps :expressionless:

No, not necessarily. I don’t think that WebGL does support such high framerates.

Maybe, but I can’t believe that 30(70) fps and ~100% cpu loading in empty scene is normal for hardware rendering. I think it’s some kind of gaps in early implementation.

My scene is not empty… :wink: Also I didn’t say anything about the CPU load. However, when running UltimateConquest the CPU load is at about 60%, using only one of four available cores.

I talk about my own tests. I`ve tested an empty scene on several configs with the same result: tooo low fps, high cpu load.
UltimateConquest consists of several balls. I don’t want to minish it, but it’s not the big deal for 8800GTS. Crysis show more fps on my pc, and I think, it’s not a problem of UltimateConquest.
So, my conclusion is simple: WebGL needs a full hardware support.

http://khronos.org/webgl/wiki/Getting_Started

“Tight integration with HTML content, including layered compositing, interaction with other HTML elements[…]”

This is the problem. It behaves like Flash with wmode=transparent by default. Which is nice. But this is also very slow and in many cases it’s also completely pointless.

We really need some kind of switch to bypass all those extra steps completely. Something which makes it behave like an opaque overlay. LWJGL applets are like that for example. The framerate is almost completely unaffected by running it in a browser.

You can disable alpha when creating the context. According to spec you can pass a WebGLContextAttributes object to the getContext() method. However, I didn’t try it yet.

Not implemented anywhere yet. But even if you disable it, you’d still get that copying around etc, because the browser is still compositing around. (I.e. you can put other HTML elements on top of it - and they will be visible.)

My suggestion is to use something like compositing=transparent|opaque|overlay instead of alpha=true|false.

Transparent would be like alpha=true, opaque would be like alpha=false, and overlay would mean it’s just rendered on top. Flash handles it exactly this way for example. Flash uses “window” instead of “overlay” though, but “overlay” is a bit clearer, I think.

Or buffer=transparent|opaque|overlay. I really don’t care how it’s called. But this option should be there. Layered compositing is very slow and generally not required.

The forum software just decided to throw my edit away. Great.

“Very slow” = ~27fps with older Chromium builds, ~85fps with a very recent one. While taking 100% CPU for drawing an empty 800x600 window.

Without compositing the CPU usage would be below 1% at this framerate.

If we want full screen gaming and good performance (=lower energy consumption) on mobile devices, we really need a way to bypass the compositing completely.

This definitely sounds like a good topic for the public WebGL mailing list, where the details of the spec are being hammered out: https://www.khronos.org/webgl/public-mailing-list/

I have been encouraged to post so that this issue receives more attention. At the moment, I’m drawing a simple 30x30 textured sphere full screen, and Flash is much faster than the 8fps speed that I’m getting. What I’m doing is a very common operation for displaying 360 degree panoramas, and this is definitely a minimum base standard that WebGL needs to be able to handle.

This is apparently due to browser compositing, with glReadPixels being used to transfer from pbuffers to display, so that HTML objects can be laid over the top of WebGL views. I have absolutely no need for this, and I do really very much need to have full screen full speed displays with the full power of OpenGL ES 2.0 being applied to compensate for Javascript slowness.

Would it be possible to have a wmode=window or other setting that will effectively say “thanks browser, I’ll look after this bit of the screen”, so that the mighty hardware powers can be unleashed onto that area of visual splendour? I feel this is a matter of life or death for WebGL!

Just to echo what people are saying on the mailing list; that does sound very slow. I’ve hacked up my last lesson (which draws a sphere with 30 lats and 30 longs and textures it) to scale it up to 1200 by 1000, and it seems absolutely fine – JS’s timing function is reporting less than a millisecond for a repaint, and while that seems a bit dubious, by eye it looks perfectly smooth so I must be getting order of 60fps. This is on a pretty low-end office-spec PC with an ATI 2400, running Minefield under Vista. Perhaps, as you were thinking on the list, it might just be the OS/browser combo you’re using right now has specific problems in that area.

The problem is that you’re utilizing 100% CPU for drawing that at merely ~60 FPS. Without that copy/compositing overhead you’d be at ~1% (at that framerate).

For example if the canvas is big enough to limit your empty scene to 60fps… and then you add some game logic which would limit the framerate to 60 if there were no copy/compositing overhead… then your effective framerate is halved.

Doesn’t sound that bad with 60/30, but what about 30/15 or 20/10?

If you do heavy math which would limit it to 30 fps, you’d also get only about 20fps instead of 30.

1000/30=33.333 ~33msec for math
1000/60=16.666 ~17msec for drawing overhead

33+17=50msec for everything

1000/50=20fps (without actually drawing anything)

I’d rather use those resources which are wasted on copying/compositing on something else. Like drawing, logic, or reducing energy consumption.

It’s an option in Flash for a reason. Compositing defaults to off there by the way.