Search code examples
androidglsurfaceview

GLSurfaceView sometimes black on Honeycomb, works on ICS


[EDIT: FIXED! The problem appears to be having an invisible VideoView overlaying my GLSurfaceView in the layout xml. Removing the VideoView from the layout restores the expected behavior.]

[EDIT #2: Making the GLSurfaceView use ARGB888 ought to also fix this (cannot mix surfaces with different color formats I presume), have since done that to show GL over video.]

I'm using a GLSurfaceView successfully, but am seeing a strange problem on an Android 3.2 tablet. The GLSurfaceView activity uses the AndroidManifest to force landscape orientation. If I start it from an existing activity in portrait orientation the screen rotates and the GLSurfaceView works as expected. If I start it from an activity in landscape orientation the GLSurfaceView is black. This is not just a texture problem, neither glClearColor nor filling solid triangles via glDrawArrays are visible.

  • If I rotate the screen (manually after removing the manifest directive, or via setRequestedOrientation with or without the manifest directive) it starts working.

  • If I press the back button I see the expected rendered GLSurfaceView for a moment as the activity exits.

  • If I start a new activity (a SettingsActivity), I see the expected rendered GLSurfaceView flicker for a moment when starting the new activity and when returning to the GLSurfaceView activty by pressing the back button (then the screen goes black again), but only if the device is in landscape orientation. If I put the device in portrait mode then start my settings activity I do not see the GL flicker, but rotate to portrait before pressing back I do see the flicker when the GLSurfaceView activity resumes.

  • I do not see this behavior in the emulator nor on an Android 4.0.4 phone.

I create the GLSurfaceView in onCreate and add it to a FrameLayout in my layout xml.

I'm calling the GLSurfaceView pause and resume methods from the corresponding activity methods. Here's my onSurfaceCreated and onSurfaceChanged handlers:

public final static void onSurfaceCreated(GL10 pGL) {
    pGL.glClearColor(0.5f, 0.5f, 0.5f, 1f);

    pGL.glEnable(GL10.GL_TEXTURE_2D);

    pGL.glEnable(GL10.GL_BLEND);
    pGL.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);

    pGL.glShadeModel(GL10.GL_FLAT);
    pGL.glDisable(GL10.GL_DEPTH_TEST);

    pGL.glDisable(GL10.GL_DITHER);
    pGL.glDisable(GL10.GL_LIGHTING);
}

public final static void onSurfaceChanged(GL10 pGL, int pWidth, int pHeight) {
    pGL.glViewport(0, 0, pWidth, pHeight);

    pGL.glMatrixMode(GL10.GL_PROJECTION);
    pGL.glLoadIdentity();
    pGL.glOrthof(0f, pWidth, 0f, pHeight, -1f, 1f);
    pGL.glMatrixMode(GL10.GL_MODELVIEW);
}

Here's how I set up the GLSurfaceView:

    mGLSurfaceView = new GLSurfaceView(pContext);
    mGLSurfaceView.setEGLConfigChooser(false);  // no depth buffer

    mGLSurfaceView.setRenderer(this);
    mGLSurfaceView.setDebugFlags(GLSurfaceView.DEBUG_CHECK_GL_ERROR);

I added logging to verify onSurfaceCreated and onSurfaceChanged (with the expected size), as well as onDrawFrame is being called.

I found a similar report from someone using a GLSurfaceView inside a TabHost, but no good resolution: https://groups.google.com/forum/?fromgroups#!topic/android-developers/fXPfgw6AoeY

I've been trying combinations of requesting focus, invalidate, request layout, and so on with no success. I'm hoping someone here can help me see the light!


Solution

  • Answering my own question: FIXED! The problem appears to be having an invisible VideoView overlaying my GLSurfaceView in the layout xml. Removing the VideoView from the layout restores the expected behavior.