在Android上使用glEGLImageTargetTexture2DOES替换glReadPixels

问题描述

鉴于textureId,我需要从纹理中提取像素数据。

glreadPixels可以工作,但是即使在使用FBO / PBO的情况下,在某些设备上也非常慢。 (在小米MI 5上,这是65毫秒,而使用PBO则更慢)。因此,我决定使用HardwarebuffereglImageKHR,它们应该快得多。但是,我无法使其正常工作。屏幕变黑,并且没有任何数据读入数据。

 //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);

这是我用glreadPixels编写的代码,将纹理附加到帧缓冲区后,它只能获取像素。

 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,width,height,GLES30.GL_RGBA,GLES30.GL_UNSIGNED_BYTE,byteBuffer)

请告诉我我做错了什么地方:(

解决方法

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

这不会读取任何数据。这只是设置纹理以引用EGLImage。如果要将数据复制到其中,则需要执行glCopyTexImage2D()或将其绑定到帧缓冲区并渲染到其中。