1705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd// Copyright 2011 Google Inc. All Rights Reserved.
2705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
3705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Doddpackage com.example.android.videochatcameratest;
4705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
5705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Doddimport android.content.Context;
6705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Doddimport android.graphics.SurfaceTexture;
7705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Doddimport android.graphics.SurfaceTexture.OnFrameAvailableListener;
8705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Doddimport android.opengl.GLES20;
9705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Doddimport android.opengl.GLSurfaceView;
10705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Doddimport android.util.AttributeSet;
11705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Doddimport android.util.Log;
12705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
13705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Doddimport java.nio.ByteBuffer;
14705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Doddimport java.nio.ByteOrder;
15705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Doddimport java.nio.FloatBuffer;
16705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Doddimport java.util.concurrent.atomic.AtomicBoolean;
17705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Doddimport java.util.concurrent.atomic.AtomicInteger;
18705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
19705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Doddimport javax.microedition.khronos.egl.EGLConfig;
20705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Doddimport javax.microedition.khronos.opengles.GL10;
21705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
22705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Doddclass SurfaceTextureView extends GLSurfaceView {
23705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    static final private String TAG = "VideoChatTest";
24705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
25705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    private int mTextureName;
26705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    private SurfaceTexture mSurfaceTexture;
27705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    public int getTextureName() {
28705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        return mTextureName;
29705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    }
30705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    public SurfaceTexture getSurfaceTexture() {
31705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        return mSurfaceTexture;
32705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    }
33705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
34705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    public static int loadShader(int shaderType, String source) {
35705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        int shader = GLES20.glCreateShader(shaderType);
36705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        if (shader != 0) {
37705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            GLES20.glShaderSource(shader, source);
38705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            GLES20.glCompileShader(shader);
39705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            int[] compiled = new int[1];
40705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
41705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            if (compiled[0] == 0) {
42705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                Log.e(TAG, "Could not compile shader " + shaderType + ":");
43705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
44705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                GLES20.glDeleteShader(shader);
45705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                shader = 0;
46705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            }
47705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        }
48705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        return shader;
49705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    }
50705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
51705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    public static void checkGlError(String op) {
52705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        int error;
53705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
54705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            Log.e(TAG, op + ": glError " + error);
55705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            throw new RuntimeException(op + ": glError " + error);
56705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        }
57705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    }
58705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
59705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    public static int createProgram(String vertexSource, String fragmentSource) {
60705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
61705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        if (vertexShader == 0) {
62705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            return 0;
63705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        }
64705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
65705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        if (pixelShader == 0) {
66705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            return 0;
67705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        }
68705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
69705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        int program = GLES20.glCreateProgram();
70705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        if (program != 0) {
71705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            GLES20.glAttachShader(program, vertexShader);
72705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            checkGlError("glAttachShader");
73705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            GLES20.glAttachShader(program, pixelShader);
74705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            checkGlError("glAttachShader");
75705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            GLES20.glLinkProgram(program);
76705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            int[] linkStatus = new int[1];
77705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
78705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            if (linkStatus[0] != GLES20.GL_TRUE) {
79705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                Log.e(TAG, "Could not link program: ");
80705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                Log.e(TAG, GLES20.glGetProgramInfoLog(program));
81705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                GLES20.glDeleteProgram(program);
82705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                program = 0;
83705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            }
84705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        }
85705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        return program;
86705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    }
87705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
88705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    AtomicInteger mReportedFrameCount = new AtomicInteger();
89705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    AtomicBoolean mCameraEnabled = new AtomicBoolean();
90705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    AtomicInteger mCameraFrameCount = new AtomicInteger();
91705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
92705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    /**
93705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd     * @param context
94705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd     */
95705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    public SurfaceTextureView(Context context) {
96705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        super(context);
97705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        init();
98705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    }
99705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
100705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    public SurfaceTextureView(Context context, AttributeSet attrs) {
101705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        super(context, attrs);
102705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        init();
103705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    }
104705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
105705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    private void init() {
106705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        setEGLContextClientVersion(2);
107705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        setRenderer(new Renderer());
108705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    }
109705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
110705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    public void setCameraEnabled(boolean enabled) {
111705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        mCameraEnabled.set(enabled);
112705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    }
113705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
114705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    public void resetFrameCounter() {
115705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        mReportedFrameCount.set(0);
116705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    }
117705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
118705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    public int getFrameCounter() {
119705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        return mReportedFrameCount.get();
120705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    }
121705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
122705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    class Renderer implements GLSurfaceView.Renderer {
123705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private final static String VERTEX_SHADER =
124705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            "attribute vec4 vPosition;\n" +
125705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            "attribute vec2 a_texCoord;\n" +
126705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            "varying vec2 v_texCoord;\n" +
127705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            "uniform mat4 u_xform;\n" +
128705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            "void main() {\n" +
129705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            "  gl_Position = vPosition;\n" +
130705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            "  v_texCoord = vec2(u_xform * vec4(a_texCoord, 1.0, 1.0));\n" +
131705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            "}\n";
132705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
133705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private final static String FRAGMENT_SHADER =
134705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            "#extension GL_OES_EGL_image_external : require\n" +
135705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            "precision mediump float;\n" +
136705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            "uniform samplerExternalOES s_texture;\n" +
137705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            "varying vec2 v_texCoord;\n" +
138705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            "void main() {\n" +
139705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            "  gl_FragColor = texture2D(s_texture, v_texCoord);\n" +
140705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            "}\n";
141705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
142705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private final float[] TEXTURE_VERTICES =
143705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            { 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
144705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
145705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private final float[] QUAD_VERTICES =
146705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            { 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f };
147705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
148705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private final static int FLOAT_SIZE_BYTES = 4;
149705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
150705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private final FloatBuffer mTextureVertices;
151705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private final FloatBuffer mQuadVertices;
152705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
153705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
154705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private int mGLProgram;
155705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private int mTexHandle;
156705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private int mTexCoordHandle;
157705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private int mTriangleVerticesHandle;
158705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private int mTransformHandle;
159705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private int mViewWidth;
160705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private int mViewHeight;
161705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private float[] mTransformMatrix;
162705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private int mLastCameraFrameCount;
163705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        public Renderer() {
164705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            mTextureVertices = ByteBuffer.allocateDirect(TEXTURE_VERTICES.length *
165705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                    FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
166705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            mTextureVertices.put(TEXTURE_VERTICES).position(0);
167705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            mQuadVertices = ByteBuffer.allocateDirect(QUAD_VERTICES.length *
168705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                    FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
169705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            mQuadVertices.put(QUAD_VERTICES).position(0);
170705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            mTransformMatrix = new float[16];
171705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            mLastCameraFrameCount = mCameraFrameCount.get();
172705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        }
173705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
174705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        @Override
175705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
176705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            mGLProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
177705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
178705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            mTexHandle = GLES20.glGetUniformLocation(mGLProgram, "s_texture");
179705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            mTexCoordHandle = GLES20.glGetAttribLocation(mGLProgram, "a_texCoord");
180705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            mTriangleVerticesHandle = GLES20.glGetAttribLocation(mGLProgram, "vPosition");
181705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            mTransformHandle = GLES20.glGetUniformLocation(mGLProgram, "u_xform");
182705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            int[] textures = new int[1];
183705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            GLES20.glGenTextures(1, textures, 0);
184705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            mTextureName = textures[0];
185705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            GLES20.glUseProgram(mGLProgram);
186705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            GLES20.glVertexAttribPointer(mTexCoordHandle, 2, GLES20.GL_FLOAT,
187705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                    false, 0, mTextureVertices);
188705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            GLES20.glVertexAttribPointer(mTriangleVerticesHandle, 2, GLES20.GL_FLOAT,
189705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                    false, 0, mQuadVertices);
190705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            checkGlError("initialization");
191705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            mSurfaceTexture = new SurfaceTexture(mTextureName);
192705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            mSurfaceTexture.setOnFrameAvailableListener(new OnFrameAvailableListener() {
193705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                @Override
194705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                public void onFrameAvailable(SurfaceTexture surfaceTexture) {
195705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                    mCameraFrameCount.incrementAndGet();
196705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                }
197705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            });
198705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        }
199705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
200705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        /* (non-Javadoc)
201705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd         * @see android.opengl.GLSurfaceView.Renderer#onSurfaceChanged(javax.microedition.khronos.opengles.GL10, int, int)
202705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd         */
203705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        @Override
204705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        public void onSurfaceChanged(GL10 gl, int width, int height) {
205705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            mViewWidth = width;
206705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            mViewHeight = height;
207705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        }
208705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
209705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        private static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65;
210705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        @Override
211705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        public void onDrawFrame(GL10 gl) {
212705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            GLES20.glUseProgram(mGLProgram);
213705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            GLES20.glViewport(0, 0, mViewWidth, mViewHeight);
214705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            checkGlError("glViewport");
215705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
216705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            if (mCameraEnabled.get()) {
217705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                int cameraFrameCount = mCameraFrameCount.get();
218705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                if (mLastCameraFrameCount != cameraFrameCount) {
219705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                    mReportedFrameCount.incrementAndGet();
220705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                    mSurfaceTexture.updateTexImage();
221705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                    mSurfaceTexture.getTransformMatrix(mTransformMatrix);
222705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                    GLES20.glUniformMatrix4fv(mTransformHandle, 1, false, mTransformMatrix, 0);
223705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                    checkGlError("glUniformMatrix4fv");
224705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                    mLastCameraFrameCount = cameraFrameCount;
225705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                }
226705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                GLES20.glDisable(GLES20.GL_BLEND);
227705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                checkGlError("setup");
228705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
229705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                checkGlError("setup");
230705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
231705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                checkGlError("setup");
232705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                GLES20.glUniform1i(mTexHandle, 0);
233705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                checkGlError("setup");
234705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                GLES20.glEnableVertexAttribArray(mTexCoordHandle);
235705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                checkGlError("setup");
236705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                GLES20.glEnableVertexAttribArray(mTriangleVerticesHandle);
237705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                checkGlError("setup");
238705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4);
239705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                checkGlError("glDrawArrays");
240705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            } else {
241705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd                GLES20.glClearColor(0,0,0,0);
242705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd            }
243705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd        }
244705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd
245705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd    }
246705bbba5147654bd9fb46d6b92f0e0c72b560483Mike Dodd}
247