Is Android direct texture supported on imx6q?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Is Android direct texture supported on imx6q?

1,456 Views
DraganOstojic
Contributor V

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

Labels (3)
0 Kudos
3 Replies

656 Views
b36401
NXP Employee
NXP Employee

Android Surfaceflinger mostly use GPU 2D to accelerate surface composition, the interface is Hwcomposer provided by Vivante.

According to the test, composition with GPU 2D has high efficiency and lower power consumption than GPU 3D.

Have a great day,

Victor

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

-----------------------------------------------------------------------------------------------------------------------

0 Kudos

656 Views
rgngl
Contributor I

I'm having the exact same issue. The same code path works in every other GPU except Vivante. I'm wondering is there any other way to read data from a texture? I tried using glTexDirectVIV but that one is also always returning a null pointer to me.

0 Kudos

656 Views
Richard2
Contributor III

I appear to have the exact same issue.

Using the IMX6 Quad, how do you copy a rendered image to another OpenGLES/EGL Context or CPU application?

Emphasis on the RENDERED. The image was made in OpenGLES and it's in an FBO.

glReadPixels() has utterly hideous performance, and context sharing doesn't seem to work at all.

0 Kudos