1baf412994612ae72a3db9698b1d216078297b48aChris Craik/* 2baf412994612ae72a3db9698b1d216078297b48aChris Craik * Copyright (C) 2015 The Android Open Source Project 3baf412994612ae72a3db9698b1d216078297b48aChris Craik * 4baf412994612ae72a3db9698b1d216078297b48aChris Craik * Licensed under the Apache License, Version 2.0 (the "License"); 5baf412994612ae72a3db9698b1d216078297b48aChris Craik * you may not use this file except in compliance with the License. 6baf412994612ae72a3db9698b1d216078297b48aChris Craik * You may obtain a copy of the License at 7baf412994612ae72a3db9698b1d216078297b48aChris Craik * 8baf412994612ae72a3db9698b1d216078297b48aChris Craik * http://www.apache.org/licenses/LICENSE-2.0 9baf412994612ae72a3db9698b1d216078297b48aChris Craik * 10baf412994612ae72a3db9698b1d216078297b48aChris Craik * Unless required by applicable law or agreed to in writing, software 11baf412994612ae72a3db9698b1d216078297b48aChris Craik * distributed under the License is distributed on an "AS IS" BASIS, 12baf412994612ae72a3db9698b1d216078297b48aChris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13baf412994612ae72a3db9698b1d216078297b48aChris Craik * See the License for the specific language governing permissions and 14baf412994612ae72a3db9698b1d216078297b48aChris Craik * limitations under the License. 15baf412994612ae72a3db9698b1d216078297b48aChris Craik */ 16baf412994612ae72a3db9698b1d216078297b48aChris Craikpackage com.android.test.uibench.opengl; 17baf412994612ae72a3db9698b1d216078297b48aChris Craik 18baf412994612ae72a3db9698b1d216078297b48aChris Craikimport android.content.res.Resources; 19baf412994612ae72a3db9698b1d216078297b48aChris Craikimport android.graphics.Bitmap; 20baf412994612ae72a3db9698b1d216078297b48aChris Craikimport android.graphics.BitmapFactory; 21baf412994612ae72a3db9698b1d216078297b48aChris Craikimport android.graphics.SurfaceTexture; 22baf412994612ae72a3db9698b1d216078297b48aChris Craikimport android.opengl.GLUtils; 23baf412994612ae72a3db9698b1d216078297b48aChris Craikimport android.util.Log; 24baf412994612ae72a3db9698b1d216078297b48aChris Craik 25baf412994612ae72a3db9698b1d216078297b48aChris Craikimport com.android.test.uibench.R; 26baf412994612ae72a3db9698b1d216078297b48aChris Craik 27baf412994612ae72a3db9698b1d216078297b48aChris Craikimport java.nio.ByteBuffer; 28baf412994612ae72a3db9698b1d216078297b48aChris Craikimport java.nio.ByteOrder; 29baf412994612ae72a3db9698b1d216078297b48aChris Craikimport java.nio.FloatBuffer; 30baf412994612ae72a3db9698b1d216078297b48aChris Craik 31baf412994612ae72a3db9698b1d216078297b48aChris Craikimport javax.microedition.khronos.egl.EGL10; 32baf412994612ae72a3db9698b1d216078297b48aChris Craikimport javax.microedition.khronos.egl.EGLConfig; 33baf412994612ae72a3db9698b1d216078297b48aChris Craikimport javax.microedition.khronos.egl.EGLContext; 34baf412994612ae72a3db9698b1d216078297b48aChris Craikimport javax.microedition.khronos.egl.EGLDisplay; 35baf412994612ae72a3db9698b1d216078297b48aChris Craikimport javax.microedition.khronos.egl.EGLSurface; 36baf412994612ae72a3db9698b1d216078297b48aChris Craik 37baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_CLAMP_TO_EDGE; 38baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_COLOR_BUFFER_BIT; 39baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_COMPILE_STATUS; 40baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_FLOAT; 41baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_FRAGMENT_SHADER; 42baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_LINEAR; 43baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_LINK_STATUS; 44baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_NO_ERROR; 45baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_RGBA; 46baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_TEXTURE0; 47baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_TEXTURE_2D; 48baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_TEXTURE_MAG_FILTER; 49baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_TEXTURE_MIN_FILTER; 50baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_TEXTURE_WRAP_S; 51baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_TEXTURE_WRAP_T; 52baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_TRIANGLE_STRIP; 53baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_TRUE; 54baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_UNSIGNED_BYTE; 55baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.GL_VERTEX_SHADER; 56baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glActiveTexture; 57baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glAttachShader; 58baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glBindTexture; 59baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glClear; 60baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glClearColor; 61baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glCompileShader; 62baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glCreateProgram; 63baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glCreateShader; 64baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glDeleteProgram; 65baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glDeleteShader; 66baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glDrawArrays; 67baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glEnableVertexAttribArray; 68baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glGenTextures; 69baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glGetAttribLocation; 70baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glGetError; 71baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glGetProgramInfoLog; 72baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glGetProgramiv; 73baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glGetShaderInfoLog; 74baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glGetShaderiv; 75baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glGetUniformLocation; 76baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glLinkProgram; 77baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glShaderSource; 78baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glTexParameteri; 79baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glUniform1i; 80baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glUseProgram; 81baf412994612ae72a3db9698b1d216078297b48aChris Craikimport static android.opengl.GLES20.glVertexAttribPointer; 82baf412994612ae72a3db9698b1d216078297b48aChris Craik 83baf412994612ae72a3db9698b1d216078297b48aChris Craikpublic class ImageFlipRenderThread extends Thread { 84baf412994612ae72a3db9698b1d216078297b48aChris Craik public static final String LOG_TAG = "GLTextureView"; 85baf412994612ae72a3db9698b1d216078297b48aChris Craik 86baf412994612ae72a3db9698b1d216078297b48aChris Craik static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; 87baf412994612ae72a3db9698b1d216078297b48aChris Craik static final int EGL_OPENGL_ES2_BIT = 4; 88baf412994612ae72a3db9698b1d216078297b48aChris Craik 89baf412994612ae72a3db9698b1d216078297b48aChris Craik private volatile boolean mFinished; 90baf412994612ae72a3db9698b1d216078297b48aChris Craik 91baf412994612ae72a3db9698b1d216078297b48aChris Craik private final Resources mResources; 92baf412994612ae72a3db9698b1d216078297b48aChris Craik private final SurfaceTexture mSurface; 93baf412994612ae72a3db9698b1d216078297b48aChris Craik 94baf412994612ae72a3db9698b1d216078297b48aChris Craik private EGL10 mEgl; 95baf412994612ae72a3db9698b1d216078297b48aChris Craik private EGLDisplay mEglDisplay; 96baf412994612ae72a3db9698b1d216078297b48aChris Craik private EGLConfig mEglConfig; 97baf412994612ae72a3db9698b1d216078297b48aChris Craik private EGLContext mEglContext; 98baf412994612ae72a3db9698b1d216078297b48aChris Craik private EGLSurface mEglSurface; 99baf412994612ae72a3db9698b1d216078297b48aChris Craik 100baf412994612ae72a3db9698b1d216078297b48aChris Craik public ImageFlipRenderThread(Resources resources, SurfaceTexture surface) { 101baf412994612ae72a3db9698b1d216078297b48aChris Craik mResources = resources; 102baf412994612ae72a3db9698b1d216078297b48aChris Craik mSurface = surface; 103baf412994612ae72a3db9698b1d216078297b48aChris Craik } 104baf412994612ae72a3db9698b1d216078297b48aChris Craik 105baf412994612ae72a3db9698b1d216078297b48aChris Craik private static final String sSimpleVS = 106baf412994612ae72a3db9698b1d216078297b48aChris Craik "attribute vec4 position;\n" + 107baf412994612ae72a3db9698b1d216078297b48aChris Craik "attribute vec2 texCoords;\n" + 108baf412994612ae72a3db9698b1d216078297b48aChris Craik "varying vec2 outTexCoords;\n" + 109baf412994612ae72a3db9698b1d216078297b48aChris Craik "\nvoid main(void) {\n" + 110baf412994612ae72a3db9698b1d216078297b48aChris Craik " outTexCoords = texCoords;\n" + 111baf412994612ae72a3db9698b1d216078297b48aChris Craik " gl_Position = position;\n" + 112baf412994612ae72a3db9698b1d216078297b48aChris Craik "}\n\n"; 113baf412994612ae72a3db9698b1d216078297b48aChris Craik private static final String sSimpleFS = 114baf412994612ae72a3db9698b1d216078297b48aChris Craik "precision mediump float;\n\n" + 115baf412994612ae72a3db9698b1d216078297b48aChris Craik "varying vec2 outTexCoords;\n" + 116baf412994612ae72a3db9698b1d216078297b48aChris Craik "uniform sampler2D texture;\n" + 117baf412994612ae72a3db9698b1d216078297b48aChris Craik "\nvoid main(void) {\n" + 118baf412994612ae72a3db9698b1d216078297b48aChris Craik " gl_FragColor = texture2D(texture, outTexCoords);\n" + 119baf412994612ae72a3db9698b1d216078297b48aChris Craik "}\n\n"; 120baf412994612ae72a3db9698b1d216078297b48aChris Craik 121baf412994612ae72a3db9698b1d216078297b48aChris Craik private static final int FLOAT_SIZE_BYTES = 4; 122baf412994612ae72a3db9698b1d216078297b48aChris Craik private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES; 123baf412994612ae72a3db9698b1d216078297b48aChris Craik private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; 124baf412994612ae72a3db9698b1d216078297b48aChris Craik private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; 125baf412994612ae72a3db9698b1d216078297b48aChris Craik private final float[] mTriangleVerticesData = { 126baf412994612ae72a3db9698b1d216078297b48aChris Craik // X, Y, Z, U, V 127baf412994612ae72a3db9698b1d216078297b48aChris Craik -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 128baf412994612ae72a3db9698b1d216078297b48aChris Craik 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 129baf412994612ae72a3db9698b1d216078297b48aChris Craik -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 130baf412994612ae72a3db9698b1d216078297b48aChris Craik 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 131baf412994612ae72a3db9698b1d216078297b48aChris Craik }; 132baf412994612ae72a3db9698b1d216078297b48aChris Craik 133baf412994612ae72a3db9698b1d216078297b48aChris Craik @Override 134baf412994612ae72a3db9698b1d216078297b48aChris Craik public void run() { 135baf412994612ae72a3db9698b1d216078297b48aChris Craik initGL(); 136baf412994612ae72a3db9698b1d216078297b48aChris Craik 137baf412994612ae72a3db9698b1d216078297b48aChris Craik FloatBuffer triangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length 138baf412994612ae72a3db9698b1d216078297b48aChris Craik * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer(); 139baf412994612ae72a3db9698b1d216078297b48aChris Craik triangleVertices.put(mTriangleVerticesData).position(0); 140baf412994612ae72a3db9698b1d216078297b48aChris Craik 141baf412994612ae72a3db9698b1d216078297b48aChris Craik int texture = loadTexture(R.drawable.large_photo); 142baf412994612ae72a3db9698b1d216078297b48aChris Craik int program = buildProgram(sSimpleVS, sSimpleFS); 143baf412994612ae72a3db9698b1d216078297b48aChris Craik 144baf412994612ae72a3db9698b1d216078297b48aChris Craik int attribPosition = glGetAttribLocation(program, "position"); 145baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 146baf412994612ae72a3db9698b1d216078297b48aChris Craik 147baf412994612ae72a3db9698b1d216078297b48aChris Craik int attribTexCoords = glGetAttribLocation(program, "texCoords"); 148baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 149baf412994612ae72a3db9698b1d216078297b48aChris Craik 150baf412994612ae72a3db9698b1d216078297b48aChris Craik int uniformTexture = glGetUniformLocation(program, "texture"); 151baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 152baf412994612ae72a3db9698b1d216078297b48aChris Craik 153baf412994612ae72a3db9698b1d216078297b48aChris Craik glBindTexture(GL_TEXTURE_2D, texture); 154baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 155baf412994612ae72a3db9698b1d216078297b48aChris Craik 156baf412994612ae72a3db9698b1d216078297b48aChris Craik glUseProgram(program); 157baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 158baf412994612ae72a3db9698b1d216078297b48aChris Craik 159baf412994612ae72a3db9698b1d216078297b48aChris Craik glEnableVertexAttribArray(attribPosition); 160baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 161baf412994612ae72a3db9698b1d216078297b48aChris Craik 162baf412994612ae72a3db9698b1d216078297b48aChris Craik glEnableVertexAttribArray(attribTexCoords); 163baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 164baf412994612ae72a3db9698b1d216078297b48aChris Craik 165baf412994612ae72a3db9698b1d216078297b48aChris Craik glUniform1i(uniformTexture, 0); 166baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 167baf412994612ae72a3db9698b1d216078297b48aChris Craik 168baf412994612ae72a3db9698b1d216078297b48aChris Craik // drawQuad 169baf412994612ae72a3db9698b1d216078297b48aChris Craik triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); 170baf412994612ae72a3db9698b1d216078297b48aChris Craik glVertexAttribPointer(attribPosition, 3, GL_FLOAT, false, 171baf412994612ae72a3db9698b1d216078297b48aChris Craik TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); 172baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 173baf412994612ae72a3db9698b1d216078297b48aChris Craik 174baf412994612ae72a3db9698b1d216078297b48aChris Craik triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); 175baf412994612ae72a3db9698b1d216078297b48aChris Craik glVertexAttribPointer(attribTexCoords, 3, GL_FLOAT, false, 176baf412994612ae72a3db9698b1d216078297b48aChris Craik TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); 177baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 178baf412994612ae72a3db9698b1d216078297b48aChris Craik 179baf412994612ae72a3db9698b1d216078297b48aChris Craik glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 180baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 181baf412994612ae72a3db9698b1d216078297b48aChris Craik 182baf412994612ae72a3db9698b1d216078297b48aChris Craik while (!mFinished) { 183baf412994612ae72a3db9698b1d216078297b48aChris Craik checkCurrent(); 184baf412994612ae72a3db9698b1d216078297b48aChris Craik 185baf412994612ae72a3db9698b1d216078297b48aChris Craik glClear(GL_COLOR_BUFFER_BIT); 186baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 187baf412994612ae72a3db9698b1d216078297b48aChris Craik 188baf412994612ae72a3db9698b1d216078297b48aChris Craik glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 189baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 190baf412994612ae72a3db9698b1d216078297b48aChris Craik 191baf412994612ae72a3db9698b1d216078297b48aChris Craik if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) { 192baf412994612ae72a3db9698b1d216078297b48aChris Craik throw new RuntimeException("Cannot swap buffers"); 193baf412994612ae72a3db9698b1d216078297b48aChris Craik } 194baf412994612ae72a3db9698b1d216078297b48aChris Craik checkEglError(); 195baf412994612ae72a3db9698b1d216078297b48aChris Craik 196baf412994612ae72a3db9698b1d216078297b48aChris Craik try { 197baf412994612ae72a3db9698b1d216078297b48aChris Craik Thread.sleep(2000); 198baf412994612ae72a3db9698b1d216078297b48aChris Craik } catch (InterruptedException e) { 199baf412994612ae72a3db9698b1d216078297b48aChris Craik // Ignore 200baf412994612ae72a3db9698b1d216078297b48aChris Craik } 201baf412994612ae72a3db9698b1d216078297b48aChris Craik } 202baf412994612ae72a3db9698b1d216078297b48aChris Craik 203baf412994612ae72a3db9698b1d216078297b48aChris Craik finishGL(); 204baf412994612ae72a3db9698b1d216078297b48aChris Craik } 205baf412994612ae72a3db9698b1d216078297b48aChris Craik 206baf412994612ae72a3db9698b1d216078297b48aChris Craik private int loadTexture(int resource) { 207baf412994612ae72a3db9698b1d216078297b48aChris Craik int[] textures = new int[1]; 208baf412994612ae72a3db9698b1d216078297b48aChris Craik 209baf412994612ae72a3db9698b1d216078297b48aChris Craik glActiveTexture(GL_TEXTURE0); 210baf412994612ae72a3db9698b1d216078297b48aChris Craik glGenTextures(1, textures, 0); 211baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 212baf412994612ae72a3db9698b1d216078297b48aChris Craik 213baf412994612ae72a3db9698b1d216078297b48aChris Craik int texture = textures[0]; 214baf412994612ae72a3db9698b1d216078297b48aChris Craik glBindTexture(GL_TEXTURE_2D, texture); 215baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 216baf412994612ae72a3db9698b1d216078297b48aChris Craik 217baf412994612ae72a3db9698b1d216078297b48aChris Craik glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 218baf412994612ae72a3db9698b1d216078297b48aChris Craik glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 219baf412994612ae72a3db9698b1d216078297b48aChris Craik 220baf412994612ae72a3db9698b1d216078297b48aChris Craik glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 221baf412994612ae72a3db9698b1d216078297b48aChris Craik glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 222baf412994612ae72a3db9698b1d216078297b48aChris Craik 223baf412994612ae72a3db9698b1d216078297b48aChris Craik Bitmap bitmap = BitmapFactory.decodeResource(mResources, resource); 224baf412994612ae72a3db9698b1d216078297b48aChris Craik 225baf412994612ae72a3db9698b1d216078297b48aChris Craik GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap, GL_UNSIGNED_BYTE, 0); 226baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 227baf412994612ae72a3db9698b1d216078297b48aChris Craik 228baf412994612ae72a3db9698b1d216078297b48aChris Craik bitmap.recycle(); 229baf412994612ae72a3db9698b1d216078297b48aChris Craik 230baf412994612ae72a3db9698b1d216078297b48aChris Craik return texture; 231baf412994612ae72a3db9698b1d216078297b48aChris Craik } 232baf412994612ae72a3db9698b1d216078297b48aChris Craik 233baf412994612ae72a3db9698b1d216078297b48aChris Craik private static int buildProgram(String vertex, String fragment) { 234baf412994612ae72a3db9698b1d216078297b48aChris Craik int vertexShader = buildShader(vertex, GL_VERTEX_SHADER); 235baf412994612ae72a3db9698b1d216078297b48aChris Craik if (vertexShader == 0) return 0; 236baf412994612ae72a3db9698b1d216078297b48aChris Craik 237baf412994612ae72a3db9698b1d216078297b48aChris Craik int fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER); 238baf412994612ae72a3db9698b1d216078297b48aChris Craik if (fragmentShader == 0) return 0; 239baf412994612ae72a3db9698b1d216078297b48aChris Craik 240baf412994612ae72a3db9698b1d216078297b48aChris Craik int program = glCreateProgram(); 241baf412994612ae72a3db9698b1d216078297b48aChris Craik glAttachShader(program, vertexShader); 242baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 243baf412994612ae72a3db9698b1d216078297b48aChris Craik 244baf412994612ae72a3db9698b1d216078297b48aChris Craik glAttachShader(program, fragmentShader); 245baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 246baf412994612ae72a3db9698b1d216078297b48aChris Craik 247baf412994612ae72a3db9698b1d216078297b48aChris Craik glLinkProgram(program); 248baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 249baf412994612ae72a3db9698b1d216078297b48aChris Craik 250baf412994612ae72a3db9698b1d216078297b48aChris Craik int[] status = new int[1]; 251baf412994612ae72a3db9698b1d216078297b48aChris Craik glGetProgramiv(program, GL_LINK_STATUS, status, 0); 252baf412994612ae72a3db9698b1d216078297b48aChris Craik if (status[0] != GL_TRUE) { 253baf412994612ae72a3db9698b1d216078297b48aChris Craik String error = glGetProgramInfoLog(program); 254baf412994612ae72a3db9698b1d216078297b48aChris Craik Log.d(LOG_TAG, "Error while linking program:\n" + error); 255baf412994612ae72a3db9698b1d216078297b48aChris Craik glDeleteShader(vertexShader); 256baf412994612ae72a3db9698b1d216078297b48aChris Craik glDeleteShader(fragmentShader); 257baf412994612ae72a3db9698b1d216078297b48aChris Craik glDeleteProgram(program); 258baf412994612ae72a3db9698b1d216078297b48aChris Craik return 0; 259baf412994612ae72a3db9698b1d216078297b48aChris Craik } 260baf412994612ae72a3db9698b1d216078297b48aChris Craik 261baf412994612ae72a3db9698b1d216078297b48aChris Craik return program; 262baf412994612ae72a3db9698b1d216078297b48aChris Craik } 263baf412994612ae72a3db9698b1d216078297b48aChris Craik 264baf412994612ae72a3db9698b1d216078297b48aChris Craik private static int buildShader(String source, int type) { 265baf412994612ae72a3db9698b1d216078297b48aChris Craik int shader = glCreateShader(type); 266baf412994612ae72a3db9698b1d216078297b48aChris Craik 267baf412994612ae72a3db9698b1d216078297b48aChris Craik glShaderSource(shader, source); 268baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 269baf412994612ae72a3db9698b1d216078297b48aChris Craik 270baf412994612ae72a3db9698b1d216078297b48aChris Craik glCompileShader(shader); 271baf412994612ae72a3db9698b1d216078297b48aChris Craik checkGlError(); 272baf412994612ae72a3db9698b1d216078297b48aChris Craik 273baf412994612ae72a3db9698b1d216078297b48aChris Craik int[] status = new int[1]; 274baf412994612ae72a3db9698b1d216078297b48aChris Craik glGetShaderiv(shader, GL_COMPILE_STATUS, status, 0); 275baf412994612ae72a3db9698b1d216078297b48aChris Craik if (status[0] != GL_TRUE) { 276baf412994612ae72a3db9698b1d216078297b48aChris Craik String error = glGetShaderInfoLog(shader); 277baf412994612ae72a3db9698b1d216078297b48aChris Craik Log.d(LOG_TAG, "Error while compiling shader:\n" + error); 278baf412994612ae72a3db9698b1d216078297b48aChris Craik glDeleteShader(shader); 279baf412994612ae72a3db9698b1d216078297b48aChris Craik return 0; 280baf412994612ae72a3db9698b1d216078297b48aChris Craik } 281baf412994612ae72a3db9698b1d216078297b48aChris Craik 282baf412994612ae72a3db9698b1d216078297b48aChris Craik return shader; 283baf412994612ae72a3db9698b1d216078297b48aChris Craik } 284baf412994612ae72a3db9698b1d216078297b48aChris Craik 285baf412994612ae72a3db9698b1d216078297b48aChris Craik private void checkEglError() { 286baf412994612ae72a3db9698b1d216078297b48aChris Craik int error = mEgl.eglGetError(); 287baf412994612ae72a3db9698b1d216078297b48aChris Craik if (error != EGL10.EGL_SUCCESS) { 288baf412994612ae72a3db9698b1d216078297b48aChris Craik Log.w(LOG_TAG, "EGL error = 0x" + Integer.toHexString(error)); 289baf412994612ae72a3db9698b1d216078297b48aChris Craik } 290baf412994612ae72a3db9698b1d216078297b48aChris Craik } 291baf412994612ae72a3db9698b1d216078297b48aChris Craik 292baf412994612ae72a3db9698b1d216078297b48aChris Craik private static void checkGlError() { 293baf412994612ae72a3db9698b1d216078297b48aChris Craik int error = glGetError(); 294baf412994612ae72a3db9698b1d216078297b48aChris Craik if (error != GL_NO_ERROR) { 295baf412994612ae72a3db9698b1d216078297b48aChris Craik Log.w(LOG_TAG, "GL error = 0x" + Integer.toHexString(error)); 296baf412994612ae72a3db9698b1d216078297b48aChris Craik } 297baf412994612ae72a3db9698b1d216078297b48aChris Craik } 298baf412994612ae72a3db9698b1d216078297b48aChris Craik 299baf412994612ae72a3db9698b1d216078297b48aChris Craik private void finishGL() { 300baf412994612ae72a3db9698b1d216078297b48aChris Craik mEgl.eglDestroyContext(mEglDisplay, mEglContext); 301baf412994612ae72a3db9698b1d216078297b48aChris Craik mEgl.eglDestroySurface(mEglDisplay, mEglSurface); 302baf412994612ae72a3db9698b1d216078297b48aChris Craik } 303baf412994612ae72a3db9698b1d216078297b48aChris Craik 304baf412994612ae72a3db9698b1d216078297b48aChris Craik private void checkCurrent() { 305baf412994612ae72a3db9698b1d216078297b48aChris Craik if (!mEglContext.equals(mEgl.eglGetCurrentContext()) || 306baf412994612ae72a3db9698b1d216078297b48aChris Craik !mEglSurface.equals(mEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) { 307baf412994612ae72a3db9698b1d216078297b48aChris Craik if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { 308baf412994612ae72a3db9698b1d216078297b48aChris Craik throw new RuntimeException("eglMakeCurrent failed " 309baf412994612ae72a3db9698b1d216078297b48aChris Craik + GLUtils.getEGLErrorString(mEgl.eglGetError())); 310baf412994612ae72a3db9698b1d216078297b48aChris Craik } 311baf412994612ae72a3db9698b1d216078297b48aChris Craik } 312baf412994612ae72a3db9698b1d216078297b48aChris Craik } 313baf412994612ae72a3db9698b1d216078297b48aChris Craik 314baf412994612ae72a3db9698b1d216078297b48aChris Craik private void initGL() { 315baf412994612ae72a3db9698b1d216078297b48aChris Craik mEgl = (EGL10) EGLContext.getEGL(); 316baf412994612ae72a3db9698b1d216078297b48aChris Craik 317baf412994612ae72a3db9698b1d216078297b48aChris Craik mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); 318baf412994612ae72a3db9698b1d216078297b48aChris Craik if (mEglDisplay == EGL10.EGL_NO_DISPLAY) { 319baf412994612ae72a3db9698b1d216078297b48aChris Craik throw new RuntimeException("eglGetDisplay failed " 320baf412994612ae72a3db9698b1d216078297b48aChris Craik + GLUtils.getEGLErrorString(mEgl.eglGetError())); 321baf412994612ae72a3db9698b1d216078297b48aChris Craik } 322baf412994612ae72a3db9698b1d216078297b48aChris Craik 323baf412994612ae72a3db9698b1d216078297b48aChris Craik int[] version = new int[2]; 324baf412994612ae72a3db9698b1d216078297b48aChris Craik if (!mEgl.eglInitialize(mEglDisplay, version)) { 325baf412994612ae72a3db9698b1d216078297b48aChris Craik throw new RuntimeException("eglInitialize failed " + 326baf412994612ae72a3db9698b1d216078297b48aChris Craik GLUtils.getEGLErrorString(mEgl.eglGetError())); 327baf412994612ae72a3db9698b1d216078297b48aChris Craik } 328baf412994612ae72a3db9698b1d216078297b48aChris Craik 329baf412994612ae72a3db9698b1d216078297b48aChris Craik mEglConfig = chooseEglConfig(); 330baf412994612ae72a3db9698b1d216078297b48aChris Craik if (mEglConfig == null) { 331baf412994612ae72a3db9698b1d216078297b48aChris Craik throw new RuntimeException("eglConfig not initialized"); 332baf412994612ae72a3db9698b1d216078297b48aChris Craik } 333baf412994612ae72a3db9698b1d216078297b48aChris Craik 334baf412994612ae72a3db9698b1d216078297b48aChris Craik mEglContext = createContext(mEgl, mEglDisplay, mEglConfig); 335baf412994612ae72a3db9698b1d216078297b48aChris Craik 336baf412994612ae72a3db9698b1d216078297b48aChris Craik mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface, null); 337baf412994612ae72a3db9698b1d216078297b48aChris Craik 338baf412994612ae72a3db9698b1d216078297b48aChris Craik if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) { 339baf412994612ae72a3db9698b1d216078297b48aChris Craik int error = mEgl.eglGetError(); 340baf412994612ae72a3db9698b1d216078297b48aChris Craik if (error == EGL10.EGL_BAD_NATIVE_WINDOW) { 341baf412994612ae72a3db9698b1d216078297b48aChris Craik Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW."); 342baf412994612ae72a3db9698b1d216078297b48aChris Craik return; 343baf412994612ae72a3db9698b1d216078297b48aChris Craik } 344baf412994612ae72a3db9698b1d216078297b48aChris Craik throw new RuntimeException("createWindowSurface failed " 345baf412994612ae72a3db9698b1d216078297b48aChris Craik + GLUtils.getEGLErrorString(error)); 346baf412994612ae72a3db9698b1d216078297b48aChris Craik } 347baf412994612ae72a3db9698b1d216078297b48aChris Craik 348baf412994612ae72a3db9698b1d216078297b48aChris Craik if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { 349baf412994612ae72a3db9698b1d216078297b48aChris Craik throw new RuntimeException("eglMakeCurrent failed " 350baf412994612ae72a3db9698b1d216078297b48aChris Craik + GLUtils.getEGLErrorString(mEgl.eglGetError())); 351baf412994612ae72a3db9698b1d216078297b48aChris Craik } 352baf412994612ae72a3db9698b1d216078297b48aChris Craik } 353baf412994612ae72a3db9698b1d216078297b48aChris Craik 354baf412994612ae72a3db9698b1d216078297b48aChris Craik 355baf412994612ae72a3db9698b1d216078297b48aChris Craik EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) { 356baf412994612ae72a3db9698b1d216078297b48aChris Craik int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE}; 357baf412994612ae72a3db9698b1d216078297b48aChris Craik return egl.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list); 358baf412994612ae72a3db9698b1d216078297b48aChris Craik } 359baf412994612ae72a3db9698b1d216078297b48aChris Craik 360baf412994612ae72a3db9698b1d216078297b48aChris Craik private EGLConfig chooseEglConfig() { 361baf412994612ae72a3db9698b1d216078297b48aChris Craik int[] configsCount = new int[1]; 362baf412994612ae72a3db9698b1d216078297b48aChris Craik EGLConfig[] configs = new EGLConfig[1]; 363baf412994612ae72a3db9698b1d216078297b48aChris Craik int[] configSpec = getConfig(); 364baf412994612ae72a3db9698b1d216078297b48aChris Craik if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) { 365baf412994612ae72a3db9698b1d216078297b48aChris Craik throw new IllegalArgumentException("eglChooseConfig failed " + 366baf412994612ae72a3db9698b1d216078297b48aChris Craik GLUtils.getEGLErrorString(mEgl.eglGetError())); 367baf412994612ae72a3db9698b1d216078297b48aChris Craik } else if (configsCount[0] > 0) { 368baf412994612ae72a3db9698b1d216078297b48aChris Craik return configs[0]; 369baf412994612ae72a3db9698b1d216078297b48aChris Craik } 370baf412994612ae72a3db9698b1d216078297b48aChris Craik return null; 371baf412994612ae72a3db9698b1d216078297b48aChris Craik } 372baf412994612ae72a3db9698b1d216078297b48aChris Craik 373baf412994612ae72a3db9698b1d216078297b48aChris Craik private static int[] getConfig() { 374baf412994612ae72a3db9698b1d216078297b48aChris Craik return new int[]{ 375baf412994612ae72a3db9698b1d216078297b48aChris Craik EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 376baf412994612ae72a3db9698b1d216078297b48aChris Craik EGL10.EGL_RED_SIZE, 8, 377baf412994612ae72a3db9698b1d216078297b48aChris Craik EGL10.EGL_GREEN_SIZE, 8, 378baf412994612ae72a3db9698b1d216078297b48aChris Craik EGL10.EGL_BLUE_SIZE, 8, 379baf412994612ae72a3db9698b1d216078297b48aChris Craik EGL10.EGL_ALPHA_SIZE, 8, 380baf412994612ae72a3db9698b1d216078297b48aChris Craik EGL10.EGL_DEPTH_SIZE, 0, 381baf412994612ae72a3db9698b1d216078297b48aChris Craik EGL10.EGL_STENCIL_SIZE, 0, 382baf412994612ae72a3db9698b1d216078297b48aChris Craik EGL10.EGL_NONE 383baf412994612ae72a3db9698b1d216078297b48aChris Craik }; 384baf412994612ae72a3db9698b1d216078297b48aChris Craik } 385baf412994612ae72a3db9698b1d216078297b48aChris Craik 386baf412994612ae72a3db9698b1d216078297b48aChris Craik public void finish() { 387baf412994612ae72a3db9698b1d216078297b48aChris Craik mFinished = true; 388baf412994612ae72a3db9698b1d216078297b48aChris Craik } 389baf412994612ae72a3db9698b1d216078297b48aChris Craik} 390