Use glEGLImageTargetTexture2DOES to replace glReadPixels on Android

Given a textureId, I need to extract pixel data from the texture.

glReadPixels works, but it is extremely slow on some devices, even with FBO/PBO. (On Xiaomi MI 5, it is 65 ms, and even slower with PBO). So I decided to use Hardwarebuffer and eglImageKHR, which should be much faster. However, I cannot get it to work. The screen goes black, and nothing is read into the data.

 //attach inputTexture to FBO glBindFrameBuffer(GL_FRAMEBUFFER, fbo) glFrameBufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0) //allocate hardware buffer AHardwareBuffer* buffer = nullptr; AHardwareBuffer_Desc desc = {}; desc.width = width; desc.height = height; desc.layers = 1; desc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER | AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT ; desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; //create eglImageKHR EGLint eglAttributes[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(buffer); EGLImageKHR eglImageKhr = eglCreateImageKHR(eglDisplay, eglContext, EGL_NATIVE_BUFFER_ANDROID, clientBuffer, eglAttributes); //read pixels to hardware buffer ???? glBindTexture(GL_TEXTURE_2D, textureId); glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImageKhr); //copy pixels into memory void *readPtr; AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, -1, nullptr, (void**)&readPtr); memcpy(writePtr, readPtr, width * 4); AHardwareBuffer_unlock(buffer, nullptr); 

This is my code with glReadPixels, and it just can get the pixels after attaching the texture to framebuffer.

 GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, fboBuffer!![0]) GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, inputTextureId, 0) GLES30.glReadPixels(0, 0, width, height, GLES30.GL_RGBA, GLES30.GL_UNSIGNED_BYTE, byteBuffer) 

Please tell me where I did wrong :(

1 Answer

 //read pixels to hardware buffer ???? glBindTexture(GL_TEXTURE_2D, textureId); glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImageKhr); 

This doesn't do any reading of data. This is just setting up the texture to refer to the EGLImage. If you want data to be copied into it you need to either do glCopyTexImage2D() or bind it to a framebuffer and render in to it.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like