blob: 70b46f758588a78419a5d4e719ab2917d8a59210 [file] [log] [blame]
/*
** Copyright 2018, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-function"
#include <android_runtime/AndroidRuntime.h>
#include <nativehelper/JNIHelp.h>
#include <utils/misc.h>
#include "jni.h"
#include <EGL/egl.h>
#include <assert.h>
#include <ui/ANativeObjectBase.h>
static int initialized = 0;
// classes from EGL 1.4
static jclass egldisplayClass;
static jclass eglsurfaceClass;
static jclass eglconfigClass;
static jclass eglcontextClass;
static jclass bufferClass;
static jclass nioAccessClass;
static jfieldID positionID;
static jfieldID limitID;
static jfieldID elementSizeShiftID;
static jmethodID getBasePointerID;
static jmethodID getBaseArrayID;
static jmethodID getBaseArrayOffsetID;
static jmethodID egldisplayGetHandleID;
static jmethodID eglconfigGetHandleID;
static jmethodID eglcontextGetHandleID;
static jmethodID eglsurfaceGetHandleID;
static jmethodID egldisplayConstructor;
static jmethodID eglcontextConstructor;
static jmethodID eglsurfaceConstructor;
static jmethodID eglconfigConstructor;
static jobject eglNoContextObject;
static jobject eglNoDisplayObject;
static jobject eglNoSurfaceObject;
// classes from EGL 1.5
static jclass eglimageClass;
static jclass eglsyncClass;
static jmethodID eglimageGetHandleID;
static jmethodID eglsyncGetHandleID;
static jmethodID eglimageConstructor;
static jmethodID eglsyncConstructor;
static jobject eglNoImageObject;
static jobject eglNoSyncObject;
/* Cache method IDs each time the class is loaded. */
static void nativeClassInit(JNIEnv *_env, jclass glImplClass) {
// EGL 1.4 Init
jclass eglconfigClassLocal = _env->FindClass("android/opengl/EGLConfig");
eglconfigClass = (jclass)_env->NewGlobalRef(eglconfigClassLocal);
jclass eglcontextClassLocal = _env->FindClass("android/opengl/EGLContext");
eglcontextClass = (jclass)_env->NewGlobalRef(eglcontextClassLocal);
jclass egldisplayClassLocal = _env->FindClass("android/opengl/EGLDisplay");
egldisplayClass = (jclass)_env->NewGlobalRef(egldisplayClassLocal);
jclass eglsurfaceClassLocal = _env->FindClass("android/opengl/EGLSurface");
eglsurfaceClass = (jclass)_env->NewGlobalRef(eglsurfaceClassLocal);
eglconfigGetHandleID = _env->GetMethodID(eglconfigClass, "getNativeHandle", "()J");
eglcontextGetHandleID = _env->GetMethodID(eglcontextClass, "getNativeHandle", "()J");
egldisplayGetHandleID = _env->GetMethodID(egldisplayClass, "getNativeHandle", "()J");
eglsurfaceGetHandleID = _env->GetMethodID(eglsurfaceClass, "getNativeHandle", "()J");
eglconfigConstructor = _env->GetMethodID(eglconfigClass, "<init>", "(J)V");
eglcontextConstructor = _env->GetMethodID(eglcontextClass, "<init>", "(J)V");
egldisplayConstructor = _env->GetMethodID(egldisplayClass, "<init>", "(J)V");
eglsurfaceConstructor = _env->GetMethodID(eglsurfaceClass, "<init>", "(J)V");
jobject localeglNoContextObject = _env->NewObject(eglcontextClass, eglcontextConstructor,
reinterpret_cast<jlong>(EGL_NO_CONTEXT));
eglNoContextObject = _env->NewGlobalRef(localeglNoContextObject);
jobject localeglNoDisplayObject = _env->NewObject(egldisplayClass, egldisplayConstructor,
reinterpret_cast<jlong>(EGL_NO_DISPLAY));
eglNoDisplayObject = _env->NewGlobalRef(localeglNoDisplayObject);
jobject localeglNoSurfaceObject = _env->NewObject(eglsurfaceClass, eglsurfaceConstructor,
reinterpret_cast<jlong>(EGL_NO_SURFACE));
eglNoSurfaceObject = _env->NewGlobalRef(localeglNoSurfaceObject);
jclass eglClass = _env->FindClass("android/opengl/EGL15");
jfieldID noContextFieldID =
_env->GetStaticFieldID(eglClass, "EGL_NO_CONTEXT", "Landroid/opengl/EGLContext;");
_env->SetStaticObjectField(eglClass, noContextFieldID, eglNoContextObject);
jfieldID noDisplayFieldID =
_env->GetStaticFieldID(eglClass, "EGL_NO_DISPLAY", "Landroid/opengl/EGLDisplay;");
_env->SetStaticObjectField(eglClass, noDisplayFieldID, eglNoDisplayObject);
jfieldID noSurfaceFieldID =
_env->GetStaticFieldID(eglClass, "EGL_NO_SURFACE", "Landroid/opengl/EGLSurface;");
_env->SetStaticObjectField(eglClass, noSurfaceFieldID, eglNoSurfaceObject);
// EGL 1.5 init
jclass nioAccessClassLocal = _env->FindClass("java/nio/NIOAccess");
nioAccessClass = (jclass)_env->NewGlobalRef(nioAccessClassLocal);
jclass bufferClassLocal = _env->FindClass("java/nio/Buffer");
bufferClass = (jclass)_env->NewGlobalRef(bufferClassLocal);
getBasePointerID =
_env->GetStaticMethodID(nioAccessClass, "getBasePointer", "(Ljava/nio/Buffer;)J");
getBaseArrayID = _env->GetStaticMethodID(nioAccessClass, "getBaseArray",
"(Ljava/nio/Buffer;)Ljava/lang/Object;");
getBaseArrayOffsetID =
_env->GetStaticMethodID(nioAccessClass, "getBaseArrayOffset", "(Ljava/nio/Buffer;)I");
positionID = _env->GetFieldID(bufferClass, "position", "I");
limitID = _env->GetFieldID(bufferClass, "limit", "I");
elementSizeShiftID = _env->GetFieldID(bufferClass, "_elementSizeShift", "I");
jclass eglimageClassLocal = _env->FindClass("android/opengl/EGLImage");
eglimageClass = (jclass)_env->NewGlobalRef(eglimageClassLocal);
jclass eglsyncClassLocal = _env->FindClass("android/opengl/EGLSync");
eglsyncClass = (jclass)_env->NewGlobalRef(eglsyncClassLocal);
eglimageGetHandleID = _env->GetMethodID(eglimageClass, "getNativeHandle", "()J");
eglsyncGetHandleID = _env->GetMethodID(eglsyncClass, "getNativeHandle", "()J");
eglimageConstructor = _env->GetMethodID(eglimageClass, "<init>", "(J)V");
eglsyncConstructor = _env->GetMethodID(eglsyncClass, "<init>", "(J)V");
jfieldID noImageFieldID =
_env->GetStaticFieldID(eglClass, "EGL_NO_IMAGE", "Landroid/opengl/EGLImage;");
_env->SetStaticObjectField(eglClass, noImageFieldID, eglNoImageObject);
jfieldID noSyncFieldID =
_env->GetStaticFieldID(eglClass, "EGL_NO_SYNC", "Landroid/opengl/EGLSync;");
_env->SetStaticObjectField(eglClass, noSyncFieldID, eglNoSyncObject);
}
static void *getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining,
jint *offset) {
jint position;
jint limit;
jint elementSizeShift;
jlong pointer;
position = _env->GetIntField(buffer, positionID);
limit = _env->GetIntField(buffer, limitID);
elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
*remaining = (limit - position) << elementSizeShift;
pointer = _env->CallStaticLongMethod(nioAccessClass, getBasePointerID, buffer);
if (pointer != 0L) {
*array = NULL;
return reinterpret_cast<void *>(pointer);
}
eglimageGetHandleID = _env->GetMethodID(eglimageClass, "getNativeHandle", "()J");
eglsyncGetHandleID = _env->GetMethodID(eglsyncClass, "getNativeHandle", "()J");
*array = (jarray)_env->CallStaticObjectMethod(nioAccessClass, getBaseArrayID, buffer);
*offset = _env->CallStaticIntMethod(nioAccessClass, getBaseArrayOffsetID, buffer);
return NULL;
}
static void releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit) {
_env->ReleasePrimitiveArrayCritical(array, data, commit ? 0 : JNI_ABORT);
}
static void *fromEGLHandle(JNIEnv *_env, jmethodID mid, jobject obj) {
if (obj == NULL) {
jniThrowException(_env, "java/lang/IllegalArgumentException", "Object is set to null.");
}
jlong handle = _env->CallLongMethod(obj, mid);
return reinterpret_cast<void *>(handle);
}
static jobject toEGLHandle(JNIEnv *_env, jclass cls, jmethodID con, void *handle) {
if (cls == eglimageClass && (EGLImage)handle == EGL_NO_IMAGE) {
return eglNoImageObject;
}
return _env->NewObject(cls, con, reinterpret_cast<jlong>(handle));
}
// --------------------------------------------------------------------------