diff options
| author | Juan Linietsky | 2014-02-09 22:10:30 -0300 |
|---|---|---|
| committer | Juan Linietsky | 2014-02-09 22:10:30 -0300 |
| commit | 0b806ee0fc9097fa7bda7ac0109191c9c5e0a1ac (patch) | |
| tree | 276c4d099e178eb67fbd14f61d77b05e3808e9e3 /platform/bb10/bbutil.c | |
| parent | 0e49da1687bc8192ed210947da52c9e5c5f301bb (diff) | |
| download | godot-0b806ee.tar.gz godot-0b806ee.tar.zst godot-0b806ee.zip | |
GODOT IS OPEN SOURCE
Diffstat (limited to 'platform/bb10/bbutil.c')
| -rw-r--r-- | platform/bb10/bbutil.c | 513 |
1 files changed, 513 insertions, 0 deletions
diff --git a/platform/bb10/bbutil.c b/platform/bb10/bbutil.c new file mode 100644 index 000000000..fce52c5b8 --- /dev/null +++ b/platform/bb10/bbutil.c @@ -0,0 +1,513 @@ +#include <assert.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/keycodes.h> +#include <time.h> + +#include "bbutil.h" + +EGLDisplay egl_disp; +EGLSurface egl_surf; + +static EGLConfig egl_conf; +static EGLContext egl_ctx; + +static screen_context_t screen_ctx; +static screen_window_t screen_win; +static screen_display_t screen_disp; + + +static void +bbutil_egl_perror(const char *msg) { + static const char *errmsg[] = { + "function succeeded", + "EGL is not initialized, or could not be initialized, for the specified display", + "cannot access a requested resource", + "failed to allocate resources for the requested operation", + "an unrecognized attribute or attribute value was passed in an attribute list", + "an EGLConfig argument does not name a valid EGLConfig", + "an EGLContext argument does not name a valid EGLContext", + "the current surface of the calling thread is no longer valid", + "an EGLDisplay argument does not name a valid EGLDisplay", + "arguments are inconsistent", + "an EGLNativePixmapType argument does not refer to a valid native pixmap", + "an EGLNativeWindowType argument does not refer to a valid native window", + "one or more argument values are invalid", + "an EGLSurface argument does not name a valid surface configured for rendering", + "a power management event has occurred", + }; + + fprintf(stderr, "%s: %s\n", msg, errmsg[eglGetError() - EGL_SUCCESS]); +} +EGLConfig bbutil_choose_config(EGLDisplay egl_disp, enum RENDERING_API api) { + EGLConfig egl_conf = (EGLConfig)0; + EGLConfig *egl_configs; + EGLint egl_num_configs; + EGLint val; + EGLBoolean rc; + EGLint i; + + rc = eglGetConfigs(egl_disp, NULL, 0, &egl_num_configs); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglGetConfigs"); + return egl_conf; + } + if (egl_num_configs == 0) { + fprintf(stderr, "eglGetConfigs: could not find a configuration\n"); + return egl_conf; + } + + egl_configs = malloc(egl_num_configs * sizeof(*egl_configs)); + if (egl_configs == NULL) { + fprintf(stderr, "could not allocate memory for %d EGL configs\n", egl_num_configs); + return egl_conf; + } + + rc = eglGetConfigs(egl_disp, egl_configs, + egl_num_configs, &egl_num_configs); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglGetConfigs"); + free(egl_configs); + return egl_conf; + } + + for (i = 0; i < egl_num_configs; i++) { + eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_SURFACE_TYPE, &val); + if (!(val & EGL_WINDOW_BIT)) { + continue; + } + + eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_RENDERABLE_TYPE, &val); + if (!(val & api)) { + continue; + } + + eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_DEPTH_SIZE, &val); + if ((api & (GL_ES_1|GL_ES_2)) && (val == 0)) { + continue; + } + + eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_RED_SIZE, &val); + if (val != 8) { + continue; + } + eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_GREEN_SIZE, &val); + if (val != 8) { + continue; + } + + eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_BLUE_SIZE, &val); + if (val != 8) { + continue; + } + + eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_BUFFER_SIZE, &val); + if (val != 32) { + continue; + } + + egl_conf = egl_configs[i]; + break; + } + + free(egl_configs); + + if (egl_conf == (EGLConfig)0) { + fprintf(stderr, "bbutil_choose_config: could not find a matching configuration\n"); + } + + return egl_conf; +} + +int +bbutil_init_egl(screen_context_t ctx, enum RENDERING_API api) { + int usage; + int format = SCREEN_FORMAT_RGBX8888; + int nbuffers = 2; + EGLint interval = 1; + int rc; + EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; + + if (api == GL_ES_1) { + usage = SCREEN_USAGE_OPENGL_ES1 | SCREEN_USAGE_ROTATION; + } else if (api == GL_ES_2) { + usage = SCREEN_USAGE_OPENGL_ES2 | SCREEN_USAGE_ROTATION; + } else if (api == VG) { + usage = SCREEN_USAGE_OPENVG | SCREEN_USAGE_ROTATION; + } else { + fprintf(stderr, "invalid api setting\n"); + return EXIT_FAILURE; + } + + //Simple egl initialization + screen_ctx = ctx; + + egl_disp = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (egl_disp == EGL_NO_DISPLAY) { + bbutil_egl_perror("eglGetDisplay"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = eglInitialize(egl_disp, NULL, NULL); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglInitialize"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + if ((api == GL_ES_1) || (api == GL_ES_2)) { + rc = eglBindAPI(EGL_OPENGL_ES_API); + } else if (api == VG) { + rc = eglBindAPI(EGL_OPENVG_API); + } + + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglBindApi"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + egl_conf = bbutil_choose_config(egl_disp, api); + if (egl_conf == (EGLConfig)0) { + bbutil_terminate(); + return EXIT_FAILURE; + } + + if (api == GL_ES_2) { + egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, attributes); + } else { + egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, NULL); + } + + if (egl_ctx == EGL_NO_CONTEXT) { + bbutil_egl_perror("eglCreateContext"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_create_window(&screen_win, screen_ctx); + if (rc) { + perror("screen_create_window"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_FORMAT, &format); + if (rc) { + perror("screen_set_window_property_iv(SCREEN_PROPERTY_FORMAT)"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage); + if (rc) { + perror("screen_set_window_property_iv(SCREEN_PROPERTY_USAGE)"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_DISPLAY, (void **)&screen_disp); + if (rc) { + perror("screen_get_window_property_pv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + int screen_resolution[2]; + + rc = screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_SIZE, screen_resolution); + if (rc) { + perror("screen_get_display_property_iv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + int angle = atoi(getenv("ORIENTATION")); + + screen_display_mode_t screen_mode; + rc = screen_get_display_property_pv(screen_disp, SCREEN_PROPERTY_MODE, (void**)&screen_mode); + if (rc) { + perror("screen_get_display_property_pv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + int size[2]; + rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size); + if (rc) { + perror("screen_get_window_property_iv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + int buffer_size[2] = {size[0], size[1]}; + + if ((angle == 0) || (angle == 180)) { + if (((screen_mode.width > screen_mode.height) && (size[0] < size[1])) || + ((screen_mode.width < screen_mode.height) && (size[0] > size[1]))) { + buffer_size[1] = size[0]; + buffer_size[0] = size[1]; + } + } else if ((angle == 90) || (angle == 270)){ + if (((screen_mode.width > screen_mode.height) && (size[0] > size[1])) || + ((screen_mode.width < screen_mode.height && size[0] < size[1]))) { + buffer_size[1] = size[0]; + buffer_size[0] = size[1]; + } + } else { + fprintf(stderr, "Navigator returned an unexpected orientation angle.\n"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, buffer_size); + if (rc) { + perror("screen_set_window_property_iv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle); + if (rc) { + perror("screen_set_window_property_iv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_create_window_buffers(screen_win, nbuffers); + if (rc) { + perror("screen_create_window_buffers"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_create_window_group(screen_win, get_window_group_id()); + if (rc) { + perror("screen_create_window_group"); + bbutil_terminate(); + return EXIT_FAILURE; + } + /* if (screen_create_window_group(screen_win, get_window_group_id()) != 0) goto fail; */ + + int idle_mode = SCREEN_IDLE_MODE_KEEP_AWAKE; + screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_IDLE_MODE, &idle_mode); + + egl_surf = eglCreateWindowSurface(egl_disp, egl_conf, screen_win, NULL); + if (egl_surf == EGL_NO_SURFACE) { + bbutil_egl_perror("eglCreateWindowSurface"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = eglMakeCurrent(egl_disp, egl_surf, egl_surf, egl_ctx); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglMakeCurrent"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = eglSwapInterval(egl_disp, interval); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglSwapInterval"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +int +bbutil_init_gl2d() { +#if 0 + EGLint surface_width, surface_height; + + if ((egl_disp == EGL_NO_DISPLAY) || (egl_surf == EGL_NO_SURFACE) ){ + return EXIT_FAILURE; + } + + eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width); + eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height); + + glShadeModel(GL_SMOOTH); + + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + + glViewport(0, 0, surface_width, surface_height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + glOrthof(0.0f, (float)(surface_width) / (float)(surface_height), 0.0f, 1.0f, -1.0f, 1.0f); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +#endif + + return EXIT_SUCCESS; +} + +int +bbutil_init(screen_context_t ctx, enum RENDERING_API api) { + if (EXIT_SUCCESS != bbutil_init_egl(ctx, api)) { + return EXIT_FAILURE; + } + + if ((GL_ES_1 == api) && (EXIT_SUCCESS != bbutil_init_gl2d())) { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +int bbutil_is_flipped() { + + int ret; + screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_FLIP, &ret); + return ret; +}; + +int bbutil_get_rotation() { + + int ret; + screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &ret); + return ret; +}; + + +void +bbutil_terminate() { + //Typical EGL cleanup + if (egl_disp != EGL_NO_DISPLAY) { + eglMakeCurrent(egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (egl_surf != EGL_NO_SURFACE) { + eglDestroySurface(egl_disp, egl_surf); + egl_surf = EGL_NO_SURFACE; + } + if (egl_ctx != EGL_NO_CONTEXT) { + eglDestroyContext(egl_disp, egl_ctx); + egl_ctx = EGL_NO_CONTEXT; + } + if (screen_win != NULL) { + screen_destroy_window(screen_win); + screen_win = NULL; + } + eglTerminate(egl_disp); + egl_disp = EGL_NO_DISPLAY; + } + eglReleaseThread(); +} + +void +bbutil_swap() { + int rc = eglSwapBuffers(egl_disp, egl_surf); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglSwapBuffers"); + } +} + +void +bbutil_clear() { + glClear(GL_COLOR_BUFFER_BIT); +} + +char * +get_window_group_id() +{ + static char s_window_group_id[16] = ""; + + if (s_window_group_id[0] == '\0') { + snprintf(s_window_group_id, sizeof(s_window_group_id), "%d", getpid()); + } + + return s_window_group_id; +} + + +int bbutil_rotate_screen_surface(int angle) { + int rc, rotation, skip = 1, temp;; + EGLint interval = 1; + int size[2]; + + if ((angle != 0) && (angle != 90) && (angle != 180) && (angle != 270)) { + fprintf(stderr, "Invalid angle\n"); + return EXIT_FAILURE; + } + + rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &rotation); + if (rc) { + perror("screen_set_window_property_iv"); + return EXIT_FAILURE; + } + + rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size); + if (rc) { + perror("screen_set_window_property_iv"); + return EXIT_FAILURE; + } + + switch (angle - rotation) { + case -270: + case -90: + case 90: + case 270: + temp = size[0]; + size[0] = size[1]; + size[1] = temp; + skip = 0; + break; + } + + if (!skip) { + rc = eglMakeCurrent(egl_disp, NULL, NULL, NULL); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglMakeCurrent"); + return EXIT_FAILURE; + } + + rc = eglDestroySurface(egl_disp, egl_surf); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglMakeCurrent"); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_SOURCE_SIZE, size); + if (rc) { + perror("screen_set_window_property_iv"); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size); + if (rc) { + perror("screen_set_window_property_iv"); + return EXIT_FAILURE; + } + egl_surf = eglCreateWindowSurface(egl_disp, egl_conf, screen_win, NULL); + if (egl_surf == EGL_NO_SURFACE) { + bbutil_egl_perror("eglCreateWindowSurface"); + return EXIT_FAILURE; + } + + rc = eglMakeCurrent(egl_disp, egl_surf, egl_surf, egl_ctx); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglMakeCurrent"); + return EXIT_FAILURE; + } + + rc = eglSwapInterval(egl_disp, interval); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglSwapInterval"); + return EXIT_FAILURE; + } + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle); + if (rc) { + perror("screen_set_window_property_iv"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + |
