blob: 11dfb6e78474b1b91ea64826f1c06c344c72337c [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
Mathias Agopian1d3bcd62009-08-10 16:48:22 -070026#include <ui/FramebufferNativeWindow.h>
27#include <ui/EGLUtils.h>
28
Mathias Agopian076b1cc2009-04-10 14:24:30 -070029#define EGL_EGLEXT_PROTOTYPES
30#define GL_GLEXT_PROTOTYPES
31
32#include <EGL/egl.h>
33#include <EGL/eglext.h>
34
35#include <GLES/gl.h>
36#include <GLES/glext.h>
37
Mathias Agopian076b1cc2009-04-10 14:24:30 -070038using namespace android;
39
40EGLDisplay eglDisplay;
41EGLSurface eglSurface;
42EGLContext eglContext;
43GLuint texture;
44
45hw_module_t const* gralloc_module;
46alloc_device_t *sAllocDev;
47
Jack Palevich8f75e092009-04-13 22:03:39 -070048#define FIXED_ONE 0x10000 /* 1.0 in 16.16 fixed point. */
Mathias Agopian076b1cc2009-04-10 14:24:30 -070049
50int init_gl_surface();
51void free_gl_surface();
52void init_scene();
53
54int create_physical_texture();
55int readTimer();
56
57// ===========================================================================
Mathias Agopian7e2a9372009-06-09 21:38:08 -070058// Buffer an implementation of android_native_buffer_t
Mathias Agopian076b1cc2009-04-10 14:24:30 -070059// ===========================================================================
60
61class NativeBuffer;
62
Mathias Agopian7e2a9372009-06-09 21:38:08 -070063class Buffer : public android::SurfaceBuffer
Mathias Agopian076b1cc2009-04-10 14:24:30 -070064{
65public:
Mathias Agopian076b1cc2009-04-10 14:24:30 -070066 // creates w * h buffer
Mathias Agopian7e2a9372009-06-09 21:38:08 -070067 Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage);
Mathias Agopian076b1cc2009-04-10 14:24:30 -070068
69 // return status
70 status_t initCheck() const;
71
Mathias Agopian7e2a9372009-06-09 21:38:08 -070072 uint32_t getWidth() const { return width; }
73 uint32_t getHeight() const { return height; }
74 uint32_t getStride() const { return stride; }
75 uint32_t getUsage() const { return usage; }
76 PixelFormat getPixelFormat() const { return format; }
77
78
Mathias Agopian076b1cc2009-04-10 14:24:30 -070079 android_native_buffer_t* getNativeBuffer() const;
80
81 void setPixel(int x, int y, int r, int g, int b, int a);
82
Mathias Agopian7e2a9372009-06-09 21:38:08 -070083 status_t lock(GGLSurface* surface, uint32_t usage);
84 void lock() {
85 GGLSurface s;
86 lock(&s, GRALLOC_USAGE_SW_WRITE_OFTEN);
87 mData = (void*)s.data;
88 }
89
Mathias Agopian076b1cc2009-04-10 14:24:30 -070090private:
91 friend class LightRefBase<Buffer>;
92 Buffer(const Buffer& rhs);
Mathias Agopian7e2a9372009-06-09 21:38:08 -070093 virtual ~Buffer();
Mathias Agopian076b1cc2009-04-10 14:24:30 -070094 Buffer& operator = (const Buffer& rhs);
95 const Buffer& operator = (const Buffer& rhs) const;
96
97 status_t initSize(uint32_t w, uint32_t h);
98
Mathias Agopian076b1cc2009-04-10 14:24:30 -070099 ssize_t mInitCheck;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700100 void* mData;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700101};
102
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700103Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage)
Mathias Agopian0a3139a2009-06-10 16:01:54 -0700104 : SurfaceBuffer(), mInitCheck(NO_INIT)
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700105{
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700106 this->usage = usage;
107 this->format = format;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700108 if (w>0 && h>0) {
109 mInitCheck = initSize(w, h);
110 }
111}
112
113Buffer::~Buffer()
114{
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700115 if (handle) {
116 sAllocDev->free(sAllocDev, handle);
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700117 }
118}
119
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700120status_t Buffer::initCheck() const {
121 return mInitCheck;
122}
123
124android_native_buffer_t* Buffer::getNativeBuffer() const
125{
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700126 return static_cast<android_native_buffer_t*>(const_cast<Buffer*>(this));
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700127}
128
129status_t Buffer::initSize(uint32_t w, uint32_t h)
130{
131 status_t err = NO_ERROR;
132
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700133 err = sAllocDev->alloc(sAllocDev, w, h, format, usage, &handle, &stride);
134
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700135 if (err == NO_ERROR) {
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700136 if (err == NO_ERROR) {
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700137 width = w;
138 height = h;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700139 }
140 }
141
142 return err;
143}
144
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700145status_t Buffer::lock(GGLSurface* sur, uint32_t usage)
146{
147 void* vaddr;
148 status_t res = SurfaceBuffer::lock(usage, &vaddr);
149 if (res == NO_ERROR && sur) {
150 sur->version = sizeof(GGLSurface);
151 sur->width = width;
152 sur->height = height;
153 sur->stride = stride;
154 sur->format = format;
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700155 sur->data = static_cast<GGLubyte*>(vaddr);
156 }
157 return res;
158}
159
160
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700161void Buffer::setPixel(int x, int y, int r, int g, int b, int a) {
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700162 if (x < 0 || (unsigned int) x >= width
163 || y < 0 || (unsigned int) y >= height) {
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700164 // clipped
165 return;
166 }
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700167 int index = stride * y + x;
168 switch (format) {
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700169 case HAL_PIXEL_FORMAT_RGB_565: {
170 unsigned short val = (unsigned short) (
171 ((0x1f & (r >> 3)) << 11)
172 | ((0x3f & (g >> 2)) << 5)
173 | (0x1f & (b >> 3)));
174 ((unsigned short*) mData)[index]= val;
175 }
176 break;
177 case HAL_PIXEL_FORMAT_RGBA_8888: { // ABGR
178 unsigned int val = (unsigned int)
179 (((a & 0xff) << 24)
180 | ((b & 0xff) << 16)
181 | ((g & 0xff) << 8)
182 | (r & 0xff));
183 ((unsigned int*) mData)[index] = val;
184 }
185 break;
186 default:
187 // Unsupported pixel format
188 break;
189 }
190}
191
192
193static void gluLookAt(float eyeX, float eyeY, float eyeZ,
194 float centerX, float centerY, float centerZ, float upX, float upY,
195 float upZ)
196{
197 // See the OpenGL GLUT documentation for gluLookAt for a description
198 // of the algorithm. We implement it in a straightforward way:
199
200 float fx = centerX - eyeX;
201 float fy = centerY - eyeY;
202 float fz = centerZ - eyeZ;
203
204 // Normalize f
205 float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz);
206 fx *= rlf;
207 fy *= rlf;
208 fz *= rlf;
209
210 // Normalize up
211 float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ);
212 upX *= rlup;
213 upY *= rlup;
214 upZ *= rlup;
215
216 // compute s = f x up (x means "cross product")
217
218 float sx = fy * upZ - fz * upY;
219 float sy = fz * upX - fx * upZ;
220 float sz = fx * upY - fy * upX;
221
222 // compute u = s x f
223 float ux = sy * fz - sz * fy;
224 float uy = sz * fx - sx * fz;
225 float uz = sx * fy - sy * fx;
226
227 float m[16] ;
228 m[0] = sx;
229 m[1] = ux;
230 m[2] = -fx;
231 m[3] = 0.0f;
232
233 m[4] = sy;
234 m[5] = uy;
235 m[6] = -fy;
236 m[7] = 0.0f;
237
238 m[8] = sz;
239 m[9] = uz;
240 m[10] = -fz;
241 m[11] = 0.0f;
242
243 m[12] = 0.0f;
244 m[13] = 0.0f;
245 m[14] = 0.0f;
246 m[15] = 1.0f;
247
248 glMultMatrixf(m);
249 glTranslatef(-eyeX, -eyeY, -eyeZ);
250}
251
252int init_gralloc() {
253 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &gralloc_module);
254 LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
255
256 if (err == 0) {
257 gralloc_open(gralloc_module, &sAllocDev);
258 }
259 return err;
260}
261
262int init_gl_surface(void)
263{
264 EGLint numConfigs = 1;
265 EGLConfig myConfig = {0};
266 EGLint attrib[] =
267 {
268 EGL_DEPTH_SIZE, 16,
269 EGL_NONE
270 };
271
Mathias Agopian1d3bcd62009-08-10 16:48:22 -0700272 EGLNativeWindowType window = android_createDisplaySurface();
273
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700274 printf("init_gl_surface\n");
275 if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY )
276 {
277 printf("eglGetDisplay failed\n");
278 return 0;
279 }
280
281 if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE )
282 {
283 printf("eglInitialize failed\n");
284 return 0;
285 }
286
Mathias Agopian1d3bcd62009-08-10 16:48:22 -0700287 if ( EGLUtils::selectConfigForNativeWindow(eglDisplay, attrib, window, &myConfig) != 0)
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700288 {
Mathias Agopian1d3bcd62009-08-10 16:48:22 -0700289 printf("EGLUtils::selectConfigForNativeWindow failed\n");
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700290 return 0;
291 }
Mathias Agopian1d3bcd62009-08-10 16:48:22 -0700292
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700293
294 if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig,
Mathias Agopian1d3bcd62009-08-10 16:48:22 -0700295 window, 0)) == EGL_NO_SURFACE )
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700296 {
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
Mathias Agopian0a3139a2009-06-10 16:01:54 -0700358//#define USE_GL_MODULATE
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700359
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] = {
Mathias Agopian0a3139a2009-06-10 16:01:54 -0700482 0.24f, 0.25f, 0.5f, 0.75f, 1.0f,
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700483 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.
Mathias Agopian0a3139a2009-06-10 16:01:54 -0700573 glClearColor(0.4, 1.0, 0.4, 1.0);
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700574 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
575 eglSwapBuffers(eglDisplay, eglSurface);
Mathias Agopian0a3139a2009-06-10 16:01:54 -0700576
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700577 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);
Mathias Agopian0a3139a2009-06-10 16:01:54 -0700595 LOGD("wait 1s");
596 usleep(1000000);
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700597 }
598 return 0;
599}
600
601int testRot90()
602{
603 static const int WIDTH = 8;
604 static const int HEIGHT = 8;
605
606 if (create_physical_texture(WIDTH, HEIGHT) != 0) {
607 return -1;
608 }
609
610 glMatrixMode(GL_PROJECTION);
611 glLoadIdentity();
612 glOrthof(0, 320, 480, 0, 0, 1);
613
614 glMatrixMode(GL_MODELVIEW);
615
616 glLoadIdentity();
617
618 // Need to do a dummy eglSwapBuffers first. Don't know why.
619 glClearColor(0.4, 0.4, 0.4, 0.4);
620 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
621 eglSwapBuffers(eglDisplay, eglSurface);
622
623 glEnable(GL_TEXTURE_2D);
624 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
625 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
626 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
627 glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
628 glDisable(GL_BLEND);
629 glShadeModel(GL_FLAT);
630 glDisable(GL_DITHER);
631 glDisable(GL_CULL_FACE);
632
633 for(int frame = 0; frame < 2; frame++) {
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700634 LOGD("frame = %d", frame);
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700635 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
636 int baseX = 10;
637 for (int x = 0; x < SCALE_COUNT; x++) {
638 int baseY = 10;
639 int width = scale(WIDTH, x);
640 for (int y = 0; y < SCALE_COUNT; y++) {
641 int height = scale(HEIGHT, y);
642
643 // Code copied from SurfaceFlinger LayerBase.cpp
644
645 const GLfixed texCoords[4][2] = {
646 { 0, 0 },
647 { 0, 0x10000 },
648 { 0x10000, 0x10000 },
649 { 0x10000, 0 }
650 };
651
652 GLfixed fx = baseX << 16;
653 GLfixed fy = baseY << 16;
654 GLfixed fw = width << 16;
655 GLfixed fh = height << 16;
656
657 /*
658 * Vertex pattern:
659 * (2)--(3)
660 * |\ |
661 * | \ |
662 * | \ |
663 * | \|
664 * (1)--(0)
665 *
666 */
667
668 const GLfixed vertices[4][2] = {
669 {fx + fw, fy},
670 {fx, fy},
671 {fx, fy + fh},
672 {fx + fw, fy + fh}
673 };
674
675 static const bool rotate90 = true;
676
677 glMatrixMode(GL_TEXTURE);
678 glLoadIdentity();
679
680 glEnableClientState(GL_VERTEX_ARRAY);
681 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
682 glVertexPointer(2, GL_FIXED, 0, vertices);
683 glTexCoordPointer(2, GL_FIXED, 0, texCoords);
684
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700685 LOGD("testRot90 %d, %d %d, %d", baseX, baseY, width, height);
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700686 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
687
688 baseY += height + 10;
689 }
690 baseX += width + 10;
691 }
692
693 eglSwapBuffers(eglDisplay, eglSurface);
694 }
695 return 0;
696}
697
698int main(int argc, char **argv)
699{
700
701 int q;
702 int start, end;
703
704 if (init_gralloc()) {
705 printf("gralloc initialization failed - exiting\n");
706 return 0;
707 }
708
709 printf("Initializing EGL...\n");
710
711 if(!init_gl_surface())
712 {
713 printf("GL initialisation failed - exiting\n");
714 return 0;
715 }
716
717 init_scene();
718
719 printf("Start test...\n");
720 // testTime();
Mathias Agopian7e2a9372009-06-09 21:38:08 -0700721 testStretch();
722 //testRot90();
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700723 free_gl_surface();
724
725 return 0;
726}