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