blob: f8ca9b2e0eeea7399cfd0284d832f8cf07556fee [file] [log] [blame]
Mathias Agopian076b1cc2009-04-10 14:24:30 -07001// Test software OpenGL hardware accelleration using copybits.
2
3#define LOG_TAG "copybits_test"
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <math.h>
8#include <sys/types.h>
9#include <stdlib.h>
10#include <string.h>
11#include <sys/time.h>
12
13#include <ui/PixelFormat.h>
14
15#include <cutils/log.h>
16#include <cutils/native_handle.h>
17
18#include <utils/Atomic.h>
19
Mathias Agopian7e2a9372009-06-09 21:38:08 -070020#include <private/ui/SurfaceBuffer.h>
21#include <pixelflinger/pixelflinger.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070022
23#include <hardware/gralloc.h>
24#include <hardware/hardware.h>
25
26#define EGL_EGLEXT_PROTOTYPES
27#define GL_GLEXT_PROTOTYPES
28
29#include <EGL/egl.h>
30#include <EGL/eglext.h>
31
32#include <GLES/gl.h>
33#include <GLES/glext.h>
34
35extern "C" EGLNativeWindowType android_createDisplaySurface(void);
36
37using namespace android;
38
39EGLDisplay eglDisplay;
40EGLSurface eglSurface;
41EGLContext eglContext;
42GLuint texture;
43
44hw_module_t const* gralloc_module;
45alloc_device_t *sAllocDev;
46
Jack Palevich8f75e092009-04-13 22:03:39 -070047#define FIXED_ONE 0x10000 /* 1.0 in 16.16 fixed point. */
Mathias Agopian076b1cc2009-04-10 14:24:30 -070048
49int init_gl_surface();
50void free_gl_surface();
51void init_scene();
52
53int create_physical_texture();
54int readTimer();
55
56// ===========================================================================
Mathias Agopian7e2a9372009-06-09 21:38:08 -070057// Buffer an implementation of android_native_buffer_t
Mathias Agopian076b1cc2009-04-10 14:24:30 -070058// ===========================================================================
59
60class NativeBuffer;
61
Mathias Agopian7e2a9372009-06-09 21:38:08 -070062class Buffer : public android::SurfaceBuffer
Mathias Agopian076b1cc2009-04-10 14:24:30 -070063{
64public:
Mathias Agopian076b1cc2009-04-10 14:24:30 -070065 // creates w * h buffer
Mathias Agopian7e2a9372009-06-09 21:38:08 -070066 Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage);
Mathias Agopian076b1cc2009-04-10 14:24:30 -070067
68 // return status
69 status_t initCheck() const;
70
Mathias Agopian7e2a9372009-06-09 21:38:08 -070071 uint32_t getWidth() const { return width; }
72 uint32_t getHeight() const { return height; }
73 uint32_t getStride() const { return stride; }
74 uint32_t getUsage() const { return usage; }
75 PixelFormat getPixelFormat() const { return format; }
76
77
Mathias Agopian076b1cc2009-04-10 14:24:30 -070078 android_native_buffer_t* getNativeBuffer() const;
79
80 void setPixel(int x, int y, int r, int g, int b, int a);
81
Mathias Agopian7e2a9372009-06-09 21:38:08 -070082 status_t lock(GGLSurface* surface, uint32_t usage);
83 void lock() {
84 GGLSurface s;
85 lock(&s, GRALLOC_USAGE_SW_WRITE_OFTEN);
86 mData = (void*)s.data;
87 }
88
Mathias Agopian076b1cc2009-04-10 14:24:30 -070089private:
90 friend class LightRefBase<Buffer>;
91 Buffer(const Buffer& rhs);
Mathias Agopian7e2a9372009-06-09 21:38:08 -070092 virtual ~Buffer();
Mathias Agopian076b1cc2009-04-10 14:24:30 -070093 Buffer& operator = (const Buffer& rhs);
94 const Buffer& operator = (const Buffer& rhs) const;
95
96 status_t initSize(uint32_t w, uint32_t h);
97
Mathias Agopian076b1cc2009-04-10 14:24:30 -070098 ssize_t mInitCheck;
Mathias Agopian076b1cc2009-04-10 14:24:30 -070099 void* mData;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700100};
101
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700102Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage)
Mathias Agopian0a3139a2009-06-10 16:01:54 -0700103 : SurfaceBuffer(), mInitCheck(NO_INIT)
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700104{
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700105 this->usage = usage;
106 this->format = format;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700107 if (w>0 && h>0) {
108 mInitCheck = initSize(w, h);
109 }
110}
111
112Buffer::~Buffer()
113{
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700114 if (handle) {
115 sAllocDev->free(sAllocDev, handle);
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700116 }
117}
118
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700119status_t Buffer::initCheck() const {
120 return mInitCheck;
121}
122
123android_native_buffer_t* Buffer::getNativeBuffer() const
124{
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700125 return static_cast<android_native_buffer_t*>(const_cast<Buffer*>(this));
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700126}
127
128status_t Buffer::initSize(uint32_t w, uint32_t h)
129{
130 status_t err = NO_ERROR;
131
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700132 err = sAllocDev->alloc(sAllocDev, w, h, format, usage, &handle, &stride);
133
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700134 if (err == NO_ERROR) {
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700135 if (err == NO_ERROR) {
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700136 width = w;
137 height = h;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700138 }
139 }
140
141 return err;
142}
143
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700144status_t Buffer::lock(GGLSurface* sur, uint32_t usage)
145{
146 void* vaddr;
147 status_t res = SurfaceBuffer::lock(usage, &vaddr);
148 if (res == NO_ERROR && sur) {
149 sur->version = sizeof(GGLSurface);
150 sur->width = width;
151 sur->height = height;
152 sur->stride = stride;
153 sur->format = format;
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700154 sur->data = static_cast<GGLubyte*>(vaddr);
155 }
156 return res;
157}
158
159
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700160void Buffer::setPixel(int x, int y, int r, int g, int b, int a) {
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700161 if (x < 0 || (unsigned int) x >= width
162 || y < 0 || (unsigned int) y >= height) {
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700163 // clipped
164 return;
165 }
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700166 int index = stride * y + x;
167 switch (format) {
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700168 case HAL_PIXEL_FORMAT_RGB_565: {
169 unsigned short val = (unsigned short) (
170 ((0x1f & (r >> 3)) << 11)
171 | ((0x3f & (g >> 2)) << 5)
172 | (0x1f & (b >> 3)));
173 ((unsigned short*) mData)[index]= val;
174 }
175 break;
176 case HAL_PIXEL_FORMAT_RGBA_8888: { // ABGR
177 unsigned int val = (unsigned int)
178 (((a & 0xff) << 24)
179 | ((b & 0xff) << 16)
180 | ((g & 0xff) << 8)
181 | (r & 0xff));
182 ((unsigned int*) mData)[index] = val;
183 }
184 break;
185 default:
186 // Unsupported pixel format
187 break;
188 }
189}
190
191
192static void gluLookAt(float eyeX, float eyeY, float eyeZ,
193 float centerX, float centerY, float centerZ, float upX, float upY,
194 float upZ)
195{
196 // See the OpenGL GLUT documentation for gluLookAt for a description
197 // of the algorithm. We implement it in a straightforward way:
198
199 float fx = centerX - eyeX;
200 float fy = centerY - eyeY;
201 float fz = centerZ - eyeZ;
202
203 // Normalize f
204 float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz);
205 fx *= rlf;
206 fy *= rlf;
207 fz *= rlf;
208
209 // Normalize up
210 float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ);
211 upX *= rlup;
212 upY *= rlup;
213 upZ *= rlup;
214
215 // compute s = f x up (x means "cross product")
216
217 float sx = fy * upZ - fz * upY;
218 float sy = fz * upX - fx * upZ;
219 float sz = fx * upY - fy * upX;
220
221 // compute u = s x f
222 float ux = sy * fz - sz * fy;
223 float uy = sz * fx - sx * fz;
224 float uz = sx * fy - sy * fx;
225
226 float m[16] ;
227 m[0] = sx;
228 m[1] = ux;
229 m[2] = -fx;
230 m[3] = 0.0f;
231
232 m[4] = sy;
233 m[5] = uy;
234 m[6] = -fy;
235 m[7] = 0.0f;
236
237 m[8] = sz;
238 m[9] = uz;
239 m[10] = -fz;
240 m[11] = 0.0f;
241
242 m[12] = 0.0f;
243 m[13] = 0.0f;
244 m[14] = 0.0f;
245 m[15] = 1.0f;
246
247 glMultMatrixf(m);
248 glTranslatef(-eyeX, -eyeY, -eyeZ);
249}
250
251int init_gralloc() {
252 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &gralloc_module);
253 LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
254
255 if (err == 0) {
256 gralloc_open(gralloc_module, &sAllocDev);
257 }
258 return err;
259}
260
261int init_gl_surface(void)
262{
263 EGLint numConfigs = 1;
264 EGLConfig myConfig = {0};
265 EGLint attrib[] =
266 {
267 EGL_DEPTH_SIZE, 16,
268 EGL_NONE
269 };
270
271 printf("init_gl_surface\n");
272 if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY )
273 {
274 printf("eglGetDisplay failed\n");
275 return 0;
276 }
277
278 if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE )
279 {
280 printf("eglInitialize failed\n");
281 return 0;
282 }
283
284 if ( eglChooseConfig(eglDisplay, attrib, &myConfig, 1, &numConfigs) != EGL_TRUE )
285 {
286 printf("eglChooseConfig failed\n");
287 return 0;
288 }
289
290 if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig,
291 android_createDisplaySurface(), 0)) == EGL_NO_SURFACE )
292 {
293 printf("eglCreateWindowSurface failed\n");
294 return 0;
295 }
296
297 if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT )
298 {
299 printf("eglCreateContext failed\n");
300 return 0;
301 }
302
303 if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE )
304 {
305 printf("eglMakeCurrent failed\n");
306 return 0;
307 }
308
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700309#if EGL_ANDROID_swap_rectangle
310 eglSetSwapRectangleANDROID(eglDisplay, eglSurface, 0, 0, 320, 480);
311#endif
312
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700313 return 1;
314}
315
316void free_gl_surface(void)
317{
318 if (eglDisplay != EGL_NO_DISPLAY)
319 {
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700320 eglMakeCurrent( eglDisplay, EGL_NO_SURFACE,
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700321 EGL_NO_SURFACE, EGL_NO_CONTEXT );
322 eglDestroyContext( eglDisplay, eglContext );
323 eglDestroySurface( eglDisplay, eglSurface );
324 eglTerminate( eglDisplay );
325 eglDisplay = EGL_NO_DISPLAY;
326 }
327}
328
329void init_scene(void)
330{
331 glDisable(GL_DITHER);
332 glEnable(GL_CULL_FACE);
333 float ratio = 320.0f / 480.0f;
334 glViewport(0, 0, 320, 480);
335
336 glMatrixMode(GL_PROJECTION);
337 glLoadIdentity();
338 glFrustumf(-ratio, ratio, -1, 1, 1, 10);
339
340 glMatrixMode(GL_MODELVIEW);
341
342 glLoadIdentity();
343 gluLookAt(
344 0, 0, 3, // eye
345 0, 0, 0, // center
346 0, 1, 0); // up
347
348 glEnable(GL_TEXTURE_2D);
349}
350
351// #define USE_ALPHA_COLOR
352
353#define USE_GL_REPLACE
Mathias Agopian0a3139a2009-06-10 16:01:54 -0700354//#define USE_GL_MODULATE
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700355
356// #define USE_BLEND
357
358#define USE_565
359// #define USE_8888
360
361// #define USE_NEAREST
362#define USE_LINEAR
363
364#define USE_SCALE
365
366void setSmoothGradient(Buffer* bufferObject) {
367 int pixels = bufferObject->getHeight() * bufferObject->getWidth();
368 int step = 0;
369 for (unsigned int y = 0; y < bufferObject->getHeight(); y++) {
370 for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) {
371 int grey = step * 255 / pixels;
372 bufferObject->setPixel(x, y, grey, grey, grey, 255);
373 ++step;
374 }
375 }
376}
377
378void setSmoothAlphaGradient(Buffer* bufferObject) {
379 int pixels = bufferObject->getHeight() * bufferObject->getWidth();
380 int step = 0;
381 for (unsigned int y = 0; y < bufferObject->getHeight(); y++) {
382 for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) {
383 int grey = step * 255 / pixels;
384 bufferObject->setPixel(x, y, 255, 255, 255, grey);
385 ++step;
386 }
387 }
388}
389
390void setOrientedCheckerboard(Buffer* bufferObject) {
391 bufferObject->setPixel(0, 0, 0, 0, 0, 255);
392 for(unsigned int x = 1; x < bufferObject->getWidth() ; x++) {
393 bufferObject->setPixel(x, 0, 0, 255, 0, 255);
394 }
395 for (unsigned int y = 1; y < bufferObject->getHeight(); y++) {
396 for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) {
397 if ((x ^ y ) & 1) {
398 bufferObject->setPixel(x, y, 255, 255, 255, 255);
399 } else {
400 bufferObject->setPixel(x, y, 255, 0, 0, 255);
401 }
402 }
403 }
404}
405
406int create_physical_texture(unsigned int w, unsigned int h)
407{
408
409#ifdef USE_565
410 PixelFormat format = HAL_PIXEL_FORMAT_RGB_565;
411#else
412 PixelFormat format = HAL_PIXEL_FORMAT_RGBA_8888;
413#endif
414 int usage = GRALLOC_USAGE_SW_READ_OFTEN |
415 GRALLOC_USAGE_SW_WRITE_OFTEN |
416 GRALLOC_USAGE_HW_TEXTURE |
417 GRALLOC_USAGE_HW_2D; /* This is the key to allocating the texture in pmem. */
418 int32_t stride;
419 buffer_handle_t handle;
420
421 // Allocate the hardware buffer
422 Buffer* bufferObject = new Buffer(w, h, format, usage);
423
424 android_native_buffer_t* buffer = bufferObject->getNativeBuffer();
425
426 buffer->common.incRef(&buffer->common);
427
428 // create the new EGLImageKHR
429 EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_NONE };
430 EGLDisplay dpy = eglGetCurrentDisplay();
431 EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
432 (EGLClientBuffer)buffer, attrs);
433 if (image == EGL_NO_IMAGE_KHR) {
434 printf("Could not create an image %d\n", eglGetError());
435 return -1;
436 }
437
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700438 bufferObject->lock();
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700439 setOrientedCheckerboard(bufferObject);
440 // setSmoothGradient(bufferObject);
441 // setSmoothAlphaGradient(bufferObject);
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700442 bufferObject->unlock();
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700443
444 glGenTextures(1, &texture);
445 glBindTexture(GL_TEXTURE_2D, texture);
446 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
447#ifdef USE_LINEAR
448 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
449 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
450#elif defined(USE_NEAREST)
451 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
452 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
453#endif
454
455#ifdef USE_GL_REPLACE
456 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
457#elif defined(USE_GL_MODULATE)
458 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
459#endif
460
461#ifdef USE_ALPHA_COLOR
462 glColor4f(1.0f, 1.0f, 1.0f, 0.4f);
463#else
464 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
465#endif
466
467#ifdef USE_BLEND
468 glEnable(GL_BLEND);
469 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
470#endif
471 return 0;
472}
473
474static const int SCALE_COUNT = 12;
475
476int scale(int base, int factor) {
477 static const float kTable[SCALE_COUNT] = {
Mathias Agopian0a3139a2009-06-10 16:01:54 -0700478 0.24f, 0.25f, 0.5f, 0.75f, 1.0f,
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700479 1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 5.0f
480 };
481 return base * kTable[factor];
482}
483
484class Timer {
485 struct timeval first;
486 double elapsedSeconds;
487
488public:
489 Timer() {}
490 void start() {
491 gettimeofday(&first, NULL);
492 }
493
494 void stop() {
495 struct timeval second,
496 elapsed;
497 gettimeofday(&second, NULL);
498
499 if (first.tv_usec > second.tv_usec) {
500 second.tv_usec += 1000000;
501 second.tv_sec--;
502 }
503
504 elapsedSeconds = (second.tv_sec - first.tv_sec) +
505 (second.tv_usec - first.tv_usec) / 1000000.0;
506 }
507
508 double getElapsedSeconds() {
509 return elapsedSeconds;
510 }
511
512 double getElapsedMs() {
513 return elapsedSeconds* 1000.0f;
514 }
515};
516
517int testTime()
518{
519 static const int WIDTH = 320;
520 static const int HEIGHT = 480;
521 static const int SCALE = 8;
522
523 if (create_physical_texture(WIDTH, HEIGHT) != 0) {
524 return -1;
525 }
526 // Need to do a dummy eglSwapBuffers first. Don't know why.
527 glClearColor(0.4, 1.0, 0.4, 0.4);
528 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
529 eglSwapBuffers(eglDisplay, eglSurface);
530
531 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
532
533#if defined(USE_SCALE)
534 static const int scaleOffset = 0;
535#else
536 static const int scaleOffset = 1;
537#endif
538 printf("ms\n");
539 for(int j = 0; j < SCALE; j++) {
540 int w = WIDTH >> (j + scaleOffset);
541 int h = HEIGHT >> j;
542 int cropRect[4] = {0,h,w,-h}; // Left bottom width height. Width and Height can be neg to flip.
543 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect);
544 Timer timer;
545 timer.start();
546
547 int copyCount = 1000;
548 for (int i = 0; i < copyCount; i++) {
549 glDrawTexiOES(0, 0, 0, w, h);
550 }
551
552 timer.stop();
553 printf("%g\n", timer.getElapsedMs() / copyCount);
554 }
555
556 eglSwapBuffers(eglDisplay, eglSurface);
557 return 0;
558}
559
560int testStretch()
561{
562 static const int WIDTH = 8;
563 static const int HEIGHT = 8;
564
565 if (create_physical_texture(WIDTH, HEIGHT) != 0) {
566 return -1;
567 }
568 // Need to do a dummy eglSwapBuffers first. Don't know why.
Mathias Agopian0a3139a2009-06-10 16:01:54 -0700569 glClearColor(0.4, 1.0, 0.4, 1.0);
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700570 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
571 eglSwapBuffers(eglDisplay, eglSurface);
Mathias Agopian0a3139a2009-06-10 16:01:54 -0700572
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700573 int cropRect[4] = {0,HEIGHT,WIDTH,-HEIGHT}; // Left bottom width height. Width and Height can be neg to flip.
574 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect);
575
576 for(int frame = 0; frame < 2; frame++) {
577 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
578 int baseX = 10;
579 for (int x = 0; x < SCALE_COUNT; x++) {
580 int baseY = 10;
581 int width = scale(WIDTH, x);
582 for (int y = 0; y < SCALE_COUNT; y++) {
583 int height = scale(HEIGHT, y);
584 glDrawTexxOES(baseX << 16, baseY << 16, 0, width << 16, height << 16);
585 baseY += height + 10;
586 }
587 baseX += width + 10;
588 }
589
590 eglSwapBuffers(eglDisplay, eglSurface);
Mathias Agopian0a3139a2009-06-10 16:01:54 -0700591 LOGD("wait 1s");
592 usleep(1000000);
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700593 }
594 return 0;
595}
596
597int testRot90()
598{
599 static const int WIDTH = 8;
600 static const int HEIGHT = 8;
601
602 if (create_physical_texture(WIDTH, HEIGHT) != 0) {
603 return -1;
604 }
605
606 glMatrixMode(GL_PROJECTION);
607 glLoadIdentity();
608 glOrthof(0, 320, 480, 0, 0, 1);
609
610 glMatrixMode(GL_MODELVIEW);
611
612 glLoadIdentity();
613
614 // Need to do a dummy eglSwapBuffers first. Don't know why.
615 glClearColor(0.4, 0.4, 0.4, 0.4);
616 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
617 eglSwapBuffers(eglDisplay, eglSurface);
618
619 glEnable(GL_TEXTURE_2D);
620 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
621 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
622 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
623 glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
624 glDisable(GL_BLEND);
625 glShadeModel(GL_FLAT);
626 glDisable(GL_DITHER);
627 glDisable(GL_CULL_FACE);
628
629 for(int frame = 0; frame < 2; frame++) {
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700630 LOGD("frame = %d", frame);
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700631 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
632 int baseX = 10;
633 for (int x = 0; x < SCALE_COUNT; x++) {
634 int baseY = 10;
635 int width = scale(WIDTH, x);
636 for (int y = 0; y < SCALE_COUNT; y++) {
637 int height = scale(HEIGHT, y);
638
639 // Code copied from SurfaceFlinger LayerBase.cpp
640
641 const GLfixed texCoords[4][2] = {
642 { 0, 0 },
643 { 0, 0x10000 },
644 { 0x10000, 0x10000 },
645 { 0x10000, 0 }
646 };
647
648 GLfixed fx = baseX << 16;
649 GLfixed fy = baseY << 16;
650 GLfixed fw = width << 16;
651 GLfixed fh = height << 16;
652
653 /*
654 * Vertex pattern:
655 * (2)--(3)
656 * |\ |
657 * | \ |
658 * | \ |
659 * | \|
660 * (1)--(0)
661 *
662 */
663
664 const GLfixed vertices[4][2] = {
665 {fx + fw, fy},
666 {fx, fy},
667 {fx, fy + fh},
668 {fx + fw, fy + fh}
669 };
670
671 static const bool rotate90 = true;
672
673 glMatrixMode(GL_TEXTURE);
674 glLoadIdentity();
675
676 glEnableClientState(GL_VERTEX_ARRAY);
677 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
678 glVertexPointer(2, GL_FIXED, 0, vertices);
679 glTexCoordPointer(2, GL_FIXED, 0, texCoords);
680
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700681 LOGD("testRot90 %d, %d %d, %d", baseX, baseY, width, height);
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700682 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
683
684 baseY += height + 10;
685 }
686 baseX += width + 10;
687 }
688
689 eglSwapBuffers(eglDisplay, eglSurface);
690 }
691 return 0;
692}
693
694int main(int argc, char **argv)
695{
696
697 int q;
698 int start, end;
699
700 if (init_gralloc()) {
701 printf("gralloc initialization failed - exiting\n");
702 return 0;
703 }
704
705 printf("Initializing EGL...\n");
706
707 if(!init_gl_surface())
708 {
709 printf("GL initialisation failed - exiting\n");
710 return 0;
711 }
712
713 init_scene();
714
715 printf("Start test...\n");
716 // testTime();
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700717 testStretch();
718 //testRot90();
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700719 free_gl_surface();
720
721 return 0;
722}