I have also been trying to find an alternative to using the notoriously
slow glReadPixels() in order to get GPU textures copied to CPU memory,
which seems to be the only officially supported way to achieve this. While
there are several examples out on the web that attempt to use
GraphicBuffer, it probably won't be worth trying to implement them for your
case. I've been there and can say: don't go there if you don't really have
Not only will you have to deal with dynamically loading libraries and
symbols (Hello, hard-coded mangled function names!), manual GraphicBuffer
instance management, etc., all of which will result in a hacky mess.
The real problem is that the API is internal and therefore not supported on
many devices. All bets are off when attempting to use it. Even if the
library seems to be there and whatever is callable does not return any
error states, there will still be mysterious crashes on some devices. Which
also makes it impossible to write a dual code path that uses GraphicBuffer
in some instances and glReadPixels() in others. (Unless you want to
manually whitelist devices... no good alternative either.)
The sad part is that in the cases where it did work, it provided a
significant and noticeable speedup compared to using glReadPixels() on the
respective devices; think along the lines of 5x faster.
An efficient and officially supported method to read data from GPU to CPU
memory is sorely lacking on Android, and this lack can severely degrade
performance in many real-time applications. Or rather: There is currently
no good way for developers to use the optimal method.
For example, when dealing with the camera preview, it is possible to get
the preview image either as a texture on the GPU side (to then display it),
or to get it via preview callback as a memory region on the CPU side. The
flow of 1) acquiring the preview texture, 2) processing on the GPU, and 3)
further processing/interpretation on the CPU is simply infeasible due to
the slowness of getting the data to the CPU side between steps 2) and 3).
I'm sure that for the preview callback, the data is internally read in
highly optimized ways, but why the Android engineers chose not to expose
this method I do not know.
One could argue that glReadPixels() should be the function to do this, but
then why is it so inefficient compared to using the GraphicBuffer method?
I'm no expert on what the OpenGL standard mandates regarding its operation,
but I guess there is some pipeline flushing happening prior to reading the
Maybe one of the involved engineers could comment on the issue or even
point out fast alternatives that have been overlooked so far?
On Saturday, July 13, 2013 10:25:54 PM UTC+2, Chen wrote:
I'm trying to use GraphicBuffer in order to avoid the slow glReadPixels.
The problem is that GraphicBuffer.h is not found, libui does not exist, etc.
I did find source code for GraphicBuffer and I did find some git
repositories with native android source code, but I'm not sure:
1. How to compile them all to be used as shared libraries in my project
2. If I do compile and link to my local libui, will it work on Android
I'm a bit confused by the different versions of ndk release, api level,
android version... and how they all work (or don't) together.
I see a lot of examples using GraphicBuffer and even when I'm trying to
target android-9 (like the examples) I can't find it on the android-ndk-r8e.
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firstname.lastname@example.org.
To post to this group, send email to email@example.com.
Visit this group at http://groups.google.com/group/android-ndk.
For more options, visit https://groups.google.com/groups/opt_out.