1

I have a setup with OpenGL ES 2.0 and EGL on Android 4.4.2 (API level 19).

My goal is to access the buffer of the window (the default framebuffer in OpenGL terms) directly from the CPU / user space.

I have tried using ANativeWindow_fromSurface to get ANativeWindow from the Surface of a GLSurfaceView. Then trying to get access to the buffer with ANativeWindow_lock fails with status -22. Logcat gives

03-25 10:50:25.363: E/BufferQueue(171): [SurfaceView](this:0xb8d5d978,id:32,api:1,p:6488,c:171) connect: already connected (cur=1, req=2)

From this discussion it seems you can't do that with GLSurfaceView, because EGL has already acquired the surface.

How could you get to the memory of the window? Can you somehow do it through an EGLSurface? I am willing to use android::GraphicBuffer, even tough it is not part of the NDK.

If this is not possible, can you use the other direction, by first creating an android::GraphicBuffer and then binding it to an EGLSurface and the displayed window?

Sogartar
  • 2,035
  • 2
  • 19
  • 35

2 Answers2

1

Android devices may not have a framebuffer (i.e. /dev/graphics/fb). It's still widely used by the recovery UI, but it's being phased out.

If it does have a framebuffer, it will be opened and held by the Hardware Composer unless the app framework has been shut down. Since you're trying to use the NDK, I assume the framework is still running.

If your NDK code is running as root or system, you can request a top window from SurfaceFlinger. The San Angeles demo provides an example.

Additional information can be found here, here, and here. If you want to work with graphics at a low level, you should also read the graphics architecture doc.

Community
  • 1
  • 1
fadden
  • 51,356
  • 5
  • 116
  • 166
  • I was talking in OpenGL terms, when referring to the default framebuffer. – Sogartar Mar 27 '15 at 08:46
  • Something like http://stackoverflow.com/questions/21151259/replacing-glreadpixels-with-egl-khr-image-base-for-faster-pixel-copy/ ? – fadden Mar 27 '15 at 15:19
0

This is not doable with just NDK API, you will need to pull-in some OS headers, that are not guaranteed to be stable.

You will need to subclass ANativeWindow, similarly to what is done in frameworks/native/include/ui/FramebufferNativeWindow.h. However you may need to construct your own buffer queue using own-created android::GraphicBuffer objects, and properly respond to all dequeue() and enqueue() requests.

On enqueue() you will need to sync (GPU renders asynchronously) and than map enqueued buffer to CPU memory.

Note that this approach may be underperformant, due to explicit GPU<->CPU sync needed.

sacygan
  • 99
  • 4