blob: d15526c65e948cf6eaa6771095aece585197e9ad [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 Agopian7e2a9372009-06-09 21:38:08 -070099 uint32_t mFlags;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700100 uint32_t mVStride;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700101 void* mData;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700102};
103
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700104Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage)
105 : SurfaceBuffer(), mInitCheck(NO_INIT), mVStride(0)
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700106{
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700107 this->usage = usage;
108 this->format = format;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700109 if (w>0 && h>0) {
110 mInitCheck = initSize(w, h);
111 }
112}
113
114Buffer::~Buffer()
115{
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700116 if (handle) {
117 sAllocDev->free(sAllocDev, handle);
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700118 }
119}
120
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700121status_t Buffer::initCheck() const {
122 return mInitCheck;
123}
124
125android_native_buffer_t* Buffer::getNativeBuffer() const
126{
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700127 return static_cast<android_native_buffer_t*>(const_cast<Buffer*>(this));
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700128}
129
130status_t Buffer::initSize(uint32_t w, uint32_t h)
131{
132 status_t err = NO_ERROR;
133
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700134 err = sAllocDev->alloc(sAllocDev, w, h, format, usage, &handle, &stride);
135
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700136 if (err == NO_ERROR) {
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700137 if (err == NO_ERROR) {
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700138 width = w;
139 height = h;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700140 mVStride = 0;
141 }
142 }
143
144 return err;
145}
146
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700147status_t Buffer::lock(GGLSurface* sur, uint32_t usage)
148{
149 void* vaddr;
150 status_t res = SurfaceBuffer::lock(usage, &vaddr);
151 if (res == NO_ERROR && sur) {
152 sur->version = sizeof(GGLSurface);
153 sur->width = width;
154 sur->height = height;
155 sur->stride = stride;
156 sur->format = format;
157 sur->vstride = mVStride;
158 sur->data = static_cast<GGLubyte*>(vaddr);
159 }
160 return res;
161}
162
163
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700164void Buffer::setPixel(int x, int y, int r, int g, int b, int a) {
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700165 if (x < 0 || (unsigned int) x >= width
166 || y < 0 || (unsigned int) y >= height) {
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700167 // clipped
168 return;
169 }
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700170 int index = stride * y + x;
171 switch (format) {
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700172 case HAL_PIXEL_FORMAT_RGB_565: {
173 unsigned short val = (unsigned short) (
174 ((0x1f & (r >> 3)) << 11)
175 | ((0x3f & (g >> 2)) << 5)
176 | (0x1f & (b >> 3)));
177 ((unsigned short*) mData)[index]= val;
178 }
179 break;
180 case HAL_PIXEL_FORMAT_RGBA_8888: { // ABGR
181 unsigned int val = (unsigned int)
182 (((a & 0xff) << 24)
183 | ((b & 0xff) << 16)
184 | ((g & 0xff) << 8)
185 | (r & 0xff));
186 ((unsigned int*) mData)[index] = val;
187 }
188 break;
189 default:
190 // Unsupported pixel format
191 break;
192 }
193}
194
195
196static void gluLookAt(float eyeX, float eyeY, float eyeZ,
197 float centerX, float centerY, float centerZ, float upX, float upY,
198 float upZ)
199{
200 // See the OpenGL GLUT documentation for gluLookAt for a description
201 // of the algorithm. We implement it in a straightforward way:
202
203 float fx = centerX - eyeX;
204 float fy = centerY - eyeY;
205 float fz = centerZ - eyeZ;
206
207 // Normalize f
208 float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz);
209 fx *= rlf;
210 fy *= rlf;
211 fz *= rlf;
212
213 // Normalize up
214 float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ);
215 upX *= rlup;
216 upY *= rlup;
217 upZ *= rlup;
218
219 // compute s = f x up (x means "cross product")
220
221 float sx = fy * upZ - fz * upY;
222 float sy = fz * upX - fx * upZ;
223 float sz = fx * upY - fy * upX;
224
225 // compute u = s x f
226 float ux = sy * fz - sz * fy;
227 float uy = sz * fx - sx * fz;
228 float uz = sx * fy - sy * fx;
229
230 float m[16] ;
231 m[0] = sx;
232 m[1] = ux;
233 m[2] = -fx;
234 m[3] = 0.0f;
235
236 m[4] = sy;
237 m[5] = uy;
238 m[6] = -fy;
239 m[7] = 0.0f;
240
241 m[8] = sz;
242 m[9] = uz;
243 m[10] = -fz;
244 m[11] = 0.0f;
245
246 m[12] = 0.0f;
247 m[13] = 0.0f;
248 m[14] = 0.0f;
249 m[15] = 1.0f;
250
251 glMultMatrixf(m);
252 glTranslatef(-eyeX, -eyeY, -eyeZ);
253}
254
255int init_gralloc() {
256 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &gralloc_module);
257 LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
258
259 if (err == 0) {
260 gralloc_open(gralloc_module, &sAllocDev);
261 }
262 return err;
263}
264
265int init_gl_surface(void)
266{
267 EGLint numConfigs = 1;
268 EGLConfig myConfig = {0};
269 EGLint attrib[] =
270 {
271 EGL_DEPTH_SIZE, 16,
272 EGL_NONE
273 };
274
275 printf("init_gl_surface\n");
276 if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY )
277 {
278 printf("eglGetDisplay failed\n");
279 return 0;
280 }
281
282 if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE )
283 {
284 printf("eglInitialize failed\n");
285 return 0;
286 }
287
288 if ( eglChooseConfig(eglDisplay, attrib, &myConfig, 1, &numConfigs) != EGL_TRUE )
289 {
290 printf("eglChooseConfig failed\n");
291 return 0;
292 }
293
294 if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig,
295 android_createDisplaySurface(), 0)) == EGL_NO_SURFACE )
296 {
297 printf("eglCreateWindowSurface failed\n");
298 return 0;
299 }
300
301 if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT )
302 {
303 printf("eglCreateContext failed\n");
304 return 0;
305 }
306
307 if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE )
308 {
309 printf("eglMakeCurrent failed\n");
310 return 0;
311 }
312
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700313#if EGL_ANDROID_swap_rectangle
314 eglSetSwapRectangleANDROID(eglDisplay, eglSurface, 0, 0, 320, 480);
315#endif
316
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700317 return 1;
318}
319
320void free_gl_surface(void)
321{
322 if (eglDisplay != EGL_NO_DISPLAY)
323 {
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700324 eglMakeCurrent( eglDisplay, EGL_NO_SURFACE,
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700325 EGL_NO_SURFACE, EGL_NO_CONTEXT );
326 eglDestroyContext( eglDisplay, eglContext );
327 eglDestroySurface( eglDisplay, eglSurface );
328 eglTerminate( eglDisplay );
329 eglDisplay = EGL_NO_DISPLAY;
330 }
331}
332
333void init_scene(void)
334{
335 glDisable(GL_DITHER);
336 glEnable(GL_CULL_FACE);
337 float ratio = 320.0f / 480.0f;
338 glViewport(0, 0, 320, 480);
339
340 glMatrixMode(GL_PROJECTION);
341 glLoadIdentity();
342 glFrustumf(-ratio, ratio, -1, 1, 1, 10);
343
344 glMatrixMode(GL_MODELVIEW);
345
346 glLoadIdentity();
347 gluLookAt(
348 0, 0, 3, // eye
349 0, 0, 0, // center
350 0, 1, 0); // up
351
352 glEnable(GL_TEXTURE_2D);
353}
354
355// #define USE_ALPHA_COLOR
356
357#define USE_GL_REPLACE
358// #define USE_GL_MODULATE
359
360// #define USE_BLEND
361
362#define USE_565
363// #define USE_8888
364
365// #define USE_NEAREST
366#define USE_LINEAR
367
368#define USE_SCALE
369
370void setSmoothGradient(Buffer* bufferObject) {
371 int pixels = bufferObject->getHeight() * bufferObject->getWidth();
372 int step = 0;
373 for (unsigned int y = 0; y < bufferObject->getHeight(); y++) {
374 for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) {
375 int grey = step * 255 / pixels;
376 bufferObject->setPixel(x, y, grey, grey, grey, 255);
377 ++step;
378 }
379 }
380}
381
382void setSmoothAlphaGradient(Buffer* bufferObject) {
383 int pixels = bufferObject->getHeight() * bufferObject->getWidth();
384 int step = 0;
385 for (unsigned int y = 0; y < bufferObject->getHeight(); y++) {
386 for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) {
387 int grey = step * 255 / pixels;
388 bufferObject->setPixel(x, y, 255, 255, 255, grey);
389 ++step;
390 }
391 }
392}
393
394void setOrientedCheckerboard(Buffer* bufferObject) {
395 bufferObject->setPixel(0, 0, 0, 0, 0, 255);
396 for(unsigned int x = 1; x < bufferObject->getWidth() ; x++) {
397 bufferObject->setPixel(x, 0, 0, 255, 0, 255);
398 }
399 for (unsigned int y = 1; y < bufferObject->getHeight(); y++) {
400 for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) {
401 if ((x ^ y ) & 1) {
402 bufferObject->setPixel(x, y, 255, 255, 255, 255);
403 } else {
404 bufferObject->setPixel(x, y, 255, 0, 0, 255);
405 }
406 }
407 }
408}
409
410int create_physical_texture(unsigned int w, unsigned int h)
411{
412
413#ifdef USE_565
414 PixelFormat format = HAL_PIXEL_FORMAT_RGB_565;
415#else
416 PixelFormat format = HAL_PIXEL_FORMAT_RGBA_8888;
417#endif
418 int usage = GRALLOC_USAGE_SW_READ_OFTEN |
419 GRALLOC_USAGE_SW_WRITE_OFTEN |
420 GRALLOC_USAGE_HW_TEXTURE |
421 GRALLOC_USAGE_HW_2D; /* This is the key to allocating the texture in pmem. */
422 int32_t stride;
423 buffer_handle_t handle;
424
425 // Allocate the hardware buffer
426 Buffer* bufferObject = new Buffer(w, h, format, usage);
427
428 android_native_buffer_t* buffer = bufferObject->getNativeBuffer();
429
430 buffer->common.incRef(&buffer->common);
431
432 // create the new EGLImageKHR
433 EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_NONE };
434 EGLDisplay dpy = eglGetCurrentDisplay();
435 EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
436 (EGLClientBuffer)buffer, attrs);
437 if (image == EGL_NO_IMAGE_KHR) {
438 printf("Could not create an image %d\n", eglGetError());
439 return -1;
440 }
441
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700442 bufferObject->lock();
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700443 setOrientedCheckerboard(bufferObject);
444 // setSmoothGradient(bufferObject);
445 // setSmoothAlphaGradient(bufferObject);
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700446 bufferObject->unlock();
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700447
448 glGenTextures(1, &texture);
449 glBindTexture(GL_TEXTURE_2D, texture);
450 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
451#ifdef USE_LINEAR
452 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
453 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
454#elif defined(USE_NEAREST)
455 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
456 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
457#endif
458
459#ifdef USE_GL_REPLACE
460 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
461#elif defined(USE_GL_MODULATE)
462 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
463#endif
464
465#ifdef USE_ALPHA_COLOR
466 glColor4f(1.0f, 1.0f, 1.0f, 0.4f);
467#else
468 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
469#endif
470
471#ifdef USE_BLEND
472 glEnable(GL_BLEND);
473 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
474#endif
475 return 0;
476}
477
478static const int SCALE_COUNT = 12;
479
480int scale(int base, int factor) {
481 static const float kTable[SCALE_COUNT] = {
482 0.1f, 0.25f, 0.5f, 0.75f, 1.0f,
483 1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 5.0f
484 };
485 return base * kTable[factor];
486}
487
488class Timer {
489 struct timeval first;
490 double elapsedSeconds;
491
492public:
493 Timer() {}
494 void start() {
495 gettimeofday(&first, NULL);
496 }
497
498 void stop() {
499 struct timeval second,
500 elapsed;
501 gettimeofday(&second, NULL);
502
503 if (first.tv_usec > second.tv_usec) {
504 second.tv_usec += 1000000;
505 second.tv_sec--;
506 }
507
508 elapsedSeconds = (second.tv_sec - first.tv_sec) +
509 (second.tv_usec - first.tv_usec) / 1000000.0;
510 }
511
512 double getElapsedSeconds() {
513 return elapsedSeconds;
514 }
515
516 double getElapsedMs() {
517 return elapsedSeconds* 1000.0f;
518 }
519};
520
521int testTime()
522{
523 static const int WIDTH = 320;
524 static const int HEIGHT = 480;
525 static const int SCALE = 8;
526
527 if (create_physical_texture(WIDTH, HEIGHT) != 0) {
528 return -1;
529 }
530 // Need to do a dummy eglSwapBuffers first. Don't know why.
531 glClearColor(0.4, 1.0, 0.4, 0.4);
532 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
533 eglSwapBuffers(eglDisplay, eglSurface);
534
535 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
536
537#if defined(USE_SCALE)
538 static const int scaleOffset = 0;
539#else
540 static const int scaleOffset = 1;
541#endif
542 printf("ms\n");
543 for(int j = 0; j < SCALE; j++) {
544 int w = WIDTH >> (j + scaleOffset);
545 int h = HEIGHT >> j;
546 int cropRect[4] = {0,h,w,-h}; // Left bottom width height. Width and Height can be neg to flip.
547 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect);
548 Timer timer;
549 timer.start();
550
551 int copyCount = 1000;
552 for (int i = 0; i < copyCount; i++) {
553 glDrawTexiOES(0, 0, 0, w, h);
554 }
555
556 timer.stop();
557 printf("%g\n", timer.getElapsedMs() / copyCount);
558 }
559
560 eglSwapBuffers(eglDisplay, eglSurface);
561 return 0;
562}
563
564int testStretch()
565{
566 static const int WIDTH = 8;
567 static const int HEIGHT = 8;
568
569 if (create_physical_texture(WIDTH, HEIGHT) != 0) {
570 return -1;
571 }
572 // Need to do a dummy eglSwapBuffers first. Don't know why.
573 glClearColor(0.4, 1.0, 0.4, 0.4);
574 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
575 eglSwapBuffers(eglDisplay, eglSurface);
576
577 int cropRect[4] = {0,HEIGHT,WIDTH,-HEIGHT}; // Left bottom width height. Width and Height can be neg to flip.
578 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect);
579
580 for(int frame = 0; frame < 2; frame++) {
581 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
582 int baseX = 10;
583 for (int x = 0; x < SCALE_COUNT; x++) {
584 int baseY = 10;
585 int width = scale(WIDTH, x);
586 for (int y = 0; y < SCALE_COUNT; y++) {
587 int height = scale(HEIGHT, y);
588 glDrawTexxOES(baseX << 16, baseY << 16, 0, width << 16, height << 16);
589 baseY += height + 10;
590 }
591 baseX += width + 10;
592 }
593
594 eglSwapBuffers(eglDisplay, eglSurface);
595 }
596 return 0;
597}
598
599int testRot90()
600{
601 static const int WIDTH = 8;
602 static const int HEIGHT = 8;
603
604 if (create_physical_texture(WIDTH, HEIGHT) != 0) {
605 return -1;
606 }
607
608 glMatrixMode(GL_PROJECTION);
609 glLoadIdentity();
610 glOrthof(0, 320, 480, 0, 0, 1);
611
612 glMatrixMode(GL_MODELVIEW);
613
614 glLoadIdentity();
615
616 // Need to do a dummy eglSwapBuffers first. Don't know why.
617 glClearColor(0.4, 0.4, 0.4, 0.4);
618 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
619 eglSwapBuffers(eglDisplay, eglSurface);
620
621 glEnable(GL_TEXTURE_2D);
622 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
623 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
624 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
625 glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
626 glDisable(GL_BLEND);
627 glShadeModel(GL_FLAT);
628 glDisable(GL_DITHER);
629 glDisable(GL_CULL_FACE);
630
631 for(int frame = 0; frame < 2; frame++) {
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700632 LOGD("frame = %d", frame);
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700633 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
634 int baseX = 10;
635 for (int x = 0; x < SCALE_COUNT; x++) {
636 int baseY = 10;
637 int width = scale(WIDTH, x);
638 for (int y = 0; y < SCALE_COUNT; y++) {
639 int height = scale(HEIGHT, y);
640
641 // Code copied from SurfaceFlinger LayerBase.cpp
642
643 const GLfixed texCoords[4][2] = {
644 { 0, 0 },
645 { 0, 0x10000 },
646 { 0x10000, 0x10000 },
647 { 0x10000, 0 }
648 };
649
650 GLfixed fx = baseX << 16;
651 GLfixed fy = baseY << 16;
652 GLfixed fw = width << 16;
653 GLfixed fh = height << 16;
654
655 /*
656 * Vertex pattern:
657 * (2)--(3)
658 * |\ |
659 * | \ |
660 * | \ |
661 * | \|
662 * (1)--(0)
663 *
664 */
665
666 const GLfixed vertices[4][2] = {
667 {fx + fw, fy},
668 {fx, fy},
669 {fx, fy + fh},
670 {fx + fw, fy + fh}
671 };
672
673 static const bool rotate90 = true;
674
675 glMatrixMode(GL_TEXTURE);
676 glLoadIdentity();
677
678 glEnableClientState(GL_VERTEX_ARRAY);
679 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
680 glVertexPointer(2, GL_FIXED, 0, vertices);
681 glTexCoordPointer(2, GL_FIXED, 0, texCoords);
682
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700683 LOGD("testRot90 %d, %d %d, %d", baseX, baseY, width, height);
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700684 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
685
686 baseY += height + 10;
687 }
688 baseX += width + 10;
689 }
690
691 eglSwapBuffers(eglDisplay, eglSurface);
692 }
693 return 0;
694}
695
696int main(int argc, char **argv)
697{
698
699 int q;
700 int start, end;
701
702 if (init_gralloc()) {
703 printf("gralloc initialization failed - exiting\n");
704 return 0;
705 }
706
707 printf("Initializing EGL...\n");
708
709 if(!init_gl_surface())
710 {
711 printf("GL initialisation failed - exiting\n");
712 return 0;
713 }
714
715 init_scene();
716
717 printf("Start test...\n");
718 // testTime();
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700719 testStretch();
720 //testRot90();
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700721 free_gl_surface();
722
723 return 0;
724}