1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "fragment_shaders.cpp" 18 19FILE * fOut = NULL; 20void ptSwap(); 21 22static char gCurrentTestName[1024]; 23static uint32_t gWidth = 0; 24static uint32_t gHeight = 0; 25 26static void checkGlError(const char* op) { 27 for (GLint error = glGetError(); error; error 28 = glGetError()) { 29 ALOGE("after %s() glError (0x%x)\n", op, error); 30 } 31} 32 33GLuint loadShader(GLenum shaderType, const char* pSource) { 34 GLuint shader = glCreateShader(shaderType); 35 if (shader) { 36 glShaderSource(shader, 1, &pSource, NULL); 37 glCompileShader(shader); 38 GLint compiled = 0; 39 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 40 if (!compiled) { 41 GLint infoLen = 0; 42 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 43 if (infoLen) { 44 char* buf = (char*) malloc(infoLen); 45 if (buf) { 46 glGetShaderInfoLog(shader, infoLen, NULL, buf); 47 ALOGE("Could not compile shader %d:\n%s\n", shaderType, buf); 48 free(buf); 49 } 50 glDeleteShader(shader); 51 shader = 0; 52 } 53 } 54 } 55 return shader; 56} 57 58enum { 59 A_POS, 60 A_COLOR, 61 A_TEX0, 62 A_TEX1 63}; 64 65GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) { 66 GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); 67 if (!vertexShader) { 68 return 0; 69 } 70 71 GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); 72 if (!pixelShader) { 73 return 0; 74 } 75 76 GLuint program = glCreateProgram(); 77 if (program) { 78 glAttachShader(program, vertexShader); 79 checkGlError("glAttachShader v"); 80 glAttachShader(program, pixelShader); 81 checkGlError("glAttachShader p"); 82 83 glBindAttribLocation(program, A_POS, "a_pos"); 84 glBindAttribLocation(program, A_COLOR, "a_color"); 85 glBindAttribLocation(program, A_TEX0, "a_tex0"); 86 glBindAttribLocation(program, A_TEX1, "a_tex1"); 87 glLinkProgram(program); 88 GLint linkStatus = GL_FALSE; 89 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 90 if (linkStatus != GL_TRUE) { 91 GLint bufLength = 0; 92 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); 93 if (bufLength) { 94 char* buf = (char*) malloc(bufLength); 95 if (buf) { 96 glGetProgramInfoLog(program, bufLength, NULL, buf); 97 ALOGE("Could not link program:\n%s\n", buf); 98 free(buf); 99 } 100 } 101 glDeleteProgram(program); 102 program = 0; 103 } 104 } 105 checkGlError("createProgram"); 106 glUseProgram(program); 107 return program; 108} 109 110uint64_t getTime() { 111 struct timespec t; 112 clock_gettime(CLOCK_MONOTONIC, &t); 113 return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000); 114} 115 116uint64_t gTime; 117void startTimer() { 118 gTime = getTime(); 119} 120 121 122static void endTimer(int count) { 123 uint64_t t2 = getTime(); 124 double delta = ((double)(t2 - gTime)) / 1000000000; 125 double pixels = (gWidth * gHeight) * count; 126 double mpps = pixels / delta / 1000000; 127 double dc60 = ((double)count) / delta / 60; 128 129 if (fOut) { 130 fprintf(fOut, "%s, %f, %f\r\n", gCurrentTestName, mpps, dc60); 131 fflush(fOut); 132 } else { 133 printf("%s, %f, %f\n", gCurrentTestName, mpps, dc60); 134 } 135 ALOGI("%s, %f, %f\r\n", gCurrentTestName, mpps, dc60); 136} 137 138 139static const char gVertexShader[] = 140 "attribute vec4 a_pos;\n" 141 "attribute vec4 a_color;\n" 142 "attribute vec2 a_tex0;\n" 143 "attribute vec2 a_tex1;\n" 144 "varying vec4 v_color;\n" 145 "varying vec2 v_tex0;\n" 146 "varying vec2 v_tex1;\n" 147 "uniform vec2 u_texOff;\n" 148 149 "void main() {\n" 150 " v_color = a_color;\n" 151 " v_tex0 = a_tex0;\n" 152 " v_tex1 = a_tex1;\n" 153 " v_tex0.x += u_texOff.x;\n" 154 " v_tex1.y += u_texOff.y;\n" 155 " gl_Position = a_pos;\n" 156 "}\n"; 157 158static void setupVA() { 159 static const float vtx[] = { 160 -1.0f,-1.0f, 161 1.0f,-1.0f, 162 -1.0f, 1.0f, 163 1.0f, 1.0f }; 164 static const float color[] = { 165 1.0f,0.0f,1.0f,1.0f, 166 0.0f,0.0f,1.0f,1.0f, 167 1.0f,1.0f,0.0f,1.0f, 168 1.0f,1.0f,1.0f,1.0f }; 169 static const float tex0[] = { 170 0.0f,0.0f, 171 1.0f,0.0f, 172 0.0f,1.0f, 173 1.0f,1.0f }; 174 static const float tex1[] = { 175 1.0f,0.0f, 176 1.0f,1.0f, 177 0.0f,1.0f, 178 0.0f,0.0f }; 179 180 glEnableVertexAttribArray(A_POS); 181 glEnableVertexAttribArray(A_COLOR); 182 glEnableVertexAttribArray(A_TEX0); 183 glEnableVertexAttribArray(A_TEX1); 184 185 glVertexAttribPointer(A_POS, 2, GL_FLOAT, false, 8, vtx); 186 glVertexAttribPointer(A_COLOR, 4, GL_FLOAT, false, 16, color); 187 glVertexAttribPointer(A_TEX0, 2, GL_FLOAT, false, 8, tex0); 188 glVertexAttribPointer(A_TEX1, 2, GL_FLOAT, false, 8, tex1); 189} 190 191static void randUniform(int pgm, const char *var) { 192 GLint loc = glGetUniformLocation(pgm, var); 193 if (loc >= 0) { 194 float x = ((float)rand()) / RAND_MAX; 195 float y = ((float)rand()) / RAND_MAX; 196 float z = ((float)rand()) / RAND_MAX; 197 float w = ((float)rand()) / RAND_MAX; 198 glUniform4f(loc, x, y, z, w); 199 } 200} 201 202static void doLoop(bool warmup, int pgm, uint32_t passCount) { 203 if (warmup) { 204 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 205 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 206 ptSwap(); 207 glFinish(); 208 return; 209 } 210 211 startTimer(); 212 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 213 for (uint32_t ct=0; ct < passCount; ct++) { 214 GLint loc = glGetUniformLocation(pgm, "u_texOff"); 215 glUniform2f(loc, ((float)ct) / passCount, ((float)ct) / 2.f / passCount); 216 217 randUniform(pgm, "u_color"); 218 randUniform(pgm, "u_0"); 219 randUniform(pgm, "u_1"); 220 randUniform(pgm, "u_2"); 221 randUniform(pgm, "u_3"); 222 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 223 } 224 ptSwap(); 225 glFinish(); 226 endTimer(passCount); 227} 228 229 230static uint32_t rgb(uint32_t r, uint32_t g, uint32_t b) 231{ 232 uint32_t ret = 0xff000000; 233 ret |= r & 0xff; 234 ret |= (g & 0xff) << 8; 235 ret |= (b & 0xff) << 16; 236 return ret; 237} 238 239void genTextures() { 240 uint32_t *m = (uint32_t *)malloc(1024*1024*4); 241 for (int y=0; y < 1024; y++){ 242 for (int x=0; x < 1024; x++){ 243 m[y*1024 + x] = rgb(x, (((x+y) & 0xff) == 0x7f) * 0xff, y); 244 } 245 } 246 glBindTexture(GL_TEXTURE_2D, 1); 247 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, m); 248 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 249 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 250 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 251 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 252 253 for (int y=0; y < 16; y++){ 254 for (int x=0; x < 16; x++){ 255 m[y*16 + x] = rgb(x << 4, (((x+y) & 0xf) == 0x7) * 0xff, y << 4); 256 } 257 } 258 glBindTexture(GL_TEXTURE_2D, 2); 259 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, m); 260 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 261 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 263 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 264 free(m); 265} 266 267static void doSingleTest(uint32_t pgmNum, int tex) { 268 const char *pgmTxt = gFragmentTests[pgmNum]->txt; 269 int pgm = createProgram(gVertexShader, pgmTxt); 270 if (!pgm) { 271 printf("error running test\n"); 272 return; 273 } 274 GLint loc = glGetUniformLocation(pgm, "u_tex0"); 275 if (loc >= 0) glUniform1i(loc, 0); 276 loc = glGetUniformLocation(pgm, "u_tex1"); 277 if (loc >= 0) glUniform1i(loc, 1); 278 279 280 glActiveTexture(GL_TEXTURE0); 281 glBindTexture(GL_TEXTURE_2D, tex); 282 glActiveTexture(GL_TEXTURE1); 283 glBindTexture(GL_TEXTURE_2D, tex); 284 glActiveTexture(GL_TEXTURE0); 285 286 glBlendFunc(GL_ONE, GL_ONE); 287 glDisable(GL_BLEND); 288 //sprintf(str2, "%i, %i, %i, %i, %i, 0", 289 //useVarColor, texCount, modulateFirstTex, extraMath, tex0); 290 //doLoop(true, pgm, w, h, str2); 291 //doLoop(false, pgm, w, h, str2); 292 293 glEnable(GL_BLEND); 294 sprintf(gCurrentTestName, "%s, %i, %i, 1", gFragmentTests[pgmNum]->name, pgmNum, tex); 295 doLoop(true, pgm, 100); 296 doLoop(false, pgm, 100); 297} 298 299