1430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd// Copyright 2011 Google Inc. All Rights Reserved. 2430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 3430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Doddpackage com.example.android.videochatcameratest; 4430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 5430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Doddimport android.content.Context; 6430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Doddimport android.graphics.SurfaceTexture; 7430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Doddimport android.graphics.SurfaceTexture.OnFrameAvailableListener; 8430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Doddimport android.opengl.GLES20; 9430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Doddimport android.opengl.GLSurfaceView; 10430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Doddimport android.util.AttributeSet; 11430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Doddimport android.util.Log; 12430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 13430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Doddimport java.nio.ByteBuffer; 14430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Doddimport java.nio.ByteOrder; 15430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Doddimport java.nio.FloatBuffer; 16430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Doddimport java.util.concurrent.atomic.AtomicBoolean; 17430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Doddimport java.util.concurrent.atomic.AtomicInteger; 18430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 19430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Doddimport javax.microedition.khronos.egl.EGLConfig; 20430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Doddimport javax.microedition.khronos.opengles.GL10; 21430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 22430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Doddclass SurfaceTextureView extends GLSurfaceView { 23430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd static final private String TAG = "VideoChatTest"; 24430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 25430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private int mTextureName; 26430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private SurfaceTexture mSurfaceTexture; 27430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd public int getTextureName() { 28430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd return mTextureName; 29430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 30430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd public SurfaceTexture getSurfaceTexture() { 31430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd return mSurfaceTexture; 32430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 33430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 34430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd public static int loadShader(int shaderType, String source) { 35430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd int shader = GLES20.glCreateShader(shaderType); 36430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd if (shader != 0) { 37430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glShaderSource(shader, source); 38430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glCompileShader(shader); 39430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd int[] compiled = new int[1]; 40430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0); 41430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd if (compiled[0] == 0) { 42430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd Log.e(TAG, "Could not compile shader " + shaderType + ":"); 43430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd Log.e(TAG, GLES20.glGetShaderInfoLog(shader)); 44430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glDeleteShader(shader); 45430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd shader = 0; 46430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 47430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 48430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd return shader; 49430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 50430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 51430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd public static void checkGlError(String op) { 52430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd int error; 53430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { 54430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd Log.e(TAG, op + ": glError " + error); 55430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd throw new RuntimeException(op + ": glError " + error); 56430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 57430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 58430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 59430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd public static int createProgram(String vertexSource, String fragmentSource) { 60430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource); 61430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd if (vertexShader == 0) { 62430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd return 0; 63430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 64430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource); 65430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd if (pixelShader == 0) { 66430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd return 0; 67430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 68430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 69430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd int program = GLES20.glCreateProgram(); 70430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd if (program != 0) { 71430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glAttachShader(program, vertexShader); 72430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd checkGlError("glAttachShader"); 73430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glAttachShader(program, pixelShader); 74430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd checkGlError("glAttachShader"); 75430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glLinkProgram(program); 76430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd int[] linkStatus = new int[1]; 77430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0); 78430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd if (linkStatus[0] != GLES20.GL_TRUE) { 79430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd Log.e(TAG, "Could not link program: "); 80430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd Log.e(TAG, GLES20.glGetProgramInfoLog(program)); 81430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glDeleteProgram(program); 82430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd program = 0; 83430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 84430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 85430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd return program; 86430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 87430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 88430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd AtomicInteger mReportedFrameCount = new AtomicInteger(); 89430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd AtomicBoolean mCameraEnabled = new AtomicBoolean(); 90430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd AtomicInteger mCameraFrameCount = new AtomicInteger(); 91430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 92430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd /** 93430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd * @param context 94430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd */ 95430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd public SurfaceTextureView(Context context) { 96430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd super(context); 97430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd init(); 98430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 99430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 100430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd public SurfaceTextureView(Context context, AttributeSet attrs) { 101430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd super(context, attrs); 102430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd init(); 103430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 104430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 105430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private void init() { 106430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd setEGLContextClientVersion(2); 107430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd setRenderer(new Renderer()); 108430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 109430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 110430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd public void setCameraEnabled(boolean enabled) { 111430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mCameraEnabled.set(enabled); 112430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 113430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 114430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd public void resetFrameCounter() { 115430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mReportedFrameCount.set(0); 116430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 117430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 118430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd public int getFrameCounter() { 119430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd return mReportedFrameCount.get(); 120430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 121430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 122430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd class Renderer implements GLSurfaceView.Renderer { 123430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private final static String VERTEX_SHADER = 124430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd "attribute vec4 vPosition;\n" + 125430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd "attribute vec2 a_texCoord;\n" + 126430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd "varying vec2 v_texCoord;\n" + 127430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd "uniform mat4 u_xform;\n" + 128430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd "void main() {\n" + 129430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd " gl_Position = vPosition;\n" + 130430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd " v_texCoord = vec2(u_xform * vec4(a_texCoord, 1.0, 1.0));\n" + 131430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd "}\n"; 132430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 133430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private final static String FRAGMENT_SHADER = 134430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd "#extension GL_OES_EGL_image_external : require\n" + 135430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd "precision mediump float;\n" + 136430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd "uniform samplerExternalOES s_texture;\n" + 137430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd "varying vec2 v_texCoord;\n" + 138430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd "void main() {\n" + 139430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd " gl_FragColor = texture2D(s_texture, v_texCoord);\n" + 140430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd "}\n"; 141430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 142430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private final float[] TEXTURE_VERTICES = 143430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd { 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f }; 144430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 145430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private final float[] QUAD_VERTICES = 146430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd { 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f }; 147430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 148430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private final static int FLOAT_SIZE_BYTES = 4; 149430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 150430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private final FloatBuffer mTextureVertices; 151430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private final FloatBuffer mQuadVertices; 152430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 153430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 154430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private int mGLProgram; 155430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private int mTexHandle; 156430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private int mTexCoordHandle; 157430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private int mTriangleVerticesHandle; 158430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private int mTransformHandle; 159430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private int mViewWidth; 160430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private int mViewHeight; 161430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private float[] mTransformMatrix; 162430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private int mLastCameraFrameCount; 163430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd public Renderer() { 164430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mTextureVertices = ByteBuffer.allocateDirect(TEXTURE_VERTICES.length * 165430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer(); 166430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mTextureVertices.put(TEXTURE_VERTICES).position(0); 167430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mQuadVertices = ByteBuffer.allocateDirect(QUAD_VERTICES.length * 168430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer(); 169430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mQuadVertices.put(QUAD_VERTICES).position(0); 170430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mTransformMatrix = new float[16]; 171430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mLastCameraFrameCount = mCameraFrameCount.get(); 172430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 173430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 174430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd @Override 175430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd public void onSurfaceCreated(GL10 gl, EGLConfig config) { 176430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mGLProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER); 177430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 178430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mTexHandle = GLES20.glGetUniformLocation(mGLProgram, "s_texture"); 179430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mTexCoordHandle = GLES20.glGetAttribLocation(mGLProgram, "a_texCoord"); 180430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mTriangleVerticesHandle = GLES20.glGetAttribLocation(mGLProgram, "vPosition"); 181430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mTransformHandle = GLES20.glGetUniformLocation(mGLProgram, "u_xform"); 182430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd int[] textures = new int[1]; 183430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glGenTextures(1, textures, 0); 184430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mTextureName = textures[0]; 185430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glUseProgram(mGLProgram); 186430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glVertexAttribPointer(mTexCoordHandle, 2, GLES20.GL_FLOAT, 187430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd false, 0, mTextureVertices); 188430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glVertexAttribPointer(mTriangleVerticesHandle, 2, GLES20.GL_FLOAT, 189430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd false, 0, mQuadVertices); 190430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd checkGlError("initialization"); 191430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mSurfaceTexture = new SurfaceTexture(mTextureName); 192430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mSurfaceTexture.setOnFrameAvailableListener(new OnFrameAvailableListener() { 193430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd @Override 194430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd public void onFrameAvailable(SurfaceTexture surfaceTexture) { 195430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mCameraFrameCount.incrementAndGet(); 196430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 197430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd }); 198430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 199430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 200430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd /* (non-Javadoc) 201430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd * @see android.opengl.GLSurfaceView.Renderer#onSurfaceChanged(javax.microedition.khronos.opengles.GL10, int, int) 202430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd */ 203430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd @Override 204430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd public void onSurfaceChanged(GL10 gl, int width, int height) { 205430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mViewWidth = width; 206430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mViewHeight = height; 207430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 208430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 209430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd private static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65; 210430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd @Override 211430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd public void onDrawFrame(GL10 gl) { 212430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glUseProgram(mGLProgram); 213430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glViewport(0, 0, mViewWidth, mViewHeight); 214430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd checkGlError("glViewport"); 215430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 216430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd if (mCameraEnabled.get()) { 217430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd int cameraFrameCount = mCameraFrameCount.get(); 218430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd if (mLastCameraFrameCount != cameraFrameCount) { 219430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mReportedFrameCount.incrementAndGet(); 220430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mSurfaceTexture.updateTexImage(); 221430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mSurfaceTexture.getTransformMatrix(mTransformMatrix); 222430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glUniformMatrix4fv(mTransformHandle, 1, false, mTransformMatrix, 0); 223430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd checkGlError("glUniformMatrix4fv"); 224430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd mLastCameraFrameCount = cameraFrameCount; 225430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 226430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glDisable(GLES20.GL_BLEND); 227430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd checkGlError("setup"); 228430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 229430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd checkGlError("setup"); 230430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName); 231430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd checkGlError("setup"); 232430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glUniform1i(mTexHandle, 0); 233430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd checkGlError("setup"); 234430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glEnableVertexAttribArray(mTexCoordHandle); 235430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd checkGlError("setup"); 236430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glEnableVertexAttribArray(mTriangleVerticesHandle); 237430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd checkGlError("setup"); 238430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4); 239430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd checkGlError("glDrawArrays"); 240430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } else { 241430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd GLES20.glClearColor(0,0,0,0); 242430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 243430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 244430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd 245430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd } 246430aa048a20aa42f089d213d8b4b6c67ab1b43feMike Dodd} 247