[Interest] 60FPS and FBO
Samuel Rødal
samuel.rodal at digia.com
Tue Nov 27 10:12:58 CET 2012
On 11/26/2012 05:50 PM, Thomas Senyk wrote:
> Hi,
>
> the context of this is mail is:
> - scenegraph
> - FBO based effects
> (plain shader-effects, qtgraphicaleffects, qt3d)
> - embedded hardware / opengl es 2.0
>
>
> I've noticed that on a lot of embedded systems the FPS drops rather
> drastically (e.g. from 60 to 30 with one effect, from 30 to 10-15 with two
> effects) when using FBO based effects.
> ... even simple effects, sometimes even if they have 'visible: false'
>
> Is this somewhat expected?
> It does sound like a vsync vs. fbo problem ... doesn't it?
> Is this a fault/bug in the embedded opengl drivers?
As Florian also commented I've noticed that the FPS very easily drops to
30 when not using the threaded renderer.
But even if that's not the case, I guess FBOs can be heavy on the GPU,
especially if they're large (screen sized) as it basically implies
another full-screen render pass, plus some synchronization overhead
depending on the architecture; when rendering to the main framebuffer
some GPUs have a deep pipeline of several frames being in flight at the
same time, this pipeline might not be possible to utilize for FBOs since
the result of rendering to the FBO is typically used quite immediately
for rendering into another FBO or the main framebuffer. An interesting
experiment might be to do double buffering by keeping two FBOs and only
using the FBO that was rendered to during the last frame as a source
during the current frame. That would mean the FBO content and non-FBO
content would not be completely in sync though (unless you used
predictive timing for the FBO content or introduced extra latency). It
would have significant implications for memory use and its effectiveness
would depend highly on the driver and GPU architecture.
I would be surprised if rendering to an FBO involved a vsync, since
there's no eglSwapBuffers() call involved in the process. You simply
bind an FBO, render to it, release it, and use it as a texture (this
step is where you get the synchronization hit).
> Did anyone ever had a setup, using one or multiple FBO based effects did still
> result in 60fps? (as it should be for simple(!) effects?)
At least on the Raspberry Pi I believe I've gotten 60 fps performance
out of ShaderEffects on ShaderEffectItems or layers. Not sure they were
fullscreen though.
There are some general tricks you can use to get better performance when
using ShaderEffects:
If you're applying effects on a sub-tree that is not animating, and the
ShaderEffect involves some heavy fragment program computation (such as a
nice blur effect), you can trade memory for performance by caching the
result of the ShaderEffect in a texture. This can be done simply by
setting "layer.enabled: true" on the ShaderEffect. Careful though, if
the sub-tree that is a source for the shader effect _is_ animating, this
will instead cause a drop in performance since the layer would need to
be updated each frame.
In some cases you might get away with applying the effect at a lower
level in the Item hierarchy, for example instead of applying an effect
on a Rectangle that contains a rotating Image, separate the effect into
two components, one that applies to the Rectangle and one that applies
to the Image, cache the result of applying the effect to the image with
the "layer.enabled: true", and apply the rotation animation on the
effect instead of the source Image. This assumes that the effect is
rotation independent though, for example if it's doing a pure color
transform (gray-scale or sepia etc). Of course, even better would be to
have a PNG with the effect pre-applied :)
In general, shader effects or not, you can always use "layer.enabled:
true" on non-animating sub-trees to trade memory for performance.
--
Samuel
More information about the Interest
mailing list