GLTextureViewActivity.java revision cf559377b750271472aa0a717bf3b7d34abc0b39
18f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy/*
28f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * Copyright (C) 2011 The Android Open Source Project
38f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy *
48f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * Licensed under the Apache License, Version 2.0 (the "License");
58f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * you may not use this file except in compliance with the License.
68f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * You may obtain a copy of the License at
78f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy *
88f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy *      http://www.apache.org/licenses/LICENSE-2.0
98f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy *
108f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * Unless required by applicable law or agreed to in writing, software
118f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * distributed under the License is distributed on an "AS IS" BASIS,
128f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * See the License for the specific language governing permissions and
148f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy * limitations under the License.
158f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy */
168f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
178f0095cd33558e9cc8a440047908e53b68906f5fRomain Guypackage com.android.test.hwui;
188f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
198f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.animation.ObjectAnimator;
208f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.animation.ValueAnimator;
218f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.app.Activity;
228f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.graphics.SurfaceTexture;
238f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.opengl.GLES20;
248f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.os.Bundle;
258f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.util.Log;
268f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.view.Gravity;
278f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.view.TextureView;
288f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.view.View;
298f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.widget.FrameLayout;
308f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
318f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport javax.microedition.khronos.egl.EGL10;
328f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport javax.microedition.khronos.egl.EGL11;
338f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport javax.microedition.khronos.egl.EGLConfig;
348f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport javax.microedition.khronos.egl.EGLContext;
358f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport javax.microedition.khronos.egl.EGLDisplay;
368f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport javax.microedition.khronos.egl.EGLSurface;
378f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport javax.microedition.khronos.opengles.GL;
388f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
398f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy@SuppressWarnings({"UnusedDeclaration"})
408f0095cd33558e9cc8a440047908e53b68906f5fRomain Guypublic class GLTextureViewActivity extends Activity implements TextureView.SurfaceTextureListener {
418f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    private RenderThread mRenderThread;
428f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    private TextureView mTextureView;
438f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
448f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    @Override
458f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    protected void onCreate(Bundle savedInstanceState) {
468f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        super.onCreate(savedInstanceState);
478f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
488f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        mTextureView = new TextureView(this);
498f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        mTextureView.setSurfaceTextureListener(this);
508f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
518f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        setContentView(mTextureView, new FrameLayout.LayoutParams(500, 400, Gravity.CENTER));
528f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    }
538f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
548f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    @Override
55451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
568f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        mRenderThread = new RenderThread(surface);
578f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        mRenderThread.start();
588f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
598f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        mTextureView.setCameraDistance(5000);
608f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
618f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        ObjectAnimator animator = ObjectAnimator.ofFloat(mTextureView, "rotationY", 0.0f, 360.0f);
628f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        animator.setRepeatMode(ObjectAnimator.REVERSE);
638f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        animator.setRepeatCount(ObjectAnimator.INFINITE);
648f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        animator.setDuration(4000);
658f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
668f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            @Override
678f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            public void onAnimationUpdate(ValueAnimator animation) {
688f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                ((View) mTextureView.getParent()).invalidate();
698f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
708f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        });
718f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        animator.start();
728f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    }
738f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
748f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    @Override
758f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
768f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    }
778f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
78451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy    @Override
79451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy    public void onSurfaceTextureDestroyed(SurfaceTexture surface) {
80451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy        mRenderThread.finish();
81451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy        try {
82451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy            mRenderThread.join();
83451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy        } catch (InterruptedException e) {
84451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy            Log.e(RenderThread.LOG_TAG, "Could not wait for render thread");
85451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy        }
86451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy    }
87451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy
88cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba    @Override
89cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
90cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba    }
91cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba
928f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    private static class RenderThread extends Thread {
938f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private static final String LOG_TAG = "GLTextureView";
948f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
958f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
968f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        static final int EGL_SURFACE_TYPE = 0x3033;
978f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        static final int EGL_SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400;
988f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        static final int EGL_OPENGL_ES2_BIT = 4;
998f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1008f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private volatile boolean mFinished;
1018f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1028f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private SurfaceTexture mSurface;
1038f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1048f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private EGL10 mEgl;
1058f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private EGLDisplay mEglDisplay;
1068f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private EGLConfig mEglConfig;
1078f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private EGLContext mEglContext;
1088f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private EGLSurface mEglSurface;
1098f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private GL mGL;
1108f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1118f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        RenderThread(SurfaceTexture surface) {
1128f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mSurface = surface;
1138f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
1148f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1158f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        @Override
1168f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        public void run() {
1178f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            initGL();
1188f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
119451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy            float red = 1.0f;
1208f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            while (!mFinished) {
1218f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                checkCurrent();
1228f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
123451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy                Log.d(LOG_TAG, "Rendering frame");
124451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy
1258f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                GLES20.glClearColor(red, 0.0f, 0.0f, 1.0f);
126451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy                checkGlError();
1278f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1288f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
129451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy                checkGlError();
1308f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1318f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
1328f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    throw new RuntimeException("Cannot swap buffers");
1338f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                }
134451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy                checkEglError();
135451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy
1368f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                try {
1378f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    Thread.sleep(20);
1388f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                } catch (InterruptedException e) {
1398f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    // Ignore
1408f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                }
1418f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1428f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                red += 0.021f;
1438f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                if (red > 1.0f) red = 0.0f;
1448f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
1458f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1468f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            finishGL();
1478f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
1488f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
149451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy        private void checkEglError() {
150451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy            int error = mEgl.eglGetError();
151451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy            if (error != EGL10.EGL_SUCCESS) {
152451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy                Log.w(LOG_TAG, "EGL error = 0x" + Integer.toHexString(error));
153451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy            }
154451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy        }
155451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy
156451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy        private void checkGlError() {
157451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy            int error = GLES20.glGetError();
158451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy            if (error != GLES20.GL_NO_ERROR) {
159451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy                Log.w(LOG_TAG, "GL error = 0x" + Integer.toHexString(error));
160451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy            }
161451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy        }
162451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy
1638f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private void finishGL() {
1648f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mEgl.eglDestroyContext(mEglDisplay, mEglContext);
1658f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
1668f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
1678f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1688f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private void checkCurrent() {
1698f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            if (!mEglContext.equals(mEgl.eglGetCurrentContext()) ||
1708f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    !mEglSurface.equals(mEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) {
1718f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
1728f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    throw new RuntimeException("eglMakeCurrent failed "
1738f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                            + getEGLErrorString(mEgl.eglGetError()));
1748f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                }
1758f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
1768f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
1778f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1788f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private void initGL() {
1798f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mEgl = (EGL10) EGLContext.getEGL();
1808f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1818f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
1828f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
1838f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                throw new RuntimeException("eglGetDisplay failed "
1848f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                        + getEGLErrorString(mEgl.eglGetError()));
1858f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
1868f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1878f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            int[] version = new int[2];
1888f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            if (!mEgl.eglInitialize(mEglDisplay, version)) {
1898f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                throw new RuntimeException("eglInitialize failed " +
1908f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                        getEGLErrorString(mEgl.eglGetError()));
1918f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
1928f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1938f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mEglConfig = chooseEglConfig();
1948f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            if (mEglConfig == null) {
1958f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                throw new RuntimeException("eglConfig not initialized");
1968f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
1978f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1988f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mEglContext = createContext(mEgl, mEglDisplay, mEglConfig);
1998f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
2008f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface, null);
2018f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
2028f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
2038f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                int error = mEgl.eglGetError();
2048f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                if (error == EGL10.EGL_BAD_NATIVE_WINDOW) {
2058f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
2068f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return;
2078f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                }
2088f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                throw new RuntimeException("createWindowSurface failed "
2098f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                        + getEGLErrorString(error));
2108f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
2118f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
2128f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
2138f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                throw new RuntimeException("eglMakeCurrent failed "
2148f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                        + getEGLErrorString(mEgl.eglGetError()));
2158f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
2168f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
2178f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mGL = mEglContext.getGL();
2188f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
2198f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
2208f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
2218f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
2228f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
2238f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            return egl.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
2248f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
2258f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
2268f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private EGLConfig chooseEglConfig() {
2278f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            int[] configsCount = new int[1];
2288f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            EGLConfig[] configs = new EGLConfig[1];
2298f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            int[] configSpec = getConfig();
2308f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) {
2318f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                throw new IllegalArgumentException("eglChooseConfig failed " +
2328f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                        getEGLErrorString(mEgl.eglGetError()));
2338f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            } else if (configsCount[0] > 0) {
2348f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                return configs[0];
2358f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
2368f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            return null;
2378f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
2388f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
2398f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private int[] getConfig() {
2408f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            return new int[] {
2418f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
2428f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    EGL10.EGL_RED_SIZE, 8,
2438f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    EGL10.EGL_GREEN_SIZE, 8,
2448f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    EGL10.EGL_BLUE_SIZE, 8,
2458f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    EGL10.EGL_ALPHA_SIZE, 8,
2468f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    EGL10.EGL_DEPTH_SIZE, 0,
2478f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    EGL10.EGL_STENCIL_SIZE, 0,
2488f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    EGL10.EGL_NONE
2498f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            };
2508f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
2518f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
2528f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        static String getEGLErrorString(int error) {
2538f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            switch (error) {
2548f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                case EGL10.EGL_SUCCESS:
2558f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return "EGL_SUCCESS";
2568f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                case EGL10.EGL_NOT_INITIALIZED:
2578f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return "EGL_NOT_INITIALIZED";
2588f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                case EGL10.EGL_BAD_ACCESS:
2598f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return "EGL_BAD_ACCESS";
2608f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                case EGL10.EGL_BAD_ALLOC:
2618f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return "EGL_BAD_ALLOC";
2628f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                case EGL10.EGL_BAD_ATTRIBUTE:
2638f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return "EGL_BAD_ATTRIBUTE";
2648f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                case EGL10.EGL_BAD_CONFIG:
2658f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return "EGL_BAD_CONFIG";
2668f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                case EGL10.EGL_BAD_CONTEXT:
2678f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return "EGL_BAD_CONTEXT";
2688f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                case EGL10.EGL_BAD_CURRENT_SURFACE:
2698f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return "EGL_BAD_CURRENT_SURFACE";
2708f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                case EGL10.EGL_BAD_DISPLAY:
2718f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return "EGL_BAD_DISPLAY";
2728f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                case EGL10.EGL_BAD_MATCH:
2738f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return "EGL_BAD_MATCH";
2748f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                case EGL10.EGL_BAD_NATIVE_PIXMAP:
2758f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return "EGL_BAD_NATIVE_PIXMAP";
2768f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                case EGL10.EGL_BAD_NATIVE_WINDOW:
2778f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return "EGL_BAD_NATIVE_WINDOW";
2788f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                case EGL10.EGL_BAD_PARAMETER:
2798f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return "EGL_BAD_PARAMETER";
2808f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                case EGL10.EGL_BAD_SURFACE:
2818f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return "EGL_BAD_SURFACE";
2828f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                case EGL11.EGL_CONTEXT_LOST:
2838f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return "EGL_CONTEXT_LOST";
2848f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                default:
2858f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return "0x" + Integer.toHexString(error);
2868f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
2878f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
2888f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
2898f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        void finish() {
2908f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mFinished = true;
2918f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
2928f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    }
2938f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy}
294