1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include <EGL/egl.h>
  27 
  28 #include "com_sun_glass_ui_monocle_EGL.h"
  29 #include "Monocle.h"
  30 
  31 #include <stdlib.h>
  32 
  33 
  34 void setEGLAttrs(jint *attrs, int *eglAttrs) {
  35     int index = 0;
  36 
  37     eglAttrs[index++] = EGL_SURFACE_TYPE;
  38     if (attrs[6] != 0) {
  39         eglAttrs[index++] = (EGL_WINDOW_BIT);
  40     } else {
  41         eglAttrs[index++] = EGL_PBUFFER_BIT;
  42     }
  43 
  44     // TODO:  We are depending on the order of attributes defined in
  45     // GLPixelFormat - we need a better way to manage this
  46 
  47     if (attrs[0] == 5 && attrs[1] == 6
  48             && attrs[2] == 5 && attrs[3] == 0) {
  49         // Optimization for Raspberry Pi model B. Even though the result
  50         // of setting EGL_BUFFER_SIZE to 16 should be the same as setting
  51         // component sizes separately, we get less per-frame overhead if we
  52         // only set EGL_BUFFER_SIZE.
  53         eglAttrs[index++] = EGL_BUFFER_SIZE;
  54         eglAttrs[index++] = 16;
  55     } else {
  56         eglAttrs[index++] = EGL_RED_SIZE;
  57         eglAttrs[index++] = attrs[0];
  58         eglAttrs[index++] = EGL_GREEN_SIZE;
  59         eglAttrs[index++] = attrs[1];
  60         eglAttrs[index++] = EGL_BLUE_SIZE;
  61         eglAttrs[index++] = attrs[2];
  62         eglAttrs[index++] = EGL_ALPHA_SIZE;
  63         eglAttrs[index++] = attrs[3];
  64     }
  65 
  66     eglAttrs[index++] = EGL_DEPTH_SIZE;
  67     eglAttrs[index++] = attrs[4];
  68     eglAttrs[index++] = EGL_RENDERABLE_TYPE;
  69     eglAttrs[index++] = EGL_OPENGL_ES2_BIT;
  70     eglAttrs[index] = EGL_NONE;
  71 }
  72 
  73 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_monocle_EGL_eglGetDisplay
  74     (JNIEnv *env, jclass clazz, jlong display) {
  75     // EGLNativeDisplayType is defined differently on different systems; can be an int or a ptr so cast with care
  76     EGLDisplay dpy = eglGetDisplay(((EGLNativeDisplayType) (unsigned long)(display)));
  77     return asJLong(dpy);
  78 }
  79 
  80 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_monocle_EGL_eglInitialize
  81     (JNIEnv *env, jclass clazz, jlong eglDisplay, jintArray majorArray,
  82      jintArray minorArray){
  83 
  84     EGLint major, minor;
  85     if (!eglInitialize(asPtr(eglDisplay), &major, &minor)) {
  86          (*env)->SetIntArrayRegion(env, majorArray, 0, 1, &major);
  87          (*env)->SetIntArrayRegion(env, minorArray, 0, 1, &minor);
  88         return JNI_FALSE;
  89     } else {
  90         return JNI_TRUE;
  91     }
  92 }
  93 
  94 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_monocle_EGL_eglBindAPI
  95     (JNIEnv *env, jclass clazz, jint api) {
  96 
  97     if (eglBindAPI(api)) {
  98         return JNI_TRUE;
  99     } else {
 100         return JNI_FALSE;
 101     }
 102 }
 103 
 104 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_monocle_EGL_eglChooseConfig
 105     (JNIEnv *env, jclass clazz, jlong eglDisplay, jintArray attribs,
 106      jlongArray configs, jint configSize, jintArray numConfigs) {
 107 
 108     int i=0;
 109 
 110     int eglAttrs[50]; /* value, attr pair plus a None */
 111     jint *attrArray;
 112 
 113     attrArray = (*env)->GetIntArrayElements(env, attribs, JNI_FALSE);
 114     setEGLAttrs(attrArray, eglAttrs);
 115     (*env)->ReleaseIntArrayElements(env, attribs, attrArray, JNI_ABORT);
 116     EGLConfig *configArray = malloc(sizeof(EGLConfig) * configSize);
 117     jlong *longConfigArray = malloc(sizeof(long) * configSize);
 118     EGLint numConfigPtr=5;
 119     jboolean retval;
 120 
 121     if (!eglChooseConfig(asPtr(eglDisplay), eglAttrs, configArray, configSize,
 122                                &numConfigPtr)) {
 123         retval = JNI_FALSE;
 124     } else {
 125         retval = JNI_TRUE;
 126     }
 127 
 128 
 129     (*env)->SetIntArrayRegion(env, numConfigs, 0, 1, &numConfigPtr);
 130     for (i = 0; i < numConfigPtr; i++) {
 131         longConfigArray[i] = asJLong(configArray[i]);
 132         //printf("i is %d\n", i);
 133     }
 134 
 135     (*env)->SetLongArrayRegion(env, configs, 0, configSize, longConfigArray);
 136     free(configArray);
 137     free(longConfigArray);
 138     return retval;
 139 }
 140 
 141 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_monocle_EGL__1eglCreateWindowSurface
 142     (JNIEnv *env, jclass clazz, jlong eglDisplay, jlong config,
 143      jlong nativeWindow, jintArray attribs) {
 144 
 145     EGLSurface eglSurface;
 146     EGLint *attrArray = NULL;
 147 
 148     if (attribs != NULL)
 149         attrArray = (*env)->GetIntArrayElements(env, attribs, JNI_FALSE);
 150 
 151     eglSurface =  eglCreateWindowSurface(asPtr(eglDisplay), asPtr(config),
 152                                                asPtr(nativeWindow),
 153                                                NULL);
 154     if (attrArray != NULL) {
 155         (*env)->ReleaseIntArrayElements(env, attribs, attrArray, JNI_ABORT);
 156     }
 157     return asJLong(eglSurface);
 158 }
 159 
 160 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_monocle_EGL_eglCreateContext
 161     (JNIEnv *env, jclass clazz, jlong eglDisplay, jlong config,
 162       jlong shareContext, jintArray attribs){
 163 
 164     // we don't support any passed-in context attributes presently
 165     // we don't support any share context presently
 166     EGLint contextAttrs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
 167     EGLContext context = eglCreateContext(asPtr(eglDisplay), asPtr(config),
 168                                           NULL, contextAttrs);
 169 
 170     if (context == EGL_NO_CONTEXT) {
 171         fprintf(stderr, "eglCreateContext() failed - %d\n", eglGetError());
 172         return 0;
 173     } else {
 174         return asJLong(context);
 175     }
 176 }
 177 
 178 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_monocle_EGL_eglMakeCurrent
 179    (JNIEnv *env, jclass clazz, jlong eglDisplay, jlong drawSurface,
 180     jlong readSurface, jlong eglContext) {
 181 
 182     if (eglMakeCurrent(asPtr(eglDisplay), asPtr(drawSurface), asPtr(readSurface),
 183                    asPtr(eglContext))) {
 184         return JNI_TRUE;
 185     } else {
 186         return JNI_FALSE;
 187     }
 188 }
 189 
 190 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_monocle_EGL_eglSwapBuffers
 191     (JNIEnv *env, jclass clazz, jlong eglDisplay, jlong eglSurface) {
 192     if (eglSwapBuffers(asPtr(eglDisplay), asPtr(eglSurface))) {
 193         return JNI_TRUE;
 194     } else {
 195         return JNI_FALSE;
 196     }
 197 }
 198 
 199 
 200 
 201 
 202 
 203 
 204 
 205 
 206 
 207 
 208 
 209 
 210