blob: 3d5757fb0981e590c75780ae0bf6b9972772fd08 [file] [log] [blame]
Jason Samse448dd12010-07-09 15:34:32 -07001/*
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>
Andy McFaddena5c381f2010-07-12 09:17:13 -070022#include <string.h>
Jason Samse448dd12010-07-09 15:34:32 -070023
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}