aboutsummaryrefslogtreecommitdiff
path: root/platform/bb10/bbutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/bb10/bbutil.c')
-rw-r--r--platform/bb10/bbutil.c513
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;
+}
+