high cpu usage with JOGL

I have some odd cpu usage behaviour for my JOGL 3D applet. The only way I can characterise it is that cpu usage goes through the roof (i.e. near to 100%) when I get within a certain distance of a 3D object. When I am close to an object there is obvously more screen coverage of shaded pixels. My shader is a home grown GLSL shader - but It does little more than per-pixel phong shading. I do have quite a bit of CPU calculation going on but it is invariant with distance to object or pixel screen coverage. So I don’t think it is that. When I comment out the call to the geometry display list for the object, the CPU is as I would expect - a lot lower. Ditto when I use the opengl fixed pipeline shaders.

So what seems to be happening is with my own GLSL shaders there is a huge cpu overhead the more pixels are fragment shaded. This is a bit unituitive for me because that’s what I thought the GPU was for. I have an nVidia 8300GS 512Mb memory with latest drivers.

I am probably missing some fundamental point about how the whole display pipeline works! Can anyone give me any clues?

[I would profile the code but have singularly failed to profile a Java applet from within Eclipse - I follow the manual but the maual refers to menu options that do not exist - even after several installs.]

Do not use nor Animator neither FPSAnimator.

Why not?

What should I use instead?

hi quitequick,

[quote]…goes through the roof (i.e. near to 100%) when I get within a certain distance of a 3D object.
[/quote]
this smells like software rendering. I think nvidia has tools which let you debug a bit better what is going on with your shaders. And always doublecheck the shader logs after compiling and linking for compiler warnings.

The Animator tries to call display() as often as possible, so naturally it uses all of your processing power. I wonder though why the behaviour seems to depend on the amount of shaded pixels, so bienator might have hit the spot. Try FPSAnimator and limit the amount of frames to process per second. It’s timing is not the best (which might be the reason why gouessej disses it), but it should help to investigate.

Bienator - no messages whatsoever from the shader compiler.

Cylab - I am already using FPSAnimator. I limit my app to 25 fps which it manages to maintain with ease - until the cpu goes up when we get lots of shaded pixels.

Is there a way of controlling software fallback - like switching it off altogether? I want to use the CPU for things I ask it to deal with, not things the GPU asks it to deal with!

Are you using a GLJPanel or a GLCanvas in your applet? You might want to try running it as an application and see if that improves your performance. Another option is to try one of the jogl demos that use glsl shaders and see if you have the same performance hit.

lhkbob - I’m using a GLCanvas. Is that good or bad? Why should an application behave any different from an applet as far as the shaders go?

I’ve tried the demos at https://jogl-demos.dev.java.net/ and no, they don’t react the same way. However, those demos have virtually no geometry and maps apart from the Grand Canyon Demo - (which for me has been flaky and runs only occasionaly on any machine I have tried it on). But anyway the demos in https://jogl-demos.dev.java.net/ seem to point to “Original source code by NVidia” if it points to any source at all and I can find no no actual Java/Jogl/GLSL code. So I can not try their glsl shaders in my app.

When I write a program in c/c++/java my expectation of how it will run is usually borne out. However, beyond the remotely trivial, with glsl/gpu-programming it seems that I have no reasonable expectation over it's behaviour. If I am not alone, surely the gpu programming community must be spending vast amounts of time, painfully and indiscriminatly debugging glsl/gpu code and little time building up hiearchies of knowledge. Other shading languages like RenderMan RSL, as implemented by at least one major renderer ;), is totally predictable and you can easily and quickly build up shaders and libraries. Ok, RSL is not engineered for the GPU (by the renderer I obliquely refer to) but maybe the GPU should be engineered so it can be used effectively without prgramming it in assembler! Is the Gelato implementation of RSL, but exclusively for the gpu, the answer?

And… relax!

Anyway, here are my shaders. In so far as shader programming goes, they are trivial. So why do they apparently randomly swamp my cpu!

Vertex Shader


varying vec3 L[2], N, E;

void main()
	{	
	int i;
	
	/* normal in eye space */
	N = gl_NormalMatrix * gl_Normal;

	/* vertex in eye space */
	vec3 P = vec3(gl_ModelViewMatrix * gl_Vertex);

	E = normalize(-P);

	for (i = 0; i < 2; i++)
		{
		/* light vector in eye space */
		L[i] = normalize(gl_LightSource[i].position.xyz - P);
		}

	/* assign the uvs */		
	gl_TexCoord[0] = gl_MultiTexCoord0;
	
	gl_Position = ftransform();
}

Fragment Shader


varying vec3 L[2], N, E;

uniform sampler2D colourmap;

void main()
{
	int i, j;
	vec3 nN = normalize(N);
	
	vec4 tcol = texture2D(colourmap, gl_TexCoord[0].st);

	vec4 amb = vec4(0);
	vec4 diff = vec4(0);
	vec4 spec = vec4(0);
	for (i = 0; i < 2; i++)
		{		
		vec3 nL = normalize(L[i]);
		
		/* ambient term */
		amb += gl_LightSource[i].ambient;

		/* the diffuse term */		
		diff += clamp(dot(nN, nL), 0.0, 1.0)*gl_LightSource[i].diffuse;
		
		/* specular term */
		float NdotH = clamp(dot(reflect(-nL, nN), normalize(E)), 0.0, 1.0);
		spec += pow(NdotH, gl_FrontMaterial.shininess)*gl_LightSource[i].specular;
		}
		
	vec4 color = tcol*(gl_FrontMaterial.ambient*amb+gl_FrontMaterial.diffuse*diff)+gl_FrontMaterial.specular*spec;
		
	gl_FragColor = color;
}

GLCanvas usually gives better performance, and I vaguely remember hearing issues on some platforms with GLJPanel and hardware acceleration (but it’s been a while). I had a hunch that your browser was playing havoc with the gfx drivers, making it difficult to use hardware rendering for the shader program. Sometimes, the drivers will fallback to software rendering during shader execution, although I don’t know the details of these choices.

I have never had this inconsistency with shaders. I will notice performance drops when the full screen is shaded when doing per-pixel normal mapping, but that’s a more complex shader and it was no where near the degree with which you seem to be afflicted.

My recommendation is to run your applet as a java application, if its trivial, to see if the performance oddities are the same. If they are, then I’d recommend posting a small test case for others to try out. HTH

@gouessej: I think it hasn’t been answered yet. Could you please tell us why not? (Would you suggest using active rendering instead?)

The behavior of FPSAnimator is NOT cross-platform, you don’t get the same frame rate under Linux and Windows, I don’t know why. It is better to enable the V-sync.

Animator eats a lot of CPU time, it performs active waiting and it gives a very strange result when I try to use it in TUER (then I explicitly call display() in my main loop).