GLTextureViewActivity.java revision 402f05530352f34d5320c2d23be43c274d97c4e2
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; 288f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.util.Log; 298f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.view.Gravity; 308f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.view.TextureView; 318f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.view.View; 32d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guyimport android.view.ViewGroup; 338f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport android.widget.FrameLayout; 348f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 358f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport javax.microedition.khronos.egl.EGL10; 368f0095cd33558e9cc8a440047908e53b68906f5fRomain Guyimport javax.microedition.khronos.egl.EGL11; 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; 43ec19b4a764d512091a780fc93ced567dfbf80914Romain Guyimport java.io.FileNotFoundException; 44ec19b4a764d512091a780fc93ced567dfbf80914Romain Guyimport java.io.FileOutputStream; 45ec19b4a764d512091a780fc93ced567dfbf80914Romain Guyimport java.io.IOException; 46d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guyimport java.nio.ByteBuffer; 47d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guyimport java.nio.ByteOrder; 48d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guyimport java.nio.FloatBuffer; 49d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 50d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guyimport static android.opengl.GLES20.*; 51d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 528f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy@SuppressWarnings({"UnusedDeclaration"}) 538f0095cd33558e9cc8a440047908e53b68906f5fRomain Guypublic class GLTextureViewActivity extends Activity implements TextureView.SurfaceTextureListener { 548f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy private RenderThread mRenderThread; 558f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy private TextureView mTextureView; 568f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 578f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy @Override 588f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy protected void onCreate(Bundle savedInstanceState) { 598f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy super.onCreate(savedInstanceState); 608f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 618f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy mTextureView = new TextureView(this); 628f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy mTextureView.setSurfaceTextureListener(this); 63ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy mTextureView.setOnClickListener(new View.OnClickListener() { 64ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy @Override 65ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy public void onClick(View v) { 66cfacbeadffb5dccbf0434d9c05b19430a5237c3bRomain Guy Bitmap b = mTextureView.getBitmap(800, 800); 67ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy BufferedOutputStream out = null; 68ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy try { 69ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy out = new BufferedOutputStream(new FileOutputStream("/sdcard/out.png")); 70ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy b.compress(Bitmap.CompressFormat.PNG, 100, out); 71ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy } catch (FileNotFoundException e) { 72ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy e.printStackTrace(); 73ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy } finally { 74ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy if (out != null) try { 75ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy out.close(); 76ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy } catch (IOException e) { 77ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy e.printStackTrace(); 78ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy } 79ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy } 80ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy } 81ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy }); 828f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 83d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy setContentView(mTextureView, new FrameLayout.LayoutParams( 84d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 85d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy Gravity.CENTER)); 868f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 878f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 888f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy @Override 89451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 90d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy mRenderThread = new RenderThread(getResources(), surface); 918f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy mRenderThread.start(); 928f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 938f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy mTextureView.setCameraDistance(5000); 948f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 958f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy ObjectAnimator animator = ObjectAnimator.ofFloat(mTextureView, "rotationY", 0.0f, 360.0f); 968f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy animator.setRepeatMode(ObjectAnimator.REVERSE); 978f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy animator.setRepeatCount(ObjectAnimator.INFINITE); 988f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy animator.setDuration(4000); 998f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 1008f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy @Override 1018f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy public void onAnimationUpdate(ValueAnimator animation) { 102ec19b4a764d512091a780fc93ced567dfbf80914Romain Guy mTextureView.invalidate(); 1038f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 1048f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy }); 1058f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy animator.start(); 1068f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 1078f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 1088f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy @Override 1098f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 1108f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 1118f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 112451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy @Override 113402f05530352f34d5320c2d23be43c274d97c4e2Grace Kloba public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 114451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy mRenderThread.finish(); 115451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy try { 116451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy mRenderThread.join(); 117451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy } catch (InterruptedException e) { 118451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy Log.e(RenderThread.LOG_TAG, "Could not wait for render thread"); 119451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy } 120402f05530352f34d5320c2d23be43c274d97c4e2Grace Kloba return true; 121451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy } 122451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy 123cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba @Override 124cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba public void onSurfaceTextureUpdated(SurfaceTexture surface) { 125cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba } 126cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba 1278f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy private static class RenderThread extends Thread { 1288f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy private static final String LOG_TAG = "GLTextureView"; 1298f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 1308f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; 1318f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy static final int EGL_OPENGL_ES2_BIT = 4; 1328f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 1338f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy private volatile boolean mFinished; 1348f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 135d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy private final Resources mResources; 136d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy private final SurfaceTexture mSurface; 1378f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 1388f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy private EGL10 mEgl; 1398f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy private EGLDisplay mEglDisplay; 1408f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy private EGLConfig mEglConfig; 1418f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy private EGLContext mEglContext; 1428f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy private EGLSurface mEglSurface; 1438f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy private GL mGL; 1448f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 145d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy RenderThread(Resources resources, SurfaceTexture surface) { 146d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy mResources = resources; 1478f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy mSurface = surface; 1488f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 1498f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 150d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy private static final String sSimpleVS = 151d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy "attribute vec4 position;\n" + 152d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy "attribute vec2 texCoords;\n" + 153d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy "varying vec2 outTexCoords;\n" + 154d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy "\nvoid main(void) {\n" + 155d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy " outTexCoords = texCoords;\n" + 156d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy " gl_Position = position;\n" + 157d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy "}\n\n"; 158d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy private static final String sSimpleFS = 159d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy "precision mediump float;\n\n" + 160d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy "varying vec2 outTexCoords;\n" + 161d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy "uniform sampler2D texture;\n" + 162d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy "\nvoid main(void) {\n" + 163d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy " gl_FragColor = texture2D(texture, outTexCoords);\n" + 164d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy "}\n\n"; 165d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 166d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy private static final int FLOAT_SIZE_BYTES = 4; 167d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES; 168d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; 169d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; 170d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy private final float[] mTriangleVerticesData = { 171d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy // X, Y, Z, U, V 172d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy -1.0f, -1.0f, 0, 0.f, 0.f, 173d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 1.0f, -1.0f, 0, 1.f, 0.f, 174d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy -1.0f, 1.0f, 0, 0.f, 1.f, 175d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 1.0f, 1.0f, 0, 1.f, 1.f, 176d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy }; 177d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 1788f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy @Override 1798f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy public void run() { 1808f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy initGL(); 181d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 182d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy FloatBuffer triangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length 183d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer(); 184d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy triangleVertices.put(mTriangleVerticesData).position(0); 185d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 186d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy int texture = loadTexture(R.drawable.large_photo); 187d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy int program = buildProgram(sSimpleVS, sSimpleFS); 188d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 189d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy int attribPosition = glGetAttribLocation(program, "position"); 190d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy checkGlError(); 191d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 192d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy int attribTexCoords = glGetAttribLocation(program, "texCoords"); 193d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy checkGlError(); 194d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 195d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy int uniformTexture = glGetUniformLocation(program, "texture"); 196d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy checkGlError(); 197d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 198d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glBindTexture(GL_TEXTURE_2D, texture); 199d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy checkGlError(); 200d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 201d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glUseProgram(program); 202d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy checkGlError(); 2038f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 204d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glEnableVertexAttribArray(attribPosition); 205d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy checkGlError(); 206d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 207d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glEnableVertexAttribArray(attribTexCoords); 208d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy checkGlError(); 209d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 210d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glUniform1i(texture, 0); 211d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy checkGlError(); 212d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 2138f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy while (!mFinished) { 2148f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy checkCurrent(); 2158f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 216451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy Log.d(LOG_TAG, "Rendering frame"); 217451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy 218d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 219451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy checkGlError(); 2208f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 221d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glClear(GL_COLOR_BUFFER_BIT); 222451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy checkGlError(); 2238f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 224d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy // drawQuad 225d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); 226d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glVertexAttribPointer(attribPosition, 3, GL_FLOAT, false, 227d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); 228d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 229d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); 230d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glVertexAttribPointer(attribTexCoords, 3, GL_FLOAT, false, 231d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); 232d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 233d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 234d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 2358f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) { 2368f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy throw new RuntimeException("Cannot swap buffers"); 2378f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 238451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy checkEglError(); 239451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy 2408f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy try { 2418f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy Thread.sleep(20); 2428f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } catch (InterruptedException e) { 2438f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy // Ignore 2448f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 2458f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 2468f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 2478f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy finishGL(); 2488f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 2498f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 250d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy private int loadTexture(int resource) { 251d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy int[] textures = new int[1]; 252d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 253d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glActiveTexture(GL_TEXTURE0); 254d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glGenTextures(1, textures, 0); 255d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy checkGlError(); 256d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 257d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy int texture = textures[0]; 258d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glBindTexture(GL_TEXTURE_2D, texture); 259d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy checkGlError(); 260d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 261d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 262d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 263d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 264d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 265d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 266d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 267d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy Bitmap bitmap = BitmapFactory.decodeResource(mResources, resource); 268d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 269d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap, GL_UNSIGNED_BYTE, 0); 270d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy checkGlError(); 271d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 272d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy bitmap.recycle(); 273d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 274d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy return texture; 275d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy } 276d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 277d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy private int buildProgram(String vertex, String fragment) { 278d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy int vertexShader = buildShader(vertex, GL_VERTEX_SHADER); 279d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy if (vertexShader == 0) return 0; 280d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 281d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy int fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER); 282d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy if (fragmentShader == 0) return 0; 283d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 284d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy int program = glCreateProgram(); 285d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glAttachShader(program, vertexShader); 286d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy checkGlError(); 287d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 288d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glAttachShader(program, fragmentShader); 289d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy checkGlError(); 290d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 291d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glLinkProgram(program); 292d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy checkGlError(); 293d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 294d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy int[] status = new int[1]; 295d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glGetProgramiv(program, GL_LINK_STATUS, status, 0); 296d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy if (status[0] != GL_TRUE) { 297d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy String error = glGetProgramInfoLog(program); 298d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy Log.d(LOG_TAG, "Error while linking program:\n" + error); 299d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glDeleteShader(vertexShader); 300d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glDeleteShader(fragmentShader); 301d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glDeleteProgram(program); 302d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy return 0; 303d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy } 304d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 305d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy return program; 306d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy } 307d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 308d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy private int buildShader(String source, int type) { 309d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy int shader = glCreateShader(type); 310d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 311d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glShaderSource(shader, source); 312d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy checkGlError(); 313d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 314d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glCompileShader(shader); 315d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy checkGlError(); 316d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 317d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy int[] status = new int[1]; 318d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glGetShaderiv(shader, GL_COMPILE_STATUS, status, 0); 319d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy if (status[0] != GL_TRUE) { 320d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy String error = glGetShaderInfoLog(shader); 321d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy Log.d(LOG_TAG, "Error while compiling shader:\n" + error); 322d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy glDeleteShader(shader); 323d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy return 0; 324d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy } 325d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 326d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy return shader; 327d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy } 328d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy 329451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy private void checkEglError() { 330451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy int error = mEgl.eglGetError(); 331451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy if (error != EGL10.EGL_SUCCESS) { 332451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy Log.w(LOG_TAG, "EGL error = 0x" + Integer.toHexString(error)); 333451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy } 334451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy } 335451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy 336451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy private void checkGlError() { 337d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy int error = glGetError(); 338d0d07059943603c8d20ab9e2ee31ba5c7d477fbaRomain Guy if (error != GL_NO_ERROR) { 339451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy Log.w(LOG_TAG, "GL error = 0x" + Integer.toHexString(error)); 340451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy } 341451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy } 342451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy 3438f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy private void finishGL() { 3448f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy mEgl.eglDestroyContext(mEglDisplay, mEglContext); 3458f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy mEgl.eglDestroySurface(mEglDisplay, mEglSurface); 3468f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 3478f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 3488f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy private void checkCurrent() { 3498f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy if (!mEglContext.equals(mEgl.eglGetCurrentContext()) || 3508f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy !mEglSurface.equals(mEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) { 3518f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { 3528f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy throw new RuntimeException("eglMakeCurrent failed " 3538f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy + getEGLErrorString(mEgl.eglGetError())); 3548f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 3558f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 3568f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 3578f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 3588f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy private void initGL() { 3598f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy mEgl = (EGL10) EGLContext.getEGL(); 3608f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 3618f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); 3628f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy if (mEglDisplay == EGL10.EGL_NO_DISPLAY) { 3638f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy throw new RuntimeException("eglGetDisplay failed " 3648f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy + getEGLErrorString(mEgl.eglGetError())); 3658f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 3668f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 3678f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy int[] version = new int[2]; 3688f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy if (!mEgl.eglInitialize(mEglDisplay, version)) { 3698f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy throw new RuntimeException("eglInitialize failed " + 3708f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy getEGLErrorString(mEgl.eglGetError())); 3718f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 3728f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 3738f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy mEglConfig = chooseEglConfig(); 3748f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy if (mEglConfig == null) { 3758f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy throw new RuntimeException("eglConfig not initialized"); 3768f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 3778f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 3788f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy mEglContext = createContext(mEgl, mEglDisplay, mEglConfig); 3798f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 3808f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface, null); 3818f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 3828f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) { 3838f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy int error = mEgl.eglGetError(); 3848f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy if (error == EGL10.EGL_BAD_NATIVE_WINDOW) { 3858f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW."); 3868f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return; 3878f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 3888f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy throw new RuntimeException("createWindowSurface failed " 3898f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy + getEGLErrorString(error)); 3908f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 3918f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 3928f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { 3938f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy throw new RuntimeException("eglMakeCurrent failed " 3948f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy + getEGLErrorString(mEgl.eglGetError())); 3958f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 3968f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 3978f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy mGL = mEglContext.getGL(); 3988f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 3998f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 4008f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 4018f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) { 4028f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; 4038f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return egl.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list); 4048f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 4058f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 4068f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy private EGLConfig chooseEglConfig() { 4078f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy int[] configsCount = new int[1]; 4088f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy EGLConfig[] configs = new EGLConfig[1]; 4098f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy int[] configSpec = getConfig(); 4108f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) { 4118f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy throw new IllegalArgumentException("eglChooseConfig failed " + 4128f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy getEGLErrorString(mEgl.eglGetError())); 4138f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } else if (configsCount[0] > 0) { 4148f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return configs[0]; 4158f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 4168f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return null; 4178f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 4188f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 4198f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy private int[] getConfig() { 4208f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return new int[] { 4218f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 4228f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy EGL10.EGL_RED_SIZE, 8, 4238f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy EGL10.EGL_GREEN_SIZE, 8, 4248f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy EGL10.EGL_BLUE_SIZE, 8, 4258f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy EGL10.EGL_ALPHA_SIZE, 8, 4268f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy EGL10.EGL_DEPTH_SIZE, 0, 4278f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy EGL10.EGL_STENCIL_SIZE, 0, 4288f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy EGL10.EGL_NONE 4298f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy }; 4308f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 4318f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 4328f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy static String getEGLErrorString(int error) { 4338f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy switch (error) { 4348f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy case EGL10.EGL_SUCCESS: 4358f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return "EGL_SUCCESS"; 4368f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy case EGL10.EGL_NOT_INITIALIZED: 4378f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return "EGL_NOT_INITIALIZED"; 4388f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy case EGL10.EGL_BAD_ACCESS: 4398f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return "EGL_BAD_ACCESS"; 4408f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy case EGL10.EGL_BAD_ALLOC: 4418f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return "EGL_BAD_ALLOC"; 4428f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy case EGL10.EGL_BAD_ATTRIBUTE: 4438f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return "EGL_BAD_ATTRIBUTE"; 4448f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy case EGL10.EGL_BAD_CONFIG: 4458f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return "EGL_BAD_CONFIG"; 4468f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy case EGL10.EGL_BAD_CONTEXT: 4478f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return "EGL_BAD_CONTEXT"; 4488f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy case EGL10.EGL_BAD_CURRENT_SURFACE: 4498f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return "EGL_BAD_CURRENT_SURFACE"; 4508f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy case EGL10.EGL_BAD_DISPLAY: 4518f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return "EGL_BAD_DISPLAY"; 4528f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy case EGL10.EGL_BAD_MATCH: 4538f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return "EGL_BAD_MATCH"; 4548f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy case EGL10.EGL_BAD_NATIVE_PIXMAP: 4558f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return "EGL_BAD_NATIVE_PIXMAP"; 4568f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy case EGL10.EGL_BAD_NATIVE_WINDOW: 4578f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return "EGL_BAD_NATIVE_WINDOW"; 4588f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy case EGL10.EGL_BAD_PARAMETER: 4598f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return "EGL_BAD_PARAMETER"; 4608f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy case EGL10.EGL_BAD_SURFACE: 4618f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return "EGL_BAD_SURFACE"; 4628f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy case EGL11.EGL_CONTEXT_LOST: 4638f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return "EGL_CONTEXT_LOST"; 4648f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy default: 4658f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy return "0x" + Integer.toHexString(error); 4668f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 4678f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 4688f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 4698f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy void finish() { 4708f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy mFinished = true; 4718f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 4728f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 4738f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy} 474