Imagination PowerVR SDK Blog

Blending on SGX


I recently ported some ES1 application to ES2 as I'm trying to get some experience with shaders.

for my textured model renderer and bitmap font renderer appear to be
similar to the ES1 version. I still have to support lighting though.
when I render a full screen 2D transparent quad with blending as my
menu background on top of my scene I loose like 6 FPS from 31 down to
25. The ES1 build handles that effortlessly. So I was wondering what is
it that I'm doing wrong? In this specific case it's no problem anyway
since 25 FPS remains quite good. But still I would like to understand
why the performance drop as it might be a problem when the scene
complexity increases.

I have one shader program for my bitmap
font drawing, one for the model rendering and one for the menu
background. All of them are very simple programs.
When I disable the
glDraw call for my transparent menu background I get no performance
drop. So I gather there must be something wrong with my shaders even
though it is a very simple program.

I posted the code for the background rendering program there:

Target device is Samsung i8910.


Funny enough I did not observe such a performance drop on Satio.
Slion2010-06-02 10:26:39


Hmm, did you render all opaque objects before the alpha-blended objects?
Did you deactivate alpha blending for the model rendering?
Did you deactivate the alpha test for all the rendering?
(See Section 1.2 “Opaque objects must be correctly flagged as opaque” of the “POWERVR 3D Application Development Recommendations”.)
Other than that I guess non-opaque objects are always a problem for tile-based rendering; maybe there are some optimizations that are not possible in OpenGL ES 2.0 that were possible in OpenGL ES 1.1


As Martin has pointed out, you should refer to the POWERVR 3D Application Development Recommendations document for advice on the best way to structure your rendering code for optimal performance.

Your shader looks fine. The problem is most likely due to the way that you handle render states in your application. You should make sure that blending is only turned on for objects that require it (i.e. call glDisable(GL_BLEND) after you have drawn your objects that require blending).

Where possible, you should avoid using alpha test or discard in your fragment shaders as these operations negate certain performance advantages that TBDR provides. In some cases, the same result can be achieved using a blend and setting the alpha value to 0 in your fragment shaders.

Rendering a full screen transparent quad is very wasteful. Instead, you can achieve much more efficient render by breaking all of your menu elements into separate alpha blended polygons. As all of your menu elements will require the same effect, you can batch these polygons into a single draw call. This allows your application to limit blending to the key areas of your scene that require it.

If the menu is only full screen when the application is paused you can improve your frame rate by rendering the current scene to a texture. This texture can then be used repeatedly instead of continuously redrawing your scene in the background.


Also note: it may seem that two devices have very similar CPUs and GPUs and that they should behave the same, but there may still be differences in the drivers, composition systems etc. that means you will see different results between them.