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