1441e847feb0e055ecb004802802cea07782ab228Andy McFadden/* 2441e847feb0e055ecb004802802cea07782ab228Andy McFadden * Copyright 2013 The Android Open Source Project 3441e847feb0e055ecb004802802cea07782ab228Andy McFadden * 4441e847feb0e055ecb004802802cea07782ab228Andy McFadden * Licensed under the Apache License, Version 2.0 (the "License"); 5441e847feb0e055ecb004802802cea07782ab228Andy McFadden * you may not use this file except in compliance with the License. 6441e847feb0e055ecb004802802cea07782ab228Andy McFadden * You may obtain a copy of the License at 7441e847feb0e055ecb004802802cea07782ab228Andy McFadden * 8441e847feb0e055ecb004802802cea07782ab228Andy McFadden * http://www.apache.org/licenses/LICENSE-2.0 9441e847feb0e055ecb004802802cea07782ab228Andy McFadden * 10441e847feb0e055ecb004802802cea07782ab228Andy McFadden * Unless required by applicable law or agreed to in writing, software 11441e847feb0e055ecb004802802cea07782ab228Andy McFadden * distributed under the License is distributed on an "AS IS" BASIS, 12441e847feb0e055ecb004802802cea07782ab228Andy McFadden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13441e847feb0e055ecb004802802cea07782ab228Andy McFadden * See the License for the specific language governing permissions and 14441e847feb0e055ecb004802802cea07782ab228Andy McFadden * limitations under the License. 15441e847feb0e055ecb004802802cea07782ab228Andy McFadden */ 16441e847feb0e055ecb004802802cea07782ab228Andy McFadden 17441e847feb0e055ecb004802802cea07782ab228Andy McFadden#define LOG_TAG "ScreenRecord" 18441e847feb0e055ecb004802802cea07782ab228Andy McFadden//#define LOG_NDEBUG 0 19441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <utils/Log.h> 20441e847feb0e055ecb004802802cea07782ab228Andy McFadden 21441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include "Program.h" 22441e847feb0e055ecb004802802cea07782ab228Andy McFadden 23441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <GLES2/gl2.h> 24441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <GLES2/gl2ext.h> 25441e847feb0e055ecb004802802cea07782ab228Andy McFadden 26441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <assert.h> 27441e847feb0e055ecb004802802cea07782ab228Andy McFadden 28441e847feb0e055ecb004802802cea07782ab228Andy McFaddenusing namespace android; 29441e847feb0e055ecb004802802cea07782ab228Andy McFadden 30441e847feb0e055ecb004802802cea07782ab228Andy McFadden// 4x4 identity matrix 31441e847feb0e055ecb004802802cea07782ab228Andy McFaddenconst float Program::kIdentity[] = { 32441e847feb0e055ecb004802802cea07782ab228Andy McFadden 1.0f, 0.0f, 0.0f, 0.0f, 33441e847feb0e055ecb004802802cea07782ab228Andy McFadden 0.0f, 1.0f, 0.0f, 0.0f, 34441e847feb0e055ecb004802802cea07782ab228Andy McFadden 0.0f, 0.0f, 1.0f, 0.0f, 35441e847feb0e055ecb004802802cea07782ab228Andy McFadden 0.0f, 0.0f, 0.0f, 1.0f 36441e847feb0e055ecb004802802cea07782ab228Andy McFadden}; 37441e847feb0e055ecb004802802cea07782ab228Andy McFadden 38441e847feb0e055ecb004802802cea07782ab228Andy McFadden// Simple vertex shader. Texture coord calc includes matrix for GLConsumer 39441e847feb0e055ecb004802802cea07782ab228Andy McFadden// transform. 40441e847feb0e055ecb004802802cea07782ab228Andy McFaddenstatic const char* kVertexShader = 41441e847feb0e055ecb004802802cea07782ab228Andy McFadden "uniform mat4 uMVPMatrix;\n" 42441e847feb0e055ecb004802802cea07782ab228Andy McFadden "uniform mat4 uGLCMatrix;\n" 43441e847feb0e055ecb004802802cea07782ab228Andy McFadden "attribute vec4 aPosition;\n" 44441e847feb0e055ecb004802802cea07782ab228Andy McFadden "attribute vec4 aTextureCoord;\n" 45441e847feb0e055ecb004802802cea07782ab228Andy McFadden "varying vec2 vTextureCoord;\n" 46441e847feb0e055ecb004802802cea07782ab228Andy McFadden "void main() {\n" 47441e847feb0e055ecb004802802cea07782ab228Andy McFadden " gl_Position = uMVPMatrix * aPosition;\n" 48441e847feb0e055ecb004802802cea07782ab228Andy McFadden " vTextureCoord = (uGLCMatrix * aTextureCoord).xy;\n" 49441e847feb0e055ecb004802802cea07782ab228Andy McFadden "}\n"; 50441e847feb0e055ecb004802802cea07782ab228Andy McFadden 51441e847feb0e055ecb004802802cea07782ab228Andy McFadden// Trivial fragment shader for external texture. 52441e847feb0e055ecb004802802cea07782ab228Andy McFaddenstatic const char* kExtFragmentShader = 53441e847feb0e055ecb004802802cea07782ab228Andy McFadden "#extension GL_OES_EGL_image_external : require\n" 54441e847feb0e055ecb004802802cea07782ab228Andy McFadden "precision mediump float;\n" 55441e847feb0e055ecb004802802cea07782ab228Andy McFadden "varying vec2 vTextureCoord;\n" 56441e847feb0e055ecb004802802cea07782ab228Andy McFadden "uniform samplerExternalOES uTexture;\n" 57441e847feb0e055ecb004802802cea07782ab228Andy McFadden "void main() {\n" 58441e847feb0e055ecb004802802cea07782ab228Andy McFadden " gl_FragColor = texture2D(uTexture, vTextureCoord);\n" 59441e847feb0e055ecb004802802cea07782ab228Andy McFadden "}\n"; 60441e847feb0e055ecb004802802cea07782ab228Andy McFadden 61441e847feb0e055ecb004802802cea07782ab228Andy McFadden// Trivial fragment shader for mundane texture. 62441e847feb0e055ecb004802802cea07782ab228Andy McFaddenstatic const char* kFragmentShader = 63441e847feb0e055ecb004802802cea07782ab228Andy McFadden "precision mediump float;\n" 64441e847feb0e055ecb004802802cea07782ab228Andy McFadden "varying vec2 vTextureCoord;\n" 65441e847feb0e055ecb004802802cea07782ab228Andy McFadden "uniform sampler2D uTexture;\n" 66441e847feb0e055ecb004802802cea07782ab228Andy McFadden "void main() {\n" 67441e847feb0e055ecb004802802cea07782ab228Andy McFadden " gl_FragColor = texture2D(uTexture, vTextureCoord);\n" 68441e847feb0e055ecb004802802cea07782ab228Andy McFadden //" gl_FragColor = vec4(0.2, 1.0, 0.2, 1.0);\n" 69441e847feb0e055ecb004802802cea07782ab228Andy McFadden "}\n"; 70441e847feb0e055ecb004802802cea07782ab228Andy McFadden 71441e847feb0e055ecb004802802cea07782ab228Andy McFaddenstatus_t Program::setup(ProgramType type) { 72441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGV("Program::setup type=%d", type); 73441e847feb0e055ecb004802802cea07782ab228Andy McFadden status_t err; 74441e847feb0e055ecb004802802cea07782ab228Andy McFadden 75441e847feb0e055ecb004802802cea07782ab228Andy McFadden mProgramType = type; 76441e847feb0e055ecb004802802cea07782ab228Andy McFadden 77441e847feb0e055ecb004802802cea07782ab228Andy McFadden GLuint program; 78441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (type == PROGRAM_TEXTURE_2D) { 79441e847feb0e055ecb004802802cea07782ab228Andy McFadden err = createProgram(&program, kVertexShader, kFragmentShader); 80441e847feb0e055ecb004802802cea07782ab228Andy McFadden } else { 81441e847feb0e055ecb004802802cea07782ab228Andy McFadden err = createProgram(&program, kVertexShader, kExtFragmentShader); 82441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 83441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (err != NO_ERROR) { 84441e847feb0e055ecb004802802cea07782ab228Andy McFadden return err; 85441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 86441e847feb0e055ecb004802802cea07782ab228Andy McFadden assert(program != 0); 87441e847feb0e055ecb004802802cea07782ab228Andy McFadden 88441e847feb0e055ecb004802802cea07782ab228Andy McFadden maPositionLoc = glGetAttribLocation(program, "aPosition"); 89441e847feb0e055ecb004802802cea07782ab228Andy McFadden maTextureCoordLoc = glGetAttribLocation(program, "aTextureCoord"); 90441e847feb0e055ecb004802802cea07782ab228Andy McFadden muMVPMatrixLoc = glGetUniformLocation(program, "uMVPMatrix"); 91441e847feb0e055ecb004802802cea07782ab228Andy McFadden muGLCMatrixLoc = glGetUniformLocation(program, "uGLCMatrix"); 92441e847feb0e055ecb004802802cea07782ab228Andy McFadden muTextureLoc = glGetUniformLocation(program, "uTexture"); 93441e847feb0e055ecb004802802cea07782ab228Andy McFadden if ((maPositionLoc | maTextureCoordLoc | muMVPMatrixLoc | 94441e847feb0e055ecb004802802cea07782ab228Andy McFadden muGLCMatrixLoc | muTextureLoc) == -1) { 95441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("Attrib/uniform lookup failed: %#x", glGetError()); 96441e847feb0e055ecb004802802cea07782ab228Andy McFadden glDeleteProgram(program); 97441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 98441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 99441e847feb0e055ecb004802802cea07782ab228Andy McFadden 100441e847feb0e055ecb004802802cea07782ab228Andy McFadden mProgram = program; 101441e847feb0e055ecb004802802cea07782ab228Andy McFadden return NO_ERROR; 102441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 103441e847feb0e055ecb004802802cea07782ab228Andy McFadden 104441e847feb0e055ecb004802802cea07782ab228Andy McFaddenvoid Program::release() { 105441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGV("Program::release"); 106441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (mProgram != 0) { 107441e847feb0e055ecb004802802cea07782ab228Andy McFadden glDeleteProgram(mProgram); 108441e847feb0e055ecb004802802cea07782ab228Andy McFadden mProgram = 0; 109441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 110441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 111441e847feb0e055ecb004802802cea07782ab228Andy McFadden 112441e847feb0e055ecb004802802cea07782ab228Andy McFaddenstatus_t Program::createProgram(GLuint* outPgm, const char* vertexShader, 113441e847feb0e055ecb004802802cea07782ab228Andy McFadden const char* fragmentShader) { 114441e847feb0e055ecb004802802cea07782ab228Andy McFadden GLuint vs, fs; 115441e847feb0e055ecb004802802cea07782ab228Andy McFadden status_t err; 116441e847feb0e055ecb004802802cea07782ab228Andy McFadden 117441e847feb0e055ecb004802802cea07782ab228Andy McFadden err = compileShader(GL_VERTEX_SHADER, vertexShader, &vs); 118441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (err != NO_ERROR) { 119441e847feb0e055ecb004802802cea07782ab228Andy McFadden return err; 120441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 121441e847feb0e055ecb004802802cea07782ab228Andy McFadden err = compileShader(GL_FRAGMENT_SHADER, fragmentShader, &fs); 122441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (err != NO_ERROR) { 123441e847feb0e055ecb004802802cea07782ab228Andy McFadden glDeleteShader(vs); 124441e847feb0e055ecb004802802cea07782ab228Andy McFadden return err; 125441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 126441e847feb0e055ecb004802802cea07782ab228Andy McFadden 127441e847feb0e055ecb004802802cea07782ab228Andy McFadden GLuint program; 128441e847feb0e055ecb004802802cea07782ab228Andy McFadden err = linkShaderProgram(vs, fs, &program); 129441e847feb0e055ecb004802802cea07782ab228Andy McFadden glDeleteShader(vs); 130441e847feb0e055ecb004802802cea07782ab228Andy McFadden glDeleteShader(fs); 131441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (err == NO_ERROR) { 132441e847feb0e055ecb004802802cea07782ab228Andy McFadden *outPgm = program; 133441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 134441e847feb0e055ecb004802802cea07782ab228Andy McFadden return err; 135441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 136441e847feb0e055ecb004802802cea07782ab228Andy McFadden 137441e847feb0e055ecb004802802cea07782ab228Andy McFaddenstatus_t Program::compileShader(GLenum shaderType, const char* src, 138441e847feb0e055ecb004802802cea07782ab228Andy McFadden GLuint* outShader) { 139441e847feb0e055ecb004802802cea07782ab228Andy McFadden GLuint shader = glCreateShader(shaderType); 140441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (shader == 0) { 141441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("glCreateShader error: %#x", glGetError()); 142441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 143441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 144441e847feb0e055ecb004802802cea07782ab228Andy McFadden 145441e847feb0e055ecb004802802cea07782ab228Andy McFadden glShaderSource(shader, 1, &src, NULL); 146441e847feb0e055ecb004802802cea07782ab228Andy McFadden glCompileShader(shader); 147441e847feb0e055ecb004802802cea07782ab228Andy McFadden 148441e847feb0e055ecb004802802cea07782ab228Andy McFadden GLint compiled = 0; 149441e847feb0e055ecb004802802cea07782ab228Andy McFadden glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 150441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (!compiled) { 151441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("Compile of shader type %d failed", shaderType); 152441e847feb0e055ecb004802802cea07782ab228Andy McFadden GLint infoLen = 0; 153441e847feb0e055ecb004802802cea07782ab228Andy McFadden glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 154441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (infoLen) { 155441e847feb0e055ecb004802802cea07782ab228Andy McFadden char* buf = new char[infoLen]; 156441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (buf) { 157441e847feb0e055ecb004802802cea07782ab228Andy McFadden glGetShaderInfoLog(shader, infoLen, NULL, buf); 158441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("Compile log: %s", buf); 159441e847feb0e055ecb004802802cea07782ab228Andy McFadden delete[] buf; 160441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 161441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 162441e847feb0e055ecb004802802cea07782ab228Andy McFadden glDeleteShader(shader); 163441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 164441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 165441e847feb0e055ecb004802802cea07782ab228Andy McFadden *outShader = shader; 166441e847feb0e055ecb004802802cea07782ab228Andy McFadden return NO_ERROR; 167441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 168441e847feb0e055ecb004802802cea07782ab228Andy McFadden 169441e847feb0e055ecb004802802cea07782ab228Andy McFaddenstatus_t Program::linkShaderProgram(GLuint vs, GLuint fs, GLuint* outPgm) { 170441e847feb0e055ecb004802802cea07782ab228Andy McFadden GLuint program = glCreateProgram(); 171441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (program == 0) { 172441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("glCreateProgram error: %#x", glGetError()); 173441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 174441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 175441e847feb0e055ecb004802802cea07782ab228Andy McFadden 176441e847feb0e055ecb004802802cea07782ab228Andy McFadden glAttachShader(program, vs); 177441e847feb0e055ecb004802802cea07782ab228Andy McFadden glAttachShader(program, fs); 178441e847feb0e055ecb004802802cea07782ab228Andy McFadden glLinkProgram(program); 179441e847feb0e055ecb004802802cea07782ab228Andy McFadden GLint linkStatus = GL_FALSE; 180441e847feb0e055ecb004802802cea07782ab228Andy McFadden glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 181441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (linkStatus != GL_TRUE) { 182441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("glLinkProgram failed"); 183441e847feb0e055ecb004802802cea07782ab228Andy McFadden GLint bufLength = 0; 184441e847feb0e055ecb004802802cea07782ab228Andy McFadden glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); 185441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (bufLength) { 186441e847feb0e055ecb004802802cea07782ab228Andy McFadden char* buf = new char[bufLength]; 187441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (buf) { 188441e847feb0e055ecb004802802cea07782ab228Andy McFadden glGetProgramInfoLog(program, bufLength, NULL, buf); 189441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("Link log: %s", buf); 190441e847feb0e055ecb004802802cea07782ab228Andy McFadden delete[] buf; 191441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 192441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 193441e847feb0e055ecb004802802cea07782ab228Andy McFadden glDeleteProgram(program); 194441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 195441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 196441e847feb0e055ecb004802802cea07782ab228Andy McFadden 197441e847feb0e055ecb004802802cea07782ab228Andy McFadden *outPgm = program; 198441e847feb0e055ecb004802802cea07782ab228Andy McFadden return NO_ERROR; 199441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 200441e847feb0e055ecb004802802cea07782ab228Andy McFadden 201441e847feb0e055ecb004802802cea07782ab228Andy McFadden 202441e847feb0e055ecb004802802cea07782ab228Andy McFadden 203441e847feb0e055ecb004802802cea07782ab228Andy McFaddenstatus_t Program::blit(GLuint texName, const float* texMatrix, 204587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden int32_t x, int32_t y, int32_t w, int32_t h, bool invert) const { 205441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGV("Program::blit %d xy=%d,%d wh=%d,%d", texName, x, y, w, h); 206441e847feb0e055ecb004802802cea07782ab228Andy McFadden 207441e847feb0e055ecb004802802cea07782ab228Andy McFadden const float pos[] = { 208441e847feb0e055ecb004802802cea07782ab228Andy McFadden float(x), float(y+h), 209441e847feb0e055ecb004802802cea07782ab228Andy McFadden float(x+w), float(y+h), 210441e847feb0e055ecb004802802cea07782ab228Andy McFadden float(x), float(y), 211441e847feb0e055ecb004802802cea07782ab228Andy McFadden float(x+w), float(y), 212441e847feb0e055ecb004802802cea07782ab228Andy McFadden }; 213441e847feb0e055ecb004802802cea07782ab228Andy McFadden const float uv[] = { 214441e847feb0e055ecb004802802cea07782ab228Andy McFadden 0.0f, 0.0f, 215441e847feb0e055ecb004802802cea07782ab228Andy McFadden 1.0f, 0.0f, 216441e847feb0e055ecb004802802cea07782ab228Andy McFadden 0.0f, 1.0f, 217441e847feb0e055ecb004802802cea07782ab228Andy McFadden 1.0f, 1.0f, 218441e847feb0e055ecb004802802cea07782ab228Andy McFadden }; 219441e847feb0e055ecb004802802cea07782ab228Andy McFadden status_t err; 220441e847feb0e055ecb004802802cea07782ab228Andy McFadden 221587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden err = beforeDraw(texName, texMatrix, pos, uv, invert); 222441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (err == NO_ERROR) { 223441e847feb0e055ecb004802802cea07782ab228Andy McFadden glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 224441e847feb0e055ecb004802802cea07782ab228Andy McFadden err = afterDraw(); 225441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 226441e847feb0e055ecb004802802cea07782ab228Andy McFadden return err; 227441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 228441e847feb0e055ecb004802802cea07782ab228Andy McFadden 229441e847feb0e055ecb004802802cea07782ab228Andy McFaddenstatus_t Program::drawTriangles(GLuint texName, const float* texMatrix, 230441e847feb0e055ecb004802802cea07782ab228Andy McFadden const float* vertices, const float* texes, size_t count) const { 231441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGV("Program::drawTriangles texName=%d", texName); 232441e847feb0e055ecb004802802cea07782ab228Andy McFadden 233441e847feb0e055ecb004802802cea07782ab228Andy McFadden status_t err; 234441e847feb0e055ecb004802802cea07782ab228Andy McFadden 235587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden err = beforeDraw(texName, texMatrix, vertices, texes, false); 236441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (err == NO_ERROR) { 237441e847feb0e055ecb004802802cea07782ab228Andy McFadden glDrawArrays(GL_TRIANGLES, 0, count); 238441e847feb0e055ecb004802802cea07782ab228Andy McFadden err = afterDraw(); 239441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 240441e847feb0e055ecb004802802cea07782ab228Andy McFadden return err; 241441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 242441e847feb0e055ecb004802802cea07782ab228Andy McFadden 243441e847feb0e055ecb004802802cea07782ab228Andy McFaddenstatus_t Program::beforeDraw(GLuint texName, const float* texMatrix, 244587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden const float* vertices, const float* texes, bool invert) const { 245441e847feb0e055ecb004802802cea07782ab228Andy McFadden // Create an orthographic projection matrix based on viewport size. 246441e847feb0e055ecb004802802cea07782ab228Andy McFadden GLint vp[4]; 247441e847feb0e055ecb004802802cea07782ab228Andy McFadden glGetIntegerv(GL_VIEWPORT, vp); 248441e847feb0e055ecb004802802cea07782ab228Andy McFadden float screenToNdc[16] = { 249441e847feb0e055ecb004802802cea07782ab228Andy McFadden 2.0f/float(vp[2]), 0.0f, 0.0f, 0.0f, 250441e847feb0e055ecb004802802cea07782ab228Andy McFadden 0.0f, -2.0f/float(vp[3]), 0.0f, 0.0f, 251441e847feb0e055ecb004802802cea07782ab228Andy McFadden 0.0f, 0.0f, 1.0f, 0.0f, 252441e847feb0e055ecb004802802cea07782ab228Andy McFadden -1.0f, 1.0f, 0.0f, 1.0f, 253441e847feb0e055ecb004802802cea07782ab228Andy McFadden }; 254587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden if (invert) { 255587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden screenToNdc[5] = -screenToNdc[5]; 256587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden screenToNdc[13] = -screenToNdc[13]; 257587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden } 258441e847feb0e055ecb004802802cea07782ab228Andy McFadden 259441e847feb0e055ecb004802802cea07782ab228Andy McFadden glUseProgram(mProgram); 260441e847feb0e055ecb004802802cea07782ab228Andy McFadden 261441e847feb0e055ecb004802802cea07782ab228Andy McFadden glVertexAttribPointer(maPositionLoc, 2, GL_FLOAT, GL_FALSE, 0, vertices); 262441e847feb0e055ecb004802802cea07782ab228Andy McFadden glVertexAttribPointer(maTextureCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, texes); 263441e847feb0e055ecb004802802cea07782ab228Andy McFadden glEnableVertexAttribArray(maPositionLoc); 264441e847feb0e055ecb004802802cea07782ab228Andy McFadden glEnableVertexAttribArray(maTextureCoordLoc); 265441e847feb0e055ecb004802802cea07782ab228Andy McFadden 266441e847feb0e055ecb004802802cea07782ab228Andy McFadden glUniformMatrix4fv(muMVPMatrixLoc, 1, GL_FALSE, screenToNdc); 267441e847feb0e055ecb004802802cea07782ab228Andy McFadden glUniformMatrix4fv(muGLCMatrixLoc, 1, GL_FALSE, texMatrix); 268441e847feb0e055ecb004802802cea07782ab228Andy McFadden 269441e847feb0e055ecb004802802cea07782ab228Andy McFadden glActiveTexture(GL_TEXTURE0); 270441e847feb0e055ecb004802802cea07782ab228Andy McFadden 271441e847feb0e055ecb004802802cea07782ab228Andy McFadden switch (mProgramType) { 272441e847feb0e055ecb004802802cea07782ab228Andy McFadden case PROGRAM_EXTERNAL_TEXTURE: 273441e847feb0e055ecb004802802cea07782ab228Andy McFadden glBindTexture(GL_TEXTURE_EXTERNAL_OES, texName); 274441e847feb0e055ecb004802802cea07782ab228Andy McFadden break; 275441e847feb0e055ecb004802802cea07782ab228Andy McFadden case PROGRAM_TEXTURE_2D: 276441e847feb0e055ecb004802802cea07782ab228Andy McFadden glBindTexture(GL_TEXTURE_2D, texName); 277441e847feb0e055ecb004802802cea07782ab228Andy McFadden break; 278441e847feb0e055ecb004802802cea07782ab228Andy McFadden default: 279441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("unexpected program type %d", mProgramType); 280441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 281441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 282441e847feb0e055ecb004802802cea07782ab228Andy McFadden 283441e847feb0e055ecb004802802cea07782ab228Andy McFadden glUniform1i(muTextureLoc, 0); 284441e847feb0e055ecb004802802cea07782ab228Andy McFadden 285441e847feb0e055ecb004802802cea07782ab228Andy McFadden GLenum glErr; 286441e847feb0e055ecb004802802cea07782ab228Andy McFadden if ((glErr = glGetError()) != GL_NO_ERROR) { 287441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("GL error before draw: %#x", glErr); 288441e847feb0e055ecb004802802cea07782ab228Andy McFadden glDisableVertexAttribArray(maPositionLoc); 289441e847feb0e055ecb004802802cea07782ab228Andy McFadden glDisableVertexAttribArray(maTextureCoordLoc); 290441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 291441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 292441e847feb0e055ecb004802802cea07782ab228Andy McFadden 293441e847feb0e055ecb004802802cea07782ab228Andy McFadden return NO_ERROR; 294441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 295441e847feb0e055ecb004802802cea07782ab228Andy McFadden 296441e847feb0e055ecb004802802cea07782ab228Andy McFaddenstatus_t Program::afterDraw() const { 297441e847feb0e055ecb004802802cea07782ab228Andy McFadden glDisableVertexAttribArray(maPositionLoc); 298441e847feb0e055ecb004802802cea07782ab228Andy McFadden glDisableVertexAttribArray(maTextureCoordLoc); 299441e847feb0e055ecb004802802cea07782ab228Andy McFadden 300441e847feb0e055ecb004802802cea07782ab228Andy McFadden GLenum glErr; 301441e847feb0e055ecb004802802cea07782ab228Andy McFadden if ((glErr = glGetError()) != GL_NO_ERROR) { 302441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("GL error after draw: %#x", glErr); 303441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 304441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 305441e847feb0e055ecb004802802cea07782ab228Andy McFadden 306441e847feb0e055ecb004802802cea07782ab228Andy McFadden return NO_ERROR; 307441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 308