We are using firefly board and run Android 4.4.4.
And we want to display the frame buffer (content generated from GPU) directly instead of using elgswap() for speed critical application.
But we meet one question, how to get the window surface's ion handler or frame buffer virtual address?
window surface is created via eglCreateWindowSurface(),
so how to get the ion handler or frame buffer virtual address?
After the handler or frame buffer virtual address is available, it could be converted to frame buffer physical address, then we could display the frame buffer directly.
Thanks in advance.
Hi,
On Android the GPU driver doesn't write directly to the framebuffer: everything goes through SurfaceFlinger (The compositor), and all the memory allocations come from Gralloc (The graphic allocator).
So, if you want to directly access the framebuffer (And bypass both Gralloc and SurfaceFlinger) then you'll have to dig into Gralloc/SurfaceFlinger's code or the kernel sources to find out how they access the framebuffer.
Regarding the EGL Window Surfaces: There is no way of accessing the underlying buffers (Each surface is generally multi-buffered), and even if you could it would most likely not point at the framebuffer as the window surface would still have to be composited by SurfaceFlinger before reaching the screen.
Hope this helps,
Anthony
Hi, Anthony,
Thanks for your quick response.
Yes, you are right, we will try to bypass surfaceflinger for the time critical app.
Due to EGL driver codes are not available for us, I guest EGL called ANativeWindow::dequeueBuffer/ANativeWindow::queueBuffer to allocate the buffer.
So is it possible to get the buffer (which will be handover to surfaceflinger) pointer from window surface?
Thanks & Br
Nehemiah
Hi Nehemiah,
You're correct the driver indeed calls dequeueBuffer / queueBuffer on the native window, however there is no way for an application to access these buffers.
What you could do is call dequeue / queue yourself and wrap the android_native_buffer_t as EGLImageKHR and use these as render targets in OpenGLES (Instead of an EGL Window Surface).
Thanks for your input, we will investigate your suggestion.
In opengl ES 2.0, there is a function glEGLImageTargetTexture2DOES() could turn EGLImageKHR into a texture,
But we now use opengl ES 3.0, I could not find corresponding functions or extensions.
Someone sugget use glreadpixel() function to read data from framebuffer, but this funciton does not meet our performance requirement.
How to figure this out?
The opengl ES 2.0 sample codes are here, image is EGLImageKHR
GLuint tname, name;
// turn our EGLImage into a texture
glGenTextures(1, &tname);
glBindTexture(GL_TEXTURE_2D, tname);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
// create a Framebuffer Object to render into
glGenFramebuffers(1, &name);
glBindFramebuffer(GL_FRAMEBUFFER, name);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
You can use OpenGL ES 2.0 extensions with OpenGL ES 3.0 because GLES 3.0 is backward compatible with GLES 2.0. Just use the same gl2ext.h. If you look Khronos OpenGL ES Registry this is mentioned both under Open GL ES 3.0 and Open GL ES 3.1 headers.
HTH.
/Wasim
Thanks Wasim, I will have a try.