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;
22d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guyimport android.content.res.Resources;
23d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guyimport android.graphics.Bitmap;
24d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guyimport android.graphics.BitmapFactory;
258f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.graphics.SurfaceTexture;
26d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guyimport android.opengl.GLUtils;
278f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.os.Bundle;
28a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guyimport android.os.Environment;
298f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.util.Log;
308f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.view.Gravity;
318f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.view.TextureView;
328f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.view.View;
33d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guyimport android.view.ViewGroup;
348f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.widget.FrameLayout;
358f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
368f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport javax.microedition.khronos.egl.EGL10;
378f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport javax.microedition.khronos.egl.EGLConfig;
388f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport javax.microedition.khronos.egl.EGLContext;
398f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport javax.microedition.khronos.egl.EGLDisplay;
408f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport javax.microedition.khronos.egl.EGLSurface;
418f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport javax.microedition.khronos.opengles.GL;
42ec19b4a764d512091a780fc93ced567dfbf80914Romain Guyimport java.io.BufferedOutputStream;
43a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guyimport java.io.File;
44ec19b4a764d512091a780fc93ced567dfbf80914Romain Guyimport java.io.FileNotFoundException;
45ec19b4a764d512091a780fc93ced567dfbf80914Romain Guyimport java.io.FileOutputStream;
46ec19b4a764d512091a780fc93ced567dfbf80914Romain Guyimport java.io.IOException;
47d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guyimport java.nio.ByteBuffer;
48d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guyimport java.nio.ByteOrder;
49d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guyimport java.nio.FloatBuffer;
50d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
51d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guyimport static android.opengl.GLES20.*;
52d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
538f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy@SuppressWarnings({"UnusedDeclaration"})
548f0095cd33558e9cc8a440047908e53b68906f5fRomain Guypublic class GLTextureViewActivity extends Activity implements TextureView.SurfaceTextureListener {
558f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    private RenderThread mRenderThread;
568f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    private TextureView mTextureView;
578f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
588f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    @Override
598f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    protected void onCreate(Bundle savedInstanceState) {
608f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        super.onCreate(savedInstanceState);
618f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
628f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        mTextureView = new TextureView(this);
638f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        mTextureView.setSurfaceTextureListener(this);
64ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy        mTextureView.setOnClickListener(new View.OnClickListener() {
65ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy            @Override
66ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy            public void onClick(View v) {
67cfacbeadffb5dccbf0434d9c05b19430a5237c3bRomain Guy                Bitmap b = mTextureView.getBitmap(800, 800);
68ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy                BufferedOutputStream out = null;
69ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy                try {
70a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy                    File dump = new File(Environment.getExternalStorageDirectory(), "out.png");
71a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy                    out = new BufferedOutputStream(new FileOutputStream(dump));
72ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy                    b.compress(Bitmap.CompressFormat.PNG, 100, out);
73ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy                } catch (FileNotFoundException e) {
74ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy                    e.printStackTrace();
75ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy                } finally {
76ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy                    if (out != null) try {
77ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy                        out.close();
78ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy                    } catch (IOException e) {
79ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy                        e.printStackTrace();
80ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy                    }
81ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy                }
82ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy            }
83ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy        });
848f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
85d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        setContentView(mTextureView, new FrameLayout.LayoutParams(
86d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT,
87d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                Gravity.CENTER));
888f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    }
898f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
908f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    @Override
91451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
92d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        mRenderThread = new RenderThread(getResources(), surface);
938f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        mRenderThread.start();
948f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
958f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        mTextureView.setCameraDistance(5000);
968f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
978f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        ObjectAnimator animator = ObjectAnimator.ofFloat(mTextureView, "rotationY", 0.0f, 360.0f);
988f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        animator.setRepeatMode(ObjectAnimator.REVERSE);
998f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        animator.setRepeatCount(ObjectAnimator.INFINITE);
1008f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        animator.setDuration(4000);
1018f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
1028f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            @Override
1038f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            public void onAnimationUpdate(ValueAnimator animation) {
104ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy                mTextureView.invalidate();
1058f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
1068f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        });
1078f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        animator.start();
1088f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    }
1098f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1108f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    @Override
1118f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
1128f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    }
1138f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
114451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy    @Override
115402f05530352f34d5320c2d23be43c274d97c4e2Grace Kloba    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
116451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy        mRenderThread.finish();
117451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy        try {
118451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy            mRenderThread.join();
119451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy        } catch (InterruptedException e) {
120451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy            Log.e(RenderThread.LOG_TAG, "Could not wait for render thread");
121451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy        }
122402f05530352f34d5320c2d23be43c274d97c4e2Grace Kloba        return true;
123451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy    }
124451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy
125cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba    @Override
126cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
127cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba    }
128cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba
1298f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    private static class RenderThread extends Thread {
1308f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private static final String LOG_TAG = "GLTextureView";
1318f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1328f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
1338f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        static final int EGL_OPENGL_ES2_BIT = 4;
1348f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1358f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private volatile boolean mFinished;
1368f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
137d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        private final Resources mResources;
138d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        private final SurfaceTexture mSurface;
1398f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
1408f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private EGL10 mEgl;
1418f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private EGLDisplay mEglDisplay;
1428f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private EGLConfig mEglConfig;
1438f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private EGLContext mEglContext;
1448f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private EGLSurface mEglSurface;
1458f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private GL mGL;
1468f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
147d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        RenderThread(Resources resources, SurfaceTexture surface) {
148d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            mResources = resources;
1498f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mSurface = surface;
1508f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
1518f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
152d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        private static final String sSimpleVS =
153d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                "attribute vec4 position;\n" +
154d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                "attribute vec2 texCoords;\n" +
155d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                "varying vec2 outTexCoords;\n" +
156d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                "\nvoid main(void) {\n" +
157d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                "    outTexCoords = texCoords;\n" +
158d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                "    gl_Position = position;\n" +
159d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                "}\n\n";
160d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        private static final String sSimpleFS =
161d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                "precision mediump float;\n\n" +
162d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                "varying vec2 outTexCoords;\n" +
163d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                "uniform sampler2D texture;\n" +
164d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                "\nvoid main(void) {\n" +
165d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                "    gl_FragColor = texture2D(texture, outTexCoords);\n" +
166d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                "}\n\n";
167d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
168d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        private static final int FLOAT_SIZE_BYTES = 4;
169d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
170d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
171d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
172d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        private final float[] mTriangleVerticesData = {
173d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                // X, Y, Z, U, V
174a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy                -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
175a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy                 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
176a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy                -1.0f,  1.0f, 0.0f, 0.0f, 1.0f,
177a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy                 1.0f,  1.0f, 0.0f, 1.0f, 1.0f,
178d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        };
179d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
1808f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        @Override
1818f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        public void run() {
1828f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            initGL();
183d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
184d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            FloatBuffer triangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length
185d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                    * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
186d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            triangleVertices.put(mTriangleVerticesData).position(0);
187d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
188d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            int texture = loadTexture(R.drawable.large_photo);
189d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            int program = buildProgram(sSimpleVS, sSimpleFS);
190d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
191d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            int attribPosition = glGetAttribLocation(program, "position");
192d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            checkGlError();
193d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
194d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            int attribTexCoords = glGetAttribLocation(program, "texCoords");
195d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            checkGlError();
196d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
197d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            int uniformTexture = glGetUniformLocation(program, "texture");
198d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            checkGlError();
199d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
200d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glBindTexture(GL_TEXTURE_2D, texture);
201d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            checkGlError();
202d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
203d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glUseProgram(program);
204d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            checkGlError();
2058f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
206d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glEnableVertexAttribArray(attribPosition);
207d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            checkGlError();
208d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
209d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glEnableVertexAttribArray(attribTexCoords);
210d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            checkGlError();
211d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
2124c43f66d06fe7f75ad6f9c860cf0936b8ee36082Romain Guy            glUniform1i(uniformTexture, 0);
2134c43f66d06fe7f75ad6f9c860cf0936b8ee36082Romain Guy            checkGlError();
2144c43f66d06fe7f75ad6f9c860cf0936b8ee36082Romain Guy
2154c43f66d06fe7f75ad6f9c860cf0936b8ee36082Romain Guy            // drawQuad
2164c43f66d06fe7f75ad6f9c860cf0936b8ee36082Romain Guy            triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
2174c43f66d06fe7f75ad6f9c860cf0936b8ee36082Romain Guy            glVertexAttribPointer(attribPosition, 3, GL_FLOAT, false,
2184c43f66d06fe7f75ad6f9c860cf0936b8ee36082Romain Guy                    TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
2194c43f66d06fe7f75ad6f9c860cf0936b8ee36082Romain Guy            checkGlError();
2204c43f66d06fe7f75ad6f9c860cf0936b8ee36082Romain Guy
2214c43f66d06fe7f75ad6f9c860cf0936b8ee36082Romain Guy            triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
2224c43f66d06fe7f75ad6f9c860cf0936b8ee36082Romain Guy            glVertexAttribPointer(attribTexCoords, 3, GL_FLOAT, false,
2234c43f66d06fe7f75ad6f9c860cf0936b8ee36082Romain Guy                    TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
2244c43f66d06fe7f75ad6f9c860cf0936b8ee36082Romain Guy            checkGlError();
2254c43f66d06fe7f75ad6f9c860cf0936b8ee36082Romain Guy
2264c43f66d06fe7f75ad6f9c860cf0936b8ee36082Romain Guy            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
227d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            checkGlError();
228d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
2298f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            while (!mFinished) {
2308f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                checkCurrent();
2318f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
232d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                glClear(GL_COLOR_BUFFER_BIT);
233451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy                checkGlError();
2348f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
235d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2364c43f66d06fe7f75ad6f9c860cf0936b8ee36082Romain Guy                checkGlError();
237d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
2388f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
2398f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    throw new RuntimeException("Cannot swap buffers");
2408f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                }
241451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy                checkEglError();
242451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy
2438f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                try {
244a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy                    Thread.sleep(2000);
2458f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                } catch (InterruptedException e) {
2468f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    // Ignore
2478f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                }
2488f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
2498f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
2508f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            finishGL();
2518f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
2528f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
253d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        private int loadTexture(int resource) {
254d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            int[] textures = new int[1];
255d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
256d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glActiveTexture(GL_TEXTURE0);
257d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glGenTextures(1, textures, 0);
258d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            checkGlError();
259d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
260d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            int texture = textures[0];
261d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glBindTexture(GL_TEXTURE_2D, texture);
262d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            checkGlError();
263d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
264d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
265d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
266d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
267d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
268d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
269d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
270d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            Bitmap bitmap = BitmapFactory.decodeResource(mResources, resource);
271d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
272d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap, GL_UNSIGNED_BYTE, 0);
273d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            checkGlError();
274d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
275d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            bitmap.recycle();
276d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
277d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            return texture;
278d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        }
279d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
280786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy        private static int buildProgram(String vertex, String fragment) {
281d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            int vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
282d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            if (vertexShader == 0) return 0;
283d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
284d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            int fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
285d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            if (fragmentShader == 0) return 0;
286d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
287d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            int program = glCreateProgram();
288d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glAttachShader(program, vertexShader);
289d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            checkGlError();
290d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
291d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glAttachShader(program, fragmentShader);
292d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            checkGlError();
293d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
294d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glLinkProgram(program);
295d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            checkGlError();
296d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
297d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            int[] status = new int[1];
298d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glGetProgramiv(program, GL_LINK_STATUS, status, 0);
299d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            if (status[0] != GL_TRUE) {
300d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                String error = glGetProgramInfoLog(program);
301d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                Log.d(LOG_TAG, "Error while linking program:\n" + error);
302d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                glDeleteShader(vertexShader);
303d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                glDeleteShader(fragmentShader);
304d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                glDeleteProgram(program);
305d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                return 0;
306d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            }
307d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
308d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            return program;
309d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        }
310d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
311786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy        private static int buildShader(String source, int type) {
312d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            int shader = glCreateShader(type);
313d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
314d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glShaderSource(shader, source);
315d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            checkGlError();
316d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
317d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glCompileShader(shader);
318d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            checkGlError();
319d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
320d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            int[] status = new int[1];
321d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            glGetShaderiv(shader, GL_COMPILE_STATUS, status, 0);
322d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            if (status[0] != GL_TRUE) {
323d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                String error = glGetShaderInfoLog(shader);
324d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                Log.d(LOG_TAG, "Error while compiling shader:\n" + error);
325d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                glDeleteShader(shader);
326d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy                return 0;
327d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            }
328d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
329d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            return shader;
330d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy        }
331d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy
332451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy        private void checkEglError() {
333451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy            int error = mEgl.eglGetError();
334451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy            if (error != EGL10.EGL_SUCCESS) {
335451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy                Log.w(LOG_TAG, "EGL error = 0x" + Integer.toHexString(error));
336451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy            }
337451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy        }
338451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy
339786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy        private static void checkGlError() {
340d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            int error = glGetError();
341d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy            if (error != GL_NO_ERROR) {
342451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy                Log.w(LOG_TAG, "GL error = 0x" + Integer.toHexString(error));
343451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy            }
344451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy        }
345451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy
3468f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private void finishGL() {
3478f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mEgl.eglDestroyContext(mEglDisplay, mEglContext);
3488f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
3498f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
3508f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
3518f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private void checkCurrent() {
3528f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            if (!mEglContext.equals(mEgl.eglGetCurrentContext()) ||
3538f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    !mEglSurface.equals(mEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) {
3548f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
3558f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    throw new RuntimeException("eglMakeCurrent failed "
356407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                            + GLUtils.getEGLErrorString(mEgl.eglGetError()));
3578f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                }
3588f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
3598f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
3608f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
3618f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private void initGL() {
3628f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mEgl = (EGL10) EGLContext.getEGL();
3638f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
3648f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
3658f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
3668f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                throw new RuntimeException("eglGetDisplay failed "
367407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                        + GLUtils.getEGLErrorString(mEgl.eglGetError()));
3688f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
3698f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
3708f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            int[] version = new int[2];
3718f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            if (!mEgl.eglInitialize(mEglDisplay, version)) {
3728f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                throw new RuntimeException("eglInitialize failed " +
373407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                        GLUtils.getEGLErrorString(mEgl.eglGetError()));
3748f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
3758f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
3768f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mEglConfig = chooseEglConfig();
3778f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            if (mEglConfig == null) {
3788f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                throw new RuntimeException("eglConfig not initialized");
3798f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
3808f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
3818f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mEglContext = createContext(mEgl, mEglDisplay, mEglConfig);
3828f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
3838f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface, null);
3848f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
3858f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
3868f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                int error = mEgl.eglGetError();
3878f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                if (error == EGL10.EGL_BAD_NATIVE_WINDOW) {
3888f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
3898f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    return;
3908f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                }
3918f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                throw new RuntimeException("createWindowSurface failed "
392407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                        + GLUtils.getEGLErrorString(error));
3938f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
3948f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
3958f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
3968f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                throw new RuntimeException("eglMakeCurrent failed "
397407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                        + GLUtils.getEGLErrorString(mEgl.eglGetError()));
3988f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
3998f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
4008f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mGL = mEglContext.getGL();
4018f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
4028f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
4038f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
4048f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
4058f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
4068f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            return egl.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
4078f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
4088f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
4098f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        private EGLConfig chooseEglConfig() {
4108f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            int[] configsCount = new int[1];
4118f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            EGLConfig[] configs = new EGLConfig[1];
4128f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            int[] configSpec = getConfig();
4138f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) {
4148f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                throw new IllegalArgumentException("eglChooseConfig failed " +
415407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                        GLUtils.getEGLErrorString(mEgl.eglGetError()));
4168f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            } else if (configsCount[0] > 0) {
4178f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                return configs[0];
4188f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            }
4198f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            return null;
4208f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
4218f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
422786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy        private static int[] getConfig() {
4238f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            return new int[] {
4248f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
4258f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    EGL10.EGL_RED_SIZE, 8,
4268f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    EGL10.EGL_GREEN_SIZE, 8,
4278f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    EGL10.EGL_BLUE_SIZE, 8,
4288f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    EGL10.EGL_ALPHA_SIZE, 8,
4298f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    EGL10.EGL_DEPTH_SIZE, 0,
4308f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    EGL10.EGL_STENCIL_SIZE, 0,
4318f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                    EGL10.EGL_NONE
4328f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            };
4338f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
4348f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
4358f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        void finish() {
4368f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy            mFinished = true;
4378f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy        }
4388f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    }
4398f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy}
440