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