AnsweredAssumed Answered

Is Android direct texture supported on imx6q?

Question asked by Dragan Ostojic on Apr 16, 2015
Latest reply on Feb 8, 2016 by Richard Thompson

I encountered the following issue on imx6q (Android ICS): "GraphicBuffer memory attached as the texture to FBO not updated after rendering".

 

I'm trying to render into texture that is attached to the frame buffer object. However in order to avoid a lengthy glReadPixels operation from the GPU texture, I'm trying to do the following:

 

1) Create GraphicBuffer object:


GraphicBuffer *renderGraphicBuffer = new GraphicBuffer(imageWidth,

                                                imageHeight,

                                                PIXEL_FORMAT_RGBA_8888,

                                                GraphicBuffer::USAGE_SW_READ_OFTEN |

                                                GraphicBuffer::USAGE_SW_WRITE_OFTEN |

                                                GraphicBuffer::USAGE_HW_TEXTURE);

2) Create EGL Image from GraphicBuffer object:

const EGLint imageAttrs[] = {

   EGL_WIDTH, displayWidth,

   EGL_HEIGHT, displayHeight,

   EGL_MATCH_FORMAT_KHR, EGL_FORMAT_RGBA_8888_KHR,

    EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,

    EGL_NONE

};

EGLImageKHR eglRenderImageHandle = eglCreateImageKHR(eglDisplay,

                                                                                             EGL_NO_CONTEXT,

                                                                                             EGL_NATIVE_BUFFER_ANDROID,

                                                                                             renderGraphicBuffer->getNativeBuffer(),

                                                                                             imageAttrs);

3) Create a texture and attach the EGL Image to the same texture:

GLuint framebufferTexture;

glGenTextures(1, &framebufferTexture);

glBindTexture(GL_TEXTURE_2D, framebufferTexture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)eglRenderImageHandle);

 

 

4) Create FBO and attach texture as GL_COLOR_ATTACHMENT0:

GLuint framebuffer;

glGenFramebuffers(1, &framebuffer);

glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferTexture, 0);

 

5) I render some pixels into framebufferTexture:

glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

glViewport(0, 0, imageWidth, imageHeight);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glFinish();

 

6) After I complete rendering, I copy the contest of renderGraphicBuffer into some temporary buffer destination that I transfer to my PC for inspection:

 

void *tex = 0;

renderGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &tex);

memcpy(destination, tex, imageWidth * imageHeight * 4);

renderGraphicBuffer->unlock();

 

The problem  is that when I use the code from 6) I get black image. If I replace code from 6) with the following, picture looks good:

glReadPixels(0, 0, imageWidth, imageHeight, GL_RGBA, GL_UNSIGNED_BYTE, destination);

 

My question: Does imx6q GPU support attaching GraphicBuffer to the output texture and if it does, what I'm doing wrong?

Has anyone tried this? BTW, this approach is well documented on the Internet and people tried this before (not necessarily on imx6)

 

I attached complete test program with the makefile. The program works but to read pixels I use glReadPixels. If I replace glReadPixels with byte by byte copy from target texture buffer to the texture buffer I get black image as if target buffer doesn't reflect changes done to its texture during rendering pass. In the attached test code, lines 236-238 work. Lines 240-247 don't work.

 

Update:

After looking into ASOP code and reading some useful links I'm starting to understand Android mechanism to move graphic buffers through processing stages without using glReadPixels or memcpy. But the problem I encountered seems to be a supported feature on other GPUs so I was suprised that it didn't work as I expected. It could be still the case that there is an error in the code and if somebody knows the fix it would be good to know it because we could still use that method in some cases to simplify implementation.

 

If somebody is interested the following links are good to understand Android graphic buffers pipeline:

https://github.com/google/grafika

https://source.android.com/devices/graphics.html

https://source.android.com/devices/graphics/architecture.html

Original Attachment has been moved to: galileo_direct_texture_test.zip

Outcomes