Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a SurfaceHolder with a valid Surface (needed by EGL.eglCreateWindowSurface)?

I try to initialize GLES with EGL (because I want to draw from the main thread instead of using a Renderer and drawing from inside onDrawFrame). I get the error: "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface". Obviously mEgl.eglCreateWindowSurface fails because surfaceHolder has not a valid surface. How do I get a SurfaceHolder with a valid Surface to proceed?

My Activity.onCreate method is:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    GLSurfaceView surfaceView = new GLSurfaceView(this);
    setContentView(surfaceView);
    SurfaceHolder surfaceHolder = surfaceView.getHolder();
    Surface surface = surfaceHolder.getSurface();
    Log.v("HelloAndroid", "surface.isValid()= " + Boolean.toString(surface.isValid()));

    EGL10 mEgl = (EGL10) EGLContext.getEGL();
    EGLDisplay mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
    int[] version = new int[2];
    mEgl.eglInitialize(mEglDisplay, version);
    EGLConfig[] configs = new EGLConfig[1];
    int[] num_config = new int[1];
    int[] configSpec = {
            EGL10.EGL_NONE
    };
    mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, num_config);
    EGLConfig mEglConfig = configs[0];
    EGLContext mEglContext = mEgl.eglCreateContext(mEglDisplay, mEglConfig,
            EGL10.EGL_NO_CONTEXT, null);
    EGLSurface mEglSurface = null;
    Log.v("HelloAndroid", "M");
    mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay,
            mEglConfig, surfaceHolder, null);
    Log.v("HelloAndroid", "N");
    mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
            mEglContext);
    Log.v("HelloAndroid", "O");
}

The log output I get with platform-tools/adb logcat is:

V/HelloAndroid( 1861): surface.isValid()= false
D/libEGL  ( 1861): egl.cfg not found, using default config
D/libEGL  ( 1861): loaded /system/lib/egl/libGLES_android.so
V/HelloAndroid( 1861): M
D/AndroidRuntime( 1861): Shutting down VM
W/dalvikvm( 1861): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
E/AndroidRuntime( 1861): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime( 1861): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.helloandroid/com.example.helloandroid.HelloAndroid}: java.lang.IllegalArgumentException: Make sure the SurfaceView or associated SurfaceHolder has a valid Surface
E/AndroidRuntime( 1861):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)

Any help is appreciated.

like image 642
Thomas Mertes Avatar asked Apr 07 '11 07:04

Thomas Mertes


2 Answers

The check valid for surface should be did when surface is created. So, surface.isValid() should be called in onSurfaceCreated or onSurfaceChanged, obviously, you should add surfaceholder.callback.

like image 76
Lee Avatar answered Nov 11 '22 20:11

Lee


Implement SurfaceHolder.Callback, and wait until you're told that the surface has been created. Also pay attention to when it is destroyed. You should only rely on the surface being valid between matching create and destroy calls.

like image 45
Laurence Gonsalves Avatar answered Nov 11 '22 18:11

Laurence Gonsalves