I'm trying to draw something use OpenGL ES 1.0, the rendering to screen works good. Then I want to use ImageReader to get the image data from surface, but its callback ImageReader.OnImageAvailableListener is not called at all while rendering, what's wrong about my code?
public class ImageReaderActivity extends ActionBarActivity implements SurfaceHolder.Callback, Runnable {
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private Surface mSurface;
private int mWidth, mHeight;
private boolean mRunning = false;
private ImageReader mImageReader;
private OpenGLDrawer mOpenGLDrawer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_imagereader);
mSurfaceView = findViewById(R.id.surface_view);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mWidth = width;
mHeight = height;
mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);
mSurface = mImageReader.getSurface();
new Thread(this).start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mRunning = false;
}
@Override
public void run() {
EGL10 egl = (EGL10) EGLContext.getEGL();
EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
int[] version = new int[2];
egl.eglInitialize(dpy, version);
int[] configSpec = {
EGL10.EGL_RED_SIZE, 5,
EGL10.EGL_GREEN_SIZE, 6,
EGL10.EGL_BLUE_SIZE, 5,
EGL10.EGL_DEPTH_SIZE, 16,
EGL10.EGL_NONE
};
EGLConfig[] configs = new EGLConfig[1];
int[] num_config = new int[1];
egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config);
EGLConfig config = configs[0];
EGLContext context = egl.eglCreateContext(dpy, config,
EGL10.EGL_NO_CONTEXT, null);
EGLSurface drawSurface = egl.eglCreateWindowSurface(dpy, config, mSurfaceHolder, null);
EGLSurface readSurface = egl.eglCreateWindowSurface(dpy, config, mSurface, null);
egl.eglMakeCurrent(dpy, drawSurface, readSurface, context);
GL10 gl = (GL10)context.getGL();
mOpenGLDrawer = new OpenGLDrawer();
mOpenGLDrawer.setSize(gl, mWidth, mHeight);
mRunning = true;
while (mRunning) {
SystemClock.sleep(333);
synchronized (mSurfaceHolder) {
render(gl);
egl.eglSwapBuffers(dpy, drawSurface);
}
}
egl.eglMakeCurrent(dpy, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
egl.eglDestroySurface(dpy, drawSurface);
egl.eglDestroySurface(dpy, readSurface);
egl.eglDestroyContext(dpy, context);
egl.eglTerminate(dpy);
}
private void render(GL10 gl) {
gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
mOpenGLDrawer.draw(gl);
}
private ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireLatestImage();
if (image != null) {
image.close();
}
}
};
}
After long time debugging, here is the final working code: