filltest.cpp revision a5c381fd51deb4bdd8fea3141ad00925f2e2cfb6
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 <stdlib.h> 18#include <stdio.h> 19#include <time.h> 20#include <sched.h> 21#include <sys/resource.h> 22#include <string.h> 23 24#include <GLES2/gl2.h> 25#include <GLES2/gl2ext.h> 26#include <utils/Timers.h> 27#include <EGL/egl.h> 28 29 30using namespace android; 31 32static void checkGlError(const char* op) { 33 for (GLint error = glGetError(); error; error 34 = glGetError()) { 35 fprintf(stderr, "after %s() glError (0x%x)\n", op, error); 36 } 37} 38 39GLuint loadShader(GLenum shaderType, const char* pSource) { 40 GLuint shader = glCreateShader(shaderType); 41 if (shader) { 42 glShaderSource(shader, 1, &pSource, NULL); 43 glCompileShader(shader); 44 GLint compiled = 0; 45 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 46 if (!compiled) { 47 GLint infoLen = 0; 48 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 49 if (infoLen) { 50 char* buf = (char*) malloc(infoLen); 51 if (buf) { 52 glGetShaderInfoLog(shader, infoLen, NULL, buf); 53 fprintf(stderr, "Could not compile shader %d:\n%s\n", 54 shaderType, buf); 55 free(buf); 56 } 57 glDeleteShader(shader); 58 shader = 0; 59 } 60 } 61 } 62 return shader; 63} 64 65enum { 66 A_POS, 67 A_COLOR, 68 A_TEX0, 69 A_TEX1 70}; 71 72GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) { 73 GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); 74 if (!vertexShader) { 75 return 0; 76 } 77 78 GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); 79 if (!pixelShader) { 80 return 0; 81 } 82 83 GLuint program = glCreateProgram(); 84 if (program) { 85 glAttachShader(program, vertexShader); 86 checkGlError("glAttachShader v"); 87 glAttachShader(program, pixelShader); 88 checkGlError("glAttachShader p"); 89 90 glBindAttribLocation(program, A_POS, "a_pos"); 91 glBindAttribLocation(program, A_COLOR, "a_color"); 92 glBindAttribLocation(program, A_TEX0, "a_tex0"); 93 glBindAttribLocation(program, A_TEX1, "a_tex1"); 94 glLinkProgram(program); 95 GLint linkStatus = GL_FALSE; 96 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 97 if (linkStatus != GL_TRUE) { 98 GLint bufLength = 0; 99 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); 100 if (bufLength) { 101 char* buf = (char*) malloc(bufLength); 102 if (buf) { 103 glGetProgramInfoLog(program, bufLength, NULL, buf); 104 printf("Could not link program:\n%s\n", buf); 105 free(buf); 106 } 107 } 108 glDeleteProgram(program); 109 program = 0; 110 } 111 } 112 checkGlError("createProgram"); 113 glUseProgram(program); 114 return program; 115} 116 117uint64_t getTime() { 118 struct timespec t; 119 clock_gettime(CLOCK_MONOTONIC, &t); 120 return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000); 121} 122 123uint64_t gTime; 124void startTimer() { 125 gTime = getTime(); 126} 127 128void endTimer(const char *str, int w, int h, double dc, int count) { 129 uint64_t t2 = getTime(); 130 double delta = ((double)(t2 - gTime)) / 1000000000; 131 double pixels = dc * (w * h) * count; 132 double mpps = pixels / delta / 1000000; 133 double dc60 = pixels / delta / (w * h) / 60; 134 135 printf("test %s, Mpps %f, dc = %f\n", str, mpps, dc60); 136} 137 138static const char gVertexShader[] = 139 "attribute vec4 a_pos;\n" 140 "attribute vec4 a_color;\n" 141 "attribute vec2 a_tex0;\n" 142 "attribute vec2 a_tex1;\n" 143 "varying vec4 v_color;\n" 144 "varying vec2 v_tex0;\n" 145 "varying vec2 v_tex1;\n" 146 147 "void main() {\n" 148 " v_color = a_color;\n" 149 " v_tex0 = a_tex0;\n" 150 " v_tex1 = a_tex1;\n" 151 " gl_Position = a_pos;\n" 152 "}\n"; 153 154static const char gShaderPrefix[] = 155 "precision mediump float;\n" 156 "uniform vec4 u_color;\n" 157 "uniform vec4 u_0;\n" 158 "uniform vec4 u_1;\n" 159 "uniform vec4 u_2;\n" 160 "uniform vec4 u_3;\n" 161 "varying vec4 v_color;\n" 162 "varying vec2 v_tex0;\n" 163 "varying vec2 v_tex1;\n" 164 "uniform sampler2D u_tex0;\n" 165 "uniform sampler2D u_tex1;\n" 166 "void main() {\n"; 167 168static const char gShaderPostfix[] = 169 " gl_FragColor = c;\n" 170 "}\n"; 171 172 173static char * append(char *d, const char *s) { 174 size_t len = strlen(s); 175 memcpy(d, s, len); 176 return d + len; 177} 178 179static char * genShader( 180 bool useVarColor, 181 int texCount, 182 bool modulateFirstTex, 183 int extraMath) 184{ 185 char *str = (char *)calloc(16 * 1024, 1); 186 char *tmp = append(str, gShaderPrefix); 187 188 if (modulateFirstTex || !texCount) { 189 if (useVarColor) { 190 tmp = append(tmp, " vec4 c = v_color;\n"); 191 } else { 192 tmp = append(tmp, " vec4 c = u_color;\n"); 193 } 194 } else { 195 tmp = append(tmp, " vec4 c = texture2D(u_tex0, v_tex0);\n"); 196 } 197 198 if (modulateFirstTex && texCount) { 199 tmp = append(tmp, " c *= texture2D(u_tex0, v_tex0);\n"); 200 } 201 if (texCount > 1) { 202 tmp = append(tmp, " c *= texture2D(u_tex1, v_tex1);\n"); 203 } 204 205 if (extraMath > 0) { 206 tmp = append(tmp, " c *= u_0;\n"); 207 } 208 if (extraMath > 1) { 209 tmp = append(tmp, " c *= u_1;\n"); 210 } 211 if (extraMath > 2) { 212 tmp = append(tmp, " c *= u_2;\n"); 213 } 214 if (extraMath > 3) { 215 tmp = append(tmp, " c *= u_3;\n"); 216 } 217 218 219 tmp = append(tmp, gShaderPostfix); 220 tmp[0] = 0; 221 222 //printf("%s", str); 223 return str; 224} 225 226static void setupVA() { 227 static const float vtx[] = { 228 -2.0f,-1.0f, 229 1.0f,-1.0f, 230 -2.0f, 1.0f, 231 1.0f, 1.0f }; 232 static const float color[] = { 233 1.0f,0.0f,1.0f,1.0f, 234 0.0f,0.0f,1.0f,1.0f, 235 1.0f,1.0f,0.0f,1.0f, 236 1.0f,1.0f,1.0f,1.0f }; 237 static const float tex0[] = { 238 0.0f,0.0f, 239 1.0f,0.0f, 240 1.0f,1.0f, 241 0.0f,1.0f }; 242 static const float tex1[] = { 243 1.0f,0.0f, 244 1.0f,1.0f, 245 0.0f,1.0f, 246 0.0f,0.0f }; 247 248 glEnableVertexAttribArray(A_POS); 249 glEnableVertexAttribArray(A_COLOR); 250 glEnableVertexAttribArray(A_TEX0); 251 glEnableVertexAttribArray(A_TEX1); 252 253 glVertexAttribPointer(A_POS, 2, GL_FLOAT, false, 8, vtx); 254 glVertexAttribPointer(A_COLOR, 4, GL_FLOAT, false, 16, color); 255 glVertexAttribPointer(A_TEX0, 2, GL_FLOAT, false, 8, tex0); 256 glVertexAttribPointer(A_TEX1, 2, GL_FLOAT, false, 8, tex1); 257} 258 259////////////////////////// 260 261void ptSwap(); 262 263static void doLoop(uint32_t w, uint32_t h, const char *str) { 264 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 265 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 266 ptSwap(); 267 glFinish(); 268 269 startTimer(); 270 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 271 for (int ct=0; ct < 100; ct++) { 272 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 273 } 274 ptSwap(); 275 glFinish(); 276 endTimer(str, w, h, 1, 100); 277} 278 279static void doSingleTest(uint32_t w, uint32_t h, 280 bool useVarColor, 281 int texCount, 282 bool modulateFirstTex, 283 int extraMath, 284 int tex0, int tex1) { 285 char *pgmTxt = genShader(useVarColor, texCount, modulateFirstTex, extraMath); 286 int pgm = createProgram(gVertexShader, pgmTxt); 287 if (!pgm) { 288 printf("error running test\n"); 289 return; 290 } 291 int loc = glGetUniformLocation(pgm, "u_tex0"); 292 //printf("loc = %i \n", loc); 293 if (loc >= 0) glUniform1i(loc, 0); 294 loc = glGetUniformLocation(pgm, "u_tex1"); 295 if (loc >= 0) glUniform1i(loc, 1); 296 297 loc = glGetUniformLocation(pgm, "u_color"); 298 if (loc >= 0) glUniform4f(loc, 1.f, 0.4f, 0.6f, 0.8f); 299 300 loc = glGetUniformLocation(pgm, "u_0"); 301 if (loc >= 0) glUniform4f(loc, 1.f, 0.4f, 0.6f, 0.8f); 302 303 loc = glGetUniformLocation(pgm, "u_1"); 304 if (loc >= 0) glUniform4f(loc, 0.7f, 0.8f, 0.6f, 0.8f); 305 306 loc = glGetUniformLocation(pgm, "u_2"); 307 if (loc >= 0) glUniform4f(loc, 0.9f, 0.6f, 0.7f, 1.0f); 308 309 loc = glGetUniformLocation(pgm, "u_3"); 310 if (loc >= 0) glUniform4f(loc, 0.88f, 0.2f, 0.4f, 0.2f); 311 312 glActiveTexture(GL_TEXTURE0); 313 glBindTexture(GL_TEXTURE_2D, tex0); 314 glActiveTexture(GL_TEXTURE1); 315 glBindTexture(GL_TEXTURE_2D, tex1); 316 glActiveTexture(GL_TEXTURE0); 317 318 char str2[1024]; 319 320 glBlendFunc(GL_ONE, GL_ONE); 321 glDisable(GL_BLEND); 322 sprintf(str2, "Test varColor=%i, texCount=%i, modulate=%i, extraMath=%i, texSize=%i, blend=0", 323 useVarColor, texCount, modulateFirstTex, extraMath, tex0); 324 doLoop(w, h, str2); 325 326 glEnable(GL_BLEND); 327 sprintf(str2, "Test varColor=%i, texCount=%i, modulate=%i, extraMath=%i, texSize=%i, blend=1", 328 useVarColor, texCount, modulateFirstTex, extraMath, tex0); 329 doLoop(w, h, str2); 330} 331 332void genTextures() { 333 uint32_t *m = (uint32_t *)malloc(1024*1024*4); 334 for (int y=0; y < 1024; y++){ 335 for (int x=0; x < 1024; x++){ 336 m[y*1024 + x] = 0xff0000ff | ((x & 0xff) << 8) | (y << 16); 337 } 338 } 339 glBindTexture(GL_TEXTURE_2D, 1); 340 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, m); 341 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 342 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 343 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 344 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 345 346 for (int y=0; y < 16; y++){ 347 for (int x=0; x < 16; x++){ 348 m[y*16 + x] = 0xff0000ff | (x<<12) | (y<<20); 349 } 350 } 351 glBindTexture(GL_TEXTURE_2D, 2); 352 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, m); 353 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 354 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 355 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 356 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 357 358} 359 360bool doTest(uint32_t w, uint32_t h) { 361 setupVA(); 362 genTextures(); 363 364 for (int texCount = 0; texCount < 3; texCount++) { 365 for (int extraMath = 0; extraMath < 5; extraMath++) { 366 367 doSingleTest(w, h, false, texCount, false, extraMath, 1, 1); 368 doSingleTest(w, h, true, texCount, false, extraMath, 1, 1); 369 if (texCount) { 370 doSingleTest(w, h, false, texCount, true, extraMath, 1, 1); 371 doSingleTest(w, h, true, texCount, true, extraMath, 1, 1); 372 373 doSingleTest(w, h, false, texCount, false, extraMath, 2, 2); 374 doSingleTest(w, h, true, texCount, false, extraMath, 2, 2); 375 doSingleTest(w, h, false, texCount, true, extraMath, 2, 2); 376 doSingleTest(w, h, true, texCount, true, extraMath, 2, 2); 377 } 378 } 379 } 380 381 exit(0); 382 return true; 383} 384