diff options
Diffstat (limited to 'progs/es1/screen/winsys.c')
-rw-r--r-- | progs/es1/screen/winsys.c | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/progs/es1/screen/winsys.c b/progs/es1/screen/winsys.c new file mode 100644 index 00000000000..84d00471eba --- /dev/null +++ b/progs/es1/screen/winsys.c @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2009 Chia-I Wu <[email protected]> + * + * Based on eglgears by + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <sys/time.h> + +#define EGL_EGLEXT_PROTOTYPES + +#include <EGL/egl.h> +#include <EGL/eglext.h> + +#include "winsys.h" + +#define MAX_MODES 100 + +static struct { + EGLBoolean verbose; + + EGLDisplay dpy; + EGLConfig conf; + + EGLScreenMESA screen; + EGLModeMESA mode; + EGLint width, height; + + EGLContext ctx; + EGLSurface surf; +} screen; + + +static EGLBoolean +init_screen(void) +{ + EGLModeMESA modes[MAX_MODES]; + EGLint num_screens, num_modes; + EGLint width, height, best_mode; + EGLint i; + + if (!eglGetScreensMESA(screen.dpy, &screen.screen, 1, &num_screens) || + !num_screens) { + printf("eglGetScreensMESA failed\n"); + return EGL_FALSE; + } + + if (!eglGetModesMESA(screen.dpy, screen.screen, modes, MAX_MODES, + &num_modes) || + !num_modes) { + printf("eglGetModesMESA failed!\n"); + return EGL_FALSE; + } + + printf("Found %d modes:\n", num_modes); + + best_mode = 0; + width = 0; + height = 0; + for (i = 0; i < num_modes; i++) { + EGLint w, h; + eglGetModeAttribMESA(screen.dpy, modes[i], EGL_WIDTH, &w); + eglGetModeAttribMESA(screen.dpy, modes[i], EGL_HEIGHT, &h); + printf("%3d: %d x %d\n", i, w, h); + if (w > width && h > height) { + width = w; + height = h; + best_mode = i; + } + } + + screen.mode = modes[best_mode]; + screen.width = width; + screen.height = height; + + return EGL_TRUE; +} + + +static EGLBoolean +init_display(void) +{ + EGLint maj, min; + const char *exts; + const EGLint attribs[] = { + EGL_SURFACE_TYPE, 0x0, /* should be EGL_SCREEN_BIT_MESA */ + EGL_RENDERABLE_TYPE, 0x0, /* should be EGL_OPENGL_ES_BIT */ + EGL_NONE + }; + EGLint num_configs; + + screen.dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (!screen.dpy) { + printf("eglGetDisplay failed\n"); + return EGL_FALSE; + } + + if (!eglInitialize(screen.dpy, &maj, &min)) { + printf("eglInitialize failed\n"); + return EGL_FALSE; + } + + printf("EGL_VERSION = %s\n", eglQueryString(screen.dpy, EGL_VERSION)); + printf("EGL_VENDOR = %s\n", eglQueryString(screen.dpy, EGL_VENDOR)); + + exts = eglQueryString(screen.dpy, EGL_EXTENSIONS); + assert(exts); + + if (!strstr(exts, "EGL_MESA_screen_surface")) { + printf("EGL_MESA_screen_surface is not supported\n"); + return EGL_FALSE; + } + + if (!eglChooseConfig(screen.dpy, attribs, &screen.conf, 1, + &num_configs) || + !num_configs) { + printf("eglChooseConfig failed\n"); + return EGL_FALSE; + } + + return EGL_TRUE; +} + + +EGLBoolean +winsysInitScreen(void) +{ + EGLint surf_attribs[20]; + EGLint i; + EGLBoolean ok; + + if (!init_display()) + goto fail; + if (!init_screen()) + goto fail; + + /* create context */ + screen.ctx = eglCreateContext(screen.dpy, screen.conf, + EGL_NO_CONTEXT, NULL); + if (screen.ctx == EGL_NO_CONTEXT) { + printf("eglCreateContext failed\n"); + goto fail; + } + + i = 0; + surf_attribs[i++] = EGL_WIDTH; + surf_attribs[i++] = screen.width; + surf_attribs[i++] = EGL_HEIGHT; + surf_attribs[i++] = screen.height; + surf_attribs[i++] = EGL_NONE; + + /* create surface */ + printf("Using screen size: %d x %d\n", screen.width, screen.height); + screen.surf = eglCreateScreenSurfaceMESA(screen.dpy, screen.conf, + surf_attribs); + if (screen.surf == EGL_NO_SURFACE) { + printf("eglCreateScreenSurfaceMESA failed\n"); + goto fail; + } + + ok = eglMakeCurrent(screen.dpy, screen.surf, screen.surf, screen.ctx); + if (!ok) { + printf("eglMakeCurrent failed\n"); + goto fail; + } + + ok = eglShowScreenSurfaceMESA(screen.dpy, screen.screen, + screen.surf, screen.mode); + if (!ok) { + printf("eglShowScreenSurfaceMESA failed\n"); + goto fail; + } + + return EGL_TRUE; + +fail: + winsysFiniScreen(); + return EGL_FALSE; +} + + +EGLBoolean +winsysQueryScreenSize(EGLint *width, EGLint *height) +{ + if (!screen.dpy) + return EGL_FALSE; + + if (width) + *width = screen.width; + if (height) + *height = screen.height; + + return EGL_TRUE; +} + + +void +winsysFiniScreen(void) +{ + if (screen.dpy) { + eglMakeCurrent(screen.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); + if (screen.surf != EGL_NO_SURFACE) + eglDestroySurface(screen.dpy, screen.surf); + if (screen.ctx != EGL_NO_CONTEXT) + eglDestroyContext(screen.dpy, screen.ctx); + eglTerminate(screen.dpy); + + memset(&screen, 0, sizeof(screen)); + } +} + + +void +winsysSwapBuffers(void) +{ + eglSwapBuffers(screen.dpy, screen.surf); +} + + +/* return current time (in seconds) */ +double +winsysNow(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return (double) tv.tv_sec + tv.tv_usec / 1000000.0; +} + + +void +winsysRun(double seconds, void (*draw_frame)(void *data), void *data) +{ + double begin, end, last_frame, duration; + EGLint num_frames = 0; + + begin = winsysNow(); + end = begin + seconds; + + last_frame = begin; + while (last_frame < end) { + draw_frame(data); + winsysSwapBuffers(); + last_frame = winsysNow(); + num_frames++; + } + + duration = last_frame - begin; + printf("%d frames in %3.1f seconds = %6.3f FPS\n", + num_frames, duration, (double) num_frames / duration); +} |