Forums - Unexpected pixel data layout when reading from GraphicBuffer

4 posts / 0 new
Last post
Unexpected pixel data layout when reading from GraphicBuffer
emilwestergren
Join Date: 4 Jul 14
Posts: 6
Posted: Fri, 2014-07-04 08:17

I am currently working on a platform in the native Android framework where I use GraphicBuffer to allocate memory and then create an EGLImage from it. This is then used as a texture in OpenGL ES which I render to (with a simple fullscreen quad).

The problem is when I read the rendered pixel data from the GraphicBuffer, I expect it to be in a linear RGBA format in memory but the result is a texture which contains (what looks like) three parallell smaller clones of the image and with overlapping pixels. Maybe that description doesn't say much but the point is the actual pixel data makes sense but the memory layout seems to be something other than linear RGBA. I assume this is because the graphics drivers store the pixels in an internal format other than linear RGBA.

If I render to a standard OpenGL texture and read with glReadPixels everything works fine, so I assume the problem lies with my custom memory allocation with GraphicBuffer. It also works if I copy the pixels from the EGLImage with glReadPixels.

If the reason is the drivers' internal memory layout, is there any way of forcing the layout to linear RGBA? I have tried most of the usage flags supplied to the GraphicBuffer constructor with no success. If not, is there a way to output the data differently in the shader to "cancel out" the memory layout? I haven't been able to figure out the actual encoding algorithm by looking at the pixel data.

I am building Android 4.4.3 for Nexus 5.

//Allocate graphicbuffer
outputBuffer = new GraphicBuffer(outputFormat.width, outputFormat.height, outputFormat.bufferFormat,
        GraphicBuffer::USAGE_SW_READ_OFTEN |
        GraphicBuffer::USAGE_HW_RENDER |
        GraphicBuffer::USAGE_HW_TEXTURE);

/* ... */

//Create EGLImage from graphicbuffer
EGLint eglImageAttributes[] = {EGL_WIDTH, outputFormat.width, EGL_HEIGHT, outputFormat.height, EGL_MATCH_FORMAT_KHR,
        outputFormat.eglFormat, EGL_IMAGE_PRESERVED_KHR, EGL_FALSE, EGL_NONE};

EGLClientBuffer nativeBuffer = outputBuffer->getNativeBuffer();

eglImage = _eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, nativeBuffer, eglImageAttributes);

/* ... */

//Create output texture
glGenTextures(1, &outputTexture);
glBindTexture(GL_TEXTURE_2D, outputTexture);
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, eglImage);

/* ... */

//Create target fbo
glGenFramebuffers(1, &targetFBO);
glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, outputTexture, 0);

glBindFramebuffer(GL_FRAMEBUFFER, 0);
/* ... */
//Read from graphicbuffer
const Rect lockBoundsOutput(quadRenderer->outputFormat.width, quadRenderer->outputFormat.height);

status_t statusgb = quadRenderer->getOutputBuffer()->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &result);

 

  • Up0
  • Down0
mhfeldma Moderator
Join Date: 29 Nov 12
Posts: 310
Posted: Tue, 2014-07-08 07:44

Hi..

Thanks for posting and providing the code snippet.  A few questions

1) What is outputFormat.bufferFormat set to?

2) Just a note that the eglImageAttributes you're setting are invalid for eglCreateImageKHR. They are ignored.  The Format/Width/Height all come from the nativebuffer.

3) Could you detail the width/height/stride parameters that the app is expecting.

4) Could you be interpreting the stride value in bytes, when it is actually in pixels?

 

 

  • Up0
  • Down0
emilwestergren
Join Date: 4 Jul 14
Posts: 6
Posted: Tue, 2014-07-08 08:15

Hi,

First of all, thanks for answering. I just found out myself what was wrong and the solution was much simpler than I expected.

I am rendering RGBA8888 to a 480x1080 texture and the resulting texture was padded to 640x1080 so I just needed to get rid of the padding for each row and the resulting texture made sense.

Interesting point about the eglImageAttributes, are you saying I can just leave them out and it won't make a difference?

  • Up0
  • Down0
mhfeldma Moderator
Join Date: 29 Nov 12
Posts: 310
Posted: Tue, 2014-07-08 09:01

Interesting point about the eglImageAttributes, are you saying I can just leave them out and it won't make a difference?

Yes, that's correct.

 

Glad you resolved the issue w/padding

  • Up0
  • Down0
or Register

Opinions expressed in the content posted here are the personal opinions of the original authors, and do not necessarily reflect those of Qualcomm Incorporated or its subsidiaries (“Qualcomm”). The content is provided for informational purposes only and is not meant to be an endorsement or representation by Qualcomm or any other party. This site may also provide links or references to non-Qualcomm sites and resources. Qualcomm makes no representations, warranties, or other commitments whatsoever about any non-Qualcomm sites or third-party resources that may be referenced, accessible from, or linked to this site.