Merge "Added in flag to ask context to wait for debugger attach."
diff --git a/Android.mk b/Android.mk
index d9e4455..e2eabed 100644
--- a/Android.mk
+++ b/Android.mk
@@ -406,6 +406,7 @@
 LOCAL_MODULE := framework
 
 LOCAL_DX_FLAGS := --core-library --multi-dex
+LOCAL_JACK_FLAGS := --multi-dex native
 
 LOCAL_RMTYPEDEFS := true
 
@@ -417,6 +418,7 @@
 framework_res_R_stamp := \
 	$(call intermediates-dir-for,APPS,framework-res,,COMMON)/src/R.stamp
 $(full_classes_compiled_jar): $(framework_res_R_stamp)
+$(built_dex_intermediate): $(framework_res_R_stamp)
 
 $(framework_module): | $(dir $(framework_module))framework-res.apk
 
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index 2c596e5..8dec110 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -629,7 +629,7 @@
         }
 
         /**
-         * Returns an intent intent that can be used to show or edit details of the alarm clock in
+         * Returns an intent that can be used to show or edit details of the alarm clock in
          * the application that scheduled it.
          *
          * <p class="note">Beware that any application can retrieve and send this intent, 
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index b5295fb..66c40f7 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -35,6 +35,7 @@
     Bitmap getUserIcon(int userHandle);
     List<UserInfo> getUsers(boolean excludeDying);
     List<UserInfo> getProfiles(int userHandle, boolean enabledOnly);
+    boolean canAddMoreManagedProfiles();
     UserInfo getProfileParent(int userHandle);
     UserInfo getUserInfo(int userHandle);
     boolean isRestricted();
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index d124a49..b36624d 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -886,6 +886,22 @@
     }
 
     /**
+     * Checks whether it's possible to add more managed profiles. Caller must hold the MANAGE_USERS
+     * permission.
+     *
+     * @return true if more managed profiles can be added, false if limit has been reached.
+     * @hide
+     */
+    public boolean canAddMoreManagedProfiles() {
+        try {
+            return mService.canAddMoreManagedProfiles();
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not check if we can add more managed profiles", re);
+            return false;
+        }
+    }
+
+    /**
      * Returns list of the profiles of userHandle including
      * userHandle itself.
      * Note that this returns both enabled and not enabled profiles. See
diff --git a/core/java/android/security/IKeystoreService.aidl b/core/java/android/security/IKeystoreService.aidl
index 579cdbe..30ea8e7 100644
--- a/core/java/android/security/IKeystoreService.aidl
+++ b/core/java/android/security/IKeystoreService.aidl
@@ -30,33 +30,29 @@
  * @hide
  */
 interface IKeystoreService {
-    int test();
+    int getState(int userId);
     byte[] get(String name);
     int insert(String name, in byte[] item, int uid, int flags);
     int del(String name, int uid);
     int exist(String name, int uid);
-    String[] saw(String namePrefix, int uid);
+    String[] list(String namePrefix, int uid);
     int reset();
-    int password(String password);
-    int lock();
-    int unlock(String password);
-    int zero();
+    int onUserPasswordChanged(int userId, String newPassword);
+    int lock(int userId);
+    int unlock(int userId, String userPassword);
+    int isEmpty(int userId);
     int generate(String name, int uid, int keyType, int keySize, int flags,
         in KeystoreArguments args);
     int import_key(String name, in byte[] data, int uid, int flags);
     byte[] sign(String name, in byte[] data);
     int verify(String name, in byte[] data, in byte[] signature);
     byte[] get_pubkey(String name);
-    int del_key(String name, int uid);
     int grant(String name, int granteeUid);
     int ungrant(String name, int granteeUid);
     long getmtime(String name);
     int duplicate(String srcKey, int srcUid, String destKey, int destUid);
     int is_hardware_backed(String string);
     int clear_uid(long uid);
-    int reset_uid(int uid);
-    int sync_uid(int sourceUid, int targetUid);
-    int password_uid(String password, int uid);
 
     // Keymaster 0.4 methods
     int addRngEntropy(in byte[] data);
@@ -75,4 +71,6 @@
     int abort(IBinder handle);
     boolean isOperationAuthorized(IBinder token);
     int addAuthToken(in byte[] authToken);
+    int onUserAdded(int userId, int parentId);
+    int onUserRemoved(int userId);
 }
diff --git a/core/java/com/android/server/BootReceiver.java b/core/java/com/android/server/BootReceiver.java
index 155f5d3..92d5aea 100644
--- a/core/java/com/android/server/BootReceiver.java
+++ b/core/java/com/android/server/BootReceiver.java
@@ -144,10 +144,6 @@
                     -LOG_SIZE, "SYSTEM_RECOVERY_LOG");
             addFileToDropBox(db, prefs, headers, "/cache/recovery/last_kmsg",
                     -LOG_SIZE, "SYSTEM_RECOVERY_KMSG");
-            addFileToDropBox(db, prefs, headers, "/data/dontpanic/apanic_console",
-                    -LOG_SIZE, "APANIC_CONSOLE");
-            addFileToDropBox(db, prefs, headers, "/data/dontpanic/apanic_threads",
-                    -LOG_SIZE, "APANIC_THREADS");
             addAuditErrorsToDropBox(db, prefs, headers, -LOG_SIZE, "SYSTEM_AUDIT");
             addFsckErrorsToDropBox(db, prefs, headers, -LOG_SIZE, "SYSTEM_FSCK");
         } else {
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index da30044..11e9dcd 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -153,7 +153,105 @@
     jniThrowException(env, "java/lang/IllegalArgumentException", msg);
 }
 
-template<class JArray, class T>
+class ByteArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+        return _env->GetByteArrayElements(array, is_copy);
+    }
+};
+class BooleanArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+        return _env->GetBooleanArrayElements(array, is_copy);
+    }
+};
+class CharArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+        return _env->GetCharArrayElements(array, is_copy);
+    }
+};
+class ShortArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+        return _env->GetShortArrayElements(array, is_copy);
+    }
+};
+class IntArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+        return _env->GetIntArrayElements(array, is_copy);
+    }
+};
+class LongArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+        return _env->GetLongArrayElements(array, is_copy);
+    }
+};
+class FloatArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+        return _env->GetFloatArrayElements(array, is_copy);
+    }
+};
+class DoubleArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+        return _env->GetDoubleArrayElements(array, is_copy);
+    }
+};
+
+class ByteArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jint mode) {
+        _env->ReleaseByteArrayElements(array, data, mode);
+    }
+};
+class BooleanArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jint mode) {
+        _env->ReleaseBooleanArrayElements(array, data, mode);
+    }
+};
+class CharArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jcharArray array, jchar* data, jint mode) {
+        _env->ReleaseCharArrayElements(array, data, mode);
+    }
+};
+class ShortArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jshortArray array, jshort* data, jint mode) {
+        _env->ReleaseShortArrayElements(array, data, mode);
+    }
+};
+class IntArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jintArray array, jint* data, jint mode) {
+        _env->ReleaseIntArrayElements(array, data, mode);
+    }
+};
+class LongArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jlongArray array, jlong* data, jint mode) {
+        _env->ReleaseLongArrayElements(array, data, mode);
+    }
+};
+class FloatArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jint mode) {
+        _env->ReleaseFloatArrayElements(array, data, mode);
+    }
+};
+class DoubleArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jint mode) {
+        _env->ReleaseDoubleArrayElements(array, data, mode);
+    }
+};
+
+template<class JArray, class T, class ArrayGetter, class ArrayReleaser>
 class ArrayHelper {
 public:
     ArrayHelper(JNIEnv* env, JArray ref, jint offset, jint minSize) {
@@ -167,7 +265,7 @@
 
     ~ArrayHelper() {
         if (mBase) {
-            mEnv->ReleasePrimitiveArrayCritical(mRef, mBase, mReleaseParam);
+            ArrayReleaser::Release(mEnv, mRef, mBase, mReleaseParam);
         }
     }
 
@@ -198,7 +296,7 @@
     // Bind the array.
 
     void bind() {
-        mBase = (T*) mEnv->GetPrimitiveArrayCritical(mRef, (jboolean *) 0);
+        mBase = (T*) ArrayGetter::Get(mEnv, mRef, (jboolean *) 0);
         mData = mBase + mOffset;
     }
 
@@ -218,10 +316,10 @@
     int mReleaseParam;
 };
 
-typedef ArrayHelper<jfloatArray, float> FloatArrayHelper;
-typedef ArrayHelper<jcharArray, unsigned short> UnsignedShortArrayHelper;
-typedef ArrayHelper<jintArray, int> IntArrayHelper;
-typedef ArrayHelper<jbyteArray, unsigned char> ByteArrayHelper;
+typedef ArrayHelper<jfloatArray, float, FloatArrayGetter, FloatArrayReleaser> FloatArrayHelper;
+typedef ArrayHelper<jcharArray, unsigned short, CharArrayGetter, CharArrayReleaser> UnsignedShortArrayHelper;
+typedef ArrayHelper<jintArray, int, IntArrayGetter, IntArrayReleaser> IntArrayHelper;
+typedef ArrayHelper<jbyteArray, unsigned char, ByteArrayGetter, ByteArrayReleaser> ByteArrayHelper;
 
 inline float distance2(float x, float y, float z) {
     return x * x + y * y + z * z;
diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp
index 36f7963..9f5b3bc 100644
--- a/core/jni/android_opengl_EGL14.cpp
+++ b/core/jni/android_opengl_EGL14.cpp
@@ -204,7 +204,7 @@
         goto exit;
     }
     major_base = (EGLint *)
-        _env->GetPrimitiveArrayCritical(major_ref, (jboolean *)0);
+        _env->GetIntArrayElements(major_ref, (jboolean *)0);
     major = major_base + majorOffset;
 
     if (!minor_ref) {
@@ -227,7 +227,7 @@
         goto exit;
     }
     minor_base = (EGLint *)
-        _env->GetPrimitiveArrayCritical(minor_ref, (jboolean *)0);
+        _env->GetIntArrayElements(minor_ref, (jboolean *)0);
     minor = minor_base + minorOffset;
 
     _returnValue = eglInitialize(
@@ -238,11 +238,11 @@
 
 exit:
     if (minor_base) {
-        _env->ReleasePrimitiveArrayCritical(minor_ref, minor_base,
+        _env->ReleaseIntArrayElements(minor_ref, (jint*)minor_base,
             _exception ? JNI_ABORT: 0);
     }
     if (major_base) {
-        _env->ReleasePrimitiveArrayCritical(major_ref, major_base,
+        _env->ReleaseIntArrayElements(major_ref, (jint*)major_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -324,7 +324,7 @@
     }
     _num_configRemaining = _env->GetArrayLength(num_config_ref) - num_configOffset;
     num_config_base = (EGLint *)
-        _env->GetPrimitiveArrayCritical(num_config_ref, (jboolean *)0);
+        _env->GetIntArrayElements(num_config_ref, (jboolean *)0);
     num_config = num_config_base + num_configOffset;
 
     _returnValue = eglGetConfigs(
@@ -336,7 +336,7 @@
 
 exit:
     if (num_config_base) {
-        _env->ReleasePrimitiveArrayCritical(num_config_ref, num_config_base,
+        _env->ReleaseIntArrayElements(num_config_ref, (jint*)num_config_base,
             _exception ? JNI_ABORT: 0);
     }
     if (configs) {
@@ -385,7 +385,7 @@
     }
     _attrib_listRemaining = _env->GetArrayLength(attrib_list_ref) - attrib_listOffset;
     attrib_list_base = (EGLint *)
-        _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+        _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
     attrib_list = attrib_list_base + attrib_listOffset;
     attrib_list_sentinel = false;
     for (int i = _attrib_listRemaining - 1; i >= 0; i--)  {
@@ -442,7 +442,7 @@
         goto exit;
     }
     num_config_base = (EGLint *)
-        _env->GetPrimitiveArrayCritical(num_config_ref, (jboolean *)0);
+        _env->GetIntArrayElements(num_config_ref, (jboolean *)0);
     num_config = num_config_base + num_configOffset;
 
     _returnValue = eglChooseConfig(
@@ -455,11 +455,11 @@
 
 exit:
     if (num_config_base) {
-        _env->ReleasePrimitiveArrayCritical(num_config_ref, num_config_base,
+        _env->ReleaseIntArrayElements(num_config_ref, (jint*)num_config_base,
             _exception ? JNI_ABORT: 0);
     }
     if (attrib_list_base) {
-        _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+        _env->ReleaseIntArrayElements(attrib_list_ref, (jint*)attrib_list_base,
             JNI_ABORT);
     }
     if (configs) {
@@ -509,7 +509,7 @@
         goto exit;
     }
     value_base = (EGLint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     _returnValue = eglGetConfigAttrib(
@@ -521,7 +521,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -573,7 +573,7 @@
 
     _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
     attrib_list_base = (EGLint *)
-        _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+        _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
     attrib_list = attrib_list_base + offset;
     attrib_list_sentinel = 0;
     for (int i = _remaining - 1; i >= 0; i--)  {
@@ -598,7 +598,7 @@
 
 exit:
     if (attrib_list_base) {
-        _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+        _env->ReleaseIntArrayElements(attrib_list_ref, attrib_list_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -655,7 +655,7 @@
 
     _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
     attrib_list_base = (EGLint *)
-        _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+        _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
     attrib_list = attrib_list_base + offset;
     attrib_list_sentinel = 0;
     for (int i = _remaining - 1; i >= 0; i--)  {
@@ -680,7 +680,7 @@
 
 exit:
     if (attrib_list_base) {
-        _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+        _env->ReleaseIntArrayElements(attrib_list_ref, attrib_list_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -717,7 +717,7 @@
     }
     _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
     attrib_list_base = (EGLint *)
-        _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+        _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
     attrib_list = attrib_list_base + offset;
     attrib_list_sentinel = false;
     for (int i = _remaining - 1; i >= 0; i--)  {
@@ -741,7 +741,7 @@
 
 exit:
     if (attrib_list_base) {
-        _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+        _env->ReleaseIntArrayElements(attrib_list_ref, (jint*)attrib_list_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -808,7 +808,7 @@
         goto exit;
     }
     value_base = (EGLint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     _returnValue = eglQuerySurface(
@@ -820,7 +820,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -896,7 +896,7 @@
     }
     _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
     attrib_list_base = (EGLint *)
-        _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+        _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
     attrib_list = attrib_list_base + offset;
     attrib_list_sentinel = false;
     for (int i = _remaining - 1; i >= 0; i--)  {
@@ -922,7 +922,7 @@
 
 exit:
     if (attrib_list_base) {
-        _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+        _env->ReleaseIntArrayElements(attrib_list_ref, attrib_list_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -940,7 +940,6 @@
     }
     return android_eglCreatePbufferFromClientBuffer(_env, _this, dpy, buftype, buffer, config, attrib_list_ref, offset);
 }
-
 /* EGLBoolean eglSurfaceAttrib ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value ) */
 static jboolean
 android_eglSurfaceAttrib
@@ -1034,7 +1033,7 @@
     }
     _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
     attrib_list_base = (EGLint *)
-        _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+        _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
     attrib_list = attrib_list_base + offset;
     attrib_list_sentinel = false;
     for (int i = _remaining - 1; i >= 0; i--)  {
@@ -1059,7 +1058,7 @@
 
 exit:
     if (attrib_list_base) {
-        _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+        _env->ReleaseIntArrayElements(attrib_list_ref, (jint*)attrib_list_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1165,7 +1164,7 @@
         goto exit;
     }
     value_base = (EGLint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     _returnValue = eglQueryContext(
@@ -1177,7 +1176,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
diff --git a/core/jni/android_opengl_GLES10.cpp b/core/jni/android_opengl_GLES10.cpp
index c9b68bf..dac98de 100644
--- a/core/jni/android_opengl_GLES10.cpp
+++ b/core/jni/android_opengl_GLES10.cpp
@@ -126,6 +126,116 @@
     return NULL;
 }
 
+class ByteArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+        return _env->GetByteArrayElements(array, is_copy);
+    }
+};
+class BooleanArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+        return _env->GetBooleanArrayElements(array, is_copy);
+    }
+};
+class CharArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+        return _env->GetCharArrayElements(array, is_copy);
+    }
+};
+class ShortArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+        return _env->GetShortArrayElements(array, is_copy);
+    }
+};
+class IntArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+        return _env->GetIntArrayElements(array, is_copy);
+    }
+};
+class LongArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+        return _env->GetLongArrayElements(array, is_copy);
+    }
+};
+class FloatArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+        return _env->GetFloatArrayElements(array, is_copy);
+    }
+};
+class DoubleArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+        return _env->GetDoubleArrayElements(array, is_copy);
+    }
+};
+
+template<typename JTYPEARRAY, typename ARRAYGETTER>
+static void*
+getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
+    return ARRAYGETTER::Get(_env, array, is_copy);
+}
+
+class ByteArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
+        _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class BooleanArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
+        _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class CharArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
+        _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class ShortArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
+        _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class IntArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
+        _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class LongArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
+        _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class FloatArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
+        _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class DoubleArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
+        _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+
+template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
+static void
+releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
+    ARRAYRELEASER::Release(_env, array, data, commit);
+}
+
 static void
 releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
 {
@@ -229,7 +339,8 @@
     return needed;
 }
 
-template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+          typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
 static void
 get
   (JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -264,8 +375,8 @@
         _exceptionMessage = "length - offset < needed";
         goto exit;
     }
-    params_base = (CTYPE *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+    params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+        _env, params_ref, (jboolean *)0);
     params = params_base + offset;
 
     GET(
@@ -275,8 +386,8 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
-            _exception ? JNI_ABORT: 0);
+        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+            _env, params_ref, params_base, !_exception);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -284,20 +395,21 @@
 }
 
 
-template <typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+          typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
 static void
 getarray
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
     jint _exception = 0;
     const char * _exceptionType;
     const char * _exceptionMessage;
-    jarray _array = (jarray) 0;
+    JTYPEARRAY _array = (JTYPEARRAY) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     CTYPE *params = (CTYPE *) 0;
     int _needed = 0;
 
-    params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     _remaining /= sizeof(CTYPE);    // convert from bytes to item count
     _needed = getNeededCount(pname);
     // if we didn't find this pname, we just assume the user passed
@@ -310,7 +422,8 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+            _env, _array, (jboolean *) 0);
         params = (CTYPE *) (_paramsBase + _bufferOffset);
     }
     GET(
@@ -320,7 +433,8 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+            _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -515,7 +629,7 @@
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
 
-    data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+    data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (data == NULL) {
         char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         data = (GLvoid *) (_dataBase + _bufferOffset);
@@ -544,7 +658,7 @@
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
 
-    data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+    data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (data == NULL) {
         char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         data = (GLvoid *) (_dataBase + _bufferOffset);
@@ -637,7 +751,7 @@
         goto exit;
     }
     textures_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(textures_ref, (jboolean *)0);
+        _env->GetIntArrayElements(textures_ref, (jboolean *)0);
     textures = textures_base + offset;
 
     glDeleteTextures(
@@ -647,7 +761,7 @@
 
 exit:
     if (textures_base) {
-        _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
+        _env->ReleaseIntArrayElements(textures_ref, (jint*)textures_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -662,12 +776,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
 
-    textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining, &_bufferOffset);
+    textures = (GLuint *)getPointer(_env, textures_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -675,7 +789,7 @@
         goto exit;
     }
     if (textures == NULL) {
-        char * _texturesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _texturesBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         textures = (GLuint *) (_texturesBase + _bufferOffset);
     }
     glDeleteTextures(
@@ -685,7 +799,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, textures, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)textures, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -771,7 +885,7 @@
     jint _remaining;
     GLvoid *indices = (GLvoid *) 0;
 
-    indices = (GLvoid *)getPointer(_env, indices_buf, &_array, &_remaining, &_bufferOffset);
+    indices = (GLvoid *)getPointer(_env, indices_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < count) {
         _exception = 1;
         _exceptionType = "java/lang/ArrayIndexOutOfBoundsException";
@@ -882,7 +996,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glFogfv(
@@ -892,7 +1006,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -907,12 +1021,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_FOG_COLOR)
@@ -931,7 +1045,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glFogfv(
@@ -941,7 +1055,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1000,7 +1114,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glFogxv(
@@ -1010,7 +1124,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1025,12 +1139,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_FOG_COLOR)
@@ -1049,7 +1163,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glFogxv(
@@ -1059,7 +1173,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1134,7 +1248,7 @@
         goto exit;
     }
     textures_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(textures_ref, (jboolean *)0);
+        _env->GetIntArrayElements(textures_ref, (jboolean *)0);
     textures = textures_base + offset;
 
     glGenTextures(
@@ -1144,7 +1258,7 @@
 
 exit:
     if (textures_base) {
-        _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
+        _env->ReleaseIntArrayElements(textures_ref, (jint*)textures_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1159,12 +1273,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
 
-    textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining, &_bufferOffset);
+    textures = (GLuint *)getPointer(_env, textures_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -1172,7 +1286,7 @@
         goto exit;
     }
     if (textures == NULL) {
-        char * _texturesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _texturesBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         textures = (GLuint *) (_texturesBase + _bufferOffset);
     }
     glGenTextures(
@@ -1182,7 +1296,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, textures, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)textures, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1202,16 +1316,17 @@
 static void
 android_glGetIntegerv__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
-    get<jintArray, GLint, glGetIntegerv>(_env, _this, pname, params_ref, offset);
+    get<jintArray, IntArrayGetter, jint*, IntArrayReleaser, GLint, glGetIntegerv>(
+        _env, _this, pname, params_ref, offset);
 }
 
 /* void glGetIntegerv ( GLenum pname, GLint *params ) */
 static void
 android_glGetIntegerv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    getarray<GLint, glGetIntegerv>(_env, _this, pname, params_buf);
+    getarray<GLint, jintArray, IntArrayGetter, jint*, IntArrayReleaser, glGetIntegerv>(
+        _env, _this, pname, params_buf);
 }
-
 /* const GLubyte * glGetString ( GLenum name ) */
 static jstring android_glGetString(JNIEnv* _env, jobject, jint name) {
     const char* chars = (const char*) glGetString((GLenum) name);
@@ -1279,7 +1394,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glLightModelfv(
@@ -1289,7 +1404,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1304,12 +1419,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_LIGHT_MODEL_AMBIENT)
@@ -1328,7 +1443,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glLightModelfv(
@@ -1338,7 +1453,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1397,7 +1512,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glLightModelxv(
@@ -1407,7 +1522,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1422,12 +1537,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_LIGHT_MODEL_AMBIENT)
@@ -1446,7 +1561,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glLightModelxv(
@@ -1456,7 +1571,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1530,7 +1645,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glLightfv(
@@ -1541,7 +1656,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1556,12 +1671,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_SPOT_DIRECTION)
@@ -1594,7 +1709,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glLightfv(
@@ -1605,7 +1720,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1679,7 +1794,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glLightxv(
@@ -1690,7 +1805,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1705,12 +1820,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_SPOT_DIRECTION)
@@ -1743,7 +1858,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glLightxv(
@@ -1754,7 +1869,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1811,7 +1926,7 @@
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
     m_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(m_ref, (jboolean *)0);
     m = m_base + offset;
 
     glLoadMatrixf(
@@ -1820,7 +1935,7 @@
 
 exit:
     if (m_base) {
-        _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+        _env->ReleaseFloatArrayElements(m_ref, (jfloat*)m_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1832,21 +1947,21 @@
 static void
 android_glLoadMatrixf__Ljava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jobject m_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *m = (GLfloat *) 0;
 
-    m = (GLfloat *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+    m = (GLfloat *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (m == NULL) {
-        char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _mBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         m = (GLfloat *) (_mBase + _bufferOffset);
     }
     glLoadMatrixf(
         (GLfloat *)m
     );
     if (_array) {
-        releasePointer(_env, _array, m, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)m, JNI_ABORT);
     }
 }
 
@@ -1875,7 +1990,7 @@
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
     m_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+        _env->GetIntArrayElements(m_ref, (jboolean *)0);
     m = m_base + offset;
 
     glLoadMatrixx(
@@ -1884,7 +1999,7 @@
 
 exit:
     if (m_base) {
-        _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+        _env->ReleaseIntArrayElements(m_ref, (jint*)m_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1896,21 +2011,21 @@
 static void
 android_glLoadMatrixx__Ljava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jobject m_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *m = (GLfixed *) 0;
 
-    m = (GLfixed *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+    m = (GLfixed *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (m == NULL) {
-        char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _mBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         m = (GLfixed *) (_mBase + _bufferOffset);
     }
     glLoadMatrixx(
         (GLfixed *)m
     );
     if (_array) {
-        releasePointer(_env, _array, m, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)m, JNI_ABORT);
     }
 }
 
@@ -1988,7 +2103,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glMaterialfv(
@@ -1999,7 +2114,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2014,12 +2129,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_AMBIENT)
@@ -2050,7 +2165,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glMaterialfv(
@@ -2061,7 +2176,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2133,7 +2248,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glMaterialxv(
@@ -2144,7 +2259,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2159,12 +2274,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_AMBIENT)
@@ -2195,7 +2310,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glMaterialxv(
@@ -2206,7 +2321,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2247,7 +2362,7 @@
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
     m_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(m_ref, (jboolean *)0);
     m = m_base + offset;
 
     glMultMatrixf(
@@ -2256,7 +2371,7 @@
 
 exit:
     if (m_base) {
-        _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+        _env->ReleaseFloatArrayElements(m_ref, (jfloat*)m_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2268,21 +2383,21 @@
 static void
 android_glMultMatrixf__Ljava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jobject m_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *m = (GLfloat *) 0;
 
-    m = (GLfloat *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+    m = (GLfloat *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (m == NULL) {
-        char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _mBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         m = (GLfloat *) (_mBase + _bufferOffset);
     }
     glMultMatrixf(
         (GLfloat *)m
     );
     if (_array) {
-        releasePointer(_env, _array, m, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)m, JNI_ABORT);
     }
 }
 
@@ -2311,7 +2426,7 @@
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
     m_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+        _env->GetIntArrayElements(m_ref, (jboolean *)0);
     m = m_base + offset;
 
     glMultMatrixx(
@@ -2320,7 +2435,7 @@
 
 exit:
     if (m_base) {
-        _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+        _env->ReleaseIntArrayElements(m_ref, (jint*)m_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2332,21 +2447,21 @@
 static void
 android_glMultMatrixx__Ljava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jobject m_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *m = (GLfixed *) 0;
 
-    m = (GLfixed *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+    m = (GLfixed *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (m == NULL) {
-        char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _mBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         m = (GLfixed *) (_mBase + _bufferOffset);
     }
     glMultMatrixx(
         (GLfixed *)m
     );
     if (_array) {
-        releasePointer(_env, _array, m, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)m, JNI_ABORT);
     }
 }
 
@@ -2520,7 +2635,7 @@
     jint _remaining;
     GLvoid *pixels = (GLvoid *) 0;
 
-    pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+    pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (pixels == NULL) {
         char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         pixels = (GLvoid *) (_pixelsBase + _bufferOffset);
@@ -2734,7 +2849,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexEnvfv(
@@ -2745,7 +2860,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2760,12 +2875,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_TEXTURE_ENV_COLOR)
@@ -2784,7 +2899,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glTexEnvfv(
@@ -2795,7 +2910,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2855,7 +2970,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexEnvxv(
@@ -2866,7 +2981,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2881,12 +2996,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_TEXTURE_ENV_COLOR)
@@ -2905,7 +3020,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glTexEnvxv(
@@ -2916,7 +3031,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2933,7 +3048,7 @@
     GLvoid *pixels = (GLvoid *) 0;
 
     if (pixels_buf) {
-        pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+        pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     }
     if (pixels_buf && pixels == NULL) {
         char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
@@ -2987,7 +3102,7 @@
     GLvoid *pixels = (GLvoid *) 0;
 
     if (pixels_buf) {
-        pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+        pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     }
     if (pixels_buf && pixels == NULL) {
         char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
diff --git a/core/jni/android_opengl_GLES10Ext.cpp b/core/jni/android_opengl_GLES10Ext.cpp
index 4f1eaa5..95be11b 100644
--- a/core/jni/android_opengl_GLES10Ext.cpp
+++ b/core/jni/android_opengl_GLES10Ext.cpp
@@ -126,6 +126,116 @@
     return NULL;
 }
 
+class ByteArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+        return _env->GetByteArrayElements(array, is_copy);
+    }
+};
+class BooleanArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+        return _env->GetBooleanArrayElements(array, is_copy);
+    }
+};
+class CharArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+        return _env->GetCharArrayElements(array, is_copy);
+    }
+};
+class ShortArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+        return _env->GetShortArrayElements(array, is_copy);
+    }
+};
+class IntArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+        return _env->GetIntArrayElements(array, is_copy);
+    }
+};
+class LongArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+        return _env->GetLongArrayElements(array, is_copy);
+    }
+};
+class FloatArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+        return _env->GetFloatArrayElements(array, is_copy);
+    }
+};
+class DoubleArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+        return _env->GetDoubleArrayElements(array, is_copy);
+    }
+};
+
+template<typename JTYPEARRAY, typename ARRAYGETTER>
+static void*
+getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
+    return ARRAYGETTER::Get(_env, array, is_copy);
+}
+
+class ByteArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
+        _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class BooleanArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
+        _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class CharArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
+        _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class ShortArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
+        _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class IntArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
+        _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class LongArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
+        _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class FloatArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
+        _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class DoubleArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
+        _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+
+template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
+static void
+releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
+    ARRAYRELEASER::Release(_env, array, data, commit);
+}
+
 static void
 releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
 {
@@ -229,7 +339,8 @@
     return needed;
 }
 
-template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+          typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
 static void
 get
   (JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -264,8 +375,8 @@
         _exceptionMessage = "length - offset < needed";
         goto exit;
     }
-    params_base = (CTYPE *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+    params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+        _env, params_ref, (jboolean *)0);
     params = params_base + offset;
 
     GET(
@@ -275,8 +386,8 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
-            _exception ? JNI_ABORT: 0);
+        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+            _env, params_ref, params_base, !_exception);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -284,20 +395,21 @@
 }
 
 
-template <typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+          typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
 static void
 getarray
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
     jint _exception = 0;
     const char * _exceptionType;
     const char * _exceptionMessage;
-    jarray _array = (jarray) 0;
+    JTYPEARRAY _array = (JTYPEARRAY) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     CTYPE *params = (CTYPE *) 0;
     int _needed = 0;
 
-    params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     _remaining /= sizeof(CTYPE);    // convert from bytes to item count
     _needed = getNeededCount(pname);
     // if we didn't find this pname, we just assume the user passed
@@ -310,7 +422,8 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+            _env, _array, (jboolean *) 0);
         params = (CTYPE *) (_paramsBase + _bufferOffset);
     }
     GET(
@@ -320,7 +433,8 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+            _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -363,7 +477,7 @@
         goto exit;
     }
     mantissa_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(mantissa_ref, (jboolean *)0);
+        _env->GetIntArrayElements(mantissa_ref, (jboolean *)0);
     mantissa = mantissa_base + mantissaOffset;
 
     if (!exponent_ref) {
@@ -386,7 +500,7 @@
         goto exit;
     }
     exponent_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(exponent_ref, (jboolean *)0);
+        _env->GetIntArrayElements(exponent_ref, (jboolean *)0);
     exponent = exponent_base + exponentOffset;
 
     _returnValue = glQueryMatrixxOES(
@@ -396,11 +510,11 @@
 
 exit:
     if (exponent_base) {
-        _env->ReleasePrimitiveArrayCritical(exponent_ref, exponent_base,
+        _env->ReleaseIntArrayElements(exponent_ref, (jint*)exponent_base,
             _exception ? JNI_ABORT: 0);
     }
     if (mantissa_base) {
-        _env->ReleasePrimitiveArrayCritical(mantissa_ref, mantissa_base,
+        _env->ReleaseIntArrayElements(mantissa_ref, (jint*)mantissa_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -416,9 +530,9 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _mantissaArray = (jarray) 0;
+    jintArray _mantissaArray = (jintArray) 0;
     jint _mantissaBufferOffset = (jint) 0;
-    jarray _exponentArray = (jarray) 0;
+    jintArray _exponentArray = (jintArray) 0;
     jint _exponentBufferOffset = (jint) 0;
     GLbitfield _returnValue = -1;
     jint _mantissaRemaining;
@@ -426,14 +540,14 @@
     jint _exponentRemaining;
     GLint *exponent = (GLint *) 0;
 
-    mantissa = (GLfixed *)getPointer(_env, mantissa_buf, &_mantissaArray, &_mantissaRemaining, &_mantissaBufferOffset);
+    mantissa = (GLfixed *)getPointer(_env, mantissa_buf, (jarray*)&_mantissaArray, &_mantissaRemaining, &_mantissaBufferOffset);
     if (_mantissaRemaining < 16) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
         _exceptionMessage = "remaining() < 16 < needed";
         goto exit;
     }
-    exponent = (GLint *)getPointer(_env, exponent_buf, &_exponentArray, &_exponentRemaining, &_exponentBufferOffset);
+    exponent = (GLint *)getPointer(_env, exponent_buf, (jarray*)&_exponentArray, &_exponentRemaining, &_exponentBufferOffset);
     if (_exponentRemaining < 16) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -441,11 +555,11 @@
         goto exit;
     }
     if (mantissa == NULL) {
-        char * _mantissaBase = (char *)_env->GetPrimitiveArrayCritical(_mantissaArray, (jboolean *) 0);
+        char * _mantissaBase = (char *)_env->GetIntArrayElements(_mantissaArray, (jboolean *) 0);
         mantissa = (GLfixed *) (_mantissaBase + _mantissaBufferOffset);
     }
     if (exponent == NULL) {
-        char * _exponentBase = (char *)_env->GetPrimitiveArrayCritical(_exponentArray, (jboolean *) 0);
+        char * _exponentBase = (char *)_env->GetIntArrayElements(_exponentArray, (jboolean *) 0);
         exponent = (GLint *) (_exponentBase + _exponentBufferOffset);
     }
     _returnValue = glQueryMatrixxOES(
@@ -455,10 +569,10 @@
 
 exit:
     if (_exponentArray) {
-        releasePointer(_env, _exponentArray, exponent, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_exponentArray, (jint*)exponent, _exception ? JNI_ABORT : 0);
     }
     if (_mantissaArray) {
-        releasePointer(_env, _mantissaArray, mantissa, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_mantissaArray, (jint*)mantissa, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
diff --git a/core/jni/android_opengl_GLES11.cpp b/core/jni/android_opengl_GLES11.cpp
index 08c4740..6970a3c 100644
--- a/core/jni/android_opengl_GLES11.cpp
+++ b/core/jni/android_opengl_GLES11.cpp
@@ -126,6 +126,116 @@
     return NULL;
 }
 
+class ByteArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+        return _env->GetByteArrayElements(array, is_copy);
+    }
+};
+class BooleanArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+        return _env->GetBooleanArrayElements(array, is_copy);
+    }
+};
+class CharArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+        return _env->GetCharArrayElements(array, is_copy);
+    }
+};
+class ShortArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+        return _env->GetShortArrayElements(array, is_copy);
+    }
+};
+class IntArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+        return _env->GetIntArrayElements(array, is_copy);
+    }
+};
+class LongArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+        return _env->GetLongArrayElements(array, is_copy);
+    }
+};
+class FloatArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+        return _env->GetFloatArrayElements(array, is_copy);
+    }
+};
+class DoubleArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+        return _env->GetDoubleArrayElements(array, is_copy);
+    }
+};
+
+template<typename JTYPEARRAY, typename ARRAYGETTER>
+static void*
+getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
+    return ARRAYGETTER::Get(_env, array, is_copy);
+}
+
+class ByteArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
+        _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class BooleanArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
+        _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class CharArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
+        _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class ShortArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
+        _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class IntArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
+        _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class LongArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
+        _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class FloatArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
+        _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class DoubleArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
+        _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+
+template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
+static void
+releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
+    ARRAYRELEASER::Release(_env, array, data, commit);
+}
+
 static void
 releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
 {
@@ -229,7 +339,8 @@
     return needed;
 }
 
-template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+          typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
 static void
 get
   (JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -264,8 +375,8 @@
         _exceptionMessage = "length - offset < needed";
         goto exit;
     }
-    params_base = (CTYPE *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+    params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+        _env, params_ref, (jboolean *)0);
     params = params_base + offset;
 
     GET(
@@ -275,8 +386,8 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
-            _exception ? JNI_ABORT: 0);
+        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+            _env, params_ref, params_base, !_exception);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -284,20 +395,21 @@
 }
 
 
-template <typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+          typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
 static void
 getarray
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
     jint _exception = 0;
     const char * _exceptionType;
     const char * _exceptionMessage;
-    jarray _array = (jarray) 0;
+    JTYPEARRAY _array = (JTYPEARRAY) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     CTYPE *params = (CTYPE *) 0;
     int _needed = 0;
 
-    params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     _remaining /= sizeof(CTYPE);    // convert from bytes to item count
     _needed = getNeededCount(pname);
     // if we didn't find this pname, we just assume the user passed
@@ -310,7 +422,8 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+            _env, _array, (jboolean *) 0);
         params = (CTYPE *) (_paramsBase + _bufferOffset);
     }
     GET(
@@ -320,7 +433,8 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+            _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -351,7 +465,7 @@
     GLvoid *data = (GLvoid *) 0;
 
     if (data_buf) {
-        data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+        data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
         if (_remaining < size) {
             _exception = 1;
             _exceptionType = "java/lang/IllegalArgumentException";
@@ -391,7 +505,7 @@
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
 
-    data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+    data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < size) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -443,7 +557,7 @@
     }
     _remaining = _env->GetArrayLength(equation_ref) - offset;
     equation_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(equation_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(equation_ref, (jboolean *)0);
     equation = equation_base + offset;
 
     glClipPlanef(
@@ -453,7 +567,7 @@
 
 exit:
     if (equation_base) {
-        _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
+        _env->ReleaseFloatArrayElements(equation_ref, (jfloat*)equation_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -468,14 +582,14 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *equation = (GLfloat *) 0;
 
-    equation = (GLfloat *)getPointer(_env, equation_buf, &_array, &_remaining, &_bufferOffset);
+    equation = (GLfloat *)getPointer(_env, equation_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (equation == NULL) {
-        char * _equationBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _equationBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         equation = (GLfloat *) (_equationBase + _bufferOffset);
     }
     glClipPlanef(
@@ -483,7 +597,7 @@
         (GLfloat *)equation
     );
     if (_array) {
-        releasePointer(_env, _array, equation, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)equation, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -515,7 +629,7 @@
     }
     _remaining = _env->GetArrayLength(equation_ref) - offset;
     equation_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(equation_ref, (jboolean *)0);
+        _env->GetIntArrayElements(equation_ref, (jboolean *)0);
     equation = equation_base + offset;
 
     glClipPlanex(
@@ -525,7 +639,7 @@
 
 exit:
     if (equation_base) {
-        _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
+        _env->ReleaseIntArrayElements(equation_ref, (jint*)equation_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -540,14 +654,14 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *equation = (GLfixed *) 0;
 
-    equation = (GLfixed *)getPointer(_env, equation_buf, &_array, &_remaining, &_bufferOffset);
+    equation = (GLfixed *)getPointer(_env, equation_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (equation == NULL) {
-        char * _equationBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _equationBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         equation = (GLfixed *) (_equationBase + _bufferOffset);
     }
     glClipPlanex(
@@ -555,7 +669,7 @@
         (GLfixed *)equation
     );
     if (_array) {
-        releasePointer(_env, _array, equation, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)equation, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -617,7 +731,7 @@
         goto exit;
     }
     buffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(buffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(buffers_ref, (jboolean *)0);
     buffers = buffers_base + offset;
 
     glDeleteBuffers(
@@ -627,7 +741,7 @@
 
 exit:
     if (buffers_base) {
-        _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
+        _env->ReleaseIntArrayElements(buffers_ref, (jint*)buffers_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -642,12 +756,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
 
-    buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining, &_bufferOffset);
+    buffers = (GLuint *)getPointer(_env, buffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -655,7 +769,7 @@
         goto exit;
     }
     if (buffers == NULL) {
-        char * _buffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _buffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         buffers = (GLuint *) (_buffersBase + _bufferOffset);
     }
     glDeleteBuffers(
@@ -665,7 +779,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, buffers, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)buffers, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -721,7 +835,7 @@
         goto exit;
     }
     buffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(buffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(buffers_ref, (jboolean *)0);
     buffers = buffers_base + offset;
 
     glGenBuffers(
@@ -731,7 +845,7 @@
 
 exit:
     if (buffers_base) {
-        _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
+        _env->ReleaseIntArrayElements(buffers_ref, (jint*)buffers_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -746,12 +860,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
 
-    buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining, &_bufferOffset);
+    buffers = (GLuint *)getPointer(_env, buffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -759,7 +873,7 @@
         goto exit;
     }
     if (buffers == NULL) {
-        char * _buffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _buffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         buffers = (GLuint *) (_buffersBase + _bufferOffset);
     }
     glGenBuffers(
@@ -769,7 +883,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, buffers, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)buffers, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -780,14 +894,16 @@
 static void
 android_glGetBooleanv__I_3ZI
   (JNIEnv *_env, jobject _this, jint pname, jbooleanArray params_ref, jint offset) {
-    get<jbooleanArray, GLboolean, glGetBooleanv>(_env, _this, pname, params_ref, offset);
+    get<jbooleanArray, BooleanArrayGetter, jboolean*, BooleanArrayReleaser, GLboolean, glGetBooleanv>(
+        _env, _this, pname, params_ref, offset);
 }
 
 /* void glGetBooleanv ( GLenum pname, GLboolean *params ) */
 static void
 android_glGetBooleanv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    getarray<GLboolean, glGetBooleanv>(_env, _this, pname, params_buf);
+    getarray<GLboolean, jintArray, IntArrayGetter, jint*, IntArrayReleaser, glGetBooleanv>(
+        _env, _this, pname, params_buf);
 }
 /* void glGetBufferParameteriv ( GLenum target, GLenum pname, GLint *params ) */
 static void
@@ -820,7 +936,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetBufferParameteriv(
@@ -831,7 +947,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -846,12 +962,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -859,7 +975,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetBufferParameteriv(
@@ -870,7 +986,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -908,7 +1024,7 @@
         goto exit;
     }
     eqn_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(eqn_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(eqn_ref, (jboolean *)0);
     eqn = eqn_base + offset;
 
     glGetClipPlanef(
@@ -918,7 +1034,7 @@
 
 exit:
     if (eqn_base) {
-        _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
+        _env->ReleaseFloatArrayElements(eqn_ref, (jfloat*)eqn_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -933,12 +1049,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *eqn = (GLfloat *) 0;
 
-    eqn = (GLfloat *)getPointer(_env, eqn_buf, &_array, &_remaining, &_bufferOffset);
+    eqn = (GLfloat *)getPointer(_env, eqn_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 4) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -946,7 +1062,7 @@
         goto exit;
     }
     if (eqn == NULL) {
-        char * _eqnBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _eqnBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         eqn = (GLfloat *) (_eqnBase + _bufferOffset);
     }
     glGetClipPlanef(
@@ -956,7 +1072,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, eqn, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)eqn, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -994,7 +1110,7 @@
         goto exit;
     }
     eqn_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(eqn_ref, (jboolean *)0);
+        _env->GetIntArrayElements(eqn_ref, (jboolean *)0);
     eqn = eqn_base + offset;
 
     glGetClipPlanex(
@@ -1004,7 +1120,7 @@
 
 exit:
     if (eqn_base) {
-        _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
+        _env->ReleaseIntArrayElements(eqn_ref, (jint*)eqn_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1019,12 +1135,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *eqn = (GLfixed *) 0;
 
-    eqn = (GLfixed *)getPointer(_env, eqn_buf, &_array, &_remaining, &_bufferOffset);
+    eqn = (GLfixed *)getPointer(_env, eqn_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 4) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -1032,7 +1148,7 @@
         goto exit;
     }
     if (eqn == NULL) {
-        char * _eqnBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _eqnBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         eqn = (GLfixed *) (_eqnBase + _bufferOffset);
     }
     glGetClipPlanex(
@@ -1042,7 +1158,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, eqn, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)eqn, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1074,7 +1190,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetFixedv(
@@ -1084,7 +1200,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1096,14 +1212,14 @@
 static void
 android_glGetFixedv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glGetFixedv(
@@ -1111,7 +1227,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -1119,14 +1235,16 @@
 static void
 android_glGetFloatv__I_3FI
   (JNIEnv *_env, jobject _this, jint pname, jfloatArray params_ref, jint offset) {
-    get<jfloatArray, GLfloat, glGetFloatv>(_env, _this, pname, params_ref, offset);
+    get<jfloatArray, FloatArrayGetter, jfloat*, FloatArrayReleaser, GLfloat, glGetFloatv>(
+        _env, _this, pname, params_ref, offset);
 }
 
 /* void glGetFloatv ( GLenum pname, GLfloat *params ) */
 static void
 android_glGetFloatv__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    getarray<GLfloat, glGetFloatv>(_env, _this, pname, params_buf);
+    getarray<GLfloat, jfloatArray, FloatArrayGetter, jfloat*, FloatArrayReleaser, glGetFloatv>(
+        _env, _this, pname, params_buf);
 }
 /* void glGetLightfv ( GLenum light, GLenum pname, GLfloat *params ) */
 static void
@@ -1184,7 +1302,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetLightfv(
@@ -1195,7 +1313,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1210,12 +1328,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_SPOT_DIRECTION)
@@ -1248,7 +1366,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glGetLightfv(
@@ -1259,7 +1377,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1322,7 +1440,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetLightxv(
@@ -1333,7 +1451,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1348,12 +1466,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_SPOT_DIRECTION)
@@ -1386,7 +1504,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glGetLightxv(
@@ -1397,7 +1515,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1458,7 +1576,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetMaterialfv(
@@ -1469,7 +1587,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1484,12 +1602,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_AMBIENT)
@@ -1520,7 +1638,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glGetMaterialfv(
@@ -1531,7 +1649,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1592,7 +1710,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetMaterialxv(
@@ -1603,7 +1721,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1618,12 +1736,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_AMBIENT)
@@ -1654,7 +1772,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glGetMaterialxv(
@@ -1665,7 +1783,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1714,7 +1832,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexEnvfv(
@@ -1725,7 +1843,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1740,12 +1858,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_TEXTURE_ENV_COLOR)
@@ -1764,7 +1882,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glGetTexEnvfv(
@@ -1775,7 +1893,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1824,7 +1942,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexEnviv(
@@ -1835,7 +1953,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1850,12 +1968,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_TEXTURE_ENV_COLOR)
@@ -1874,7 +1992,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetTexEnviv(
@@ -1885,7 +2003,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1934,7 +2052,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexEnvxv(
@@ -1945,7 +2063,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1960,12 +2078,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_TEXTURE_ENV_COLOR)
@@ -1984,7 +2102,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glGetTexEnvxv(
@@ -1995,7 +2113,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2033,7 +2151,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexParameterfv(
@@ -2044,7 +2162,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2059,12 +2177,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2072,7 +2190,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glGetTexParameterfv(
@@ -2083,7 +2201,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2121,7 +2239,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexParameteriv(
@@ -2132,7 +2250,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2147,12 +2265,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2160,7 +2278,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetTexParameteriv(
@@ -2171,7 +2289,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2209,7 +2327,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexParameterxv(
@@ -2220,7 +2338,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2235,12 +2353,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2248,7 +2366,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glGetTexParameterxv(
@@ -2259,7 +2377,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2351,7 +2469,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glPointParameterfv(
@@ -2361,7 +2479,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2376,12 +2494,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2389,7 +2507,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glPointParameterfv(
@@ -2399,7 +2517,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2447,7 +2565,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glPointParameterxv(
@@ -2457,7 +2575,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2472,12 +2590,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2485,7 +2603,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glPointParameterxv(
@@ -2495,7 +2613,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2590,7 +2708,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexEnviv(
@@ -2601,7 +2719,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2616,12 +2734,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_TEXTURE_ENV_COLOR)
@@ -2640,7 +2758,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glTexEnviv(
@@ -2651,7 +2769,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2689,7 +2807,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexParameterfv(
@@ -2700,7 +2818,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2715,12 +2833,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2728,7 +2846,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glTexParameterfv(
@@ -2739,7 +2857,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2788,7 +2906,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexParameteriv(
@@ -2799,7 +2917,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2814,12 +2932,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2827,7 +2945,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glTexParameteriv(
@@ -2838,7 +2956,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2876,7 +2994,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexParameterxv(
@@ -2887,7 +3005,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2902,12 +3020,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2915,7 +3033,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glTexParameterxv(
@@ -2926,7 +3044,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
diff --git a/core/jni/android_opengl_GLES11Ext.cpp b/core/jni/android_opengl_GLES11Ext.cpp
index 21e5670f..6422ff2 100644
--- a/core/jni/android_opengl_GLES11Ext.cpp
+++ b/core/jni/android_opengl_GLES11Ext.cpp
@@ -126,6 +126,116 @@
     return NULL;
 }
 
+class ByteArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+        return _env->GetByteArrayElements(array, is_copy);
+    }
+};
+class BooleanArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+        return _env->GetBooleanArrayElements(array, is_copy);
+    }
+};
+class CharArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+        return _env->GetCharArrayElements(array, is_copy);
+    }
+};
+class ShortArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+        return _env->GetShortArrayElements(array, is_copy);
+    }
+};
+class IntArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+        return _env->GetIntArrayElements(array, is_copy);
+    }
+};
+class LongArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+        return _env->GetLongArrayElements(array, is_copy);
+    }
+};
+class FloatArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+        return _env->GetFloatArrayElements(array, is_copy);
+    }
+};
+class DoubleArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+        return _env->GetDoubleArrayElements(array, is_copy);
+    }
+};
+
+template<typename JTYPEARRAY, typename ARRAYGETTER>
+static void*
+getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
+    return ARRAYGETTER::Get(_env, array, is_copy);
+}
+
+class ByteArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
+        _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class BooleanArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
+        _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class CharArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
+        _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class ShortArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
+        _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class IntArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
+        _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class LongArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
+        _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class FloatArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
+        _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class DoubleArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
+        _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+
+template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
+static void
+releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
+    ARRAYRELEASER::Release(_env, array, data, commit);
+}
+
 static void
 releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
 {
@@ -229,7 +339,8 @@
     return needed;
 }
 
-template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+          typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
 static void
 get
   (JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -264,8 +375,8 @@
         _exceptionMessage = "length - offset < needed";
         goto exit;
     }
-    params_base = (CTYPE *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+    params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+        _env, params_ref, (jboolean *)0);
     params = params_base + offset;
 
     GET(
@@ -275,8 +386,8 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
-            _exception ? JNI_ABORT: 0);
+        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+            _env, params_ref, params_base, !_exception);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -284,20 +395,21 @@
 }
 
 
-template <typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+          typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
 static void
 getarray
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
     jint _exception = 0;
     const char * _exceptionType;
     const char * _exceptionMessage;
-    jarray _array = (jarray) 0;
+    JTYPEARRAY _array = (JTYPEARRAY) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     CTYPE *params = (CTYPE *) 0;
     int _needed = 0;
 
-    params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     _remaining /= sizeof(CTYPE);    // convert from bytes to item count
     _needed = getNeededCount(pname);
     // if we didn't find this pname, we just assume the user passed
@@ -310,7 +422,8 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+            _env, _array, (jboolean *) 0);
         params = (CTYPE *) (_paramsBase + _bufferOffset);
     }
     GET(
@@ -320,7 +433,8 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+            _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -429,7 +543,7 @@
         goto exit;
     }
     coords_base = (GLshort *)
-        _env->GetPrimitiveArrayCritical(coords_ref, (jboolean *)0);
+        _env->GetShortArrayElements(coords_ref, (jboolean *)0);
     coords = coords_base + offset;
 
     glDrawTexsvOES(
@@ -438,7 +552,7 @@
 
 exit:
     if (coords_base) {
-        _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
+        _env->ReleaseShortArrayElements(coords_ref, (jshort*)coords_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -453,12 +567,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jshortArray _array = (jshortArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLshort *coords = (GLshort *) 0;
 
-    coords = (GLshort *)getPointer(_env, coords_buf, &_array, &_remaining, &_bufferOffset);
+    coords = (GLshort *)getPointer(_env, coords_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 5) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -466,7 +580,7 @@
         goto exit;
     }
     if (coords == NULL) {
-        char * _coordsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _coordsBase = (char *)_env->GetShortArrayElements(_array, (jboolean *) 0);
         coords = (GLshort *) (_coordsBase + _bufferOffset);
     }
     glDrawTexsvOES(
@@ -475,7 +589,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, coords, JNI_FALSE);
+        _env->ReleaseShortArrayElements(_array, (jshort*)coords, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -513,7 +627,7 @@
         goto exit;
     }
     coords_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(coords_ref, (jboolean *)0);
+        _env->GetIntArrayElements(coords_ref, (jboolean *)0);
     coords = coords_base + offset;
 
     glDrawTexivOES(
@@ -522,7 +636,7 @@
 
 exit:
     if (coords_base) {
-        _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
+        _env->ReleaseIntArrayElements(coords_ref, (jint*)coords_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -537,12 +651,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *coords = (GLint *) 0;
 
-    coords = (GLint *)getPointer(_env, coords_buf, &_array, &_remaining, &_bufferOffset);
+    coords = (GLint *)getPointer(_env, coords_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 5) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -550,7 +664,7 @@
         goto exit;
     }
     if (coords == NULL) {
-        char * _coordsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _coordsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         coords = (GLint *) (_coordsBase + _bufferOffset);
     }
     glDrawTexivOES(
@@ -559,7 +673,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, coords, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)coords, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -597,7 +711,7 @@
         goto exit;
     }
     coords_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(coords_ref, (jboolean *)0);
+        _env->GetIntArrayElements(coords_ref, (jboolean *)0);
     coords = coords_base + offset;
 
     glDrawTexxvOES(
@@ -606,7 +720,7 @@
 
 exit:
     if (coords_base) {
-        _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
+        _env->ReleaseIntArrayElements(coords_ref, (jint*)coords_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -621,12 +735,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *coords = (GLfixed *) 0;
 
-    coords = (GLfixed *)getPointer(_env, coords_buf, &_array, &_remaining, &_bufferOffset);
+    coords = (GLfixed *)getPointer(_env, coords_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 5) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -634,7 +748,7 @@
         goto exit;
     }
     if (coords == NULL) {
-        char * _coordsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _coordsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         coords = (GLfixed *) (_coordsBase + _bufferOffset);
     }
     glDrawTexxvOES(
@@ -643,7 +757,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, coords, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)coords, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -694,7 +808,7 @@
         goto exit;
     }
     coords_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(coords_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(coords_ref, (jboolean *)0);
     coords = coords_base + offset;
 
     glDrawTexfvOES(
@@ -703,7 +817,7 @@
 
 exit:
     if (coords_base) {
-        _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
+        _env->ReleaseFloatArrayElements(coords_ref, (jfloat*)coords_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -718,12 +832,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *coords = (GLfloat *) 0;
 
-    coords = (GLfloat *)getPointer(_env, coords_buf, &_array, &_remaining, &_bufferOffset);
+    coords = (GLfloat *)getPointer(_env, coords_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 5) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -731,7 +845,7 @@
         goto exit;
     }
     if (coords == NULL) {
-        char * _coordsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _coordsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         coords = (GLfloat *) (_coordsBase + _bufferOffset);
     }
     glDrawTexfvOES(
@@ -740,7 +854,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, coords, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)coords, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -756,7 +870,7 @@
     jint _remaining;
     GLeglImageOES image = (GLeglImageOES) 0;
 
-    image = (GLeglImageOES)getPointer(_env, image_buf, &_array, &_remaining, &_bufferOffset);
+    image = (GLeglImageOES)getPointer(_env, image_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (image == NULL) {
         char * _imageBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         image = (GLeglImageOES) (_imageBase + _bufferOffset);
@@ -779,7 +893,7 @@
     jint _remaining;
     GLeglImageOES image = (GLeglImageOES) 0;
 
-    image = (GLeglImageOES)getPointer(_env, image_buf, &_array, &_remaining, &_bufferOffset);
+    image = (GLeglImageOES)getPointer(_env, image_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (image == NULL) {
         char * _imageBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         image = (GLeglImageOES) (_imageBase + _bufferOffset);
@@ -849,7 +963,7 @@
     }
     _remaining = _env->GetArrayLength(equation_ref) - offset;
     equation_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(equation_ref, (jboolean *)0);
+        _env->GetIntArrayElements(equation_ref, (jboolean *)0);
     equation = equation_base + offset;
 
     glClipPlanexOES(
@@ -859,7 +973,7 @@
 
 exit:
     if (equation_base) {
-        _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
+        _env->ReleaseIntArrayElements(equation_ref, (jint*)equation_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -871,14 +985,14 @@
 static void
 android_glClipPlanexOES__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint plane, jobject equation_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *equation = (GLfixed *) 0;
 
-    equation = (GLfixed *)getPointer(_env, equation_buf, &_array, &_remaining, &_bufferOffset);
+    equation = (GLfixed *)getPointer(_env, equation_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (equation == NULL) {
-        char * _equationBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _equationBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         equation = (GLfixed *) (_equationBase + _bufferOffset);
     }
     glClipPlanexOES(
@@ -886,7 +1000,7 @@
         (GLfixed *)equation
     );
     if (_array) {
-        releasePointer(_env, _array, equation, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)equation, JNI_ABORT);
     }
 }
 
@@ -947,7 +1061,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glFogxvOES(
@@ -957,7 +1071,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -969,14 +1083,14 @@
 static void
 android_glFogxvOES__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glFogxvOES(
@@ -984,7 +1098,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
 }
 
@@ -1033,7 +1147,7 @@
         goto exit;
     }
     eqn_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(eqn_ref, (jboolean *)0);
+        _env->GetIntArrayElements(eqn_ref, (jboolean *)0);
     eqn = eqn_base + offset;
 
     glGetClipPlanexOES(
@@ -1043,7 +1157,7 @@
 
 exit:
     if (eqn_base) {
-        _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
+        _env->ReleaseIntArrayElements(eqn_ref, (jint*)eqn_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1058,12 +1172,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *eqn = (GLfixed *) 0;
 
-    eqn = (GLfixed *)getPointer(_env, eqn_buf, &_array, &_remaining, &_bufferOffset);
+    eqn = (GLfixed *)getPointer(_env, eqn_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 4) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -1071,7 +1185,7 @@
         goto exit;
     }
     if (eqn == NULL) {
-        char * _eqnBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _eqnBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         eqn = (GLfixed *) (_eqnBase + _bufferOffset);
     }
     glGetClipPlanexOES(
@@ -1081,7 +1195,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, eqn, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)eqn, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1113,7 +1227,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetFixedvOES(
@@ -1123,7 +1237,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1135,14 +1249,14 @@
 static void
 android_glGetFixedvOES__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glGetFixedvOES(
@@ -1150,7 +1264,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -1179,7 +1293,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetLightxvOES(
@@ -1190,7 +1304,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1202,14 +1316,14 @@
 static void
 android_glGetLightxvOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint light, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glGetLightxvOES(
@@ -1218,7 +1332,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -1247,7 +1361,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetMaterialxvOES(
@@ -1258,7 +1372,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1270,14 +1384,14 @@
 static void
 android_glGetMaterialxvOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint face, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glGetMaterialxvOES(
@@ -1286,7 +1400,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -1315,7 +1429,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexEnvxvOES(
@@ -1326,7 +1440,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1338,14 +1452,14 @@
 static void
 android_glGetTexEnvxvOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint env, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glGetTexEnvxvOES(
@@ -1354,7 +1468,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -1383,7 +1497,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexParameterxvOES(
@@ -1394,7 +1508,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1406,14 +1520,14 @@
 static void
 android_glGetTexParameterxvOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glGetTexParameterxvOES(
@@ -1422,7 +1536,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -1461,7 +1575,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glLightModelxvOES(
@@ -1471,7 +1585,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1483,14 +1597,14 @@
 static void
 android_glLightModelxvOES__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glLightModelxvOES(
@@ -1498,7 +1612,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
 }
 
@@ -1538,7 +1652,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glLightxvOES(
@@ -1549,7 +1663,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1561,14 +1675,14 @@
 static void
 android_glLightxvOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint light, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glLightxvOES(
@@ -1577,7 +1691,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
 }
 
@@ -1615,7 +1729,7 @@
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
     m_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+        _env->GetIntArrayElements(m_ref, (jboolean *)0);
     m = m_base + offset;
 
     glLoadMatrixxOES(
@@ -1624,7 +1738,7 @@
 
 exit:
     if (m_base) {
-        _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+        _env->ReleaseIntArrayElements(m_ref, (jint*)m_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1636,21 +1750,21 @@
 static void
 android_glLoadMatrixxOES__Ljava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jobject m_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *m = (GLfixed *) 0;
 
-    m = (GLfixed *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+    m = (GLfixed *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (m == NULL) {
-        char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _mBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         m = (GLfixed *) (_mBase + _bufferOffset);
     }
     glLoadMatrixxOES(
         (GLfixed *)m
     );
     if (_array) {
-        releasePointer(_env, _array, m, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)m, JNI_ABORT);
     }
 }
 
@@ -1690,7 +1804,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glMaterialxvOES(
@@ -1701,7 +1815,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1713,14 +1827,14 @@
 static void
 android_glMaterialxvOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint face, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glMaterialxvOES(
@@ -1729,7 +1843,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
 }
 
@@ -1758,7 +1872,7 @@
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
     m_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+        _env->GetIntArrayElements(m_ref, (jboolean *)0);
     m = m_base + offset;
 
     glMultMatrixxOES(
@@ -1767,7 +1881,7 @@
 
 exit:
     if (m_base) {
-        _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+        _env->ReleaseIntArrayElements(m_ref, (jint*)m_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1779,21 +1893,21 @@
 static void
 android_glMultMatrixxOES__Ljava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jobject m_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *m = (GLfixed *) 0;
 
-    m = (GLfixed *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+    m = (GLfixed *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (m == NULL) {
-        char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _mBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         m = (GLfixed *) (_mBase + _bufferOffset);
     }
     glMultMatrixxOES(
         (GLfixed *)m
     );
     if (_array) {
-        releasePointer(_env, _array, m, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)m, JNI_ABORT);
     }
 }
 
@@ -1870,7 +1984,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glPointParameterxvOES(
@@ -1880,7 +1994,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1892,14 +2006,14 @@
 static void
 android_glPointParameterxvOES__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glPointParameterxvOES(
@@ -1907,7 +2021,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
 }
 
@@ -1999,7 +2113,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexEnvxvOES(
@@ -2010,7 +2124,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2022,14 +2136,14 @@
 static void
 android_glTexEnvxvOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glTexEnvxvOES(
@@ -2038,7 +2152,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
 }
 
@@ -2078,7 +2192,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexParameterxvOES(
@@ -2089,7 +2203,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2101,14 +2215,14 @@
 static void
 android_glTexParameterxvOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glTexParameterxvOES(
@@ -2117,7 +2231,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
 }
 
@@ -2184,7 +2298,7 @@
         goto exit;
     }
     renderbuffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(renderbuffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(renderbuffers_ref, (jboolean *)0);
     renderbuffers = renderbuffers_base + offset;
 
     glDeleteRenderbuffersOES(
@@ -2194,7 +2308,7 @@
 
 exit:
     if (renderbuffers_base) {
-        _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
+        _env->ReleaseIntArrayElements(renderbuffers_ref, (jint*)renderbuffers_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2209,12 +2323,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
 
-    renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, &_array, &_remaining, &_bufferOffset);
+    renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2222,7 +2336,7 @@
         goto exit;
     }
     if (renderbuffers == NULL) {
-        char * _renderbuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _renderbuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         renderbuffers = (GLuint *) (_renderbuffersBase + _bufferOffset);
     }
     glDeleteRenderbuffersOES(
@@ -2232,7 +2346,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, renderbuffers, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)renderbuffers, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2270,7 +2384,7 @@
         goto exit;
     }
     renderbuffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(renderbuffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(renderbuffers_ref, (jboolean *)0);
     renderbuffers = renderbuffers_base + offset;
 
     glGenRenderbuffersOES(
@@ -2280,7 +2394,7 @@
 
 exit:
     if (renderbuffers_base) {
-        _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
+        _env->ReleaseIntArrayElements(renderbuffers_ref, (jint*)renderbuffers_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2295,12 +2409,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
 
-    renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, &_array, &_remaining, &_bufferOffset);
+    renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2308,7 +2422,7 @@
         goto exit;
     }
     if (renderbuffers == NULL) {
-        char * _renderbuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _renderbuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         renderbuffers = (GLuint *) (_renderbuffersBase + _bufferOffset);
     }
     glGenRenderbuffersOES(
@@ -2318,7 +2432,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, renderbuffers, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)renderbuffers, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2368,7 +2482,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetRenderbufferParameterivOES(
@@ -2379,7 +2493,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2394,12 +2508,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2407,7 +2521,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetRenderbufferParameterivOES(
@@ -2418,7 +2532,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2477,7 +2591,7 @@
         goto exit;
     }
     framebuffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(framebuffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(framebuffers_ref, (jboolean *)0);
     framebuffers = framebuffers_base + offset;
 
     glDeleteFramebuffersOES(
@@ -2487,7 +2601,7 @@
 
 exit:
     if (framebuffers_base) {
-        _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
+        _env->ReleaseIntArrayElements(framebuffers_ref, (jint*)framebuffers_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2502,12 +2616,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
 
-    framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, &_array, &_remaining, &_bufferOffset);
+    framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2515,7 +2629,7 @@
         goto exit;
     }
     if (framebuffers == NULL) {
-        char * _framebuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _framebuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         framebuffers = (GLuint *) (_framebuffersBase + _bufferOffset);
     }
     glDeleteFramebuffersOES(
@@ -2525,7 +2639,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, framebuffers, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)framebuffers, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2563,7 +2677,7 @@
         goto exit;
     }
     framebuffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(framebuffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(framebuffers_ref, (jboolean *)0);
     framebuffers = framebuffers_base + offset;
 
     glGenFramebuffersOES(
@@ -2573,7 +2687,7 @@
 
 exit:
     if (framebuffers_base) {
-        _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
+        _env->ReleaseIntArrayElements(framebuffers_ref, (jint*)framebuffers_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2588,12 +2702,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
 
-    framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, &_array, &_remaining, &_bufferOffset);
+    framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2601,7 +2715,7 @@
         goto exit;
     }
     if (framebuffers == NULL) {
-        char * _framebuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _framebuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         framebuffers = (GLuint *) (_framebuffersBase + _bufferOffset);
     }
     glGenFramebuffersOES(
@@ -2611,7 +2725,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, framebuffers, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)framebuffers, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2685,7 +2799,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetFramebufferAttachmentParameterivOES(
@@ -2697,7 +2811,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2712,12 +2826,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2725,7 +2839,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetFramebufferAttachmentParameterivOES(
@@ -2737,7 +2851,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2880,7 +2994,7 @@
     }
     _remaining = _env->GetArrayLength(equation_ref) - offset;
     equation_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(equation_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(equation_ref, (jboolean *)0);
     equation = equation_base + offset;
 
     glClipPlanefOES(
@@ -2890,7 +3004,7 @@
 
 exit:
     if (equation_base) {
-        _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
+        _env->ReleaseFloatArrayElements(equation_ref, (jfloat*)equation_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2902,14 +3016,14 @@
 static void
 android_glClipPlanefOES__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint plane, jobject equation_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *equation = (GLfloat *) 0;
 
-    equation = (GLfloat *)getPointer(_env, equation_buf, &_array, &_remaining, &_bufferOffset);
+    equation = (GLfloat *)getPointer(_env, equation_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (equation == NULL) {
-        char * _equationBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _equationBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         equation = (GLfloat *) (_equationBase + _bufferOffset);
     }
     glClipPlanefOES(
@@ -2917,7 +3031,7 @@
         (GLfloat *)equation
     );
     if (_array) {
-        releasePointer(_env, _array, equation, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)equation, JNI_ABORT);
     }
 }
 
@@ -2952,7 +3066,7 @@
         goto exit;
     }
     eqn_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(eqn_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(eqn_ref, (jboolean *)0);
     eqn = eqn_base + offset;
 
     glGetClipPlanefOES(
@@ -2962,7 +3076,7 @@
 
 exit:
     if (eqn_base) {
-        _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
+        _env->ReleaseFloatArrayElements(eqn_ref, (jfloat*)eqn_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2977,12 +3091,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *eqn = (GLfloat *) 0;
 
-    eqn = (GLfloat *)getPointer(_env, eqn_buf, &_array, &_remaining, &_bufferOffset);
+    eqn = (GLfloat *)getPointer(_env, eqn_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 4) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2990,7 +3104,7 @@
         goto exit;
     }
     if (eqn == NULL) {
-        char * _eqnBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _eqnBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         eqn = (GLfloat *) (_eqnBase + _bufferOffset);
     }
     glGetClipPlanefOES(
@@ -3000,7 +3114,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, eqn, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)eqn, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3052,7 +3166,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexGenfvOES(
@@ -3063,7 +3177,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -3075,14 +3189,14 @@
 static void
 android_glTexGenfvOES__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint coord, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glTexGenfvOES(
@@ -3091,7 +3205,7 @@
         (GLfloat *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
     }
 }
 
@@ -3131,7 +3245,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexGenivOES(
@@ -3142,7 +3256,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -3154,14 +3268,14 @@
 static void
 android_glTexGenivOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint coord, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glTexGenivOES(
@@ -3170,7 +3284,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
 }
 
@@ -3210,7 +3324,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexGenxvOES(
@@ -3221,7 +3335,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -3233,14 +3347,14 @@
 static void
 android_glTexGenxvOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint coord, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glTexGenxvOES(
@@ -3249,7 +3363,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
 }
 
@@ -3278,7 +3392,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexGenfvOES(
@@ -3289,7 +3403,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3301,14 +3415,14 @@
 static void
 android_glGetTexGenfvOES__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint coord, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glGetTexGenfvOES(
@@ -3317,7 +3431,7 @@
         (GLfloat *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, 0);
     }
 }
 
@@ -3346,7 +3460,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexGenivOES(
@@ -3357,7 +3471,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3369,14 +3483,14 @@
 static void
 android_glGetTexGenivOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint coord, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetTexGenivOES(
@@ -3385,7 +3499,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -3414,7 +3528,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexGenxvOES(
@@ -3425,7 +3539,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3437,14 +3551,14 @@
 static void
 android_glGetTexGenxvOES__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint coord, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glGetTexGenxvOES(
@@ -3453,7 +3567,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
diff --git a/core/jni/android_opengl_GLES20.cpp b/core/jni/android_opengl_GLES20.cpp
index cd0c1354..f9a0dfe 100644
--- a/core/jni/android_opengl_GLES20.cpp
+++ b/core/jni/android_opengl_GLES20.cpp
@@ -126,6 +126,116 @@
     return NULL;
 }
 
+class ByteArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+        return _env->GetByteArrayElements(array, is_copy);
+    }
+};
+class BooleanArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+        return _env->GetBooleanArrayElements(array, is_copy);
+    }
+};
+class CharArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+        return _env->GetCharArrayElements(array, is_copy);
+    }
+};
+class ShortArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+        return _env->GetShortArrayElements(array, is_copy);
+    }
+};
+class IntArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+        return _env->GetIntArrayElements(array, is_copy);
+    }
+};
+class LongArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+        return _env->GetLongArrayElements(array, is_copy);
+    }
+};
+class FloatArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+        return _env->GetFloatArrayElements(array, is_copy);
+    }
+};
+class DoubleArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+        return _env->GetDoubleArrayElements(array, is_copy);
+    }
+};
+
+template<typename JTYPEARRAY, typename ARRAYGETTER>
+static void*
+getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
+    return ARRAYGETTER::Get(_env, array, is_copy);
+}
+
+class ByteArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
+        _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class BooleanArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
+        _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class CharArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
+        _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class ShortArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
+        _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class IntArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
+        _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class LongArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
+        _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class FloatArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
+        _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class DoubleArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
+        _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+
+template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
+static void
+releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
+    ARRAYRELEASER::Release(_env, array, data, commit);
+}
+
 static void
 releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
 {
@@ -229,7 +339,8 @@
     return needed;
 }
 
-template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+          typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
 static void
 get
   (JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -264,8 +375,8 @@
         _exceptionMessage = "length - offset < needed";
         goto exit;
     }
-    params_base = (CTYPE *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+    params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+        _env, params_ref, (jboolean *)0);
     params = params_base + offset;
 
     GET(
@@ -275,8 +386,8 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
-            _exception ? JNI_ABORT: 0);
+        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+            _env, params_ref, params_base, !_exception);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -284,20 +395,21 @@
 }
 
 
-template <typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+          typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
 static void
 getarray
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
     jint _exception = 0;
     const char * _exceptionType;
     const char * _exceptionMessage;
-    jarray _array = (jarray) 0;
+    JTYPEARRAY _array = (JTYPEARRAY) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     CTYPE *params = (CTYPE *) 0;
     int _needed = 0;
 
-    params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     _remaining /= sizeof(CTYPE);    // convert from bytes to item count
     _needed = getNeededCount(pname);
     // if we didn't find this pname, we just assume the user passed
@@ -310,7 +422,8 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+            _env, _array, (jboolean *) 0);
         params = (CTYPE *) (_paramsBase + _bufferOffset);
     }
     GET(
@@ -320,7 +433,8 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+            _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -486,7 +600,7 @@
     GLvoid *data = (GLvoid *) 0;
 
     if (data_buf) {
-        data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+        data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
         if (_remaining < size) {
             _exception = 1;
             _exceptionType = "java/lang/IllegalArgumentException";
@@ -526,7 +640,7 @@
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
 
-    data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+    data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < size) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -633,7 +747,7 @@
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
 
-    data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+    data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (data == NULL) {
         char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         data = (GLvoid *) (_dataBase + _bufferOffset);
@@ -662,7 +776,7 @@
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
 
-    data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+    data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (data == NULL) {
         char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         data = (GLvoid *) (_dataBase + _bufferOffset);
@@ -775,7 +889,7 @@
         goto exit;
     }
     buffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(buffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(buffers_ref, (jboolean *)0);
     buffers = buffers_base + offset;
 
     glDeleteBuffers(
@@ -785,7 +899,7 @@
 
 exit:
     if (buffers_base) {
-        _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
+        _env->ReleaseIntArrayElements(buffers_ref, (jint*)buffers_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -800,12 +914,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
 
-    buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining, &_bufferOffset);
+    buffers = (GLuint *)getPointer(_env, buffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -813,7 +927,7 @@
         goto exit;
     }
     if (buffers == NULL) {
-        char * _buffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _buffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         buffers = (GLuint *) (_buffersBase + _bufferOffset);
     }
     glDeleteBuffers(
@@ -823,7 +937,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, buffers, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)buffers, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -861,7 +975,7 @@
         goto exit;
     }
     framebuffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(framebuffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(framebuffers_ref, (jboolean *)0);
     framebuffers = framebuffers_base + offset;
 
     glDeleteFramebuffers(
@@ -871,7 +985,7 @@
 
 exit:
     if (framebuffers_base) {
-        _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
+        _env->ReleaseIntArrayElements(framebuffers_ref, (jint*)framebuffers_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -886,12 +1000,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
 
-    framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, &_array, &_remaining, &_bufferOffset);
+    framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -899,7 +1013,7 @@
         goto exit;
     }
     if (framebuffers == NULL) {
-        char * _framebuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _framebuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         framebuffers = (GLuint *) (_framebuffersBase + _bufferOffset);
     }
     glDeleteFramebuffers(
@@ -909,7 +1023,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, framebuffers, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)framebuffers, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -956,7 +1070,7 @@
         goto exit;
     }
     renderbuffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(renderbuffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(renderbuffers_ref, (jboolean *)0);
     renderbuffers = renderbuffers_base + offset;
 
     glDeleteRenderbuffers(
@@ -966,7 +1080,7 @@
 
 exit:
     if (renderbuffers_base) {
-        _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
+        _env->ReleaseIntArrayElements(renderbuffers_ref, (jint*)renderbuffers_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -981,12 +1095,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
 
-    renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, &_array, &_remaining, &_bufferOffset);
+    renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -994,7 +1108,7 @@
         goto exit;
     }
     if (renderbuffers == NULL) {
-        char * _renderbuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _renderbuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         renderbuffers = (GLuint *) (_renderbuffersBase + _bufferOffset);
     }
     glDeleteRenderbuffers(
@@ -1004,7 +1118,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, renderbuffers, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)renderbuffers, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1051,7 +1165,7 @@
         goto exit;
     }
     textures_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(textures_ref, (jboolean *)0);
+        _env->GetIntArrayElements(textures_ref, (jboolean *)0);
     textures = textures_base + offset;
 
     glDeleteTextures(
@@ -1061,7 +1175,7 @@
 
 exit:
     if (textures_base) {
-        _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
+        _env->ReleaseIntArrayElements(textures_ref, (jint*)textures_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1076,12 +1190,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
 
-    textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining, &_bufferOffset);
+    textures = (GLuint *)getPointer(_env, textures_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -1089,7 +1203,7 @@
         goto exit;
     }
     if (textures == NULL) {
-        char * _texturesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _texturesBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         textures = (GLuint *) (_texturesBase + _bufferOffset);
     }
     glDeleteTextures(
@@ -1099,7 +1213,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, textures, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)textures, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1203,7 +1317,7 @@
     jint _remaining;
     GLvoid *indices = (GLvoid *) 0;
 
-    indices = (GLvoid *)getPointer(_env, indices_buf, &_array, &_remaining, &_bufferOffset);
+    indices = (GLvoid *)getPointer(_env, indices_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < count) {
         _exception = 1;
         _exceptionType = "java/lang/ArrayIndexOutOfBoundsException";
@@ -1327,7 +1441,7 @@
         goto exit;
     }
     buffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(buffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(buffers_ref, (jboolean *)0);
     buffers = buffers_base + offset;
 
     glGenBuffers(
@@ -1337,7 +1451,7 @@
 
 exit:
     if (buffers_base) {
-        _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
+        _env->ReleaseIntArrayElements(buffers_ref, (jint*)buffers_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1352,12 +1466,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
 
-    buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining, &_bufferOffset);
+    buffers = (GLuint *)getPointer(_env, buffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -1365,7 +1479,7 @@
         goto exit;
     }
     if (buffers == NULL) {
-        char * _buffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _buffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         buffers = (GLuint *) (_buffersBase + _bufferOffset);
     }
     glGenBuffers(
@@ -1375,7 +1489,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, buffers, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)buffers, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1422,7 +1536,7 @@
         goto exit;
     }
     framebuffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(framebuffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(framebuffers_ref, (jboolean *)0);
     framebuffers = framebuffers_base + offset;
 
     glGenFramebuffers(
@@ -1432,7 +1546,7 @@
 
 exit:
     if (framebuffers_base) {
-        _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
+        _env->ReleaseIntArrayElements(framebuffers_ref, (jint*)framebuffers_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1447,12 +1561,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
 
-    framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, &_array, &_remaining, &_bufferOffset);
+    framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -1460,7 +1574,7 @@
         goto exit;
     }
     if (framebuffers == NULL) {
-        char * _framebuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _framebuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         framebuffers = (GLuint *) (_framebuffersBase + _bufferOffset);
     }
     glGenFramebuffers(
@@ -1470,7 +1584,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, framebuffers, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)framebuffers, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1508,7 +1622,7 @@
         goto exit;
     }
     renderbuffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(renderbuffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(renderbuffers_ref, (jboolean *)0);
     renderbuffers = renderbuffers_base + offset;
 
     glGenRenderbuffers(
@@ -1518,7 +1632,7 @@
 
 exit:
     if (renderbuffers_base) {
-        _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
+        _env->ReleaseIntArrayElements(renderbuffers_ref, (jint*)renderbuffers_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1533,12 +1647,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
 
-    renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, &_array, &_remaining, &_bufferOffset);
+    renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -1546,7 +1660,7 @@
         goto exit;
     }
     if (renderbuffers == NULL) {
-        char * _renderbuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _renderbuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         renderbuffers = (GLuint *) (_renderbuffersBase + _bufferOffset);
     }
     glGenRenderbuffers(
@@ -1556,7 +1670,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, renderbuffers, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)renderbuffers, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1594,7 +1708,7 @@
         goto exit;
     }
     textures_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(textures_ref, (jboolean *)0);
+        _env->GetIntArrayElements(textures_ref, (jboolean *)0);
     textures = textures_base + offset;
 
     glGenTextures(
@@ -1604,7 +1718,7 @@
 
 exit:
     if (textures_base) {
-        _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
+        _env->ReleaseIntArrayElements(textures_ref, (jint*)textures_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1619,12 +1733,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
 
-    textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining, &_bufferOffset);
+    textures = (GLuint *)getPointer(_env, textures_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -1632,7 +1746,7 @@
         goto exit;
     }
     if (textures == NULL) {
-        char * _texturesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _texturesBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         textures = (GLuint *) (_texturesBase + _bufferOffset);
     }
     glGenTextures(
@@ -1642,7 +1756,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, textures, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)textures, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1683,7 +1797,7 @@
     }
     _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
     length_base = (GLsizei *)
-        _env->GetPrimitiveArrayCritical(length_ref, (jboolean *)0);
+        _env->GetIntArrayElements(length_ref, (jboolean *)0);
     length = length_base + lengthOffset;
 
     if (!size_ref) {
@@ -1700,7 +1814,7 @@
     }
     _sizeRemaining = _env->GetArrayLength(size_ref) - sizeOffset;
     size_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(size_ref, (jboolean *)0);
+        _env->GetIntArrayElements(size_ref, (jboolean *)0);
     size = size_base + sizeOffset;
 
     if (!type_ref) {
@@ -1717,7 +1831,7 @@
     }
     _typeRemaining = _env->GetArrayLength(type_ref) - typeOffset;
     type_base = (GLenum *)
-        _env->GetPrimitiveArrayCritical(type_ref, (jboolean *)0);
+        _env->GetIntArrayElements(type_ref, (jboolean *)0);
     type = type_base + typeOffset;
 
     if (!name_ref) {
@@ -1734,7 +1848,7 @@
     }
     _nameRemaining = _env->GetArrayLength(name_ref) - nameOffset;
     name_base = (char *)
-        _env->GetPrimitiveArrayCritical(name_ref, (jboolean *)0);
+        _env->GetByteArrayElements(name_ref, (jboolean *)0);
     name = name_base + nameOffset;
 
     glGetActiveAttrib(
@@ -1749,19 +1863,19 @@
 
 exit:
     if (name_base) {
-        _env->ReleasePrimitiveArrayCritical(name_ref, name_base,
+        _env->ReleaseByteArrayElements(name_ref, (jbyte*)name_base,
             _exception ? JNI_ABORT: 0);
     }
     if (type_base) {
-        _env->ReleasePrimitiveArrayCritical(type_ref, type_base,
+        _env->ReleaseIntArrayElements(type_ref, (jint*)type_base,
             _exception ? JNI_ABORT: 0);
     }
     if (size_base) {
-        _env->ReleasePrimitiveArrayCritical(size_ref, size_base,
+        _env->ReleaseIntArrayElements(size_ref, (jint*)size_base,
             _exception ? JNI_ABORT: 0);
     }
     if (length_base) {
-        _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
+        _env->ReleaseIntArrayElements(length_ref, (jint*)length_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1773,11 +1887,11 @@
 static void
 android_glGetActiveAttrib__IIILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2B
   (JNIEnv *_env, jobject _this, jint program, jint index, jint bufsize, jobject length_buf, jobject size_buf, jobject type_buf, jbyte name) {
-    jarray _lengthArray = (jarray) 0;
+    jintArray _lengthArray = (jintArray) 0;
     jint _lengthBufferOffset = (jint) 0;
-    jarray _sizeArray = (jarray) 0;
+    jintArray _sizeArray = (jintArray) 0;
     jint _sizeBufferOffset = (jint) 0;
-    jarray _typeArray = (jarray) 0;
+    jintArray _typeArray = (jintArray) 0;
     jint _typeBufferOffset = (jint) 0;
     jint _lengthRemaining;
     GLsizei *length = (GLsizei *) 0;
@@ -1786,19 +1900,19 @@
     jint _typeRemaining;
     GLenum *type = (GLenum *) 0;
 
-    length = (GLsizei *)getPointer(_env, length_buf, &_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
-    size = (GLint *)getPointer(_env, size_buf, &_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
-    type = (GLenum *)getPointer(_env, type_buf, &_typeArray, &_typeRemaining, &_typeBufferOffset);
+    length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+    size = (GLint *)getPointer(_env, size_buf, (jarray*)&_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
+    type = (GLenum *)getPointer(_env, type_buf, (jarray*)&_typeArray, &_typeRemaining, &_typeBufferOffset);
     if (length == NULL) {
-        char * _lengthBase = (char *)_env->GetPrimitiveArrayCritical(_lengthArray, (jboolean *) 0);
+        char * _lengthBase = (char *)_env->GetIntArrayElements(_lengthArray, (jboolean *) 0);
         length = (GLsizei *) (_lengthBase + _lengthBufferOffset);
     }
     if (size == NULL) {
-        char * _sizeBase = (char *)_env->GetPrimitiveArrayCritical(_sizeArray, (jboolean *) 0);
+        char * _sizeBase = (char *)_env->GetIntArrayElements(_sizeArray, (jboolean *) 0);
         size = (GLint *) (_sizeBase + _sizeBufferOffset);
     }
     if (type == NULL) {
-        char * _typeBase = (char *)_env->GetPrimitiveArrayCritical(_typeArray, (jboolean *) 0);
+        char * _typeBase = (char *)_env->GetIntArrayElements(_typeArray, (jboolean *) 0);
         type = (GLenum *) (_typeBase + _typeBufferOffset);
     }
     glGetActiveAttrib(
@@ -1811,13 +1925,13 @@
         reinterpret_cast<char *>(name)
     );
     if (_typeArray) {
-        releasePointer(_env, _typeArray, type, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _typeArray, (jint*)type, JNI_TRUE);
     }
     if (_sizeArray) {
-        releasePointer(_env, _sizeArray, size, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _sizeArray, (jint*)size, JNI_TRUE);
     }
     if (_lengthArray) {
-        releasePointer(_env, _lengthArray, length, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _lengthArray, (jint*)length, JNI_TRUE);
     }
 }
 
@@ -1862,7 +1976,7 @@
     }
     _sizeRemaining = _env->GetArrayLength(size_ref) - sizeOffset;
     size_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(size_ref, (jboolean *)0);
+        _env->GetIntArrayElements(size_ref, (jboolean *)0);
     size = size_base + sizeOffset;
 
     if (!type_ref) {
@@ -1879,7 +1993,7 @@
     }
     _typeRemaining = _env->GetArrayLength(type_ref) - typeOffset;
     type_base = (GLenum *)
-        _env->GetPrimitiveArrayCritical(type_ref, (jboolean *)0);
+        _env->GetIntArrayElements(type_ref, (jboolean *)0);
     type = type_base + typeOffset;
 
     glGetActiveAttrib(
@@ -1893,11 +2007,11 @@
     );
 exit:
     if (type_base) {
-        _env->ReleasePrimitiveArrayCritical(type_ref, type_base,
+        _env->ReleaseIntArrayElements(type_ref, (jint*)type_base,
             _exception ? JNI_ABORT: 0);
     }
     if (size_base) {
-        _env->ReleasePrimitiveArrayCritical(size_ref, size_base,
+        _env->ReleaseIntArrayElements(size_ref, (jint*)size_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception != 1) {
@@ -1920,9 +2034,9 @@
 static jstring
 android_glGetActiveAttrib2
   (JNIEnv *_env, jobject _this, jint program, jint index, jobject size_buf, jobject type_buf) {
-    jarray _sizeArray = (jarray) 0;
+    jintArray _sizeArray = (jintArray) 0;
     jint _sizeBufferOffset = (jint) 0;
-    jarray _typeArray = (jarray) 0;
+    jintArray _typeArray = (jintArray) 0;
     jint _typeBufferOffset = (jint) 0;
     jint _lengthRemaining;
     GLsizei *length = (GLsizei *) 0;
@@ -1945,14 +2059,14 @@
         return NULL;
     }
 
-    size = (GLint *)getPointer(_env, size_buf, &_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
-    type = (GLenum *)getPointer(_env, type_buf, &_typeArray, &_typeRemaining, &_typeBufferOffset);
+    size = (GLint *)getPointer(_env, size_buf, (jarray*)&_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
+    type = (GLenum *)getPointer(_env, type_buf, (jarray*)&_typeArray, &_typeRemaining, &_typeBufferOffset);
     if (size == NULL) {
-        char * _sizeBase = (char *)_env->GetPrimitiveArrayCritical(_sizeArray, (jboolean *) 0);
+        char * _sizeBase = (char *)_env->GetIntArrayElements(_sizeArray, (jboolean *) 0);
         size = (GLint *) (_sizeBase + _sizeBufferOffset);
     }
     if (type == NULL) {
-        char * _typeBase = (char *)_env->GetPrimitiveArrayCritical(_typeArray, (jboolean *) 0);
+        char * _typeBase = (char *)_env->GetIntArrayElements(_typeArray, (jboolean *) 0);
         type = (GLenum *) (_typeBase + _typeBufferOffset);
     }
     glGetActiveAttrib(
@@ -1966,10 +2080,10 @@
     );
 
     if (_typeArray) {
-        releasePointer(_env, _typeArray, type, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _typeArray, (jint*)type, JNI_TRUE);
     }
     if (_sizeArray) {
-        releasePointer(_env, _sizeArray, size, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _sizeArray, (jint*)size, JNI_TRUE);
     }
     result = _env->NewStringUTF(buf);
     if (buf) {
@@ -2011,7 +2125,7 @@
     }
     _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
     length_base = (GLsizei *)
-        _env->GetPrimitiveArrayCritical(length_ref, (jboolean *)0);
+        _env->GetIntArrayElements(length_ref, (jboolean *)0);
     length = length_base + lengthOffset;
 
     if (!size_ref) {
@@ -2028,7 +2142,7 @@
     }
     _sizeRemaining = _env->GetArrayLength(size_ref) - sizeOffset;
     size_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(size_ref, (jboolean *)0);
+        _env->GetIntArrayElements(size_ref, (jboolean *)0);
     size = size_base + sizeOffset;
 
     if (!type_ref) {
@@ -2045,7 +2159,7 @@
     }
     _typeRemaining = _env->GetArrayLength(type_ref) - typeOffset;
     type_base = (GLenum *)
-        _env->GetPrimitiveArrayCritical(type_ref, (jboolean *)0);
+        _env->GetIntArrayElements(type_ref, (jboolean *)0);
     type = type_base + typeOffset;
 
     if (!name_ref) {
@@ -2062,7 +2176,7 @@
     }
     _nameRemaining = _env->GetArrayLength(name_ref) - nameOffset;
     name_base = (char *)
-        _env->GetPrimitiveArrayCritical(name_ref, (jboolean *)0);
+        _env->GetByteArrayElements(name_ref, (jboolean *)0);
     name = name_base + nameOffset;
 
     glGetActiveUniform(
@@ -2077,19 +2191,19 @@
 
 exit:
     if (name_base) {
-        _env->ReleasePrimitiveArrayCritical(name_ref, name_base,
+        _env->ReleaseByteArrayElements(name_ref, (jbyte*)name_base,
             _exception ? JNI_ABORT: 0);
     }
     if (type_base) {
-        _env->ReleasePrimitiveArrayCritical(type_ref, type_base,
+        _env->ReleaseIntArrayElements(type_ref, (jint*)type_base,
             _exception ? JNI_ABORT: 0);
     }
     if (size_base) {
-        _env->ReleasePrimitiveArrayCritical(size_ref, size_base,
+        _env->ReleaseIntArrayElements(size_ref, (jint*)size_base,
             _exception ? JNI_ABORT: 0);
     }
     if (length_base) {
-        _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
+        _env->ReleaseIntArrayElements(length_ref, (jint*)length_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2101,11 +2215,11 @@
 static void
 android_glGetActiveUniform__IIILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2B
   (JNIEnv *_env, jobject _this, jint program, jint index, jint bufsize, jobject length_buf, jobject size_buf, jobject type_buf, jbyte name) {
-    jarray _lengthArray = (jarray) 0;
+    jintArray _lengthArray = (jintArray) 0;
     jint _lengthBufferOffset = (jint) 0;
-    jarray _sizeArray = (jarray) 0;
+    jintArray _sizeArray = (jintArray) 0;
     jint _sizeBufferOffset = (jint) 0;
-    jarray _typeArray = (jarray) 0;
+    jintArray _typeArray = (jintArray) 0;
     jint _typeBufferOffset = (jint) 0;
     jint _lengthRemaining;
     GLsizei *length = (GLsizei *) 0;
@@ -2114,19 +2228,19 @@
     jint _typeRemaining;
     GLenum *type = (GLenum *) 0;
 
-    length = (GLsizei *)getPointer(_env, length_buf, &_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
-    size = (GLint *)getPointer(_env, size_buf, &_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
-    type = (GLenum *)getPointer(_env, type_buf, &_typeArray, &_typeRemaining, &_typeBufferOffset);
+    length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+    size = (GLint *)getPointer(_env, size_buf, (jarray*)&_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
+    type = (GLenum *)getPointer(_env, type_buf, (jarray*)&_typeArray, &_typeRemaining, &_typeBufferOffset);
     if (length == NULL) {
-        char * _lengthBase = (char *)_env->GetPrimitiveArrayCritical(_lengthArray, (jboolean *) 0);
+        char * _lengthBase = (char *)_env->GetIntArrayElements(_lengthArray, (jboolean *) 0);
         length = (GLsizei *) (_lengthBase + _lengthBufferOffset);
     }
     if (size == NULL) {
-        char * _sizeBase = (char *)_env->GetPrimitiveArrayCritical(_sizeArray, (jboolean *) 0);
+        char * _sizeBase = (char *)_env->GetIntArrayElements(_sizeArray, (jboolean *) 0);
         size = (GLint *) (_sizeBase + _sizeBufferOffset);
     }
     if (type == NULL) {
-        char * _typeBase = (char *)_env->GetPrimitiveArrayCritical(_typeArray, (jboolean *) 0);
+        char * _typeBase = (char *)_env->GetIntArrayElements(_typeArray, (jboolean *) 0);
         type = (GLenum *) (_typeBase + _typeBufferOffset);
     }
     glGetActiveUniform(
@@ -2139,13 +2253,13 @@
         reinterpret_cast<char *>(name)
     );
     if (_typeArray) {
-        releasePointer(_env, _typeArray, type, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _typeArray, (jint*)type, JNI_TRUE);
     }
     if (_sizeArray) {
-        releasePointer(_env, _sizeArray, size, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _sizeArray, (jint*)size, JNI_TRUE);
     }
     if (_lengthArray) {
-        releasePointer(_env, _lengthArray, length, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _lengthArray, (jint*)length, JNI_TRUE);
     }
 }
 
@@ -2193,7 +2307,7 @@
     }
     _sizeRemaining = _env->GetArrayLength(size_ref) - sizeOffset;
     size_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(size_ref, (jboolean *)0);
+        _env->GetIntArrayElements(size_ref, (jboolean *)0);
     size = size_base + sizeOffset;
 
     if (!type_ref) {
@@ -2210,7 +2324,7 @@
     }
     _typeRemaining = _env->GetArrayLength(type_ref) - typeOffset;
     type_base = (GLenum *)
-        _env->GetPrimitiveArrayCritical(type_ref, (jboolean *)0);
+        _env->GetIntArrayElements(type_ref, (jboolean *)0);
     type = type_base + typeOffset;
 
     glGetActiveUniform(
@@ -2225,11 +2339,11 @@
 
 exit:
     if (type_base) {
-        _env->ReleasePrimitiveArrayCritical(type_ref, type_base,
+        _env->ReleaseIntArrayElements(type_ref, (jint*)type_base,
             _exception ? JNI_ABORT: 0);
     }
     if (size_base) {
-        _env->ReleasePrimitiveArrayCritical(size_ref, size_base,
+        _env->ReleaseIntArrayElements(size_ref, (jint*)size_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception != 1) {
@@ -2251,9 +2365,9 @@
 static jstring
 android_glGetActiveUniform2
   (JNIEnv *_env, jobject _this, jint program, jint index, jobject size_buf, jobject type_buf) {
-    jarray _sizeArray = (jarray) 0;
+    jintArray _sizeArray = (jintArray) 0;
     jint _sizeBufferOffset = (jint) 0;
-    jarray _typeArray = (jarray) 0;
+    jintArray _typeArray = (jintArray) 0;
     jint _typeBufferOffset = (jint) 0;
     jint _sizeRemaining;
     GLint *size = (GLint *) 0;
@@ -2273,15 +2387,15 @@
         return NULL;
     }
 
-    size = (GLint *)getPointer(_env, size_buf, &_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
-    type = (GLenum *)getPointer(_env, type_buf, &_typeArray, &_typeRemaining, &_typeBufferOffset);
+    size = (GLint *)getPointer(_env, size_buf, (jarray*)&_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
+    type = (GLenum *)getPointer(_env, type_buf, (jarray*)&_typeArray, &_typeRemaining, &_typeBufferOffset);
 
     if (size == NULL) {
-        char * _sizeBase = (char *)_env->GetPrimitiveArrayCritical(_sizeArray, (jboolean *) 0);
+        char * _sizeBase = (char *)_env->GetIntArrayElements(_sizeArray, (jboolean *) 0);
         size = (GLint *) (_sizeBase + _sizeBufferOffset);
     }
     if (type == NULL) {
-        char * _typeBase = (char *)_env->GetPrimitiveArrayCritical(_typeArray, (jboolean *) 0);
+        char * _typeBase = (char *)_env->GetIntArrayElements(_typeArray, (jboolean *) 0);
         type = (GLenum *) (_typeBase + _typeBufferOffset);
     }
     glGetActiveUniform(
@@ -2295,10 +2409,10 @@
     );
 
     if (_typeArray) {
-        releasePointer(_env, _typeArray, type, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _typeArray, (jint*)type, JNI_TRUE);
     }
     if (_sizeArray) {
-        releasePointer(_env, _sizeArray, size, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _sizeArray, (jint*)size, JNI_TRUE);
     }
     result = _env->NewStringUTF(buf);
     if (buf) {
@@ -2340,7 +2454,7 @@
         goto exit;
     }
     count_base = (GLsizei *)
-        _env->GetPrimitiveArrayCritical(count_ref, (jboolean *)0);
+        _env->GetIntArrayElements(count_ref, (jboolean *)0);
     count = count_base + countOffset;
 
     if (!shaders_ref) {
@@ -2363,7 +2477,7 @@
         goto exit;
     }
     shaders_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(shaders_ref, (jboolean *)0);
+        _env->GetIntArrayElements(shaders_ref, (jboolean *)0);
     shaders = shaders_base + shadersOffset;
 
     glGetAttachedShaders(
@@ -2375,11 +2489,11 @@
 
 exit:
     if (shaders_base) {
-        _env->ReleasePrimitiveArrayCritical(shaders_ref, shaders_base,
+        _env->ReleaseIntArrayElements(shaders_ref, (jint*)shaders_base,
             _exception ? JNI_ABORT: 0);
     }
     if (count_base) {
-        _env->ReleasePrimitiveArrayCritical(count_ref, count_base,
+        _env->ReleaseIntArrayElements(count_ref, (jint*)count_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2394,9 +2508,9 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _countArray = (jarray) 0;
+    jintArray _countArray = (jintArray) 0;
     jint _countBufferOffset = (jint) 0;
-    jarray _shadersArray = (jarray) 0;
+    jintArray _shadersArray = (jintArray) 0;
     jint _shadersBufferOffset = (jint) 0;
     jint _countRemaining;
     GLsizei *count = (GLsizei *) 0;
@@ -2404,7 +2518,7 @@
     GLuint *shaders = (GLuint *) 0;
 
     if (count_buf) {
-        count = (GLsizei *)getPointer(_env, count_buf, &_countArray, &_countRemaining, &_countBufferOffset);
+        count = (GLsizei *)getPointer(_env, count_buf, (jarray*)&_countArray, &_countRemaining, &_countBufferOffset);
         if (_countRemaining < 1) {
             _exception = 1;
             _exceptionType = "java/lang/IllegalArgumentException";
@@ -2413,7 +2527,7 @@
         }
     }
     if (shaders_buf) {
-        shaders = (GLuint *)getPointer(_env, shaders_buf, &_shadersArray, &_shadersRemaining, &_shadersBufferOffset);
+        shaders = (GLuint *)getPointer(_env, shaders_buf, (jarray*)&_shadersArray, &_shadersRemaining, &_shadersBufferOffset);
         if (_shadersRemaining < maxcount) {
             _exception = 1;
             _exceptionType = "java/lang/IllegalArgumentException";
@@ -2422,11 +2536,11 @@
         }
     }
     if (count_buf && count == NULL) {
-        char * _countBase = (char *)_env->GetPrimitiveArrayCritical(_countArray, (jboolean *) 0);
+        char * _countBase = (char *)_env->GetIntArrayElements(_countArray, (jboolean *) 0);
         count = (GLsizei *) (_countBase + _countBufferOffset);
     }
     if (shaders_buf && shaders == NULL) {
-        char * _shadersBase = (char *)_env->GetPrimitiveArrayCritical(_shadersArray, (jboolean *) 0);
+        char * _shadersBase = (char *)_env->GetIntArrayElements(_shadersArray, (jboolean *) 0);
         shaders = (GLuint *) (_shadersBase + _shadersBufferOffset);
     }
     glGetAttachedShaders(
@@ -2438,10 +2552,10 @@
 
 exit:
     if (_shadersArray) {
-        releasePointer(_env, _shadersArray, shaders, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_shadersArray, (jint*)shaders, _exception ? JNI_ABORT : 0);
     }
     if (_countArray) {
-        releasePointer(_env, _countArray, count, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_countArray, (jint*)count, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2486,14 +2600,16 @@
 static void
 android_glGetBooleanv__I_3ZI
   (JNIEnv *_env, jobject _this, jint pname, jbooleanArray params_ref, jint offset) {
-    get<jbooleanArray, GLboolean, glGetBooleanv>(_env, _this, pname, params_ref, offset);
+    get<jbooleanArray, BooleanArrayGetter, jboolean*, BooleanArrayReleaser, GLboolean, glGetBooleanv>(
+        _env, _this, pname, params_ref, offset);
 }
 
 /* void glGetBooleanv ( GLenum pname, GLboolean *params ) */
 static void
 android_glGetBooleanv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    getarray<GLboolean, glGetBooleanv>(_env, _this, pname, params_buf);
+    getarray<GLboolean, jintArray, IntArrayGetter, jint*, IntArrayReleaser, glGetBooleanv>(
+        _env, _this, pname, params_buf);
 }
 /* void glGetBufferParameteriv ( GLenum target, GLenum pname, GLint *params ) */
 static void
@@ -2526,7 +2642,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetBufferParameteriv(
@@ -2537,7 +2653,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2552,12 +2668,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2565,7 +2681,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetBufferParameteriv(
@@ -2576,7 +2692,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2596,14 +2712,16 @@
 static void
 android_glGetFloatv__I_3FI
   (JNIEnv *_env, jobject _this, jint pname, jfloatArray params_ref, jint offset) {
-    get<jfloatArray, GLfloat, glGetFloatv>(_env, _this, pname, params_ref, offset);
+    get<jfloatArray, FloatArrayGetter, jfloat*, FloatArrayReleaser, GLfloat, glGetFloatv>(
+        _env, _this, pname, params_ref, offset);
 }
 
 /* void glGetFloatv ( GLenum pname, GLfloat *params ) */
 static void
 android_glGetFloatv__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    getarray<GLfloat, glGetFloatv>(_env, _this, pname, params_buf);
+    getarray<GLfloat, jfloatArray, FloatArrayGetter, jfloat*, FloatArrayReleaser, glGetFloatv>(
+        _env, _this, pname, params_buf);
 }
 /* void glGetFramebufferAttachmentParameteriv ( GLenum target, GLenum attachment, GLenum pname, GLint *params ) */
 static void
@@ -2630,7 +2748,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetFramebufferAttachmentParameteriv(
@@ -2642,7 +2760,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2654,14 +2772,14 @@
 static void
 android_glGetFramebufferAttachmentParameteriv__IIILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint attachment, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetFramebufferAttachmentParameteriv(
@@ -2671,7 +2789,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -2679,16 +2797,17 @@
 static void
 android_glGetIntegerv__I_3II
   (JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
-    get<jintArray, GLint, glGetIntegerv>(_env, _this, pname, params_ref, offset);
+    get<jintArray, IntArrayGetter, jint*, IntArrayReleaser, GLint, glGetIntegerv>(
+        _env, _this, pname, params_ref, offset);
 }
 
 /* void glGetIntegerv ( GLenum pname, GLint *params ) */
 static void
 android_glGetIntegerv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    getarray<GLint, glGetIntegerv>(_env, _this, pname, params_buf);
+    getarray<GLint, jintArray, IntArrayGetter, jint*, IntArrayReleaser, glGetIntegerv>(
+        _env, _this, pname, params_buf);
 }
-
 /* void glGetProgramiv ( GLuint program, GLenum pname, GLint *params ) */
 static void
 android_glGetProgramiv__II_3II
@@ -2720,7 +2839,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetProgramiv(
@@ -2731,7 +2850,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2746,12 +2865,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2759,7 +2878,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetProgramiv(
@@ -2770,7 +2889,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2827,7 +2946,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetRenderbufferParameteriv(
@@ -2838,7 +2957,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2853,12 +2972,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2866,7 +2985,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetRenderbufferParameteriv(
@@ -2877,7 +2996,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2915,7 +3034,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetShaderiv(
@@ -2926,7 +3045,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2941,12 +3060,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -2954,7 +3073,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetShaderiv(
@@ -2965,7 +3084,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3025,7 +3144,7 @@
         goto exit;
     }
     range_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(range_ref, (jboolean *)0);
+        _env->GetIntArrayElements(range_ref, (jboolean *)0);
     range = range_base + rangeOffset;
 
     if (!precision_ref) {
@@ -3048,7 +3167,7 @@
         goto exit;
     }
     precision_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(precision_ref, (jboolean *)0);
+        _env->GetIntArrayElements(precision_ref, (jboolean *)0);
     precision = precision_base + precisionOffset;
 
     glGetShaderPrecisionFormat(
@@ -3060,11 +3179,11 @@
 
 exit:
     if (precision_base) {
-        _env->ReleasePrimitiveArrayCritical(precision_ref, precision_base,
+        _env->ReleaseIntArrayElements(precision_ref, (jint*)precision_base,
             _exception ? JNI_ABORT: 0);
     }
     if (range_base) {
-        _env->ReleasePrimitiveArrayCritical(range_ref, range_base,
+        _env->ReleaseIntArrayElements(range_ref, (jint*)range_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3079,23 +3198,23 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _rangeArray = (jarray) 0;
+    jintArray _rangeArray = (jintArray) 0;
     jint _rangeBufferOffset = (jint) 0;
-    jarray _precisionArray = (jarray) 0;
+    jintArray _precisionArray = (jintArray) 0;
     jint _precisionBufferOffset = (jint) 0;
     jint _rangeRemaining;
     GLint *range = (GLint *) 0;
     jint _precisionRemaining;
     GLint *precision = (GLint *) 0;
 
-    range = (GLint *)getPointer(_env, range_buf, &_rangeArray, &_rangeRemaining, &_rangeBufferOffset);
+    range = (GLint *)getPointer(_env, range_buf, (jarray*)&_rangeArray, &_rangeRemaining, &_rangeBufferOffset);
     if (_rangeRemaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
         _exceptionMessage = "remaining() < 1 < needed";
         goto exit;
     }
-    precision = (GLint *)getPointer(_env, precision_buf, &_precisionArray, &_precisionRemaining, &_precisionBufferOffset);
+    precision = (GLint *)getPointer(_env, precision_buf, (jarray*)&_precisionArray, &_precisionRemaining, &_precisionBufferOffset);
     if (_precisionRemaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -3103,11 +3222,11 @@
         goto exit;
     }
     if (range == NULL) {
-        char * _rangeBase = (char *)_env->GetPrimitiveArrayCritical(_rangeArray, (jboolean *) 0);
+        char * _rangeBase = (char *)_env->GetIntArrayElements(_rangeArray, (jboolean *) 0);
         range = (GLint *) (_rangeBase + _rangeBufferOffset);
     }
     if (precision == NULL) {
-        char * _precisionBase = (char *)_env->GetPrimitiveArrayCritical(_precisionArray, (jboolean *) 0);
+        char * _precisionBase = (char *)_env->GetIntArrayElements(_precisionArray, (jboolean *) 0);
         precision = (GLint *) (_precisionBase + _precisionBufferOffset);
     }
     glGetShaderPrecisionFormat(
@@ -3119,10 +3238,10 @@
 
 exit:
     if (_precisionArray) {
-        releasePointer(_env, _precisionArray, precision, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_precisionArray, (jint*)precision, _exception ? JNI_ABORT : 0);
     }
     if (_rangeArray) {
-        releasePointer(_env, _rangeArray, range, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_rangeArray, (jint*)range, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3157,7 +3276,7 @@
     }
     _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
     length_base = (GLsizei *)
-        _env->GetPrimitiveArrayCritical(length_ref, (jboolean *)0);
+        _env->GetIntArrayElements(length_ref, (jboolean *)0);
     length = length_base + lengthOffset;
 
     if (!source_ref) {
@@ -3174,7 +3293,7 @@
     }
     _sourceRemaining = _env->GetArrayLength(source_ref) - sourceOffset;
     source_base = (char *)
-        _env->GetPrimitiveArrayCritical(source_ref, (jboolean *)0);
+        _env->GetByteArrayElements(source_ref, (jboolean *)0);
     source = source_base + sourceOffset;
 
     glGetShaderSource(
@@ -3186,11 +3305,11 @@
 
 exit:
     if (source_base) {
-        _env->ReleasePrimitiveArrayCritical(source_ref, source_base,
+        _env->ReleaseByteArrayElements(source_ref, (jbyte*)source_base,
             _exception ? JNI_ABORT: 0);
     }
     if (length_base) {
-        _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
+        _env->ReleaseIntArrayElements(length_ref, (jint*)length_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3202,14 +3321,14 @@
 static void
 android_glGetShaderSource__IILjava_nio_IntBuffer_2B
   (JNIEnv *_env, jobject _this, jint shader, jint bufsize, jobject length_buf, jbyte source) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLsizei *length = (GLsizei *) 0;
 
-    length = (GLsizei *)getPointer(_env, length_buf, &_array, &_remaining, &_bufferOffset);
+    length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (length == NULL) {
-        char * _lengthBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _lengthBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         length = (GLsizei *) (_lengthBase + _bufferOffset);
     }
     glGetShaderSource(
@@ -3219,7 +3338,7 @@
         reinterpret_cast<char *>(source)
     );
     if (_array) {
-        releasePointer(_env, _array, length, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _array, (jint*)length, JNI_TRUE);
     }
 }
 
@@ -3276,7 +3395,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexParameterfv(
@@ -3287,7 +3406,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3302,12 +3421,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -3315,7 +3434,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glGetTexParameterfv(
@@ -3326,7 +3445,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3364,7 +3483,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexParameteriv(
@@ -3375,7 +3494,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3390,12 +3509,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -3403,7 +3522,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetTexParameteriv(
@@ -3414,7 +3533,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3452,7 +3571,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetUniformfv(
@@ -3463,7 +3582,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3478,12 +3597,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -3491,7 +3610,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glGetUniformfv(
@@ -3502,7 +3621,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3540,7 +3659,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetUniformiv(
@@ -3551,7 +3670,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3566,12 +3685,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -3579,7 +3698,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetUniformiv(
@@ -3590,7 +3709,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3673,7 +3792,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetVertexAttribfv(
@@ -3684,7 +3803,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3699,12 +3818,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_CURRENT_VERTEX_ATTRIB)
@@ -3723,7 +3842,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glGetVertexAttribfv(
@@ -3734,7 +3853,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3783,7 +3902,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetVertexAttribiv(
@@ -3794,7 +3913,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3809,12 +3928,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_CURRENT_VERTEX_ATTRIB)
@@ -3833,7 +3952,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetVertexAttribiv(
@@ -3844,7 +3963,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3985,7 +4104,7 @@
     jint _remaining;
     GLvoid *pixels = (GLvoid *) 0;
 
-    pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+    pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (pixels == NULL) {
         char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         pixels = (GLvoid *) (_pixelsBase + _bufferOffset);
@@ -4074,10 +4193,10 @@
     }
     _shadersRemaining = _env->GetArrayLength(shaders_ref) - offset;
     shaders_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(shaders_ref, (jboolean *)0);
+        _env->GetIntArrayElements(shaders_ref, (jboolean *)0);
     shaders = shaders_base + offset;
 
-    binary = (GLvoid *)getPointer(_env, binary_buf, &_array, &_binaryRemaining, &_bufferOffset);
+    binary = (GLvoid *)getPointer(_env, binary_buf, (jarray*)&_array, &_binaryRemaining, &_bufferOffset);
     if (_binaryRemaining < length) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -4101,7 +4220,7 @@
         releasePointer(_env, _array, binary, JNI_FALSE);
     }
     if (shaders_base) {
-        _env->ReleasePrimitiveArrayCritical(shaders_ref, shaders_base,
+        _env->ReleaseIntArrayElements(shaders_ref, (jint*)shaders_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4116,17 +4235,17 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _shadersArray = (jarray) 0;
+    jintArray _shadersArray = (jintArray) 0;
     jint _shadersBufferOffset = (jint) 0;
-    jarray _binaryArray = (jarray) 0;
+    jintArray _binaryArray = (jintArray) 0;
     jint _binaryBufferOffset = (jint) 0;
     jint _shadersRemaining;
     GLuint *shaders = (GLuint *) 0;
     jint _binaryRemaining;
     GLvoid *binary = (GLvoid *) 0;
 
-    shaders = (GLuint *)getPointer(_env, shaders_buf, &_shadersArray, &_shadersRemaining, &_shadersBufferOffset);
-    binary = (GLvoid *)getPointer(_env, binary_buf, &_binaryArray, &_binaryRemaining, &_binaryBufferOffset);
+    shaders = (GLuint *)getPointer(_env, shaders_buf, (jarray*)&_shadersArray, &_shadersRemaining, &_shadersBufferOffset);
+    binary = (GLvoid *)getPointer(_env, binary_buf, (jarray*)&_binaryArray, &_binaryRemaining, &_binaryBufferOffset);
     if (_binaryRemaining < length) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -4134,7 +4253,7 @@
         goto exit;
     }
     if (shaders == NULL) {
-        char * _shadersBase = (char *)_env->GetPrimitiveArrayCritical(_shadersArray, (jboolean *) 0);
+        char * _shadersBase = (char *)_env->GetIntArrayElements(_shadersArray, (jboolean *) 0);
         shaders = (GLuint *) (_shadersBase + _shadersBufferOffset);
     }
     if (binary == NULL) {
@@ -4154,7 +4273,7 @@
         releasePointer(_env, _binaryArray, binary, JNI_FALSE);
     }
     if (_shadersArray) {
-        releasePointer(_env, _shadersArray, shaders, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_shadersArray, (jint*)shaders, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4253,7 +4372,7 @@
     GLvoid *pixels = (GLvoid *) 0;
 
     if (pixels_buf) {
-        pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+        pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     }
     if (pixels_buf && pixels == NULL) {
         char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
@@ -4317,7 +4436,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexParameterfv(
@@ -4328,7 +4447,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4343,12 +4462,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -4356,7 +4475,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glTexParameterfv(
@@ -4367,7 +4486,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4416,7 +4535,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexParameteriv(
@@ -4427,7 +4546,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4442,12 +4561,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -4455,7 +4574,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glTexParameteriv(
@@ -4466,7 +4585,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4483,7 +4602,7 @@
     GLvoid *pixels = (GLvoid *) 0;
 
     if (pixels_buf) {
-        pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+        pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     }
     if (pixels_buf && pixels == NULL) {
         char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
@@ -4546,7 +4665,7 @@
         goto exit;
     }
     v_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(v_ref, (jboolean *)0);
     v = v_base + offset;
 
     glUniform1fv(
@@ -4557,7 +4676,7 @@
 
 exit:
     if (v_base) {
-        _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+        _env->ReleaseFloatArrayElements(v_ref, (jfloat*)v_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4572,12 +4691,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *v = (GLfloat *) 0;
 
-    v = (GLfloat *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+    v = (GLfloat *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < count) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -4585,7 +4704,7 @@
         goto exit;
     }
     if (v == NULL) {
-        char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _vBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         v = (GLfloat *) (_vBase + _bufferOffset);
     }
     glUniform1fv(
@@ -4596,7 +4715,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, v, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)v, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4644,7 +4763,7 @@
         goto exit;
     }
     v_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+        _env->GetIntArrayElements(v_ref, (jboolean *)0);
     v = v_base + offset;
 
     glUniform1iv(
@@ -4655,7 +4774,7 @@
 
 exit:
     if (v_base) {
-        _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+        _env->ReleaseIntArrayElements(v_ref, (jint*)v_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4670,12 +4789,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *v = (GLint *) 0;
 
-    v = (GLint *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+    v = (GLint *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < count) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -4683,7 +4802,7 @@
         goto exit;
     }
     if (v == NULL) {
-        char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _vBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         v = (GLint *) (_vBase + _bufferOffset);
     }
     glUniform1iv(
@@ -4694,7 +4813,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, v, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)v, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4743,7 +4862,7 @@
         goto exit;
     }
     v_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(v_ref, (jboolean *)0);
     v = v_base + offset;
 
     glUniform2fv(
@@ -4754,7 +4873,7 @@
 
 exit:
     if (v_base) {
-        _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+        _env->ReleaseFloatArrayElements(v_ref, (jfloat*)v_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4769,12 +4888,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *v = (GLfloat *) 0;
 
-    v = (GLfloat *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+    v = (GLfloat *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < count*2) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -4782,7 +4901,7 @@
         goto exit;
     }
     if (v == NULL) {
-        char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _vBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         v = (GLfloat *) (_vBase + _bufferOffset);
     }
     glUniform2fv(
@@ -4793,7 +4912,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, v, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)v, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4842,7 +4961,7 @@
         goto exit;
     }
     v_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+        _env->GetIntArrayElements(v_ref, (jboolean *)0);
     v = v_base + offset;
 
     glUniform2iv(
@@ -4853,7 +4972,7 @@
 
 exit:
     if (v_base) {
-        _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+        _env->ReleaseIntArrayElements(v_ref, (jint*)v_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4868,12 +4987,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *v = (GLint *) 0;
 
-    v = (GLint *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+    v = (GLint *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < count*2) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -4881,7 +5000,7 @@
         goto exit;
     }
     if (v == NULL) {
-        char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _vBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         v = (GLint *) (_vBase + _bufferOffset);
     }
     glUniform2iv(
@@ -4892,7 +5011,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, v, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)v, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4942,7 +5061,7 @@
         goto exit;
     }
     v_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(v_ref, (jboolean *)0);
     v = v_base + offset;
 
     glUniform3fv(
@@ -4953,7 +5072,7 @@
 
 exit:
     if (v_base) {
-        _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+        _env->ReleaseFloatArrayElements(v_ref, (jfloat*)v_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4968,12 +5087,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *v = (GLfloat *) 0;
 
-    v = (GLfloat *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+    v = (GLfloat *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < count*3) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -4981,7 +5100,7 @@
         goto exit;
     }
     if (v == NULL) {
-        char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _vBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         v = (GLfloat *) (_vBase + _bufferOffset);
     }
     glUniform3fv(
@@ -4992,7 +5111,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, v, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)v, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5042,7 +5161,7 @@
         goto exit;
     }
     v_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+        _env->GetIntArrayElements(v_ref, (jboolean *)0);
     v = v_base + offset;
 
     glUniform3iv(
@@ -5053,7 +5172,7 @@
 
 exit:
     if (v_base) {
-        _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+        _env->ReleaseIntArrayElements(v_ref, (jint*)v_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -5068,12 +5187,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *v = (GLint *) 0;
 
-    v = (GLint *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+    v = (GLint *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < count*3) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -5081,7 +5200,7 @@
         goto exit;
     }
     if (v == NULL) {
-        char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _vBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         v = (GLint *) (_vBase + _bufferOffset);
     }
     glUniform3iv(
@@ -5092,7 +5211,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, v, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)v, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5143,7 +5262,7 @@
         goto exit;
     }
     v_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(v_ref, (jboolean *)0);
     v = v_base + offset;
 
     glUniform4fv(
@@ -5154,7 +5273,7 @@
 
 exit:
     if (v_base) {
-        _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+        _env->ReleaseFloatArrayElements(v_ref, (jfloat*)v_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -5169,12 +5288,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *v = (GLfloat *) 0;
 
-    v = (GLfloat *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+    v = (GLfloat *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < count*4) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -5182,7 +5301,7 @@
         goto exit;
     }
     if (v == NULL) {
-        char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _vBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         v = (GLfloat *) (_vBase + _bufferOffset);
     }
     glUniform4fv(
@@ -5193,7 +5312,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, v, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)v, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5244,7 +5363,7 @@
         goto exit;
     }
     v_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+        _env->GetIntArrayElements(v_ref, (jboolean *)0);
     v = v_base + offset;
 
     glUniform4iv(
@@ -5255,7 +5374,7 @@
 
 exit:
     if (v_base) {
-        _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+        _env->ReleaseIntArrayElements(v_ref, (jint*)v_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -5270,12 +5389,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *v = (GLint *) 0;
 
-    v = (GLint *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+    v = (GLint *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < count*4) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -5283,7 +5402,7 @@
         goto exit;
     }
     if (v == NULL) {
-        char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _vBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         v = (GLint *) (_vBase + _bufferOffset);
     }
     glUniform4iv(
@@ -5294,7 +5413,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, v, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)v, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5332,7 +5451,7 @@
         goto exit;
     }
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glUniformMatrix2fv(
@@ -5344,7 +5463,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -5359,12 +5478,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < count*4) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -5372,7 +5491,7 @@
         goto exit;
     }
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glUniformMatrix2fv(
@@ -5384,7 +5503,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5422,7 +5541,7 @@
         goto exit;
     }
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glUniformMatrix3fv(
@@ -5434,7 +5553,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -5449,12 +5568,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < count*9) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -5462,7 +5581,7 @@
         goto exit;
     }
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glUniformMatrix3fv(
@@ -5474,7 +5593,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5512,7 +5631,7 @@
         goto exit;
     }
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glUniformMatrix4fv(
@@ -5524,7 +5643,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -5539,12 +5658,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < count*16) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -5552,7 +5671,7 @@
         goto exit;
     }
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glUniformMatrix4fv(
@@ -5564,7 +5683,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5630,7 +5749,7 @@
         goto exit;
     }
     values_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(values_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(values_ref, (jboolean *)0);
     values = values_base + offset;
 
     glVertexAttrib1fv(
@@ -5640,7 +5759,7 @@
 
 exit:
     if (values_base) {
-        _env->ReleasePrimitiveArrayCritical(values_ref, values_base,
+        _env->ReleaseFloatArrayElements(values_ref, (jfloat*)values_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -5655,12 +5774,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *values = (GLfloat *) 0;
 
-    values = (GLfloat *)getPointer(_env, values_buf, &_array, &_remaining, &_bufferOffset);
+    values = (GLfloat *)getPointer(_env, values_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -5668,7 +5787,7 @@
         goto exit;
     }
     if (values == NULL) {
-        char * _valuesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valuesBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         values = (GLfloat *) (_valuesBase + _bufferOffset);
     }
     glVertexAttrib1fv(
@@ -5678,7 +5797,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, values, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)values, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5727,7 +5846,7 @@
         goto exit;
     }
     values_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(values_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(values_ref, (jboolean *)0);
     values = values_base + offset;
 
     glVertexAttrib2fv(
@@ -5737,7 +5856,7 @@
 
 exit:
     if (values_base) {
-        _env->ReleasePrimitiveArrayCritical(values_ref, values_base,
+        _env->ReleaseFloatArrayElements(values_ref, (jfloat*)values_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -5752,12 +5871,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *values = (GLfloat *) 0;
 
-    values = (GLfloat *)getPointer(_env, values_buf, &_array, &_remaining, &_bufferOffset);
+    values = (GLfloat *)getPointer(_env, values_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 2) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -5765,7 +5884,7 @@
         goto exit;
     }
     if (values == NULL) {
-        char * _valuesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valuesBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         values = (GLfloat *) (_valuesBase + _bufferOffset);
     }
     glVertexAttrib2fv(
@@ -5775,7 +5894,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, values, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)values, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5825,7 +5944,7 @@
         goto exit;
     }
     values_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(values_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(values_ref, (jboolean *)0);
     values = values_base + offset;
 
     glVertexAttrib3fv(
@@ -5835,7 +5954,7 @@
 
 exit:
     if (values_base) {
-        _env->ReleasePrimitiveArrayCritical(values_ref, values_base,
+        _env->ReleaseFloatArrayElements(values_ref, (jfloat*)values_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -5850,12 +5969,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *values = (GLfloat *) 0;
 
-    values = (GLfloat *)getPointer(_env, values_buf, &_array, &_remaining, &_bufferOffset);
+    values = (GLfloat *)getPointer(_env, values_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 3) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -5863,7 +5982,7 @@
         goto exit;
     }
     if (values == NULL) {
-        char * _valuesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valuesBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         values = (GLfloat *) (_valuesBase + _bufferOffset);
     }
     glVertexAttrib3fv(
@@ -5873,7 +5992,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, values, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)values, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5924,7 +6043,7 @@
         goto exit;
     }
     values_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(values_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(values_ref, (jboolean *)0);
     values = values_base + offset;
 
     glVertexAttrib4fv(
@@ -5934,7 +6053,7 @@
 
 exit:
     if (values_base) {
-        _env->ReleasePrimitiveArrayCritical(values_ref, values_base,
+        _env->ReleaseFloatArrayElements(values_ref, (jfloat*)values_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -5949,12 +6068,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *values = (GLfloat *) 0;
 
-    values = (GLfloat *)getPointer(_env, values_buf, &_array, &_remaining, &_bufferOffset);
+    values = (GLfloat *)getPointer(_env, values_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 4) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -5962,7 +6081,7 @@
         goto exit;
     }
     if (values == NULL) {
-        char * _valuesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valuesBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         values = (GLfloat *) (_valuesBase + _bufferOffset);
     }
     glVertexAttrib4fv(
@@ -5972,7 +6091,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, values, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)values, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
diff --git a/core/jni/android_opengl_GLES30.cpp b/core/jni/android_opengl_GLES30.cpp
index 226162d..1d92cd4 100644
--- a/core/jni/android_opengl_GLES30.cpp
+++ b/core/jni/android_opengl_GLES30.cpp
@@ -126,6 +126,116 @@
     return NULL;
 }
 
+class ByteArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+        return _env->GetByteArrayElements(array, is_copy);
+    }
+};
+class BooleanArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+        return _env->GetBooleanArrayElements(array, is_copy);
+    }
+};
+class CharArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+        return _env->GetCharArrayElements(array, is_copy);
+    }
+};
+class ShortArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+        return _env->GetShortArrayElements(array, is_copy);
+    }
+};
+class IntArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+        return _env->GetIntArrayElements(array, is_copy);
+    }
+};
+class LongArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+        return _env->GetLongArrayElements(array, is_copy);
+    }
+};
+class FloatArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+        return _env->GetFloatArrayElements(array, is_copy);
+    }
+};
+class DoubleArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+        return _env->GetDoubleArrayElements(array, is_copy);
+    }
+};
+
+template<typename JTYPEARRAY, typename ARRAYGETTER>
+static void*
+getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
+    return ARRAYGETTER::Get(_env, array, is_copy);
+}
+
+class ByteArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
+        _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class BooleanArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
+        _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class CharArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
+        _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class ShortArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
+        _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class IntArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
+        _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class LongArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
+        _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class FloatArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
+        _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class DoubleArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
+        _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+
+template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
+static void
+releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
+    ARRAYRELEASER::Release(_env, array, data, commit);
+}
+
 static void
 releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
 {
@@ -229,7 +339,8 @@
     return needed;
 }
 
-template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+          typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
 static void
 get
   (JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -264,8 +375,8 @@
         _exceptionMessage = "length - offset < needed";
         goto exit;
     }
-    params_base = (CTYPE *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+    params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+        _env, params_ref, (jboolean *)0);
     params = params_base + offset;
 
     GET(
@@ -275,8 +386,8 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
-            _exception ? JNI_ABORT: 0);
+        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+            _env, params_ref, params_base, !_exception);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -284,20 +395,21 @@
 }
 
 
-template <typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+          typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
 static void
 getarray
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
     jint _exception = 0;
     const char * _exceptionType;
     const char * _exceptionMessage;
-    jarray _array = (jarray) 0;
+    JTYPEARRAY _array = (JTYPEARRAY) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     CTYPE *params = (CTYPE *) 0;
     int _needed = 0;
 
-    params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     _remaining /= sizeof(CTYPE);    // convert from bytes to item count
     _needed = getNeededCount(pname);
     // if we didn't find this pname, we just assume the user passed
@@ -310,7 +422,8 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+            _env, _array, (jboolean *) 0);
         params = (CTYPE *) (_paramsBase + _bufferOffset);
     }
     GET(
@@ -320,7 +433,8 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+            _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -346,7 +460,7 @@
     jint _remaining;
     GLvoid *indices = (GLvoid *) 0;
 
-    indices = (GLvoid *)getPointer(_env, indices_buf, &_array, &_remaining, &_bufferOffset);
+    indices = (GLvoid *)getPointer(_env, indices_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (indices == NULL) {
         char * _indicesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         indices = (GLvoid *) (_indicesBase + _bufferOffset);
@@ -387,7 +501,7 @@
     jint _remaining;
     GLvoid *pixels = (GLvoid *) 0;
 
-    pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+    pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (pixels == NULL) {
         char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         pixels = (GLvoid *) (_pixelsBase + _bufferOffset);
@@ -436,7 +550,7 @@
     jint _remaining;
     GLvoid *pixels = (GLvoid *) 0;
 
-    pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+    pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (pixels == NULL) {
         char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         pixels = (GLvoid *) (_pixelsBase + _bufferOffset);
@@ -504,7 +618,7 @@
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
 
-    data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+    data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (data == NULL) {
         char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         data = (GLvoid *) (_dataBase + _bufferOffset);
@@ -551,7 +665,7 @@
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
 
-    data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+    data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (data == NULL) {
         char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         data = (GLvoid *) (_dataBase + _bufferOffset);
@@ -618,7 +732,7 @@
     }
     _remaining = _env->GetArrayLength(ids_ref) - offset;
     ids_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(ids_ref, (jboolean *)0);
+        _env->GetIntArrayElements(ids_ref, (jboolean *)0);
     ids = ids_base + offset;
 
     glGenQueries(
@@ -628,7 +742,7 @@
 
 exit:
     if (ids_base) {
-        _env->ReleasePrimitiveArrayCritical(ids_ref, ids_base,
+        _env->ReleaseIntArrayElements(ids_ref, (jint*)ids_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -640,14 +754,14 @@
 static void
 android_glGenQueries__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject ids_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *ids = (GLuint *) 0;
 
-    ids = (GLuint *)getPointer(_env, ids_buf, &_array, &_remaining, &_bufferOffset);
+    ids = (GLuint *)getPointer(_env, ids_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (ids == NULL) {
-        char * _idsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _idsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         ids = (GLuint *) (_idsBase + _bufferOffset);
     }
     glGenQueries(
@@ -655,7 +769,7 @@
         (GLuint *)ids
     );
     if (_array) {
-        releasePointer(_env, _array, ids, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)ids, 0);
     }
 }
 
@@ -684,7 +798,7 @@
     }
     _remaining = _env->GetArrayLength(ids_ref) - offset;
     ids_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(ids_ref, (jboolean *)0);
+        _env->GetIntArrayElements(ids_ref, (jboolean *)0);
     ids = ids_base + offset;
 
     glDeleteQueries(
@@ -694,7 +808,7 @@
 
 exit:
     if (ids_base) {
-        _env->ReleasePrimitiveArrayCritical(ids_ref, ids_base,
+        _env->ReleaseIntArrayElements(ids_ref, (jint*)ids_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -706,14 +820,14 @@
 static void
 android_glDeleteQueries__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject ids_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *ids = (GLuint *) 0;
 
-    ids = (GLuint *)getPointer(_env, ids_buf, &_array, &_remaining, &_bufferOffset);
+    ids = (GLuint *)getPointer(_env, ids_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (ids == NULL) {
-        char * _idsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _idsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         ids = (GLuint *) (_idsBase + _bufferOffset);
     }
     glDeleteQueries(
@@ -721,7 +835,7 @@
         (GLuint *)ids
     );
     if (_array) {
-        releasePointer(_env, _array, ids, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)ids, JNI_ABORT);
     }
 }
 
@@ -780,7 +894,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetQueryiv(
@@ -791,7 +905,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -803,14 +917,14 @@
 static void
 android_glGetQueryiv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetQueryiv(
@@ -819,7 +933,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -848,7 +962,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetQueryObjectuiv(
@@ -859,7 +973,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -871,14 +985,14 @@
 static void
 android_glGetQueryObjectuiv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint id, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *params = (GLuint *) 0;
 
-    params = (GLuint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLuint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLuint *) (_paramsBase + _bufferOffset);
     }
     glGetQueryObjectuiv(
@@ -887,7 +1001,7 @@
         (GLuint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -938,7 +1052,7 @@
     }
     _remaining = _env->GetArrayLength(bufs_ref) - offset;
     bufs_base = (GLenum *)
-        _env->GetPrimitiveArrayCritical(bufs_ref, (jboolean *)0);
+        _env->GetIntArrayElements(bufs_ref, (jboolean *)0);
     bufs = bufs_base + offset;
 
     glDrawBuffers(
@@ -948,7 +1062,7 @@
 
 exit:
     if (bufs_base) {
-        _env->ReleasePrimitiveArrayCritical(bufs_ref, bufs_base,
+        _env->ReleaseIntArrayElements(bufs_ref, (jint*)bufs_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -960,14 +1074,14 @@
 static void
 android_glDrawBuffers__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject bufs_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLenum *bufs = (GLenum *) 0;
 
-    bufs = (GLenum *)getPointer(_env, bufs_buf, &_array, &_remaining, &_bufferOffset);
+    bufs = (GLenum *)getPointer(_env, bufs_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (bufs == NULL) {
-        char * _bufsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _bufsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         bufs = (GLenum *) (_bufsBase + _bufferOffset);
     }
     glDrawBuffers(
@@ -975,7 +1089,7 @@
         (GLenum *)bufs
     );
     if (_array) {
-        releasePointer(_env, _array, bufs, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)bufs, JNI_ABORT);
     }
 }
 
@@ -1004,7 +1118,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glUniformMatrix2x3fv(
@@ -1016,7 +1130,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1028,14 +1142,14 @@
 static void
 android_glUniformMatrix2x3fv__IIZLjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint location, jint count, jboolean transpose, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glUniformMatrix2x3fv(
@@ -1045,7 +1159,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -1074,7 +1188,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glUniformMatrix3x2fv(
@@ -1086,7 +1200,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1098,14 +1212,14 @@
 static void
 android_glUniformMatrix3x2fv__IIZLjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint location, jint count, jboolean transpose, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glUniformMatrix3x2fv(
@@ -1115,7 +1229,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -1144,7 +1258,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glUniformMatrix2x4fv(
@@ -1156,7 +1270,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1168,14 +1282,14 @@
 static void
 android_glUniformMatrix2x4fv__IIZLjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint location, jint count, jboolean transpose, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glUniformMatrix2x4fv(
@@ -1185,7 +1299,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -1214,7 +1328,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glUniformMatrix4x2fv(
@@ -1226,7 +1340,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1238,14 +1352,14 @@
 static void
 android_glUniformMatrix4x2fv__IIZLjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint location, jint count, jboolean transpose, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glUniformMatrix4x2fv(
@@ -1255,7 +1369,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -1284,7 +1398,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glUniformMatrix3x4fv(
@@ -1296,7 +1410,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1308,14 +1422,14 @@
 static void
 android_glUniformMatrix3x4fv__IIZLjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint location, jint count, jboolean transpose, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glUniformMatrix3x4fv(
@@ -1325,7 +1439,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -1354,7 +1468,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glUniformMatrix4x3fv(
@@ -1366,7 +1480,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1378,14 +1492,14 @@
 static void
 android_glUniformMatrix4x3fv__IIZLjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint location, jint count, jboolean transpose, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glUniformMatrix4x3fv(
@@ -1395,7 +1509,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -1501,7 +1615,7 @@
     }
     _remaining = _env->GetArrayLength(arrays_ref) - offset;
     arrays_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(arrays_ref, (jboolean *)0);
+        _env->GetIntArrayElements(arrays_ref, (jboolean *)0);
     arrays = arrays_base + offset;
 
     glDeleteVertexArrays(
@@ -1511,7 +1625,7 @@
 
 exit:
     if (arrays_base) {
-        _env->ReleasePrimitiveArrayCritical(arrays_ref, arrays_base,
+        _env->ReleaseIntArrayElements(arrays_ref, (jint*)arrays_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1523,14 +1637,14 @@
 static void
 android_glDeleteVertexArrays__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject arrays_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *arrays = (GLuint *) 0;
 
-    arrays = (GLuint *)getPointer(_env, arrays_buf, &_array, &_remaining, &_bufferOffset);
+    arrays = (GLuint *)getPointer(_env, arrays_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (arrays == NULL) {
-        char * _arraysBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _arraysBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         arrays = (GLuint *) (_arraysBase + _bufferOffset);
     }
     glDeleteVertexArrays(
@@ -1538,7 +1652,7 @@
         (GLuint *)arrays
     );
     if (_array) {
-        releasePointer(_env, _array, arrays, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)arrays, JNI_ABORT);
     }
 }
 
@@ -1567,7 +1681,7 @@
     }
     _remaining = _env->GetArrayLength(arrays_ref) - offset;
     arrays_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(arrays_ref, (jboolean *)0);
+        _env->GetIntArrayElements(arrays_ref, (jboolean *)0);
     arrays = arrays_base + offset;
 
     glGenVertexArrays(
@@ -1577,7 +1691,7 @@
 
 exit:
     if (arrays_base) {
-        _env->ReleasePrimitiveArrayCritical(arrays_ref, arrays_base,
+        _env->ReleaseIntArrayElements(arrays_ref, (jint*)arrays_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1589,14 +1703,14 @@
 static void
 android_glGenVertexArrays__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject arrays_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *arrays = (GLuint *) 0;
 
-    arrays = (GLuint *)getPointer(_env, arrays_buf, &_array, &_remaining, &_bufferOffset);
+    arrays = (GLuint *)getPointer(_env, arrays_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (arrays == NULL) {
-        char * _arraysBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _arraysBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         arrays = (GLuint *) (_arraysBase + _bufferOffset);
     }
     glGenVertexArrays(
@@ -1604,7 +1718,7 @@
         (GLuint *)arrays
     );
     if (_array) {
-        releasePointer(_env, _array, arrays, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)arrays, 0);
     }
 }
 
@@ -1644,7 +1758,7 @@
     }
     _remaining = _env->GetArrayLength(data_ref) - offset;
     data_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(data_ref, (jboolean *)0);
+        _env->GetIntArrayElements(data_ref, (jboolean *)0);
     data = data_base + offset;
 
     glGetIntegeri_v(
@@ -1655,7 +1769,7 @@
 
 exit:
     if (data_base) {
-        _env->ReleasePrimitiveArrayCritical(data_ref, data_base,
+        _env->ReleaseIntArrayElements(data_ref, (jint*)data_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1667,14 +1781,14 @@
 static void
 android_glGetIntegeri_v__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint index, jobject data_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *data = (GLint *) 0;
 
-    data = (GLint *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+    data = (GLint *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (data == NULL) {
-        char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _dataBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         data = (GLint *) (_dataBase + _bufferOffset);
     }
     glGetIntegeri_v(
@@ -1683,7 +1797,7 @@
         (GLint *)data
     );
     if (_array) {
-        releasePointer(_env, _array, data, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)data, 0);
     }
 }
 
@@ -1810,7 +1924,7 @@
     }
     _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
     length_base = (GLsizei *)
-        _env->GetPrimitiveArrayCritical(length_ref, (jboolean *)0);
+        _env->GetIntArrayElements(length_ref, (jboolean *)0);
     length = length_base + lengthOffset;
 
     if (!size_ref) {
@@ -1827,7 +1941,7 @@
     }
     _sizeRemaining = _env->GetArrayLength(size_ref) - sizeOffset;
     size_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(size_ref, (jboolean *)0);
+        _env->GetIntArrayElements(size_ref, (jboolean *)0);
     size = size_base + sizeOffset;
 
     if (!type_ref) {
@@ -1844,7 +1958,7 @@
     }
     _typeRemaining = _env->GetArrayLength(type_ref) - typeOffset;
     type_base = (GLenum *)
-        _env->GetPrimitiveArrayCritical(type_ref, (jboolean *)0);
+        _env->GetIntArrayElements(type_ref, (jboolean *)0);
     type = type_base + typeOffset;
 
     if (!name_ref) {
@@ -1861,7 +1975,7 @@
     }
     _nameRemaining = _env->GetArrayLength(name_ref) - nameOffset;
     name_base = (char *)
-        _env->GetPrimitiveArrayCritical(name_ref, (jboolean *)0);
+        _env->GetByteArrayElements(name_ref, (jboolean *)0);
     name = name_base + nameOffset;
 
     glGetTransformFeedbackVarying(
@@ -1876,19 +1990,19 @@
 
 exit:
     if (name_base) {
-        _env->ReleasePrimitiveArrayCritical(name_ref, name_base,
+        _env->ReleaseByteArrayElements(name_ref, (jbyte*)name_base,
             _exception ? JNI_ABORT: 0);
     }
     if (type_base) {
-        _env->ReleasePrimitiveArrayCritical(type_ref, type_base,
+        _env->ReleaseIntArrayElements(type_ref, (jint*)type_base,
             _exception ? JNI_ABORT: 0);
     }
     if (size_base) {
-        _env->ReleasePrimitiveArrayCritical(size_ref, size_base,
+        _env->ReleaseIntArrayElements(size_ref, (jint*)size_base,
             _exception ? JNI_ABORT: 0);
     }
     if (length_base) {
-        _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
+        _env->ReleaseIntArrayElements(length_ref, (jint*)length_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1900,11 +2014,11 @@
 static void
 android_glGetTransformFeedbackVarying__IIILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2B
   (JNIEnv *_env, jobject _this, jint program, jint index, jint bufsize, jobject length_buf, jobject size_buf, jobject type_buf, jbyte name) {
-    jarray _lengthArray = (jarray) 0;
+    jintArray _lengthArray = (jintArray) 0;
     jint _lengthBufferOffset = (jint) 0;
-    jarray _sizeArray = (jarray) 0;
+    jintArray _sizeArray = (jintArray) 0;
     jint _sizeBufferOffset = (jint) 0;
-    jarray _typeArray = (jarray) 0;
+    jintArray _typeArray = (jintArray) 0;
     jint _typeBufferOffset = (jint) 0;
     jint _lengthRemaining;
     GLsizei *length = (GLsizei *) 0;
@@ -1913,19 +2027,19 @@
     jint _typeRemaining;
     GLenum *type = (GLenum *) 0;
 
-    length = (GLsizei *)getPointer(_env, length_buf, &_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
-    size = (GLint *)getPointer(_env, size_buf, &_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
-    type = (GLenum *)getPointer(_env, type_buf, &_typeArray, &_typeRemaining, &_typeBufferOffset);
+    length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+    size = (GLint *)getPointer(_env, size_buf, (jarray*)&_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
+    type = (GLenum *)getPointer(_env, type_buf, (jarray*)&_typeArray, &_typeRemaining, &_typeBufferOffset);
     if (length == NULL) {
-        char * _lengthBase = (char *)_env->GetPrimitiveArrayCritical(_lengthArray, (jboolean *) 0);
+        char * _lengthBase = (char *)_env->GetIntArrayElements(_lengthArray, (jboolean *) 0);
         length = (GLsizei *) (_lengthBase + _lengthBufferOffset);
     }
     if (size == NULL) {
-        char * _sizeBase = (char *)_env->GetPrimitiveArrayCritical(_sizeArray, (jboolean *) 0);
+        char * _sizeBase = (char *)_env->GetIntArrayElements(_sizeArray, (jboolean *) 0);
         size = (GLint *) (_sizeBase + _sizeBufferOffset);
     }
     if (type == NULL) {
-        char * _typeBase = (char *)_env->GetPrimitiveArrayCritical(_typeArray, (jboolean *) 0);
+        char * _typeBase = (char *)_env->GetIntArrayElements(_typeArray, (jboolean *) 0);
         type = (GLenum *) (_typeBase + _typeBufferOffset);
     }
     glGetTransformFeedbackVarying(
@@ -1942,13 +2056,13 @@
         (char *)static_cast<uintptr_t>(name)
     );
     if (_typeArray) {
-        releasePointer(_env, _typeArray, type, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _typeArray, (jint*)type, JNI_TRUE);
     }
     if (_sizeArray) {
-        releasePointer(_env, _sizeArray, size, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _sizeArray, (jint*)size, JNI_TRUE);
     }
     if (_lengthArray) {
-        releasePointer(_env, _lengthArray, length, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _lengthArray, (jint*)length, JNI_TRUE);
     }
 }
 
@@ -1993,7 +2107,7 @@
     }
     _sizeRemaining = _env->GetArrayLength(size_ref) - sizeOffset;
     size_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(size_ref, (jboolean *)0);
+        _env->GetIntArrayElements(size_ref, (jboolean *)0);
     size = size_base + sizeOffset;
 
     if (!type_ref) {
@@ -2010,7 +2124,7 @@
     }
     _typeRemaining = _env->GetArrayLength(type_ref) - typeOffset;
     type_base = (GLenum *)
-        _env->GetPrimitiveArrayCritical(type_ref, (jboolean *)0);
+        _env->GetIntArrayElements(type_ref, (jboolean *)0);
     type = type_base + typeOffset;
 
     glGetTransformFeedbackVarying(
@@ -2024,11 +2138,11 @@
     );
 exit:
     if (type_base) {
-        _env->ReleasePrimitiveArrayCritical(type_ref, type_base,
+        _env->ReleaseIntArrayElements(type_ref, (jint*)type_base,
             _exception ? JNI_ABORT: 0);
     }
     if (size_base) {
-        _env->ReleasePrimitiveArrayCritical(size_ref, size_base,
+        _env->ReleaseIntArrayElements(size_ref, (jint*)size_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception != 1) {
@@ -2051,9 +2165,9 @@
 static jstring
 android_glGetTransformFeedbackVarying2
   (JNIEnv *_env, jobject _this, jint program, jint index, jobject size_buf, jobject type_buf) {
-    jarray _sizeArray = (jarray) 0;
+    jintArray _sizeArray = (jintArray) 0;
     jint _sizeBufferOffset = (jint) 0;
-    jarray _typeArray = (jarray) 0;
+    jintArray _typeArray = (jintArray) 0;
     jint _typeBufferOffset = (jint) 0;
     jint _lengthRemaining;
     GLsizei *length = (GLsizei *) 0;
@@ -2076,14 +2190,14 @@
         return NULL;
     }
 
-    size = (GLint *)getPointer(_env, size_buf, &_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
-    type = (GLenum *)getPointer(_env, type_buf, &_typeArray, &_typeRemaining, &_typeBufferOffset);
+    size = (GLint *)getPointer(_env, size_buf, (jarray*)&_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
+    type = (GLenum *)getPointer(_env, type_buf, (jarray*)&_typeArray, &_typeRemaining, &_typeBufferOffset);
     if (size == NULL) {
-        char * _sizeBase = (char *)_env->GetPrimitiveArrayCritical(_sizeArray, (jboolean *) 0);
+        char * _sizeBase = (char *)_env->GetIntArrayElements(_sizeArray, (jboolean *) 0);
         size = (GLint *) (_sizeBase + _sizeBufferOffset);
     }
     if (type == NULL) {
-        char * _typeBase = (char *)_env->GetPrimitiveArrayCritical(_typeArray, (jboolean *) 0);
+        char * _typeBase = (char *)_env->GetIntArrayElements(_typeArray, (jboolean *) 0);
         type = (GLenum *) (_typeBase + _typeBufferOffset);
     }
     glGetTransformFeedbackVarying(
@@ -2097,10 +2211,10 @@
     );
 
     if (_typeArray) {
-        releasePointer(_env, _typeArray, type, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _typeArray, (jint*)type, JNI_TRUE);
     }
     if (_sizeArray) {
-        releasePointer(_env, _sizeArray, size, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _sizeArray, (jint*)size, JNI_TRUE);
     }
     result = _env->NewStringUTF(buf);
     if (buf) {
@@ -2171,7 +2285,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetVertexAttribIiv(
@@ -2182,7 +2296,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2194,14 +2308,14 @@
 static void
 android_glGetVertexAttribIiv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint index, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetVertexAttribIiv(
@@ -2210,7 +2324,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -2239,7 +2353,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetVertexAttribIuiv(
@@ -2250,7 +2364,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2262,14 +2376,14 @@
 static void
 android_glGetVertexAttribIuiv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint index, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *params = (GLuint *) 0;
 
-    params = (GLuint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLuint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLuint *) (_paramsBase + _bufferOffset);
     }
     glGetVertexAttribIuiv(
@@ -2278,7 +2392,7 @@
         (GLuint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -2333,7 +2447,7 @@
     }
     _remaining = _env->GetArrayLength(v_ref) - offset;
     v_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+        _env->GetIntArrayElements(v_ref, (jboolean *)0);
     v = v_base + offset;
 
     glVertexAttribI4iv(
@@ -2343,7 +2457,7 @@
 
 exit:
     if (v_base) {
-        _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+        _env->ReleaseIntArrayElements(v_ref, (jint*)v_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2355,14 +2469,14 @@
 static void
 android_glVertexAttribI4iv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint index, jobject v_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *v = (GLint *) 0;
 
-    v = (GLint *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+    v = (GLint *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (v == NULL) {
-        char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _vBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         v = (GLint *) (_vBase + _bufferOffset);
     }
     glVertexAttribI4iv(
@@ -2370,7 +2484,7 @@
         (GLint *)v
     );
     if (_array) {
-        releasePointer(_env, _array, v, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)v, JNI_ABORT);
     }
 }
 
@@ -2399,7 +2513,7 @@
     }
     _remaining = _env->GetArrayLength(v_ref) - offset;
     v_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+        _env->GetIntArrayElements(v_ref, (jboolean *)0);
     v = v_base + offset;
 
     glVertexAttribI4uiv(
@@ -2409,7 +2523,7 @@
 
 exit:
     if (v_base) {
-        _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+        _env->ReleaseIntArrayElements(v_ref, (jint*)v_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2421,14 +2535,14 @@
 static void
 android_glVertexAttribI4uiv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint index, jobject v_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *v = (GLuint *) 0;
 
-    v = (GLuint *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+    v = (GLuint *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (v == NULL) {
-        char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _vBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         v = (GLuint *) (_vBase + _bufferOffset);
     }
     glVertexAttribI4uiv(
@@ -2436,7 +2550,7 @@
         (GLuint *)v
     );
     if (_array) {
-        releasePointer(_env, _array, v, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)v, JNI_ABORT);
     }
 }
 
@@ -2465,7 +2579,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetUniformuiv(
@@ -2476,7 +2590,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2488,14 +2602,14 @@
 static void
 android_glGetUniformuiv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *params = (GLuint *) 0;
 
-    params = (GLuint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLuint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLuint *) (_paramsBase + _bufferOffset);
     }
     glGetUniformuiv(
@@ -2504,7 +2618,7 @@
         (GLuint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -2613,7 +2727,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glUniform1uiv(
@@ -2624,7 +2738,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2636,14 +2750,14 @@
 static void
 android_glUniform1uiv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint location, jint count, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *value = (GLuint *) 0;
 
-    value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         value = (GLuint *) (_valueBase + _bufferOffset);
     }
     glUniform1uiv(
@@ -2652,7 +2766,7 @@
         (GLuint *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
     }
 }
 
@@ -2681,7 +2795,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glUniform2uiv(
@@ -2692,7 +2806,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2704,14 +2818,14 @@
 static void
 android_glUniform2uiv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint location, jint count, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *value = (GLuint *) 0;
 
-    value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         value = (GLuint *) (_valueBase + _bufferOffset);
     }
     glUniform2uiv(
@@ -2720,7 +2834,7 @@
         (GLuint *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
     }
 }
 
@@ -2749,7 +2863,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glUniform3uiv(
@@ -2760,7 +2874,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2772,14 +2886,14 @@
 static void
 android_glUniform3uiv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint location, jint count, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *value = (GLuint *) 0;
 
-    value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         value = (GLuint *) (_valueBase + _bufferOffset);
     }
     glUniform3uiv(
@@ -2788,7 +2902,7 @@
         (GLuint *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
     }
 }
 
@@ -2817,7 +2931,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glUniform4uiv(
@@ -2828,7 +2942,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2840,14 +2954,14 @@
 static void
 android_glUniform4uiv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint location, jint count, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *value = (GLuint *) 0;
 
-    value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         value = (GLuint *) (_valueBase + _bufferOffset);
     }
     glUniform4uiv(
@@ -2856,7 +2970,7 @@
         (GLuint *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
     }
 }
 
@@ -2885,7 +2999,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glClearBufferiv(
@@ -2896,7 +3010,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2908,14 +3022,14 @@
 static void
 android_glClearBufferiv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint buffer, jint drawbuffer, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *value = (GLint *) 0;
 
-    value = (GLint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         value = (GLint *) (_valueBase + _bufferOffset);
     }
     glClearBufferiv(
@@ -2924,7 +3038,7 @@
         (GLint *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
     }
 }
 
@@ -2953,7 +3067,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glClearBufferuiv(
@@ -2964,7 +3078,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2976,14 +3090,14 @@
 static void
 android_glClearBufferuiv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint buffer, jint drawbuffer, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *value = (GLuint *) 0;
 
-    value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         value = (GLuint *) (_valueBase + _bufferOffset);
     }
     glClearBufferuiv(
@@ -2992,7 +3106,7 @@
         (GLuint *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
     }
 }
 
@@ -3021,7 +3135,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glClearBufferfv(
@@ -3032,7 +3146,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -3044,14 +3158,14 @@
 static void
 android_glClearBufferfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint buffer, jint drawbuffer, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glClearBufferfv(
@@ -3060,7 +3174,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -3148,7 +3262,7 @@
         _exceptionMessage = "not enough space in uniformIndices";
         goto exit;
     }
-    _indices_base = (GLuint*)_env->GetPrimitiveArrayCritical(
+    _indices_base = (GLuint*)_env->GetIntArrayElements(
             uniformIndices_ref, 0);
     _indices = _indices_base + uniformIndicesOffset;
 
@@ -3156,8 +3270,8 @@
 
 exit:
     if (_indices_base) {
-        _env->ReleasePrimitiveArrayCritical(uniformIndices_ref, _indices_base,
-                _exception ? JNI_ABORT : 0);
+        _env->ReleaseIntArrayElements(uniformIndices_ref, (jint*)_indices_base,
+            _exception ? JNI_ABORT : 0);
     }
     for (_i = _count - 1; _i >= 0; _i--) {
         if (_names[_i]) {
@@ -3184,7 +3298,7 @@
     jint _count = 0;
     jint _i;
     const char** _names = NULL;
-    jarray _uniformIndicesArray = (jarray)0;
+    jintArray _uniformIndicesArray = (jintArray)0;
     jint _uniformIndicesRemaining;
     jint _uniformIndicesOffset = 0;
     GLuint* _indices = NULL;
@@ -3217,11 +3331,11 @@
     }
 
     _indices = (GLuint*)getPointer(_env, uniformIndices_buf,
-            &_uniformIndicesArray, &_uniformIndicesRemaining,
+            (jarray*)&_uniformIndicesArray, &_uniformIndicesRemaining,
             &_uniformIndicesOffset);
     if (!_indices) {
-        _indicesBase = (char*)_env->GetPrimitiveArrayCritical(
-                _uniformIndicesArray, 0);
+        _indicesBase = (char*)_env->GetIntArrayElements(
+            _uniformIndicesArray, 0);
         _indices = (GLuint*)(_indicesBase + _uniformIndicesOffset);
     }
     if (_uniformIndicesRemaining < _count) {
@@ -3235,7 +3349,8 @@
 
 exit:
     if (_uniformIndicesArray) {
-        releasePointer(_env, _uniformIndicesArray, _indicesBase, JNI_TRUE);
+        releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(
+            _env, _uniformIndicesArray, (jint*)_indicesBase, JNI_TRUE);
     }
     for (_i = _count - 1; _i >= 0; _i--) {
         if (_names[_i]) {
@@ -3250,7 +3365,6 @@
         jniThrowException(_env, _exceptionType, _exceptionMessage);
     }
 }
-
 /* void glGetActiveUniformsiv ( GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params ) */
 static void
 android_glGetActiveUniformsiv__II_3III_3II
@@ -3279,7 +3393,7 @@
     }
     _uniformIndicesRemaining = _env->GetArrayLength(uniformIndices_ref) - uniformIndicesOffset;
     uniformIndices_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(uniformIndices_ref, (jboolean *)0);
+        _env->GetIntArrayElements(uniformIndices_ref, (jboolean *)0);
     uniformIndices = uniformIndices_base + uniformIndicesOffset;
 
     if (!params_ref) {
@@ -3296,7 +3410,7 @@
     }
     _paramsRemaining = _env->GetArrayLength(params_ref) - paramsOffset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + paramsOffset;
 
     glGetActiveUniformsiv(
@@ -3309,11 +3423,11 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (uniformIndices_base) {
-        _env->ReleasePrimitiveArrayCritical(uniformIndices_ref, uniformIndices_base,
+        _env->ReleaseIntArrayElements(uniformIndices_ref, (jint*)uniformIndices_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -3325,23 +3439,23 @@
 static void
 android_glGetActiveUniformsiv__IILjava_nio_IntBuffer_2ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint uniformCount, jobject uniformIndices_buf, jint pname, jobject params_buf) {
-    jarray _uniformIndicesArray = (jarray) 0;
+    jintArray _uniformIndicesArray = (jintArray) 0;
     jint _uniformIndicesBufferOffset = (jint) 0;
-    jarray _paramsArray = (jarray) 0;
+    jintArray _paramsArray = (jintArray) 0;
     jint _paramsBufferOffset = (jint) 0;
     jint _uniformIndicesRemaining;
     GLuint *uniformIndices = (GLuint *) 0;
     jint _paramsRemaining;
     GLint *params = (GLint *) 0;
 
-    uniformIndices = (GLuint *)getPointer(_env, uniformIndices_buf, &_uniformIndicesArray, &_uniformIndicesRemaining, &_uniformIndicesBufferOffset);
-    params = (GLint *)getPointer(_env, params_buf, &_paramsArray, &_paramsRemaining, &_paramsBufferOffset);
+    uniformIndices = (GLuint *)getPointer(_env, uniformIndices_buf, (jarray*)&_uniformIndicesArray, &_uniformIndicesRemaining, &_uniformIndicesBufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_paramsArray, &_paramsRemaining, &_paramsBufferOffset);
     if (uniformIndices == NULL) {
-        char * _uniformIndicesBase = (char *)_env->GetPrimitiveArrayCritical(_uniformIndicesArray, (jboolean *) 0);
+        char * _uniformIndicesBase = (char *)_env->GetIntArrayElements(_uniformIndicesArray, (jboolean *) 0);
         uniformIndices = (GLuint *) (_uniformIndicesBase + _uniformIndicesBufferOffset);
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_paramsArray, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_paramsArray, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _paramsBufferOffset);
     }
     glGetActiveUniformsiv(
@@ -3352,10 +3466,10 @@
         (GLint *)params
     );
     if (_paramsArray) {
-        releasePointer(_env, _paramsArray, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_paramsArray, (jint*)params, 0);
     }
     if (_uniformIndicesArray) {
-        releasePointer(_env, _uniformIndicesArray, uniformIndices, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_uniformIndicesArray, (jint*)uniformIndices, JNI_ABORT);
     }
 }
 
@@ -3418,7 +3532,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetActiveUniformBlockiv(
@@ -3430,7 +3544,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3442,14 +3556,14 @@
 static void
 android_glGetActiveUniformBlockiv__IIILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint uniformBlockIndex, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetActiveUniformBlockiv(
@@ -3459,7 +3573,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -3490,7 +3604,7 @@
         goto exit;
     }
     _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
-    _length_base = (GLsizei*)_env->GetPrimitiveArrayCritical(
+    _length_base = (GLsizei*)_env->GetIntArrayElements(
             length_ref, (jboolean*)0);
     _length = _length_base + lengthOffset;
 
@@ -3507,7 +3621,7 @@
         goto exit;
     }
     _nameRemaining = _env->GetArrayLength(name_ref) - nameOffset;
-    _name_base = (GLchar*)_env->GetPrimitiveArrayCritical(
+    _name_base = (GLchar*)_env->GetByteArrayElements(
             name_ref, (jboolean*)0);
     _name = _name_base + nameOffset;
 
@@ -3521,11 +3635,11 @@
 
 exit:
     if (_name_base) {
-        _env->ReleasePrimitiveArrayCritical(name_ref, _name_base,
+        _env->ReleaseByteArrayElements(name_ref, (jbyte*)_name_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_length_base) {
-        _env->ReleasePrimitiveArrayCritical(length_ref, _length_base,
+        _env->ReleaseIntArrayElements(length_ref, (jint*)_length_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3589,7 +3703,6 @@
     free(name);
     return result;
 }
-
 /* void glUniformBlockBinding ( GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding ) */
 static void
 android_glUniformBlockBinding__III
@@ -3651,7 +3764,6 @@
         (GLsizei)instanceCount
     );
 }
-
 /* GLsync glFenceSync ( GLenum condition, GLbitfield flags ) */
 static jlong
 android_glFenceSync__II
@@ -3733,7 +3845,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint64 *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetLongArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetInteger64v(
@@ -3743,7 +3855,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseLongArrayElements(params_ref, (jlong*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3755,14 +3867,14 @@
 static void
 android_glGetInteger64v__ILjava_nio_LongBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jlongArray _array = (jlongArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint64 *params = (GLint64 *) 0;
 
-    params = (GLint64 *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint64 *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetLongArrayElements(_array, (jboolean *) 0);
         params = (GLint64 *) (_paramsBase + _bufferOffset);
     }
     glGetInteger64v(
@@ -3770,7 +3882,7 @@
         (GLint64 *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseLongArrayElements(_array, (jlong*)params, 0);
     }
 }
 
@@ -3802,7 +3914,7 @@
     }
     _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
     length_base = (GLsizei *)
-        _env->GetPrimitiveArrayCritical(length_ref, (jboolean *)0);
+        _env->GetIntArrayElements(length_ref, (jboolean *)0);
     length = length_base + lengthOffset;
 
     if (!values_ref) {
@@ -3819,7 +3931,7 @@
     }
     _valuesRemaining = _env->GetArrayLength(values_ref) - valuesOffset;
     values_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(values_ref, (jboolean *)0);
+        _env->GetIntArrayElements(values_ref, (jboolean *)0);
     values = values_base + valuesOffset;
 
     glGetSynciv(
@@ -3832,11 +3944,11 @@
 
 exit:
     if (values_base) {
-        _env->ReleasePrimitiveArrayCritical(values_ref, values_base,
+        _env->ReleaseIntArrayElements(values_ref, (jint*)values_base,
             _exception ? JNI_ABORT: 0);
     }
     if (length_base) {
-        _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
+        _env->ReleaseIntArrayElements(length_ref, (jint*)length_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3848,23 +3960,23 @@
 static void
 android_glGetSynciv__JIILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jlong sync, jint pname, jint bufSize, jobject length_buf, jobject values_buf) {
-    jarray _lengthArray = (jarray) 0;
+    jintArray _lengthArray = (jintArray) 0;
     jint _lengthBufferOffset = (jint) 0;
-    jarray _valuesArray = (jarray) 0;
+    jintArray _valuesArray = (jintArray) 0;
     jint _valuesBufferOffset = (jint) 0;
     jint _lengthRemaining;
     GLsizei *length = (GLsizei *) 0;
     jint _valuesRemaining;
     GLint *values = (GLint *) 0;
 
-    length = (GLsizei *)getPointer(_env, length_buf, &_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
-    values = (GLint *)getPointer(_env, values_buf, &_valuesArray, &_valuesRemaining, &_valuesBufferOffset);
+    length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+    values = (GLint *)getPointer(_env, values_buf, (jarray*)&_valuesArray, &_valuesRemaining, &_valuesBufferOffset);
     if (length == NULL) {
-        char * _lengthBase = (char *)_env->GetPrimitiveArrayCritical(_lengthArray, (jboolean *) 0);
+        char * _lengthBase = (char *)_env->GetIntArrayElements(_lengthArray, (jboolean *) 0);
         length = (GLsizei *) (_lengthBase + _lengthBufferOffset);
     }
     if (values == NULL) {
-        char * _valuesBase = (char *)_env->GetPrimitiveArrayCritical(_valuesArray, (jboolean *) 0);
+        char * _valuesBase = (char *)_env->GetIntArrayElements(_valuesArray, (jboolean *) 0);
         values = (GLint *) (_valuesBase + _valuesBufferOffset);
     }
     glGetSynciv(
@@ -3875,10 +3987,10 @@
         (GLint *)values
     );
     if (_valuesArray) {
-        releasePointer(_env, _valuesArray, values, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_valuesArray, (jint*)values, 0);
     }
     if (_lengthArray) {
-        releasePointer(_env, _lengthArray, length, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_lengthArray, (jint*)length, 0);
     }
 }
 
@@ -3907,7 +4019,7 @@
     }
     _remaining = _env->GetArrayLength(data_ref) - offset;
     data_base = (GLint64 *)
-        _env->GetPrimitiveArrayCritical(data_ref, (jboolean *)0);
+        _env->GetLongArrayElements(data_ref, (jboolean *)0);
     data = data_base + offset;
 
     glGetInteger64i_v(
@@ -3918,7 +4030,7 @@
 
 exit:
     if (data_base) {
-        _env->ReleasePrimitiveArrayCritical(data_ref, data_base,
+        _env->ReleaseLongArrayElements(data_ref, (jlong*)data_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3930,14 +4042,14 @@
 static void
 android_glGetInteger64i_v__IILjava_nio_LongBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint index, jobject data_buf) {
-    jarray _array = (jarray) 0;
+    jlongArray _array = (jlongArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint64 *data = (GLint64 *) 0;
 
-    data = (GLint64 *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+    data = (GLint64 *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (data == NULL) {
-        char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _dataBase = (char *)_env->GetLongArrayElements(_array, (jboolean *) 0);
         data = (GLint64 *) (_dataBase + _bufferOffset);
     }
     glGetInteger64i_v(
@@ -3946,7 +4058,7 @@
         (GLint64 *)data
     );
     if (_array) {
-        releasePointer(_env, _array, data, JNI_TRUE);
+        _env->ReleaseLongArrayElements(_array, (jlong*)data, 0);
     }
 }
 
@@ -3975,7 +4087,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint64 *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetLongArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetBufferParameteri64v(
@@ -3986,7 +4098,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseLongArrayElements(params_ref, (jlong*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -3998,14 +4110,14 @@
 static void
 android_glGetBufferParameteri64v__IILjava_nio_LongBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jlongArray _array = (jlongArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint64 *params = (GLint64 *) 0;
 
-    params = (GLint64 *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint64 *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetLongArrayElements(_array, (jboolean *) 0);
         params = (GLint64 *) (_paramsBase + _bufferOffset);
     }
     glGetBufferParameteri64v(
@@ -4014,7 +4126,7 @@
         (GLint64 *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseLongArrayElements(_array, (jlong*)params, 0);
     }
 }
 
@@ -4043,7 +4155,7 @@
     }
     _remaining = _env->GetArrayLength(samplers_ref) - offset;
     samplers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(samplers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(samplers_ref, (jboolean *)0);
     samplers = samplers_base + offset;
 
     glGenSamplers(
@@ -4053,7 +4165,7 @@
 
 exit:
     if (samplers_base) {
-        _env->ReleasePrimitiveArrayCritical(samplers_ref, samplers_base,
+        _env->ReleaseIntArrayElements(samplers_ref, (jint*)samplers_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -4065,14 +4177,14 @@
 static void
 android_glGenSamplers__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint count, jobject samplers_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *samplers = (GLuint *) 0;
 
-    samplers = (GLuint *)getPointer(_env, samplers_buf, &_array, &_remaining, &_bufferOffset);
+    samplers = (GLuint *)getPointer(_env, samplers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (samplers == NULL) {
-        char * _samplersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _samplersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         samplers = (GLuint *) (_samplersBase + _bufferOffset);
     }
     glGenSamplers(
@@ -4080,7 +4192,7 @@
         (GLuint *)samplers
     );
     if (_array) {
-        releasePointer(_env, _array, samplers, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)samplers, 0);
     }
 }
 
@@ -4109,7 +4221,7 @@
     }
     _remaining = _env->GetArrayLength(samplers_ref) - offset;
     samplers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(samplers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(samplers_ref, (jboolean *)0);
     samplers = samplers_base + offset;
 
     glDeleteSamplers(
@@ -4119,7 +4231,7 @@
 
 exit:
     if (samplers_base) {
-        _env->ReleasePrimitiveArrayCritical(samplers_ref, samplers_base,
+        _env->ReleaseIntArrayElements(samplers_ref, (jint*)samplers_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4131,14 +4243,14 @@
 static void
 android_glDeleteSamplers__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint count, jobject samplers_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *samplers = (GLuint *) 0;
 
-    samplers = (GLuint *)getPointer(_env, samplers_buf, &_array, &_remaining, &_bufferOffset);
+    samplers = (GLuint *)getPointer(_env, samplers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (samplers == NULL) {
-        char * _samplersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _samplersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         samplers = (GLuint *) (_samplersBase + _bufferOffset);
     }
     glDeleteSamplers(
@@ -4146,7 +4258,7 @@
         (GLuint *)samplers
     );
     if (_array) {
-        releasePointer(_env, _array, samplers, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)samplers, JNI_ABORT);
     }
 }
 
@@ -4207,7 +4319,7 @@
     }
     _remaining = _env->GetArrayLength(param_ref) - offset;
     param_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(param_ref, (jboolean *)0);
+        _env->GetIntArrayElements(param_ref, (jboolean *)0);
     param = param_base + offset;
 
     glSamplerParameteriv(
@@ -4218,7 +4330,7 @@
 
 exit:
     if (param_base) {
-        _env->ReleasePrimitiveArrayCritical(param_ref, param_base,
+        _env->ReleaseIntArrayElements(param_ref, (jint*)param_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4230,14 +4342,14 @@
 static void
 android_glSamplerParameteriv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint sampler, jint pname, jobject param_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *param = (GLint *) 0;
 
-    param = (GLint *)getPointer(_env, param_buf, &_array, &_remaining, &_bufferOffset);
+    param = (GLint *)getPointer(_env, param_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (param == NULL) {
-        char * _paramBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         param = (GLint *) (_paramBase + _bufferOffset);
     }
     glSamplerParameteriv(
@@ -4246,7 +4358,7 @@
         (GLint *)param
     );
     if (_array) {
-        releasePointer(_env, _array, param, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)param, JNI_ABORT);
     }
 }
 
@@ -4286,7 +4398,7 @@
     }
     _remaining = _env->GetArrayLength(param_ref) - offset;
     param_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(param_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(param_ref, (jboolean *)0);
     param = param_base + offset;
 
     glSamplerParameterfv(
@@ -4297,7 +4409,7 @@
 
 exit:
     if (param_base) {
-        _env->ReleasePrimitiveArrayCritical(param_ref, param_base,
+        _env->ReleaseFloatArrayElements(param_ref, (jfloat*)param_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4309,14 +4421,14 @@
 static void
 android_glSamplerParameterfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint sampler, jint pname, jobject param_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *param = (GLfloat *) 0;
 
-    param = (GLfloat *)getPointer(_env, param_buf, &_array, &_remaining, &_bufferOffset);
+    param = (GLfloat *)getPointer(_env, param_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (param == NULL) {
-        char * _paramBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         param = (GLfloat *) (_paramBase + _bufferOffset);
     }
     glSamplerParameterfv(
@@ -4325,7 +4437,7 @@
         (GLfloat *)param
     );
     if (_array) {
-        releasePointer(_env, _array, param, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)param, JNI_ABORT);
     }
 }
 
@@ -4354,7 +4466,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetSamplerParameteriv(
@@ -4365,7 +4477,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -4377,14 +4489,14 @@
 static void
 android_glGetSamplerParameteriv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint sampler, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetSamplerParameteriv(
@@ -4393,7 +4505,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -4422,7 +4534,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetSamplerParameterfv(
@@ -4433,7 +4545,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -4445,14 +4557,14 @@
 static void
 android_glGetSamplerParameterfv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint sampler, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glGetSamplerParameterfv(
@@ -4461,7 +4573,7 @@
         (GLfloat *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, 0);
     }
 }
 
@@ -4510,7 +4622,7 @@
     }
     _remaining = _env->GetArrayLength(ids_ref) - offset;
     ids_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(ids_ref, (jboolean *)0);
+        _env->GetIntArrayElements(ids_ref, (jboolean *)0);
     ids = ids_base + offset;
 
     glDeleteTransformFeedbacks(
@@ -4520,7 +4632,7 @@
 
 exit:
     if (ids_base) {
-        _env->ReleasePrimitiveArrayCritical(ids_ref, ids_base,
+        _env->ReleaseIntArrayElements(ids_ref, (jint*)ids_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4532,14 +4644,14 @@
 static void
 android_glDeleteTransformFeedbacks__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject ids_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *ids = (GLuint *) 0;
 
-    ids = (GLuint *)getPointer(_env, ids_buf, &_array, &_remaining, &_bufferOffset);
+    ids = (GLuint *)getPointer(_env, ids_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (ids == NULL) {
-        char * _idsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _idsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         ids = (GLuint *) (_idsBase + _bufferOffset);
     }
     glDeleteTransformFeedbacks(
@@ -4547,7 +4659,7 @@
         (GLuint *)ids
     );
     if (_array) {
-        releasePointer(_env, _array, ids, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)ids, JNI_ABORT);
     }
 }
 
@@ -4576,7 +4688,7 @@
     }
     _remaining = _env->GetArrayLength(ids_ref) - offset;
     ids_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(ids_ref, (jboolean *)0);
+        _env->GetIntArrayElements(ids_ref, (jboolean *)0);
     ids = ids_base + offset;
 
     glGenTransformFeedbacks(
@@ -4586,7 +4698,7 @@
 
 exit:
     if (ids_base) {
-        _env->ReleasePrimitiveArrayCritical(ids_ref, ids_base,
+        _env->ReleaseIntArrayElements(ids_ref, (jint*)ids_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -4598,14 +4710,14 @@
 static void
 android_glGenTransformFeedbacks__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject ids_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *ids = (GLuint *) 0;
 
-    ids = (GLuint *)getPointer(_env, ids_buf, &_array, &_remaining, &_bufferOffset);
+    ids = (GLuint *)getPointer(_env, ids_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (ids == NULL) {
-        char * _idsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _idsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         ids = (GLuint *) (_idsBase + _bufferOffset);
     }
     glGenTransformFeedbacks(
@@ -4613,7 +4725,7 @@
         (GLuint *)ids
     );
     if (_array) {
-        releasePointer(_env, _array, ids, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)ids, 0);
     }
 }
 
@@ -4674,7 +4786,7 @@
     }
     _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
     length_base = (GLsizei *)
-        _env->GetPrimitiveArrayCritical(length_ref, (jboolean *)0);
+        _env->GetIntArrayElements(length_ref, (jboolean *)0);
     length = length_base + lengthOffset;
 
     if (!binaryFormat_ref) {
@@ -4691,10 +4803,10 @@
     }
     _binaryFormatRemaining = _env->GetArrayLength(binaryFormat_ref) - binaryFormatOffset;
     binaryFormat_base = (GLenum *)
-        _env->GetPrimitiveArrayCritical(binaryFormat_ref, (jboolean *)0);
+        _env->GetIntArrayElements(binaryFormat_ref, (jboolean *)0);
     binaryFormat = binaryFormat_base + binaryFormatOffset;
 
-    binary = (GLvoid *)getPointer(_env, binary_buf, &_array, &_binaryRemaining, &_bufferOffset);
+    binary = (GLvoid *)getPointer(_env, binary_buf, (jarray*)&_array, &_binaryRemaining, &_bufferOffset);
     if (binary == NULL) {
         char * _binaryBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         binary = (GLvoid *) (_binaryBase + _bufferOffset);
@@ -4712,11 +4824,11 @@
         releasePointer(_env, _array, binary, _exception ? JNI_FALSE : JNI_TRUE);
     }
     if (binaryFormat_base) {
-        _env->ReleasePrimitiveArrayCritical(binaryFormat_ref, binaryFormat_base,
+        _env->ReleaseIntArrayElements(binaryFormat_ref, (jint*)binaryFormat_base,
             _exception ? JNI_ABORT: 0);
     }
     if (length_base) {
-        _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
+        _env->ReleaseIntArrayElements(length_ref, (jint*)length_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -4728,11 +4840,11 @@
 static void
 android_glGetProgramBinary__IILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_Buffer_2
   (JNIEnv *_env, jobject _this, jint program, jint bufSize, jobject length_buf, jobject binaryFormat_buf, jobject binary_buf) {
-    jarray _lengthArray = (jarray) 0;
+    jintArray _lengthArray = (jintArray) 0;
     jint _lengthBufferOffset = (jint) 0;
-    jarray _binaryFormatArray = (jarray) 0;
+    jintArray _binaryFormatArray = (jintArray) 0;
     jint _binaryFormatBufferOffset = (jint) 0;
-    jarray _binaryArray = (jarray) 0;
+    jintArray _binaryArray = (jintArray) 0;
     jint _binaryBufferOffset = (jint) 0;
     jint _lengthRemaining;
     GLsizei *length = (GLsizei *) 0;
@@ -4741,15 +4853,15 @@
     jint _binaryRemaining;
     GLvoid *binary = (GLvoid *) 0;
 
-    length = (GLsizei *)getPointer(_env, length_buf, &_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
-    binaryFormat = (GLenum *)getPointer(_env, binaryFormat_buf, &_binaryFormatArray, &_binaryFormatRemaining, &_binaryFormatBufferOffset);
-    binary = (GLvoid *)getPointer(_env, binary_buf, &_binaryArray, &_binaryRemaining, &_binaryBufferOffset);
+    length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+    binaryFormat = (GLenum *)getPointer(_env, binaryFormat_buf, (jarray*)&_binaryFormatArray, &_binaryFormatRemaining, &_binaryFormatBufferOffset);
+    binary = (GLvoid *)getPointer(_env, binary_buf, (jarray*)&_binaryArray, &_binaryRemaining, &_binaryBufferOffset);
     if (length == NULL) {
-        char * _lengthBase = (char *)_env->GetPrimitiveArrayCritical(_lengthArray, (jboolean *) 0);
+        char * _lengthBase = (char *)_env->GetIntArrayElements(_lengthArray, (jboolean *) 0);
         length = (GLsizei *) (_lengthBase + _lengthBufferOffset);
     }
     if (binaryFormat == NULL) {
-        char * _binaryFormatBase = (char *)_env->GetPrimitiveArrayCritical(_binaryFormatArray, (jboolean *) 0);
+        char * _binaryFormatBase = (char *)_env->GetIntArrayElements(_binaryFormatArray, (jboolean *) 0);
         binaryFormat = (GLenum *) (_binaryFormatBase + _binaryFormatBufferOffset);
     }
     if (binary == NULL) {
@@ -4767,10 +4879,10 @@
         releasePointer(_env, _binaryArray, binary, JNI_TRUE);
     }
     if (_binaryFormatArray) {
-        releasePointer(_env, _binaryFormatArray, binaryFormat, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_binaryFormatArray, (jint*)binaryFormat, 0);
     }
     if (_lengthArray) {
-        releasePointer(_env, _lengthArray, length, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_lengthArray, (jint*)length, 0);
     }
 }
 
@@ -4783,7 +4895,7 @@
     jint _remaining;
     GLvoid *binary = (GLvoid *) 0;
 
-    binary = (GLvoid *)getPointer(_env, binary_buf, &_array, &_remaining, &_bufferOffset);
+    binary = (GLvoid *)getPointer(_env, binary_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (binary == NULL) {
         char * _binaryBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         binary = (GLvoid *) (_binaryBase + _bufferOffset);
@@ -4835,7 +4947,7 @@
     }
     _remaining = _env->GetArrayLength(attachments_ref) - offset;
     attachments_base = (GLenum *)
-        _env->GetPrimitiveArrayCritical(attachments_ref, (jboolean *)0);
+        _env->GetIntArrayElements(attachments_ref, (jboolean *)0);
     attachments = attachments_base + offset;
 
     glInvalidateFramebuffer(
@@ -4846,7 +4958,7 @@
 
 exit:
     if (attachments_base) {
-        _env->ReleasePrimitiveArrayCritical(attachments_ref, attachments_base,
+        _env->ReleaseIntArrayElements(attachments_ref, (jint*)attachments_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4858,14 +4970,14 @@
 static void
 android_glInvalidateFramebuffer__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint numAttachments, jobject attachments_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLenum *attachments = (GLenum *) 0;
 
-    attachments = (GLenum *)getPointer(_env, attachments_buf, &_array, &_remaining, &_bufferOffset);
+    attachments = (GLenum *)getPointer(_env, attachments_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (attachments == NULL) {
-        char * _attachmentsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _attachmentsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         attachments = (GLenum *) (_attachmentsBase + _bufferOffset);
     }
     glInvalidateFramebuffer(
@@ -4874,7 +4986,7 @@
         (GLenum *)attachments
     );
     if (_array) {
-        releasePointer(_env, _array, attachments, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)attachments, JNI_ABORT);
     }
 }
 
@@ -4903,7 +5015,7 @@
     }
     _remaining = _env->GetArrayLength(attachments_ref) - offset;
     attachments_base = (GLenum *)
-        _env->GetPrimitiveArrayCritical(attachments_ref, (jboolean *)0);
+        _env->GetIntArrayElements(attachments_ref, (jboolean *)0);
     attachments = attachments_base + offset;
 
     glInvalidateSubFramebuffer(
@@ -4918,7 +5030,7 @@
 
 exit:
     if (attachments_base) {
-        _env->ReleasePrimitiveArrayCritical(attachments_ref, attachments_base,
+        _env->ReleaseIntArrayElements(attachments_ref, (jint*)attachments_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4930,14 +5042,14 @@
 static void
 android_glInvalidateSubFramebuffer__IILjava_nio_IntBuffer_2IIII
   (JNIEnv *_env, jobject _this, jint target, jint numAttachments, jobject attachments_buf, jint x, jint y, jint width, jint height) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLenum *attachments = (GLenum *) 0;
 
-    attachments = (GLenum *)getPointer(_env, attachments_buf, &_array, &_remaining, &_bufferOffset);
+    attachments = (GLenum *)getPointer(_env, attachments_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (attachments == NULL) {
-        char * _attachmentsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _attachmentsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         attachments = (GLenum *) (_attachmentsBase + _bufferOffset);
     }
     glInvalidateSubFramebuffer(
@@ -4950,7 +5062,7 @@
         (GLsizei)height
     );
     if (_array) {
-        releasePointer(_env, _array, attachments, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)attachments, JNI_ABORT);
     }
 }
 
@@ -5006,7 +5118,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetInternalformativ(
@@ -5019,7 +5131,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -5031,14 +5143,14 @@
 static void
 android_glGetInternalformativ__IIIILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint internalformat, jint pname, jint bufSize, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetInternalformativ(
@@ -5049,7 +5161,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
diff --git a/core/jni/android_opengl_GLES31.cpp b/core/jni/android_opengl_GLES31.cpp
index e5ea950..92ecbe0 100644
--- a/core/jni/android_opengl_GLES31.cpp
+++ b/core/jni/android_opengl_GLES31.cpp
@@ -124,6 +124,116 @@
     return NULL;
 }
 
+class ByteArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+        return _env->GetByteArrayElements(array, is_copy);
+    }
+};
+class BooleanArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+        return _env->GetBooleanArrayElements(array, is_copy);
+    }
+};
+class CharArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+        return _env->GetCharArrayElements(array, is_copy);
+    }
+};
+class ShortArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+        return _env->GetShortArrayElements(array, is_copy);
+    }
+};
+class IntArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+        return _env->GetIntArrayElements(array, is_copy);
+    }
+};
+class LongArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+        return _env->GetLongArrayElements(array, is_copy);
+    }
+};
+class FloatArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+        return _env->GetFloatArrayElements(array, is_copy);
+    }
+};
+class DoubleArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+        return _env->GetDoubleArrayElements(array, is_copy);
+    }
+};
+
+template<typename JTYPEARRAY, typename ARRAYGETTER>
+static void*
+getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
+    return ARRAYGETTER::Get(_env, array, is_copy);
+}
+
+class ByteArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
+        _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class BooleanArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
+        _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class CharArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
+        _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class ShortArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
+        _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class IntArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
+        _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class LongArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
+        _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class FloatArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
+        _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class DoubleArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
+        _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+
+template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
+static void
+releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
+    ARRAYRELEASER::Release(_env, array, data, commit);
+}
+
 static void
 releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
 {
@@ -227,7 +337,8 @@
     return needed;
 }
 
-template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+          typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
 static void
 get
   (JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -262,8 +373,8 @@
         _exceptionMessage = "length - offset < needed";
         goto exit;
     }
-    params_base = (CTYPE *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+    params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+        _env, params_ref, (jboolean *)0);
     params = params_base + offset;
 
     GET(
@@ -273,8 +384,8 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
-            _exception ? JNI_ABORT: 0);
+        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+            _env, params_ref, params_base, !_exception);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -282,20 +393,21 @@
 }
 
 
-template <typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+          typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
 static void
 getarray
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
     jint _exception = 0;
     const char * _exceptionType;
     const char * _exceptionMessage;
-    jarray _array = (jarray) 0;
+    JTYPEARRAY _array = (JTYPEARRAY) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     CTYPE *params = (CTYPE *) 0;
     int _needed = 0;
 
-    params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     _remaining /= sizeof(CTYPE);    // convert from bytes to item count
     _needed = getNeededCount(pname);
     // if we didn't find this pname, we just assume the user passed
@@ -308,7 +420,8 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+            _env, _array, (jboolean *) 0);
         params = (CTYPE *) (_paramsBase + _bufferOffset);
     }
     GET(
@@ -318,7 +431,8 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+            _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -410,7 +524,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetFramebufferParameteriv(
@@ -421,7 +535,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -433,14 +547,14 @@
 static void
 android_glGetFramebufferParameteriv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetFramebufferParameteriv(
@@ -449,7 +563,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -478,7 +592,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetProgramInterfaceiv(
@@ -490,7 +604,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -502,14 +616,14 @@
 static void
 android_glGetProgramInterfaceiv__IIILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint programInterface, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetProgramInterfaceiv(
@@ -519,7 +633,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -597,7 +711,7 @@
     }
     _propsRemaining = _env->GetArrayLength(props_ref) - propsOffset;
     props_base = (GLenum *)
-        _env->GetPrimitiveArrayCritical(props_ref, (jboolean *)0);
+        _env->GetIntArrayElements(props_ref, (jboolean *)0);
     props = props_base + propsOffset;
 
     if (!length_ref) {
@@ -614,7 +728,7 @@
     }
     _lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
     length_base = (GLsizei *)
-        _env->GetPrimitiveArrayCritical(length_ref, (jboolean *)0);
+        _env->GetIntArrayElements(length_ref, (jboolean *)0);
     length = length_base + lengthOffset;
 
     if (!params_ref) {
@@ -631,7 +745,7 @@
     }
     _paramsRemaining = _env->GetArrayLength(params_ref) - paramsOffset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + paramsOffset;
 
     glGetProgramResourceiv(
@@ -647,15 +761,15 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (length_base) {
-        _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
+        _env->ReleaseIntArrayElements(length_ref, (jint*)length_base,
             _exception ? JNI_ABORT: 0);
     }
     if (props_base) {
-        _env->ReleasePrimitiveArrayCritical(props_ref, props_base,
+        _env->ReleaseIntArrayElements(props_ref, (jint*)props_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -667,11 +781,11 @@
 static void
 android_glGetProgramResourceiv__IIIILjava_nio_IntBuffer_2ILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint programInterface, jint index, jint propCount, jobject props_buf, jint bufSize, jobject length_buf, jobject params_buf) {
-    jarray _propsArray = (jarray) 0;
+    jintArray _propsArray = (jintArray) 0;
     jint _propsBufferOffset = (jint) 0;
-    jarray _lengthArray = (jarray) 0;
+    jintArray _lengthArray = (jintArray) 0;
     jint _lengthBufferOffset = (jint) 0;
-    jarray _paramsArray = (jarray) 0;
+    jintArray _paramsArray = (jintArray) 0;
     jint _paramsBufferOffset = (jint) 0;
     jint _propsRemaining;
     GLenum *props = (GLenum *) 0;
@@ -680,19 +794,19 @@
     jint _paramsRemaining;
     GLint *params = (GLint *) 0;
 
-    props = (GLenum *)getPointer(_env, props_buf, &_propsArray, &_propsRemaining, &_propsBufferOffset);
-    length = (GLsizei *)getPointer(_env, length_buf, &_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
-    params = (GLint *)getPointer(_env, params_buf, &_paramsArray, &_paramsRemaining, &_paramsBufferOffset);
+    props = (GLenum *)getPointer(_env, props_buf, (jarray*)&_propsArray, &_propsRemaining, &_propsBufferOffset);
+    length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_paramsArray, &_paramsRemaining, &_paramsBufferOffset);
     if (props == NULL) {
-        char * _propsBase = (char *)_env->GetPrimitiveArrayCritical(_propsArray, (jboolean *) 0);
+        char * _propsBase = (char *)_env->GetIntArrayElements(_propsArray, (jboolean *) 0);
         props = (GLenum *) (_propsBase + _propsBufferOffset);
     }
     if (length == NULL) {
-        char * _lengthBase = (char *)_env->GetPrimitiveArrayCritical(_lengthArray, (jboolean *) 0);
+        char * _lengthBase = (char *)_env->GetIntArrayElements(_lengthArray, (jboolean *) 0);
         length = (GLsizei *) (_lengthBase + _lengthBufferOffset);
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_paramsArray, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_paramsArray, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _paramsBufferOffset);
     }
     glGetProgramResourceiv(
@@ -706,13 +820,13 @@
         (GLint *)params
     );
     if (_paramsArray) {
-        releasePointer(_env, _paramsArray, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_paramsArray, (jint*)params, 0);
     }
     if (_lengthArray) {
-        releasePointer(_env, _lengthArray, length, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_lengthArray, (jint*)length, 0);
     }
     if (_propsArray) {
-        releasePointer(_env, _propsArray, props, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_propsArray, (jint*)props, JNI_ABORT);
     }
 }
 
@@ -814,7 +928,7 @@
     }
     _remaining = _env->GetArrayLength(pipelines_ref) - offset;
     pipelines_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(pipelines_ref, (jboolean *)0);
+        _env->GetIntArrayElements(pipelines_ref, (jboolean *)0);
     pipelines = pipelines_base + offset;
 
     glDeleteProgramPipelines(
@@ -824,7 +938,7 @@
 
 exit:
     if (pipelines_base) {
-        _env->ReleasePrimitiveArrayCritical(pipelines_ref, pipelines_base,
+        _env->ReleaseIntArrayElements(pipelines_ref, (jint*)pipelines_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -836,14 +950,14 @@
 static void
 android_glDeleteProgramPipelines__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject pipelines_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *pipelines = (GLuint *) 0;
 
-    pipelines = (GLuint *)getPointer(_env, pipelines_buf, &_array, &_remaining, &_bufferOffset);
+    pipelines = (GLuint *)getPointer(_env, pipelines_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (pipelines == NULL) {
-        char * _pipelinesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _pipelinesBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         pipelines = (GLuint *) (_pipelinesBase + _bufferOffset);
     }
     glDeleteProgramPipelines(
@@ -851,7 +965,7 @@
         (GLuint *)pipelines
     );
     if (_array) {
-        releasePointer(_env, _array, pipelines, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)pipelines, JNI_ABORT);
     }
 }
 
@@ -880,7 +994,7 @@
     }
     _remaining = _env->GetArrayLength(pipelines_ref) - offset;
     pipelines_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(pipelines_ref, (jboolean *)0);
+        _env->GetIntArrayElements(pipelines_ref, (jboolean *)0);
     pipelines = pipelines_base + offset;
 
     glGenProgramPipelines(
@@ -890,7 +1004,7 @@
 
 exit:
     if (pipelines_base) {
-        _env->ReleasePrimitiveArrayCritical(pipelines_ref, pipelines_base,
+        _env->ReleaseIntArrayElements(pipelines_ref, (jint*)pipelines_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -902,14 +1016,14 @@
 static void
 android_glGenProgramPipelines__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint n, jobject pipelines_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *pipelines = (GLuint *) 0;
 
-    pipelines = (GLuint *)getPointer(_env, pipelines_buf, &_array, &_remaining, &_bufferOffset);
+    pipelines = (GLuint *)getPointer(_env, pipelines_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (pipelines == NULL) {
-        char * _pipelinesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _pipelinesBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         pipelines = (GLuint *) (_pipelinesBase + _bufferOffset);
     }
     glGenProgramPipelines(
@@ -917,7 +1031,7 @@
         (GLuint *)pipelines
     );
     if (_array) {
-        releasePointer(_env, _array, pipelines, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)pipelines, 0);
     }
 }
 
@@ -957,7 +1071,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetProgramPipelineiv(
@@ -968,7 +1082,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -980,14 +1094,14 @@
 static void
 android_glGetProgramPipelineiv__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pipeline, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetProgramPipelineiv(
@@ -996,7 +1110,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -1175,7 +1289,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniform1iv(
@@ -1187,7 +1301,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1199,14 +1313,14 @@
 static void
 android_glProgramUniform1iv__IIILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *value = (GLint *) 0;
 
-    value = (GLint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         value = (GLint *) (_valueBase + _bufferOffset);
     }
     glProgramUniform1iv(
@@ -1216,7 +1330,7 @@
         (GLint *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
     }
 }
 
@@ -1245,7 +1359,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniform2iv(
@@ -1257,7 +1371,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1269,14 +1383,14 @@
 static void
 android_glProgramUniform2iv__IIILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *value = (GLint *) 0;
 
-    value = (GLint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         value = (GLint *) (_valueBase + _bufferOffset);
     }
     glProgramUniform2iv(
@@ -1286,7 +1400,7 @@
         (GLint *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
     }
 }
 
@@ -1315,7 +1429,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniform3iv(
@@ -1327,7 +1441,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1339,14 +1453,14 @@
 static void
 android_glProgramUniform3iv__IIILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *value = (GLint *) 0;
 
-    value = (GLint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         value = (GLint *) (_valueBase + _bufferOffset);
     }
     glProgramUniform3iv(
@@ -1356,7 +1470,7 @@
         (GLint *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
     }
 }
 
@@ -1385,7 +1499,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniform4iv(
@@ -1397,7 +1511,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1409,14 +1523,14 @@
 static void
 android_glProgramUniform4iv__IIILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *value = (GLint *) 0;
 
-    value = (GLint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         value = (GLint *) (_valueBase + _bufferOffset);
     }
     glProgramUniform4iv(
@@ -1426,7 +1540,7 @@
         (GLint *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
     }
 }
 
@@ -1455,7 +1569,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniform1uiv(
@@ -1467,7 +1581,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1479,14 +1593,14 @@
 static void
 android_glProgramUniform1uiv__IIILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *value = (GLuint *) 0;
 
-    value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         value = (GLuint *) (_valueBase + _bufferOffset);
     }
     glProgramUniform1uiv(
@@ -1496,7 +1610,7 @@
         (GLuint *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
     }
 }
 
@@ -1525,7 +1639,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniform2uiv(
@@ -1537,7 +1651,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1549,14 +1663,14 @@
 static void
 android_glProgramUniform2uiv__IIILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *value = (GLuint *) 0;
 
-    value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         value = (GLuint *) (_valueBase + _bufferOffset);
     }
     glProgramUniform2uiv(
@@ -1566,7 +1680,7 @@
         (GLuint *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
     }
 }
 
@@ -1595,7 +1709,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniform3uiv(
@@ -1607,7 +1721,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1619,14 +1733,14 @@
 static void
 android_glProgramUniform3uiv__IIILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *value = (GLuint *) 0;
 
-    value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         value = (GLuint *) (_valueBase + _bufferOffset);
     }
     glProgramUniform3uiv(
@@ -1636,7 +1750,7 @@
         (GLuint *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
     }
 }
 
@@ -1665,7 +1779,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetIntArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniform4uiv(
@@ -1677,7 +1791,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1689,14 +1803,14 @@
 static void
 android_glProgramUniform4uiv__IIILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *value = (GLuint *) 0;
 
-    value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         value = (GLuint *) (_valueBase + _bufferOffset);
     }
     glProgramUniform4uiv(
@@ -1706,7 +1820,7 @@
         (GLuint *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
     }
 }
 
@@ -1735,7 +1849,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniform1fv(
@@ -1747,7 +1861,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1759,14 +1873,14 @@
 static void
 android_glProgramUniform1fv__IIILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glProgramUniform1fv(
@@ -1776,7 +1890,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -1805,7 +1919,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniform2fv(
@@ -1817,7 +1931,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1829,14 +1943,14 @@
 static void
 android_glProgramUniform2fv__IIILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glProgramUniform2fv(
@@ -1846,7 +1960,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -1875,7 +1989,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniform3fv(
@@ -1887,7 +2001,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1899,14 +2013,14 @@
 static void
 android_glProgramUniform3fv__IIILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glProgramUniform3fv(
@@ -1916,7 +2030,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -1945,7 +2059,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniform4fv(
@@ -1957,7 +2071,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1969,14 +2083,14 @@
 static void
 android_glProgramUniform4fv__IIILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glProgramUniform4fv(
@@ -1986,7 +2100,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -2015,7 +2129,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniformMatrix2fv(
@@ -2028,7 +2142,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2040,14 +2154,14 @@
 static void
 android_glProgramUniformMatrix2fv__IIIZLjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glProgramUniformMatrix2fv(
@@ -2058,7 +2172,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -2087,7 +2201,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniformMatrix3fv(
@@ -2100,7 +2214,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2112,14 +2226,14 @@
 static void
 android_glProgramUniformMatrix3fv__IIIZLjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glProgramUniformMatrix3fv(
@@ -2130,7 +2244,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -2159,7 +2273,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniformMatrix4fv(
@@ -2172,7 +2286,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2184,14 +2298,14 @@
 static void
 android_glProgramUniformMatrix4fv__IIIZLjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glProgramUniformMatrix4fv(
@@ -2202,7 +2316,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -2231,7 +2345,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniformMatrix2x3fv(
@@ -2244,7 +2358,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2256,14 +2370,14 @@
 static void
 android_glProgramUniformMatrix2x3fv__IIIZLjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glProgramUniformMatrix2x3fv(
@@ -2274,7 +2388,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -2303,7 +2417,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniformMatrix3x2fv(
@@ -2316,7 +2430,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2328,14 +2442,14 @@
 static void
 android_glProgramUniformMatrix3x2fv__IIIZLjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glProgramUniformMatrix3x2fv(
@@ -2346,7 +2460,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -2375,7 +2489,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniformMatrix2x4fv(
@@ -2388,7 +2502,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2400,14 +2514,14 @@
 static void
 android_glProgramUniformMatrix2x4fv__IIIZLjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glProgramUniformMatrix2x4fv(
@@ -2418,7 +2532,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -2447,7 +2561,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniformMatrix4x2fv(
@@ -2460,7 +2574,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2472,14 +2586,14 @@
 static void
 android_glProgramUniformMatrix4x2fv__IIIZLjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glProgramUniformMatrix4x2fv(
@@ -2490,7 +2604,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -2519,7 +2633,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniformMatrix3x4fv(
@@ -2532,7 +2646,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2544,14 +2658,14 @@
 static void
 android_glProgramUniformMatrix3x4fv__IIIZLjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glProgramUniformMatrix3x4fv(
@@ -2562,7 +2676,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -2591,7 +2705,7 @@
     }
     _remaining = _env->GetArrayLength(value_ref) - offset;
     value_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(value_ref, (jboolean *)0);
     value = value_base + offset;
 
     glProgramUniformMatrix4x3fv(
@@ -2604,7 +2718,7 @@
 
 exit:
     if (value_base) {
-        _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+        _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2616,14 +2730,14 @@
 static void
 android_glProgramUniformMatrix4x3fv__IIIZLjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *value = (GLfloat *) 0;
 
-    value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+    value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (value == NULL) {
-        char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         value = (GLfloat *) (_valueBase + _bufferOffset);
     }
     glProgramUniformMatrix4x3fv(
@@ -2634,7 +2748,7 @@
         (GLfloat *)value
     );
     if (_array) {
-        releasePointer(_env, _array, value, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
     }
 }
 
@@ -2706,7 +2820,7 @@
     }
     _remaining = _env->GetArrayLength(data_ref) - offset;
     data_base = (GLboolean *)
-        _env->GetPrimitiveArrayCritical(data_ref, (jboolean *)0);
+        _env->GetBooleanArrayElements(data_ref, (jboolean *)0);
     data = data_base + offset;
 
     glGetBooleani_v(
@@ -2717,7 +2831,7 @@
 
 exit:
     if (data_base) {
-        _env->ReleasePrimitiveArrayCritical(data_ref, data_base,
+        _env->ReleaseBooleanArrayElements(data_ref, (jboolean*)data_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2729,14 +2843,14 @@
 static void
 android_glGetBooleani_v__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint index, jobject data_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLboolean *data = (GLboolean *) 0;
 
-    data = (GLboolean *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+    data = (GLboolean *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (data == NULL) {
-        char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _dataBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         data = (GLboolean *) (_dataBase + _bufferOffset);
     }
     glGetBooleani_v(
@@ -2745,7 +2859,7 @@
         (GLboolean *)data
     );
     if (_array) {
-        releasePointer(_env, _array, data, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)data, 0);
     }
 }
 
@@ -2806,7 +2920,7 @@
     }
     _remaining = _env->GetArrayLength(val_ref) - offset;
     val_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(val_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(val_ref, (jboolean *)0);
     val = val_base + offset;
 
     glGetMultisamplefv(
@@ -2817,7 +2931,7 @@
 
 exit:
     if (val_base) {
-        _env->ReleasePrimitiveArrayCritical(val_ref, val_base,
+        _env->ReleaseFloatArrayElements(val_ref, (jfloat*)val_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2829,14 +2943,14 @@
 static void
 android_glGetMultisamplefv__IILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jint index, jobject val_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *val = (GLfloat *) 0;
 
-    val = (GLfloat *)getPointer(_env, val_buf, &_array, &_remaining, &_bufferOffset);
+    val = (GLfloat *)getPointer(_env, val_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (val == NULL) {
-        char * _valBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _valBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         val = (GLfloat *) (_valBase + _bufferOffset);
     }
     glGetMultisamplefv(
@@ -2845,7 +2959,7 @@
         (GLfloat *)val
     );
     if (_array) {
-        releasePointer(_env, _array, val, JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)val, 0);
     }
 }
 
@@ -2884,7 +2998,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexLevelParameteriv(
@@ -2896,7 +3010,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2908,14 +3022,14 @@
 static void
 android_glGetTexLevelParameteriv__IIILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint level, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetTexLevelParameteriv(
@@ -2925,7 +3039,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -2954,7 +3068,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexLevelParameterfv(
@@ -2966,7 +3080,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -2978,14 +3092,14 @@
 static void
 android_glGetTexLevelParameterfv__IIILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint level, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glGetTexLevelParameterfv(
@@ -2995,7 +3109,7 @@
         (GLfloat *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, 0);
     }
 }
 
diff --git a/core/jni/android_opengl_GLES31Ext.cpp b/core/jni/android_opengl_GLES31Ext.cpp
index 7317e9f..2856308 100644
--- a/core/jni/android_opengl_GLES31Ext.cpp
+++ b/core/jni/android_opengl_GLES31Ext.cpp
@@ -125,6 +125,116 @@
     return NULL;
 }
 
+class ByteArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+        return _env->GetByteArrayElements(array, is_copy);
+    }
+};
+class BooleanArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+        return _env->GetBooleanArrayElements(array, is_copy);
+    }
+};
+class CharArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+        return _env->GetCharArrayElements(array, is_copy);
+    }
+};
+class ShortArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+        return _env->GetShortArrayElements(array, is_copy);
+    }
+};
+class IntArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+        return _env->GetIntArrayElements(array, is_copy);
+    }
+};
+class LongArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+        return _env->GetLongArrayElements(array, is_copy);
+    }
+};
+class FloatArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+        return _env->GetFloatArrayElements(array, is_copy);
+    }
+};
+class DoubleArrayGetter {
+public:
+    static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+        return _env->GetDoubleArrayElements(array, is_copy);
+    }
+};
+
+template<typename JTYPEARRAY, typename ARRAYGETTER>
+static void*
+getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
+    return ARRAYGETTER::Get(_env, array, is_copy);
+}
+
+class ByteArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
+        _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class BooleanArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
+        _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class CharArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
+        _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class ShortArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
+        _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class IntArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
+        _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class LongArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
+        _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class FloatArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
+        _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+class DoubleArrayReleaser {
+public:
+    static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
+        _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
+    }
+};
+
+template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
+static void
+releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
+    ARRAYRELEASER::Release(_env, array, data, commit);
+}
+
 static void
 releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
 {
@@ -228,7 +338,8 @@
     return needed;
 }
 
-template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+          typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
 static void
 get
   (JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -263,8 +374,8 @@
         _exceptionMessage = "length - offset < needed";
         goto exit;
     }
-    params_base = (CTYPE *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+    params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+        _env, params_ref, (jboolean *)0);
     params = params_base + offset;
 
     GET(
@@ -274,8 +385,8 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
-            _exception ? JNI_ABORT: 0);
+        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+            _env, params_ref, params_base, !_exception);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -283,20 +394,21 @@
 }
 
 
-template <typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+          typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
 static void
 getarray
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
     jint _exception = 0;
     const char * _exceptionType;
     const char * _exceptionMessage;
-    jarray _array = (jarray) 0;
+    JTYPEARRAY _array = (JTYPEARRAY) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     CTYPE *params = (CTYPE *) 0;
     int _needed = 0;
 
-    params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     _remaining /= sizeof(CTYPE);    // convert from bytes to item count
     _needed = getNeededCount(pname);
     // if we didn't find this pname, we just assume the user passed
@@ -309,7 +421,8 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+            _env, _array, (jboolean *) 0);
         params = (CTYPE *) (_paramsBase + _bufferOffset);
     }
     GET(
@@ -319,7 +432,8 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+            _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -359,7 +473,7 @@
     }
     _remaining = _env->GetArrayLength(ids_ref) - offset;
     ids_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(ids_ref, (jboolean *)0);
+        _env->GetIntArrayElements(ids_ref, (jboolean *)0);
     ids = ids_base + offset;
 
     glDebugMessageControlKHR(
@@ -373,7 +487,7 @@
 
 exit:
     if (ids_base) {
-        _env->ReleasePrimitiveArrayCritical(ids_ref, ids_base,
+        _env->ReleaseIntArrayElements(ids_ref, (jint*)ids_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -385,14 +499,14 @@
 static void
 android_glDebugMessageControlKHR__IIIILjava_nio_IntBuffer_2Z
   (JNIEnv *_env, jobject _this, jint source, jint type, jint severity, jint count, jobject ids_buf, jboolean enabled) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *ids = (GLuint *) 0;
 
-    ids = (GLuint *)getPointer(_env, ids_buf, &_array, &_remaining, &_bufferOffset);
+    ids = (GLuint *)getPointer(_env, ids_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (ids == NULL) {
-        char * _idsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _idsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         ids = (GLuint *) (_idsBase + _bufferOffset);
     }
     glDebugMessageControlKHR(
@@ -404,7 +518,7 @@
         (GLboolean)enabled
     );
     if (_array) {
-        releasePointer(_env, _array, ids, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)ids, JNI_ABORT);
     }
 }
 
@@ -784,7 +898,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexParameterIivEXT(
@@ -795,7 +909,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -807,14 +921,14 @@
 static void
 android_glTexParameterIivEXT__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glTexParameterIivEXT(
@@ -823,7 +937,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
 }
 
@@ -852,7 +966,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexParameterIuivEXT(
@@ -863,7 +977,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -875,14 +989,14 @@
 static void
 android_glTexParameterIuivEXT__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *params = (GLuint *) 0;
 
-    params = (GLuint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLuint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLuint *) (_paramsBase + _bufferOffset);
     }
     glTexParameterIuivEXT(
@@ -891,7 +1005,7 @@
         (GLuint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
 }
 
@@ -920,7 +1034,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexParameterIivEXT(
@@ -931,7 +1045,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -943,14 +1057,14 @@
 static void
 android_glGetTexParameterIivEXT__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetTexParameterIivEXT(
@@ -959,7 +1073,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -988,7 +1102,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexParameterIuivEXT(
@@ -999,7 +1113,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1011,14 +1125,14 @@
 static void
 android_glGetTexParameterIuivEXT__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *params = (GLuint *) 0;
 
-    params = (GLuint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLuint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLuint *) (_paramsBase + _bufferOffset);
     }
     glGetTexParameterIuivEXT(
@@ -1027,7 +1141,7 @@
         (GLuint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -1056,7 +1170,7 @@
     }
     _remaining = _env->GetArrayLength(param_ref) - offset;
     param_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(param_ref, (jboolean *)0);
+        _env->GetIntArrayElements(param_ref, (jboolean *)0);
     param = param_base + offset;
 
     glSamplerParameterIivEXT(
@@ -1067,7 +1181,7 @@
 
 exit:
     if (param_base) {
-        _env->ReleasePrimitiveArrayCritical(param_ref, param_base,
+        _env->ReleaseIntArrayElements(param_ref, (jint*)param_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1079,14 +1193,14 @@
 static void
 android_glSamplerParameterIivEXT__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint sampler, jint pname, jobject param_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *param = (GLint *) 0;
 
-    param = (GLint *)getPointer(_env, param_buf, &_array, &_remaining, &_bufferOffset);
+    param = (GLint *)getPointer(_env, param_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (param == NULL) {
-        char * _paramBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         param = (GLint *) (_paramBase + _bufferOffset);
     }
     glSamplerParameterIivEXT(
@@ -1095,7 +1209,7 @@
         (GLint *)param
     );
     if (_array) {
-        releasePointer(_env, _array, param, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)param, JNI_ABORT);
     }
 }
 
@@ -1124,7 +1238,7 @@
     }
     _remaining = _env->GetArrayLength(param_ref) - offset;
     param_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(param_ref, (jboolean *)0);
+        _env->GetIntArrayElements(param_ref, (jboolean *)0);
     param = param_base + offset;
 
     glSamplerParameterIuivEXT(
@@ -1135,7 +1249,7 @@
 
 exit:
     if (param_base) {
-        _env->ReleasePrimitiveArrayCritical(param_ref, param_base,
+        _env->ReleaseIntArrayElements(param_ref, (jint*)param_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1147,14 +1261,14 @@
 static void
 android_glSamplerParameterIuivEXT__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint sampler, jint pname, jobject param_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *param = (GLuint *) 0;
 
-    param = (GLuint *)getPointer(_env, param_buf, &_array, &_remaining, &_bufferOffset);
+    param = (GLuint *)getPointer(_env, param_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (param == NULL) {
-        char * _paramBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         param = (GLuint *) (_paramBase + _bufferOffset);
     }
     glSamplerParameterIuivEXT(
@@ -1163,7 +1277,7 @@
         (GLuint *)param
     );
     if (_array) {
-        releasePointer(_env, _array, param, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)param, JNI_ABORT);
     }
 }
 
@@ -1192,7 +1306,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetSamplerParameterIivEXT(
@@ -1203,7 +1317,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1215,14 +1329,14 @@
 static void
 android_glGetSamplerParameterIivEXT__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint sampler, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetSamplerParameterIivEXT(
@@ -1231,7 +1345,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -1260,7 +1374,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetSamplerParameterIuivEXT(
@@ -1271,7 +1385,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1283,14 +1397,14 @@
 static void
 android_glGetSamplerParameterIuivEXT__IILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint sampler, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *params = (GLuint *) 0;
 
-    params = (GLuint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLuint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLuint *) (_paramsBase + _bufferOffset);
     }
     glGetSamplerParameterIuivEXT(
@@ -1299,7 +1413,7 @@
         (GLuint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp
index c5f330e..f15f957 100644
--- a/core/jni/com_google_android_gles_jni_GLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp
@@ -449,7 +449,7 @@
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
 
-    data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+    data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (data == NULL) {
         char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         data = (GLvoid *) (_dataBase + _bufferOffset);
@@ -478,7 +478,7 @@
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
 
-    data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+    data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (data == NULL) {
         char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         data = (GLvoid *) (_dataBase + _bufferOffset);
@@ -571,7 +571,7 @@
         goto exit;
     }
     textures_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(textures_ref, (jboolean *)0);
+        _env->GetIntArrayElements(textures_ref, (jboolean *)0);
     textures = textures_base + offset;
 
     glDeleteTextures(
@@ -581,7 +581,7 @@
 
 exit:
     if (textures_base) {
-        _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
+        _env->ReleaseIntArrayElements(textures_ref, (jint*)textures_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -596,12 +596,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
 
-    textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining, &_bufferOffset);
+    textures = (GLuint *)getPointer(_env, textures_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -609,7 +609,7 @@
         goto exit;
     }
     if (textures == NULL) {
-        char * _texturesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _texturesBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         textures = (GLuint *) (_texturesBase + _bufferOffset);
     }
     glDeleteTextures(
@@ -619,7 +619,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, textures, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)textures, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -705,7 +705,7 @@
     jint _remaining;
     GLvoid *indices = (GLvoid *) 0;
 
-    indices = (GLvoid *)getPointer(_env, indices_buf, &_array, &_remaining, &_bufferOffset);
+    indices = (GLvoid *)getPointer(_env, indices_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < count) {
         _exception = 1;
         _exceptionType = "java/lang/ArrayIndexOutOfBoundsException";
@@ -830,7 +830,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glFogfv(
@@ -840,7 +840,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -855,12 +855,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_FOG_MODE)
@@ -893,7 +893,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glFogfv(
@@ -903,7 +903,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -976,7 +976,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glFogxv(
@@ -986,7 +986,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -1001,12 +1001,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_FOG_MODE)
@@ -1039,7 +1039,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glFogxv(
@@ -1049,7 +1049,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1124,7 +1124,7 @@
         goto exit;
     }
     textures_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(textures_ref, (jboolean *)0);
+        _env->GetIntArrayElements(textures_ref, (jboolean *)0);
     textures = textures_base + offset;
 
     glGenTextures(
@@ -1134,7 +1134,7 @@
 
 exit:
     if (textures_base) {
-        _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
+        _env->ReleaseIntArrayElements(textures_ref, (jint*)textures_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1149,12 +1149,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *textures = (GLuint *) 0;
 
-    textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining, &_bufferOffset);
+    textures = (GLuint *)getPointer(_env, textures_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -1162,7 +1162,7 @@
         goto exit;
     }
     if (textures == NULL) {
-        char * _texturesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _texturesBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         textures = (GLuint *) (_texturesBase + _bufferOffset);
     }
     glGenTextures(
@@ -1172,7 +1172,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, textures, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)textures, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1550,7 +1550,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetIntegerv(
@@ -1560,7 +1560,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -1575,12 +1575,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_ALPHA_BITS)
@@ -1919,7 +1919,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetIntegerv(
@@ -1929,7 +1929,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2008,7 +2008,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glLightModelfv(
@@ -2018,7 +2018,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2033,12 +2033,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_LIGHT_MODEL_TWO_SIDE)
@@ -2062,7 +2062,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glLightModelfv(
@@ -2072,7 +2072,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2136,7 +2136,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glLightModelxv(
@@ -2146,7 +2146,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2161,12 +2161,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_LIGHT_MODEL_TWO_SIDE)
@@ -2190,7 +2190,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glLightModelxv(
@@ -2200,7 +2200,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2291,7 +2291,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glLightfv(
@@ -2302,7 +2302,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2317,12 +2317,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_SPOT_EXPONENT)
@@ -2372,7 +2372,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glLightfv(
@@ -2383,7 +2383,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2474,7 +2474,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glLightxv(
@@ -2485,7 +2485,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2500,12 +2500,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_SPOT_EXPONENT)
@@ -2555,7 +2555,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glLightxv(
@@ -2566,7 +2566,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2623,7 +2623,7 @@
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
     m_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(m_ref, (jboolean *)0);
     m = m_base + offset;
 
     glLoadMatrixf(
@@ -2632,7 +2632,7 @@
 
 exit:
     if (m_base) {
-        _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+        _env->ReleaseFloatArrayElements(m_ref, (jfloat*)m_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2644,21 +2644,21 @@
 static void
 android_glLoadMatrixf__Ljava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jobject m_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *m = (GLfloat *) 0;
 
-    m = (GLfloat *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+    m = (GLfloat *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (m == NULL) {
-        char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _mBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         m = (GLfloat *) (_mBase + _bufferOffset);
     }
     glLoadMatrixf(
         (GLfloat *)m
     );
     if (_array) {
-        releasePointer(_env, _array, m, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)m, JNI_ABORT);
     }
 }
 
@@ -2687,7 +2687,7 @@
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
     m_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+        _env->GetIntArrayElements(m_ref, (jboolean *)0);
     m = m_base + offset;
 
     glLoadMatrixx(
@@ -2696,7 +2696,7 @@
 
 exit:
     if (m_base) {
-        _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+        _env->ReleaseIntArrayElements(m_ref, (jint*)m_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2708,21 +2708,21 @@
 static void
 android_glLoadMatrixx__Ljava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jobject m_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *m = (GLfixed *) 0;
 
-    m = (GLfixed *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+    m = (GLfixed *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (m == NULL) {
-        char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _mBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         m = (GLfixed *) (_mBase + _bufferOffset);
     }
     glLoadMatrixx(
         (GLfixed *)m
     );
     if (_array) {
-        releasePointer(_env, _array, m, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)m, JNI_ABORT);
     }
 }
 
@@ -2805,7 +2805,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glMaterialfv(
@@ -2816,7 +2816,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2831,12 +2831,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_SHININESS)
@@ -2872,7 +2872,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glMaterialfv(
@@ -2883,7 +2883,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2960,7 +2960,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glMaterialxv(
@@ -2971,7 +2971,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -2986,12 +2986,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_SHININESS)
@@ -3027,7 +3027,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glMaterialxv(
@@ -3038,7 +3038,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3079,7 +3079,7 @@
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
     m_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(m_ref, (jboolean *)0);
     m = m_base + offset;
 
     glMultMatrixf(
@@ -3088,7 +3088,7 @@
 
 exit:
     if (m_base) {
-        _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+        _env->ReleaseFloatArrayElements(m_ref, (jfloat*)m_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -3100,21 +3100,21 @@
 static void
 android_glMultMatrixf__Ljava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jobject m_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *m = (GLfloat *) 0;
 
-    m = (GLfloat *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+    m = (GLfloat *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (m == NULL) {
-        char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _mBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         m = (GLfloat *) (_mBase + _bufferOffset);
     }
     glMultMatrixf(
         (GLfloat *)m
     );
     if (_array) {
-        releasePointer(_env, _array, m, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)m, JNI_ABORT);
     }
 }
 
@@ -3143,7 +3143,7 @@
     }
     _remaining = _env->GetArrayLength(m_ref) - offset;
     m_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+        _env->GetIntArrayElements(m_ref, (jboolean *)0);
     m = m_base + offset;
 
     glMultMatrixx(
@@ -3152,7 +3152,7 @@
 
 exit:
     if (m_base) {
-        _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+        _env->ReleaseIntArrayElements(m_ref, (jint*)m_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -3164,21 +3164,21 @@
 static void
 android_glMultMatrixx__Ljava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jobject m_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *m = (GLfixed *) 0;
 
-    m = (GLfixed *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+    m = (GLfixed *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (m == NULL) {
-        char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _mBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         m = (GLfixed *) (_mBase + _bufferOffset);
     }
     glMultMatrixx(
         (GLfixed *)m
     );
     if (_array) {
-        releasePointer(_env, _array, m, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)m, JNI_ABORT);
     }
 }
 
@@ -3352,7 +3352,7 @@
     jint _remaining;
     GLvoid *pixels = (GLvoid *) 0;
 
-    pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+    pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (pixels == NULL) {
         char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
         pixels = (GLvoid *) (_pixelsBase + _bufferOffset);
@@ -3577,7 +3577,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexEnvfv(
@@ -3588,7 +3588,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -3603,12 +3603,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_TEXTURE_ENV_MODE)
@@ -3638,7 +3638,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glTexEnvfv(
@@ -3649,7 +3649,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3720,7 +3720,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexEnvxv(
@@ -3731,7 +3731,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -3746,12 +3746,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_TEXTURE_ENV_MODE)
@@ -3781,7 +3781,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glTexEnvxv(
@@ -3792,7 +3792,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3809,7 +3809,7 @@
     GLvoid *pixels = (GLvoid *) 0;
 
     if (pixels_buf) {
-        pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+        pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     }
     if (pixels_buf && pixels == NULL) {
         char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
@@ -3863,7 +3863,7 @@
     GLvoid *pixels = (GLvoid *) 0;
 
     if (pixels_buf) {
-        pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+        pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     }
     if (pixels_buf && pixels == NULL) {
         char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
@@ -3978,7 +3978,7 @@
         goto exit;
     }
     mantissa_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(mantissa_ref, (jboolean *)0);
+        _env->GetIntArrayElements(mantissa_ref, (jboolean *)0);
     mantissa = mantissa_base + mantissaOffset;
 
     if (!exponent_ref) {
@@ -4001,7 +4001,7 @@
         goto exit;
     }
     exponent_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(exponent_ref, (jboolean *)0);
+        _env->GetIntArrayElements(exponent_ref, (jboolean *)0);
     exponent = exponent_base + exponentOffset;
 
     _returnValue = glQueryMatrixxOES(
@@ -4011,11 +4011,11 @@
 
 exit:
     if (exponent_base) {
-        _env->ReleasePrimitiveArrayCritical(exponent_ref, exponent_base,
+        _env->ReleaseIntArrayElements(exponent_ref, (jint*)exponent_base,
             _exception ? JNI_ABORT: 0);
     }
     if (mantissa_base) {
-        _env->ReleasePrimitiveArrayCritical(mantissa_ref, mantissa_base,
+        _env->ReleaseIntArrayElements(mantissa_ref, (jint*)mantissa_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -4031,9 +4031,9 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _mantissaArray = (jarray) 0;
+    jintArray _mantissaArray = (jintArray) 0;
     jint _mantissaBufferOffset = (jint) 0;
-    jarray _exponentArray = (jarray) 0;
+    jintArray _exponentArray = (jintArray) 0;
     jint _exponentBufferOffset = (jint) 0;
     GLbitfield _returnValue = -1;
     jint _mantissaRemaining;
@@ -4041,14 +4041,14 @@
     jint _exponentRemaining;
     GLint *exponent = (GLint *) 0;
 
-    mantissa = (GLfixed *)getPointer(_env, mantissa_buf, &_mantissaArray, &_mantissaRemaining, &_mantissaBufferOffset);
+    mantissa = (GLfixed *)getPointer(_env, mantissa_buf, (jarray*)&_mantissaArray, &_mantissaRemaining, &_mantissaBufferOffset);
     if (_mantissaRemaining < 16) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
         _exceptionMessage = "remaining() < 16 < needed";
         goto exit;
     }
-    exponent = (GLint *)getPointer(_env, exponent_buf, &_exponentArray, &_exponentRemaining, &_exponentBufferOffset);
+    exponent = (GLint *)getPointer(_env, exponent_buf, (jarray*)&_exponentArray, &_exponentRemaining, &_exponentBufferOffset);
     if (_exponentRemaining < 16) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -4056,11 +4056,11 @@
         goto exit;
     }
     if (mantissa == NULL) {
-        char * _mantissaBase = (char *)_env->GetPrimitiveArrayCritical(_mantissaArray, (jboolean *) 0);
+        char * _mantissaBase = (char *)_env->GetIntArrayElements(_mantissaArray, (jboolean *) 0);
         mantissa = (GLfixed *) (_mantissaBase + _mantissaBufferOffset);
     }
     if (exponent == NULL) {
-        char * _exponentBase = (char *)_env->GetPrimitiveArrayCritical(_exponentArray, (jboolean *) 0);
+        char * _exponentBase = (char *)_env->GetIntArrayElements(_exponentArray, (jboolean *) 0);
         exponent = (GLint *) (_exponentBase + _exponentBufferOffset);
     }
     _returnValue = glQueryMatrixxOES(
@@ -4070,10 +4070,10 @@
 
 exit:
     if (_exponentArray) {
-        releasePointer(_env, _exponentArray, exponent, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_exponentArray, (jint*)exponent, _exception ? JNI_ABORT : 0);
     }
     if (_mantissaArray) {
-        releasePointer(_env, _mantissaArray, mantissa, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_mantissaArray, (jint*)mantissa, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4104,7 +4104,7 @@
     GLvoid *data = (GLvoid *) 0;
 
     if (data_buf) {
-        data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+        data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
         if (_remaining < size) {
             _exception = 1;
             _exceptionType = "java/lang/IllegalArgumentException";
@@ -4144,7 +4144,7 @@
     jint _remaining;
     GLvoid *data = (GLvoid *) 0;
 
-    data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+    data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < size) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -4202,7 +4202,7 @@
         goto exit;
     }
     equation_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(equation_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(equation_ref, (jboolean *)0);
     equation = equation_base + offset;
 
     glClipPlanef(
@@ -4212,7 +4212,7 @@
 
 exit:
     if (equation_base) {
-        _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
+        _env->ReleaseFloatArrayElements(equation_ref, (jfloat*)equation_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4227,12 +4227,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *equation = (GLfloat *) 0;
 
-    equation = (GLfloat *)getPointer(_env, equation_buf, &_array, &_remaining, &_bufferOffset);
+    equation = (GLfloat *)getPointer(_env, equation_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 4) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -4240,7 +4240,7 @@
         goto exit;
     }
     if (equation == NULL) {
-        char * _equationBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _equationBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         equation = (GLfloat *) (_equationBase + _bufferOffset);
     }
     glClipPlanef(
@@ -4250,7 +4250,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, equation, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)equation, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4288,7 +4288,7 @@
         goto exit;
     }
     equation_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(equation_ref, (jboolean *)0);
+        _env->GetIntArrayElements(equation_ref, (jboolean *)0);
     equation = equation_base + offset;
 
     glClipPlanex(
@@ -4298,7 +4298,7 @@
 
 exit:
     if (equation_base) {
-        _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
+        _env->ReleaseIntArrayElements(equation_ref, (jint*)equation_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4313,12 +4313,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *equation = (GLfixed *) 0;
 
-    equation = (GLfixed *)getPointer(_env, equation_buf, &_array, &_remaining, &_bufferOffset);
+    equation = (GLfixed *)getPointer(_env, equation_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 4) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -4326,7 +4326,7 @@
         goto exit;
     }
     if (equation == NULL) {
-        char * _equationBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _equationBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         equation = (GLfixed *) (_equationBase + _bufferOffset);
     }
     glClipPlanex(
@@ -4336,7 +4336,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, equation, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)equation, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4398,7 +4398,7 @@
         goto exit;
     }
     buffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(buffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(buffers_ref, (jboolean *)0);
     buffers = buffers_base + offset;
 
     glDeleteBuffers(
@@ -4408,7 +4408,7 @@
 
 exit:
     if (buffers_base) {
-        _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
+        _env->ReleaseIntArrayElements(buffers_ref, (jint*)buffers_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -4423,12 +4423,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
 
-    buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining, &_bufferOffset);
+    buffers = (GLuint *)getPointer(_env, buffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -4436,7 +4436,7 @@
         goto exit;
     }
     if (buffers == NULL) {
-        char * _buffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _buffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         buffers = (GLuint *) (_buffersBase + _bufferOffset);
     }
     glDeleteBuffers(
@@ -4446,7 +4446,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, buffers, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)buffers, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4502,7 +4502,7 @@
         goto exit;
     }
     buffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(buffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(buffers_ref, (jboolean *)0);
     buffers = buffers_base + offset;
 
     glGenBuffers(
@@ -4512,7 +4512,7 @@
 
 exit:
     if (buffers_base) {
-        _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
+        _env->ReleaseIntArrayElements(buffers_ref, (jint*)buffers_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -4527,12 +4527,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *buffers = (GLuint *) 0;
 
-    buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining, &_bufferOffset);
+    buffers = (GLuint *)getPointer(_env, buffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -4540,7 +4540,7 @@
         goto exit;
     }
     if (buffers == NULL) {
-        char * _buffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _buffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         buffers = (GLuint *) (_buffersBase + _bufferOffset);
     }
     glGenBuffers(
@@ -4550,7 +4550,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, buffers, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)buffers, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4582,7 +4582,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLboolean *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetBooleanArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetBooleanv(
@@ -4592,7 +4592,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseBooleanArrayElements(params_ref, (jboolean*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -4604,14 +4604,14 @@
 static void
 android_glGetBooleanv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLboolean *params = (GLboolean *) 0;
 
-    params = (GLboolean *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLboolean *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLboolean *) (_paramsBase + _bufferOffset);
     }
     glGetBooleanv(
@@ -4619,7 +4619,7 @@
         (GLboolean *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -4664,7 +4664,7 @@
     }
     _remaining = _env->GetArrayLength(eqn_ref) - offset;
     eqn_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(eqn_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(eqn_ref, (jboolean *)0);
     eqn = eqn_base + offset;
 
     glGetClipPlanef(
@@ -4674,7 +4674,7 @@
 
 exit:
     if (eqn_base) {
-        _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
+        _env->ReleaseFloatArrayElements(eqn_ref, (jfloat*)eqn_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -4686,14 +4686,14 @@
 static void
 android_glGetClipPlanef__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject eqn_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *eqn = (GLfloat *) 0;
 
-    eqn = (GLfloat *)getPointer(_env, eqn_buf, &_array, &_remaining, &_bufferOffset);
+    eqn = (GLfloat *)getPointer(_env, eqn_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (eqn == NULL) {
-        char * _eqnBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _eqnBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         eqn = (GLfloat *) (_eqnBase + _bufferOffset);
     }
     glGetClipPlanef(
@@ -4701,7 +4701,7 @@
         (GLfloat *)eqn
     );
     if (_array) {
-        releasePointer(_env, _array, eqn, JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)eqn, 0);
     }
 }
 
@@ -4730,7 +4730,7 @@
     }
     _remaining = _env->GetArrayLength(eqn_ref) - offset;
     eqn_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(eqn_ref, (jboolean *)0);
+        _env->GetIntArrayElements(eqn_ref, (jboolean *)0);
     eqn = eqn_base + offset;
 
     glGetClipPlanex(
@@ -4740,7 +4740,7 @@
 
 exit:
     if (eqn_base) {
-        _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
+        _env->ReleaseIntArrayElements(eqn_ref, (jint*)eqn_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -4752,14 +4752,14 @@
 static void
 android_glGetClipPlanex__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject eqn_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *eqn = (GLfixed *) 0;
 
-    eqn = (GLfixed *)getPointer(_env, eqn_buf, &_array, &_remaining, &_bufferOffset);
+    eqn = (GLfixed *)getPointer(_env, eqn_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (eqn == NULL) {
-        char * _eqnBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _eqnBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         eqn = (GLfixed *) (_eqnBase + _bufferOffset);
     }
     glGetClipPlanex(
@@ -4767,7 +4767,7 @@
         (GLfixed *)eqn
     );
     if (_array) {
-        releasePointer(_env, _array, eqn, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)eqn, 0);
     }
 }
 
@@ -4796,7 +4796,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetFixedv(
@@ -4806,7 +4806,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -4818,14 +4818,14 @@
 static void
 android_glGetFixedv__ILjava_nio_IntBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glGetFixedv(
@@ -4833,7 +4833,7 @@
         (GLfixed *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -4862,7 +4862,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetFloatv(
@@ -4872,7 +4872,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -4884,14 +4884,14 @@
 static void
 android_glGetFloatv__ILjava_nio_FloatBuffer_2
   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glGetFloatv(
@@ -4899,7 +4899,7 @@
         (GLfloat *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, 0);
     }
 }
 
@@ -4976,7 +4976,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetLightfv(
@@ -4987,7 +4987,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -5002,12 +5002,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_SPOT_EXPONENT)
@@ -5057,7 +5057,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glGetLightfv(
@@ -5068,7 +5068,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5148,7 +5148,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetLightxv(
@@ -5159,7 +5159,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -5174,12 +5174,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_SPOT_EXPONENT)
@@ -5229,7 +5229,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glGetLightxv(
@@ -5240,7 +5240,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5306,7 +5306,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetMaterialfv(
@@ -5317,7 +5317,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -5332,12 +5332,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_SHININESS)
@@ -5373,7 +5373,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glGetMaterialfv(
@@ -5384,7 +5384,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5450,7 +5450,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetMaterialxv(
@@ -5461,7 +5461,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -5476,12 +5476,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_SHININESS)
@@ -5517,7 +5517,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glGetMaterialxv(
@@ -5528,7 +5528,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5588,7 +5588,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexEnviv(
@@ -5599,7 +5599,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -5614,12 +5614,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_TEXTURE_ENV_MODE)
@@ -5649,7 +5649,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetTexEnviv(
@@ -5660,7 +5660,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5720,7 +5720,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexEnvxv(
@@ -5731,7 +5731,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -5746,12 +5746,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_TEXTURE_ENV_MODE)
@@ -5781,7 +5781,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glGetTexEnvxv(
@@ -5792,7 +5792,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5830,7 +5830,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexParameterfv(
@@ -5841,7 +5841,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -5856,12 +5856,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -5869,7 +5869,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glGetTexParameterfv(
@@ -5880,7 +5880,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5918,7 +5918,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexParameteriv(
@@ -5929,7 +5929,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -5944,12 +5944,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -5957,7 +5957,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetTexParameteriv(
@@ -5968,7 +5968,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6006,7 +6006,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexParameterxv(
@@ -6017,7 +6017,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -6032,12 +6032,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -6045,7 +6045,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glGetTexParameterxv(
@@ -6056,7 +6056,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6148,7 +6148,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glPointParameterfv(
@@ -6158,7 +6158,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -6173,12 +6173,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -6186,7 +6186,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glPointParameterfv(
@@ -6196,7 +6196,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6244,7 +6244,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glPointParameterxv(
@@ -6254,7 +6254,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -6269,12 +6269,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -6282,7 +6282,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glPointParameterxv(
@@ -6292,7 +6292,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6398,7 +6398,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexEnviv(
@@ -6409,7 +6409,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -6424,12 +6424,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     int _needed;
     switch (pname) {
 #if defined(GL_TEXTURE_ENV_MODE)
@@ -6459,7 +6459,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glTexEnviv(
@@ -6470,7 +6470,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6508,7 +6508,7 @@
         goto exit;
     }
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexParameterfv(
@@ -6519,7 +6519,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -6534,12 +6534,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -6547,7 +6547,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glTexParameterfv(
@@ -6558,7 +6558,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6607,7 +6607,7 @@
         goto exit;
     }
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexParameteriv(
@@ -6618,7 +6618,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -6633,12 +6633,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -6646,7 +6646,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glTexParameteriv(
@@ -6657,7 +6657,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6695,7 +6695,7 @@
         goto exit;
     }
     params_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexParameterxv(
@@ -6706,7 +6706,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -6721,12 +6721,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *params = (GLfixed *) 0;
 
-    params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 1) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -6734,7 +6734,7 @@
         goto exit;
     }
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLfixed *) (_paramsBase + _bufferOffset);
     }
     glTexParameterxv(
@@ -6745,7 +6745,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, params, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6817,7 +6817,7 @@
         goto exit;
     }
     coords_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(coords_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(coords_ref, (jboolean *)0);
     coords = coords_base + offset;
 
     glDrawTexfvOES(
@@ -6826,7 +6826,7 @@
 
 exit:
     if (coords_base) {
-        _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
+        _env->ReleaseFloatArrayElements(coords_ref, (jfloat*)coords_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -6841,12 +6841,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *coords = (GLfloat *) 0;
 
-    coords = (GLfloat *)getPointer(_env, coords_buf, &_array, &_remaining, &_bufferOffset);
+    coords = (GLfloat *)getPointer(_env, coords_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 5) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -6854,7 +6854,7 @@
         goto exit;
     }
     if (coords == NULL) {
-        char * _coordsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _coordsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         coords = (GLfloat *) (_coordsBase + _bufferOffset);
     }
     glDrawTexfvOES(
@@ -6863,7 +6863,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, coords, JNI_FALSE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)coords, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6914,7 +6914,7 @@
         goto exit;
     }
     coords_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(coords_ref, (jboolean *)0);
+        _env->GetIntArrayElements(coords_ref, (jboolean *)0);
     coords = coords_base + offset;
 
     glDrawTexivOES(
@@ -6923,7 +6923,7 @@
 
 exit:
     if (coords_base) {
-        _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
+        _env->ReleaseIntArrayElements(coords_ref, (jint*)coords_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -6938,12 +6938,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *coords = (GLint *) 0;
 
-    coords = (GLint *)getPointer(_env, coords_buf, &_array, &_remaining, &_bufferOffset);
+    coords = (GLint *)getPointer(_env, coords_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 5) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -6951,7 +6951,7 @@
         goto exit;
     }
     if (coords == NULL) {
-        char * _coordsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _coordsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         coords = (GLint *) (_coordsBase + _bufferOffset);
     }
     glDrawTexivOES(
@@ -6960,7 +6960,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, coords, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)coords, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -7011,7 +7011,7 @@
         goto exit;
     }
     coords_base = (GLshort *)
-        _env->GetPrimitiveArrayCritical(coords_ref, (jboolean *)0);
+        _env->GetShortArrayElements(coords_ref, (jboolean *)0);
     coords = coords_base + offset;
 
     glDrawTexsvOES(
@@ -7020,7 +7020,7 @@
 
 exit:
     if (coords_base) {
-        _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
+        _env->ReleaseShortArrayElements(coords_ref, (jshort*)coords_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -7035,12 +7035,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jshortArray _array = (jshortArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLshort *coords = (GLshort *) 0;
 
-    coords = (GLshort *)getPointer(_env, coords_buf, &_array, &_remaining, &_bufferOffset);
+    coords = (GLshort *)getPointer(_env, coords_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 5) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -7048,7 +7048,7 @@
         goto exit;
     }
     if (coords == NULL) {
-        char * _coordsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _coordsBase = (char *)_env->GetShortArrayElements(_array, (jboolean *) 0);
         coords = (GLshort *) (_coordsBase + _bufferOffset);
     }
     glDrawTexsvOES(
@@ -7057,7 +7057,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, coords, JNI_FALSE);
+        _env->ReleaseShortArrayElements(_array, (jshort*)coords, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -7108,7 +7108,7 @@
         goto exit;
     }
     coords_base = (GLfixed *)
-        _env->GetPrimitiveArrayCritical(coords_ref, (jboolean *)0);
+        _env->GetIntArrayElements(coords_ref, (jboolean *)0);
     coords = coords_base + offset;
 
     glDrawTexxvOES(
@@ -7117,7 +7117,7 @@
 
 exit:
     if (coords_base) {
-        _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
+        _env->ReleaseIntArrayElements(coords_ref, (jint*)coords_base,
             JNI_ABORT);
     }
     if (_exception) {
@@ -7132,12 +7132,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfixed *coords = (GLfixed *) 0;
 
-    coords = (GLfixed *)getPointer(_env, coords_buf, &_array, &_remaining, &_bufferOffset);
+    coords = (GLfixed *)getPointer(_env, coords_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < 5) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -7145,7 +7145,7 @@
         goto exit;
     }
     if (coords == NULL) {
-        char * _coordsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _coordsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         coords = (GLfixed *) (_coordsBase + _bufferOffset);
     }
     glDrawTexxvOES(
@@ -7154,7 +7154,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, coords, JNI_FALSE);
+        _env->ReleaseIntArrayElements(_array, (jint*)coords, JNI_ABORT);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -7368,7 +7368,7 @@
         goto exit;
     }
     framebuffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(framebuffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(framebuffers_ref, (jboolean *)0);
     framebuffers = framebuffers_base + offset;
 
     glDeleteFramebuffersOES(
@@ -7378,7 +7378,7 @@
 
 exit:
     if (framebuffers_base) {
-        _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
+        _env->ReleaseIntArrayElements(framebuffers_ref, (jint*)framebuffers_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -7398,12 +7398,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
 
-    framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, &_array, &_remaining, &_bufferOffset);
+    framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -7411,7 +7411,7 @@
         goto exit;
     }
     if (framebuffers == NULL) {
-        char * _framebuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _framebuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         framebuffers = (GLuint *) (_framebuffersBase + _bufferOffset);
     }
     glDeleteFramebuffersOES(
@@ -7421,7 +7421,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, framebuffers, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)framebuffers, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -7464,7 +7464,7 @@
         goto exit;
     }
     renderbuffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(renderbuffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(renderbuffers_ref, (jboolean *)0);
     renderbuffers = renderbuffers_base + offset;
 
     glDeleteRenderbuffersOES(
@@ -7474,7 +7474,7 @@
 
 exit:
     if (renderbuffers_base) {
-        _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
+        _env->ReleaseIntArrayElements(renderbuffers_ref, (jint*)renderbuffers_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -7494,12 +7494,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
 
-    renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, &_array, &_remaining, &_bufferOffset);
+    renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -7507,7 +7507,7 @@
         goto exit;
     }
     if (renderbuffers == NULL) {
-        char * _renderbuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _renderbuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         renderbuffers = (GLuint *) (_renderbuffersBase + _bufferOffset);
     }
     glDeleteRenderbuffersOES(
@@ -7517,7 +7517,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, renderbuffers, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)renderbuffers, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -7609,7 +7609,7 @@
         goto exit;
     }
     framebuffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(framebuffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(framebuffers_ref, (jboolean *)0);
     framebuffers = framebuffers_base + offset;
 
     glGenFramebuffersOES(
@@ -7619,7 +7619,7 @@
 
 exit:
     if (framebuffers_base) {
-        _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
+        _env->ReleaseIntArrayElements(framebuffers_ref, (jint*)framebuffers_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -7639,12 +7639,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *framebuffers = (GLuint *) 0;
 
-    framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, &_array, &_remaining, &_bufferOffset);
+    framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -7652,7 +7652,7 @@
         goto exit;
     }
     if (framebuffers == NULL) {
-        char * _framebuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _framebuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         framebuffers = (GLuint *) (_framebuffersBase + _bufferOffset);
     }
     glGenFramebuffersOES(
@@ -7662,7 +7662,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, framebuffers, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)framebuffers, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -7705,7 +7705,7 @@
         goto exit;
     }
     renderbuffers_base = (GLuint *)
-        _env->GetPrimitiveArrayCritical(renderbuffers_ref, (jboolean *)0);
+        _env->GetIntArrayElements(renderbuffers_ref, (jboolean *)0);
     renderbuffers = renderbuffers_base + offset;
 
     glGenRenderbuffersOES(
@@ -7715,7 +7715,7 @@
 
 exit:
     if (renderbuffers_base) {
-        _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
+        _env->ReleaseIntArrayElements(renderbuffers_ref, (jint*)renderbuffers_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -7735,12 +7735,12 @@
     jint _exception = 0;
     const char * _exceptionType = NULL;
     const char * _exceptionMessage = NULL;
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLuint *renderbuffers = (GLuint *) 0;
 
-    renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, &_array, &_remaining, &_bufferOffset);
+    renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (_remaining < n) {
         _exception = 1;
         _exceptionType = "java/lang/IllegalArgumentException";
@@ -7748,7 +7748,7 @@
         goto exit;
     }
     if (renderbuffers == NULL) {
-        char * _renderbuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _renderbuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         renderbuffers = (GLuint *) (_renderbuffersBase + _bufferOffset);
     }
     glGenRenderbuffersOES(
@@ -7758,7 +7758,7 @@
 
 exit:
     if (_array) {
-        releasePointer(_env, _array, renderbuffers, _exception ? JNI_FALSE : JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)renderbuffers, _exception ? JNI_ABORT : 0);
     }
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -7795,7 +7795,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetFramebufferAttachmentParameterivOES(
@@ -7807,7 +7807,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -7824,14 +7824,14 @@
             "glGetFramebufferAttachmentParameterivOES");
             return;
     }
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetFramebufferAttachmentParameterivOES(
@@ -7841,7 +7841,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -7875,7 +7875,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetRenderbufferParameterivOES(
@@ -7886,7 +7886,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -7903,14 +7903,14 @@
             "glGetRenderbufferParameterivOES");
             return;
     }
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetRenderbufferParameterivOES(
@@ -7919,7 +7919,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -7953,7 +7953,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexGenfv(
@@ -7964,7 +7964,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -7981,14 +7981,14 @@
             "glGetTexGenfv");
             return;
     }
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glGetTexGenfv(
@@ -7997,7 +7997,7 @@
         (GLfloat *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, 0);
     }
 }
 
@@ -8031,7 +8031,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexGeniv(
@@ -8042,7 +8042,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -8059,14 +8059,14 @@
             "glGetTexGeniv");
             return;
     }
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetTexGeniv(
@@ -8075,7 +8075,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -8109,7 +8109,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glGetTexGenxv(
@@ -8120,7 +8120,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -8137,14 +8137,14 @@
             "glGetTexGenxv");
             return;
     }
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glGetTexGenxv(
@@ -8153,7 +8153,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -8252,7 +8252,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLfloat *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetFloatArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexGenfv(
@@ -8263,7 +8263,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -8280,14 +8280,14 @@
             "glTexGenfv");
             return;
     }
-    jarray _array = (jarray) 0;
+    jfloatArray _array = (jfloatArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLfloat *params = (GLfloat *) 0;
 
-    params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
         params = (GLfloat *) (_paramsBase + _bufferOffset);
     }
     glTexGenfv(
@@ -8296,7 +8296,7 @@
         (GLfloat *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseFloatArrayElements(_array, (jfloat*)params, 0);
     }
 }
 
@@ -8346,7 +8346,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexGeniv(
@@ -8357,7 +8357,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -8374,14 +8374,14 @@
             "glTexGeniv");
             return;
     }
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glTexGeniv(
@@ -8390,7 +8390,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
@@ -8440,7 +8440,7 @@
     }
     _remaining = _env->GetArrayLength(params_ref) - offset;
     params_base = (GLint *)
-        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+        _env->GetIntArrayElements(params_ref, (jboolean *)0);
     params = params_base + offset;
 
     glTexGenxv(
@@ -8451,7 +8451,7 @@
 
 exit:
     if (params_base) {
-        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+        _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
             _exception ? JNI_ABORT: 0);
     }
     if (_exception) {
@@ -8468,14 +8468,14 @@
             "glTexGenxv");
             return;
     }
-    jarray _array = (jarray) 0;
+    jintArray _array = (jintArray) 0;
     jint _bufferOffset = (jint) 0;
     jint _remaining;
     GLint *params = (GLint *) 0;
 
-    params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
     if (params == NULL) {
-        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
         params = (GLint *) (_paramsBase + _bufferOffset);
     }
     glTexGenxv(
@@ -8484,7 +8484,7 @@
         (GLint *)params
     );
     if (_array) {
-        releasePointer(_env, _array, params, JNI_TRUE);
+        _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
     }
 }
 
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk
index 7839d26..78e718f 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk
@@ -27,18 +27,30 @@
 
 LOCAL_PACKAGE_NAME := MultiDexLegacyAndException
 
+LOCAL_DEX_PREOPT := false
+
 mainDexList:= \
-	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
+    $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
 
 LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
+LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\
+    -D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
 
-LOCAL_DEX_PREOPT := false
+#################################
+include $(BUILD_SYSTEM)/configure_local_jack.mk
+#################################
+
+ifdef LOCAL_JACK_ENABLED
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
+endif
 
 include $(BUILD_PACKAGE)
 
+ifndef LOCAL_JACK_ENABLED
 $(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
+	$(hide) mkdir -p $(dir $@)
 	$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
 	echo "com/android/multidexlegacyandexception/Test.class" >> $@
 
 $(built_dex_intermediate): $(mainDexList)
-
+endif
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/test.jpp b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/test.jpp
new file mode 100644
index 0000000..0d027ed
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/test.jpp
@@ -0,0 +1,3 @@
+test:
+  @@com.android.jack.annotations.ForceInMainDex
+  class com.android.multidexlegacyandexception.Test
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk
index e2ab1a8..7c699b6 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk
@@ -27,21 +27,33 @@
 
 LOCAL_PACKAGE_NAME := MultiDexLegacyTestApp
 
+LOCAL_DEX_PREOPT := false
+
 mainDexList:= \
 	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
 
 LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
+LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\
+    -D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
 
-LOCAL_DEX_PREOPT := false
+#################################
+include $(BUILD_SYSTEM)/configure_local_jack.mk
+#################################
+
+ifdef LOCAL_JACK_ENABLED
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
+endif
 
 include $(BUILD_PACKAGE)
 
+ifndef LOCAL_JACK_ENABLED
 $(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
+	$(hide) mkdir -p $(dir $@)
 	$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
 	echo "com/android/multidexlegacytestapp/Test.class" >> $@
 
 $(built_dex_intermediate): $(mainDexList)
-
+endif
 
 ## The application with a full main dex
 include $(CLEAR_VARS)
@@ -56,17 +68,30 @@
 
 LOCAL_PACKAGE_NAME := MultiDexLegacyTestApp2
 
+LOCAL_DEX_PREOPT := false
+
 mainDexList2:= \
 	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
 
 LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList2)
+LOCAL_JACK_FLAGS := -D jack.dex.output.policy=multidex -D jack.preprocessor=true\
+    -D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
 
-LOCAL_DEX_PREOPT := false
+#################################
+include $(BUILD_SYSTEM)/configure_local_jack.mk
+#################################
+
+ifdef LOCAL_JACK_ENABLED
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
+endif
 
 include $(BUILD_PACKAGE)
 
+ifndef LOCAL_JACK_ENABLED
 $(mainDexList2): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
+	$(hide) mkdir -p $(dir $@)
 	$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
 	echo "com/android/multidexlegacytestapp/Test.class" >> $@
 
 $(built_dex_intermediate): $(mainDexList2)
+endif
\ No newline at end of file
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/test.jpp b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/test.jpp
new file mode 100644
index 0000000..a1f5656
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/test.jpp
@@ -0,0 +1,3 @@
+test:
+  @@com.android.jack.annotations.ForceInMainDex
+  class com.android.multidexlegacytestapp.Test
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestServices/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyTestServices/Android.mk
index 329f544..b85c02c 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyTestServices/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestServices/Android.mk
@@ -30,13 +30,16 @@
 	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
 
 LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
+LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.dex.output.multidex.legacy=true
 
 LOCAL_DEX_PREOPT := false
 
 include $(BUILD_PACKAGE)
 
+ifndef LOCAL_JACK_ENABLED
 $(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
+	$(hide) mkdir -p $(dir $@)
 	$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
 
 $(built_dex_intermediate): $(mainDexList)
-
+endif
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk
index e79fd71..0f1d9c0 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk
@@ -26,18 +26,30 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-multidex
 
+LOCAL_DEX_PREOPT := false
+
 mainDexList:= \
 	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
 
 LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
+LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\
+    -D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
 
-LOCAL_DEX_PREOPT := false
+#################################
+include $(BUILD_SYSTEM)/configure_local_jack.mk
+#################################
+
+ifdef LOCAL_JACK_ENABLED
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
+endif
 
 include $(BUILD_PACKAGE)
 
+ifndef LOCAL_JACK_ENABLED
 $(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
+	$(hide) mkdir -p $(dir $@)
 	$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
 	echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
 
 $(built_dex_intermediate): $(mainDexList)
-
+endif
\ No newline at end of file
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/test.jpp b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/test.jpp
new file mode 100644
index 0000000..6d384e3
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/test.jpp
@@ -0,0 +1,3 @@
+test:
+  @@com.android.jack.annotations.ForceInMainDex
+  class com.android.framework.multidexlegacyversionedtestapp.MultiDexUpdateTest
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk
index 3742004..67ca483 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk
@@ -26,18 +26,30 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-multidex
 
+LOCAL_DEX_PREOPT := false
+
 mainDexList:= \
 	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
 
 LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
+LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\
+    -D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
 
-LOCAL_DEX_PREOPT := false
+#################################
+include $(BUILD_SYSTEM)/configure_local_jack.mk
+#################################
+
+ifdef LOCAL_JACK_ENABLED
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
+endif
 
 include $(BUILD_PACKAGE)
 
+ifndef LOCAL_JACK_ENABLED
 $(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
+	$(hide) mkdir -p $(dir $@)
 	$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
 	echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
 
 $(built_dex_intermediate): $(mainDexList)
-
+endif
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/test.jpp b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/test.jpp
new file mode 100644
index 0000000..6d384e3
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/test.jpp
@@ -0,0 +1,3 @@
+test:
+  @@com.android.jack.annotations.ForceInMainDex
+  class com.android.framework.multidexlegacyversionedtestapp.MultiDexUpdateTest
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk
index 7f400bc..bf2efb1 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk
@@ -29,15 +29,28 @@
 mainDexList:= \
 	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
 
-LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
-
 LOCAL_DEX_PREOPT := false
 
+LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
+LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\
+    -D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true
+
+#################################
+include $(BUILD_SYSTEM)/configure_local_jack.mk
+#################################
+
+ifdef LOCAL_JACK_ENABLED
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp
+endif
+
 include $(BUILD_PACKAGE)
 
+ifndef LOCAL_JACK_ENABLED
 $(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
+	$(hide) mkdir -p $(dir $@)
 	$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
 	echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
 
 $(built_dex_intermediate): $(mainDexList)
+endif
 
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/test.jpp b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/test.jpp
new file mode 100644
index 0000000..6d384e3
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/test.jpp
@@ -0,0 +1,3 @@
+test:
+  @@com.android.jack.annotations.ForceInMainDex
+  class com.android.framework.multidexlegacyversionedtestapp.MultiDexUpdateTest
diff --git a/keystore/java/android/security/AndroidKeyStoreProvider.java b/keystore/java/android/security/AndroidKeyStoreProvider.java
index 43f3b30..532848f 100644
--- a/keystore/java/android/security/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/AndroidKeyStoreProvider.java
@@ -110,6 +110,7 @@
      *
      * @throws IllegalArgumentException if the provided primitive is not supported or is not backed
      *         by AndroidKeyStore provider.
+     * @throws IllegalStateException if the provided primitive is not initialized.
      */
     public static Long getKeyStoreOperationHandle(Object cryptoPrimitive) {
         if (cryptoPrimitive == null) {
@@ -117,15 +118,17 @@
         }
         Object spi;
         if (cryptoPrimitive instanceof Mac) {
-            spi = ((Mac) cryptoPrimitive).getSpi();
+            spi = ((Mac) cryptoPrimitive).getCurrentSpi();
         } else if (cryptoPrimitive instanceof Cipher) {
-            spi = ((Cipher) cryptoPrimitive).getSpi();
+            spi = ((Cipher) cryptoPrimitive).getCurrentSpi();
         } else {
             throw new IllegalArgumentException("Unsupported crypto primitive: " + cryptoPrimitive);
         }
-        if (!(spi instanceof KeyStoreCryptoOperation)) {
+        if (spi == null) {
+            throw new IllegalStateException("Crypto primitive not initialized");
+        } else if (!(spi instanceof KeyStoreCryptoOperation)) {
             throw new IllegalArgumentException(
-                    "Crypto primitive not backed by AndroidKeyStore: " + cryptoPrimitive
+                    "Crypto primitive not backed by AndroidKeyStore provider: " + cryptoPrimitive
                     + ", spi: " + spi);
         }
         return ((KeyStoreCryptoOperation) spi).getOperationHandle();
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 896d1c2..2558929 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -20,8 +20,10 @@
 
 import android.os.Binder;
 import android.os.IBinder;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.security.keymaster.ExportResult;
 import android.security.keymaster.KeyCharacteristics;
 import android.security.keymaster.KeymasterArguments;
@@ -104,10 +106,10 @@
         }
     }
 
-    public State state() {
+    public State state(int userId) {
         final int ret;
         try {
-            ret = mBinder.test();
+            ret = mBinder.getState(userId);
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             throw new AssertionError(e);
@@ -121,6 +123,10 @@
         }
     }
 
+    public State state() {
+        return state(UserHandle.myUserId());
+    }
+
     public boolean isUnlocked() {
         return state() == State.UNLOCKED;
     }
@@ -169,15 +175,26 @@
         return contains(key, UID_SELF);
     }
 
-    public String[] saw(String prefix, int uid) {
+    /**
+     * List all entries in the keystore for {@code uid} starting with {@code prefix}.
+     */
+    public String[] list(String prefix, int uid) {
         try {
-            return mBinder.saw(prefix, uid);
+            return mBinder.list(prefix, uid);
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return null;
         }
     }
 
+    public String[] list(String prefix) {
+        return list(prefix, UID_SELF);
+    }
+
+    public String[] saw(String prefix, int uid) {
+        return list(prefix, uid);
+    }
+
     public String[] saw(String prefix) {
         return saw(prefix, UID_SELF);
     }
@@ -191,9 +208,15 @@
         }
     }
 
-    public boolean password(String password) {
+    /**
+     * Attempt to lock the keystore for {@code user}.
+     *
+     * @param user Android user to lock.
+     * @return whether {@code user}'s keystore was locked.
+     */
+    public boolean lock(int userId) {
         try {
-            return mBinder.password(password) == NO_ERROR;
+            return mBinder.lock(userId) == NO_ERROR;
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return false;
@@ -201,17 +224,23 @@
     }
 
     public boolean lock() {
-        try {
-            return mBinder.lock() == NO_ERROR;
-        } catch (RemoteException e) {
-            Log.w(TAG, "Cannot connect to keystore", e);
-            return false;
-        }
+        return lock(UserHandle.myUserId());
     }
 
-    public boolean unlock(String password) {
+    /**
+     * Attempt to unlock the keystore for {@code user} with the password {@code password}.
+     * This is required before keystore entries created with FLAG_ENCRYPTED can be accessed or
+     * created.
+     *
+     * @param user Android user ID to operate on
+     * @param password user's keystore password. Should be the most recent value passed to
+     * {@link #onUserPasswordChanged} for the user.
+     *
+     * @return whether the keystore was unlocked.
+     */
+    public boolean unlock(int userId, String password) {
         try {
-            mError = mBinder.unlock(password);
+            mError = mBinder.unlock(userId, password);
             return mError == NO_ERROR;
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
@@ -219,15 +248,26 @@
         }
     }
 
-    public boolean isEmpty() {
+    public boolean unlock(String password) {
+        return unlock(UserHandle.getUserId(Process.myUid()), password);
+    }
+
+    /**
+     * Check if the keystore for {@code userId} is empty.
+     */
+    public boolean isEmpty(int userId) {
         try {
-            return mBinder.zero() == KEY_NOT_FOUND;
+            return mBinder.isEmpty(userId) != 0;
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return false;
         }
     }
 
+    public boolean isEmpty() {
+        return isEmpty(UserHandle.myUserId());
+    }
+
     public boolean generate(String key, int uid, int keyType, int keySize, int flags,
             byte[][] args) {
         try {
@@ -258,12 +298,7 @@
     }
 
     public boolean delKey(String key, int uid) {
-        try {
-            return mBinder.del_key(key, uid) == NO_ERROR;
-        } catch (RemoteException e) {
-            Log.w(TAG, "Cannot connect to keystore", e);
-            return false;
-        }
+        return delete(key, uid);
     }
 
     public boolean delKey(String key) {
@@ -356,36 +391,6 @@
         }
     }
 
-    public boolean resetUid(int uid) {
-        try {
-            mError = mBinder.reset_uid(uid);
-            return mError == NO_ERROR;
-        } catch (RemoteException e) {
-            Log.w(TAG, "Cannot connect to keystore", e);
-            return false;
-        }
-    }
-
-    public boolean syncUid(int sourceUid, int targetUid) {
-        try {
-            mError = mBinder.sync_uid(sourceUid, targetUid);
-            return mError == NO_ERROR;
-        } catch (RemoteException e) {
-            Log.w(TAG, "Cannot connect to keystore", e);
-            return false;
-        }
-    }
-
-    public boolean passwordUid(String password, int uid) {
-        try {
-            mError = mBinder.password_uid(password, uid);
-            return mError == NO_ERROR;
-        } catch (RemoteException e) {
-            Log.w(TAG, "Cannot connect to keystore", e);
-            return false;
-        }
-    }
-
     public int getLastError() {
         return mError;
     }
@@ -518,6 +523,68 @@
     }
 
     /**
+     * Notify keystore that a user's password has changed.
+     *
+     * @param userId the user whose password changed.
+     * @param newPassword the new password or "" if the password was removed.
+     */
+    public boolean onUserPasswordChanged(int userId, String newPassword) {
+        // Parcel.cpp doesn't support deserializing null strings and treats them as "". Make that
+        // explicit here.
+        if (newPassword == null) {
+            newPassword = "";
+        }
+        try {
+            return mBinder.onUserPasswordChanged(userId, newPassword) == NO_ERROR;
+        } catch (RemoteException e) {
+            Log.w(TAG, "Cannot connect to keystore", e);
+            return false;
+        }
+    }
+
+    /**
+     * Notify keystore that a user was added.
+     *
+     * @param userId the new user.
+     * @param parentId the parent of the new user, or -1 if the user has no parent. If parentId is
+     * specified then the new user's keystore will be intialized with the same secure lockscreen
+     * password as the parent.
+     */
+    public void onUserAdded(int userId, int parentId) {
+        try {
+            mBinder.onUserAdded(userId, parentId);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Cannot connect to keystore", e);
+        }
+    }
+
+    /**
+     * Notify keystore that a user was added.
+     *
+     * @param userId the new user.
+     */
+    public void onUserAdded(int userId) {
+        onUserAdded(userId, -1);
+    }
+
+    /**
+     * Notify keystore that a user was removed.
+     *
+     * @param userId the removed user.
+     */
+    public void onUserRemoved(int userId) {
+        try {
+            mBinder.onUserRemoved(userId);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Cannot connect to keystore", e);
+        }
+    }
+
+    public boolean onUserPasswordChanged(String newPassword) {
+        return onUserPasswordChanged(UserHandle.getUserId(Process.myUid()), newPassword);
+    }
+
+    /**
      * Returns a {@link KeyStoreException} corresponding to the provided keystore/keymaster error
      * code.
      */
diff --git a/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java b/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
index 95d14b7..9c2f358 100644
--- a/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
+++ b/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
@@ -73,7 +73,7 @@
     }
 
     private void setupPassword() {
-        assertTrue(mAndroidKeyStore.password("1111"));
+        assertTrue(mAndroidKeyStore.onUserPasswordChanged("1111"));
         assertTrue(mAndroidKeyStore.isUnlocked());
 
         String[] aliases = mAndroidKeyStore.saw("");
@@ -288,7 +288,7 @@
             } catch (IllegalStateException expected) {
             }
 
-            assertTrue(mAndroidKeyStore.password("1111"));
+            assertTrue(mAndroidKeyStore.onUserPasswordChanged("1111"));
             assertTrue(mAndroidKeyStore.isUnlocked());
 
             final KeyPair pair2 = mGenerator.generateKeyPair();
diff --git a/keystore/tests/src/android/security/AndroidKeyStoreTest.java b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
index a7046dd2..4b2b9b5 100644
--- a/keystore/tests/src/android/security/AndroidKeyStoreTest.java
+++ b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
@@ -736,7 +736,7 @@
     }
 
     private void setupPassword() {
-        assertTrue(mAndroidKeyStore.password("1111"));
+        assertTrue(mAndroidKeyStore.onUserPasswordChanged("1111"));
         assertTrue(mAndroidKeyStore.isUnlocked());
 
         assertEquals(0, mAndroidKeyStore.saw("").length);
@@ -2089,7 +2089,7 @@
             } catch (KeyStoreException success) {
             }
 
-            assertTrue(mAndroidKeyStore.password("1111"));
+            assertTrue(mAndroidKeyStore.onUserPasswordChanged("1111"));
             assertTrue(mAndroidKeyStore.isUnlocked());
 
             mKeyStore.setEntry(TEST_ALIAS_1, entry,
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
index f3c4787..836b514 100644
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ b/keystore/tests/src/android/security/KeyStoreTest.java
@@ -152,13 +152,13 @@
     }
 
     public void testPassword() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
         assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
     }
 
     public void testGet() throws Exception {
         assertNull(mKeyStore.get(TEST_KEYNAME));
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertNull(mKeyStore.get(TEST_KEYNAME));
         assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
                 KeyStore.FLAG_ENCRYPTED));
@@ -170,7 +170,7 @@
         assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
                 KeyStore.FLAG_ENCRYPTED));
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
                 KeyStore.FLAG_ENCRYPTED));
         assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
@@ -181,7 +181,7 @@
         assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
                 KeyStore.FLAG_ENCRYPTED));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
                 KeyStore.FLAG_ENCRYPTED));
         assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
@@ -192,7 +192,7 @@
         assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
                 KeyStore.FLAG_ENCRYPTED));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
                 KeyStore.FLAG_ENCRYPTED));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
@@ -202,7 +202,7 @@
         assertFalse(mKeyStore.put(TEST_I18N_KEY, TEST_I18N_VALUE, KeyStore.UID_SELF,
                 KeyStore.FLAG_ENCRYPTED));
         assertFalse(mKeyStore.contains(TEST_I18N_KEY));
-        mKeyStore.password(TEST_I18N_KEY);
+        mKeyStore.onUserPasswordChanged(TEST_I18N_KEY);
         assertTrue(mKeyStore.put(TEST_I18N_KEY, TEST_I18N_VALUE, KeyStore.UID_SELF,
                 KeyStore.FLAG_ENCRYPTED));
         assertTrue(mKeyStore.contains(TEST_I18N_KEY));
@@ -210,7 +210,7 @@
 
     public void testDelete() throws Exception {
         assertFalse(mKeyStore.delete(TEST_KEYNAME));
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertFalse(mKeyStore.delete(TEST_KEYNAME));
 
         assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
@@ -222,7 +222,7 @@
 
     public void testDelete_grantedUid_Wifi() throws Exception {
         assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.WIFI_UID));
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.WIFI_UID));
 
         assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
@@ -234,7 +234,7 @@
 
     public void testDelete_ungrantedUid_Bluetooth() throws Exception {
         assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.BLUETOOTH_UID));
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.BLUETOOTH_UID));
 
         assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
@@ -247,7 +247,7 @@
     public void testContains() throws Exception {
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
 
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
 
         assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
@@ -258,7 +258,7 @@
     public void testContains_grantedUid_Wifi() throws Exception {
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
 
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
 
         assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
@@ -269,7 +269,7 @@
     public void testContains_grantedUid_Bluetooth() throws Exception {
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
 
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
 
         assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
@@ -282,7 +282,7 @@
         assertNotNull(emptyResult);
         assertEquals(0, emptyResult.length);
 
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
         mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
 
@@ -296,7 +296,7 @@
         String[] results1 = mKeyStore.saw(TEST_KEYNAME, Process.BLUETOOTH_UID);
         assertEquals(0, results1.length);
 
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
         mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
 
@@ -309,7 +309,7 @@
         assertNotNull(results1);
         assertEquals(0, results1.length);
 
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED);
         mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED);
 
@@ -324,7 +324,7 @@
         assertNotNull(results1);
         assertEquals(0, results1.length);
 
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, Process.VPN_UID, KeyStore.FLAG_ENCRYPTED);
         mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, Process.VPN_UID, KeyStore.FLAG_ENCRYPTED);
 
@@ -337,7 +337,7 @@
     public void testLock() throws Exception {
         assertFalse(mKeyStore.lock());
 
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
 
         assertTrue(mKeyStore.lock());
@@ -345,7 +345,7 @@
     }
 
     public void testUnlock() throws Exception {
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
         mKeyStore.lock();
 
@@ -355,7 +355,7 @@
 
     public void testIsEmpty() throws Exception {
         assertTrue(mKeyStore.isEmpty());
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         assertTrue(mKeyStore.isEmpty());
         mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
         assertFalse(mKeyStore.isEmpty());
@@ -370,7 +370,7 @@
     }
 
     public void testGenerate_Locked_Fail() throws Exception {
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         mKeyStore.lock();
         assertFalse("Should fail when keystore is locked",
                 mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
@@ -378,7 +378,7 @@
     }
 
     public void testGenerate_Success() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to generate key when unlocked",
                 mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
@@ -388,7 +388,7 @@
     }
 
     public void testGenerate_grantedUid_Wifi_Success() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to generate key when unlocked",
                 mKeyStore.generate(TEST_KEYNAME, Process.WIFI_UID, NativeConstants.EVP_PKEY_RSA,
@@ -398,7 +398,7 @@
     }
 
     public void testGenerate_ungrantedUid_Bluetooth_Failure() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertFalse(mKeyStore.generate(TEST_KEYNAME, Process.BLUETOOTH_UID,
                     NativeConstants.EVP_PKEY_RSA, RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
@@ -408,7 +408,7 @@
     }
 
     public void testImport_Success() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
                 PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
@@ -417,7 +417,7 @@
     }
 
     public void testImport_grantedUid_Wifi_Success() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
                 PRIVKEY_BYTES, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED));
@@ -426,7 +426,7 @@
     }
 
     public void testImport_ungrantedUid_Bluetooth_Failure() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertFalse(mKeyStore.importKey(TEST_KEYNAME, PRIVKEY_BYTES, Process.BLUETOOTH_UID,
                 KeyStore.FLAG_ENCRYPTED));
@@ -436,7 +436,7 @@
     }
 
     public void testImport_Failure_BadEncoding() throws Exception {
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
 
         assertFalse("Invalid DER-encoded key should not be imported", mKeyStore.importKey(
                 TEST_KEYNAME, TEST_DATA, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
@@ -445,7 +445,7 @@
     }
 
     public void testSign_Success() throws Exception {
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
 
         assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                     RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
@@ -456,7 +456,7 @@
     }
 
     public void testVerify_Success() throws Exception {
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
 
         assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
                     RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
@@ -475,7 +475,7 @@
     }
 
     public void testSign_NotGenerated_Failure() throws Exception {
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
 
         assertNull("Should not be able to sign without first generating keys",
                 mKeyStore.sign(TEST_KEYNAME, TEST_DATA));
@@ -483,7 +483,7 @@
 
     public void testGrant_Generated_Success() throws Exception {
         assertTrue("Password should work for keystore",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
                 mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
@@ -494,7 +494,7 @@
     }
 
     public void testGrant_Imported_Success() throws Exception {
-        assertTrue("Password should work for keystore", mKeyStore.password(TEST_PASSWD));
+        assertTrue("Password should work for keystore", mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to import key for testcase", mKeyStore.importKey(TEST_KEYNAME,
                 PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
@@ -504,7 +504,7 @@
 
     public void testGrant_NoKey_Failure() throws Exception {
         assertTrue("Should be able to unlock keystore for test",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertFalse("Should not be able to grant without first initializing the keystore",
                 mKeyStore.grant(TEST_KEYNAME, 0));
@@ -517,7 +517,7 @@
 
     public void testUngrant_Generated_Success() throws Exception {
         assertTrue("Password should work for keystore",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
                 mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
@@ -532,7 +532,7 @@
 
     public void testUngrant_Imported_Success() throws Exception {
         assertTrue("Password should work for keystore",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to import key for testcase", mKeyStore.importKey(TEST_KEYNAME,
                 PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
@@ -551,7 +551,7 @@
 
     public void testUngrant_NoGrant_Failure() throws Exception {
         assertTrue("Password should work for keystore",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
                 mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
@@ -563,7 +563,7 @@
 
     public void testUngrant_DoubleUngrant_Failure() throws Exception {
         assertTrue("Password should work for keystore",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
                 mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
@@ -581,7 +581,7 @@
 
     public void testUngrant_DoubleGrantUngrant_Failure() throws Exception {
         assertTrue("Password should work for keystore",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
                 mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
@@ -601,7 +601,7 @@
     }
 
     public void testDuplicate_grantedUid_Wifi_Success() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
 
@@ -640,7 +640,7 @@
     }
 
     public void testDuplicate_ungrantedUid_Bluetooth_Failure() throws Exception {
-        assertTrue(mKeyStore.password(TEST_PASSWD));
+        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
 
@@ -666,7 +666,7 @@
 
     public void testGetmtime_Success() throws Exception {
         assertTrue("Password should work for keystore",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
                 PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
@@ -697,7 +697,7 @@
 
     public void testGetmtime_NonExist_Failure() throws Exception {
         assertTrue("Password should work for keystore",
-                mKeyStore.password(TEST_PASSWD));
+                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
 
         assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
                 PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
@@ -752,7 +752,7 @@
     }
 
     public void testGetKeyCharacteristicsSuccess() throws Exception {
-        mKeyStore.password(TEST_PASSWD);
+        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
         String name = "test";
         KeyCharacteristics gen = generateRsaKey(name);
         KeyCharacteristics call = new KeyCharacteristics();
@@ -817,6 +817,9 @@
 
         KeymasterArguments out = new KeymasterArguments();
         args = new KeymasterArguments();
+        args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+        args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_GCM);
+        args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
         OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT,
                 true, args, null, out);
         IBinder token = result.token;
@@ -881,14 +884,18 @@
             hexToBytes("591ccb10d410ed26dc5ba74a31362870"),
             hexToBytes("b6ed21b99ca6f4f9f153e7b1beafed1d"),
             hexToBytes("23304b7a39f9f3ff067d8d8f9e24ecc7")};
+        KeymasterArguments beginArgs = new KeymasterArguments();
+        beginArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+        beginArgs.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
+        beginArgs.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
         for (int i = 0; i < testVectors.length; i++) {
             byte[] cipherText = doOperation(name, KeymasterDefs.KM_PURPOSE_ENCRYPT, testVectors[i],
-                    new KeymasterArguments());
+                    beginArgs);
             MoreAsserts.assertEquals(cipherVectors[i], cipherText);
         }
         for (int i = 0; i < testVectors.length; i++) {
             byte[] plainText = doOperation(name, KeymasterDefs.KM_PURPOSE_DECRYPT,
-                    cipherVectors[i], new KeymasterArguments());
+                    cipherVectors[i], beginArgs);
             MoreAsserts.assertEquals(testVectors[i], plainText);
         }
     }
@@ -912,6 +919,9 @@
 
         KeymasterArguments out = new KeymasterArguments();
         args = new KeymasterArguments();
+        args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+        args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_CTR);
+        args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
         OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT,
                 true, args, null, out);
         assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
@@ -951,4 +961,28 @@
         assertEquals("Update should require authorization",
                 KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED, result.resultCode);
     }
+
+    public void testPasswordRemovalEncryptedEntry() throws Exception {
+        mKeyStore.onUserPasswordChanged("test");
+        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
+                KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mKeyStore.contains(TEST_KEYNAME));
+        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
+        mKeyStore.onUserPasswordChanged("");
+        // Removing the password should have deleted all entries using FLAG_ENCRYPTED
+        assertNull(mKeyStore.get(TEST_KEYNAME));
+        assertFalse(mKeyStore.contains(TEST_KEYNAME));
+    }
+
+    public void testPasswordRemovalUnencryptedEntry() throws Exception {
+        mKeyStore.onUserPasswordChanged("test");
+        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
+                KeyStore.FLAG_NONE));
+        assertTrue(mKeyStore.contains(TEST_KEYNAME));
+        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
+        mKeyStore.onUserPasswordChanged("");
+        // Removing the password should not delete unencrypted entries.
+        assertTrue(mKeyStore.contains(TEST_KEYNAME));
+        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
+    }
 }
diff --git a/media/tests/MediaDump/src/com/android/mediadump/VideoDumpActivity.java b/media/tests/MediaDump/src/com/android/mediadump/VideoDumpActivity.java
index 46cb64e..b8f5704 100644
--- a/media/tests/MediaDump/src/com/android/mediadump/VideoDumpActivity.java
+++ b/media/tests/MediaDump/src/com/android/mediadump/VideoDumpActivity.java
@@ -19,7 +19,7 @@
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.Context;
-import android.content.DialogInterface;;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.os.Bundle;
diff --git a/native/graphics/jni/Android.mk b/native/graphics/jni/Android.mk
index 91c9ac6..b7f0fbd 100644
--- a/native/graphics/jni/Android.mk
+++ b/native/graphics/jni/Android.mk
@@ -31,7 +31,7 @@
 LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
 
 # TODO: This is to work around b/19059885. Remove after root cause is fixed
-LOCAL_LDFLAGS_arm := -Wl,--hash-style=sysv
+LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
 
 include $(BUILD_SHARED_LIBRARY)
 
diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java
index 4fa2c81..2ce11a2 100644
--- a/rs/java/android/renderscript/Allocation.java
+++ b/rs/java/android/renderscript/Allocation.java
@@ -1448,7 +1448,7 @@
         }
 
         final byte[] data = fp.getData();
-        int data_length = fp.getPos();
+        int data_length = data.length;
         int eSize = mType.mElement.mElements[component_number].getBytesSize();
         eSize *= mType.mElement.mArraySizes[component_number];
 
diff --git a/rs/java/android/renderscript/Element.java b/rs/java/android/renderscript/Element.java
index 60ff996..669eb45 100644
--- a/rs/java/android/renderscript/Element.java
+++ b/rs/java/android/renderscript/Element.java
@@ -548,8 +548,8 @@
      *     @hide
      */
     public static Element F16_3(RenderScript rs) {
-        if(rs.mElement_FLOAT_3 == null) {
-            rs.mElement_FLOAT_3 = createVector(rs, DataType.FLOAT_16, 3);
+        if(rs.mElement_HALF_3 == null) {
+            rs.mElement_HALF_3 = createVector(rs, DataType.FLOAT_16, 3);
         }
         return rs.mElement_HALF_3;
     }
@@ -926,6 +926,7 @@
 
         switch (dt) {
         // Support only primitive integer/float/boolean types as vectors.
+        case FLOAT_16:
         case FLOAT_32:
         case FLOAT_64:
         case SIGNED_8:
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
index 1ea7108..9acf5ad 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
@@ -1040,14 +1040,8 @@
             if (cM != cN) {
                 throw new RSRuntimeException("Matrix C is not symmetric");
             }
-            if (TransA != NO_TRANSPOSE) {
-                if (aN != cM) {
-                    throw new RSRuntimeException("Called BLAS with invalid dimensions");
-                }
-            } else {
-                if (aM != cM) {
-                    throw new RSRuntimeException("Called BLAS with invalid dimensions");
-                }
+            if (aM != cM) {
+                throw new RSRuntimeException("Called BLAS with invalid dimensions");
             }
         } else if (A != null && B != null) {
             // A and B only
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 9684b35..ec835b2 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -44,9 +44,6 @@
 
 //#define LOG_API ALOGE
 static constexpr bool kLogApi = false;
-static constexpr size_t kMaxNumberArgsAndBindings = 1000;
-static constexpr size_t kMaxNumberClosuresInScriptGroup = 1000000;
-static constexpr size_t kMaxNumberKernelArguments = 256;
 
 using namespace android;
 
@@ -376,7 +373,7 @@
       goto exit;
   }
 
-  if (numValues > kMaxNumberArgsAndBindings) {
+  if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) {
       ALOGE("Too many arguments or globals in closure creation");
       goto exit;
   }
@@ -461,7 +458,7 @@
 
   numValues = (size_t) fieldIDs_length;
 
-  if (numValues > kMaxNumberArgsAndBindings) {
+  if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) {
       ALOGE("Too many arguments or globals in closure creation");
       goto exit;
   }
@@ -526,7 +523,7 @@
 
   RsClosure* closures;
 
-  if (numClosures > (jsize) kMaxNumberClosuresInScriptGroup) {
+  if (numClosures > (jsize) RS_SCRIPT_GROUP_MAX_NUMBER_CLOSURES) {
     ALOGE("Too many closures in script group");
     goto exit;
   }
@@ -1465,7 +1462,7 @@
     rsAllocationElementRead((RsContext)con, (RsAllocation)alloc,
                             xoff, yoff, zoff,
                             lod, ptr, sizeBytes, compIdx);
-    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
+    _env->ReleaseByteArrayElements(data, ptr, 0);
 }
 
 // Copies from the Allocation pointed to by _alloc into the Java object data.
@@ -1867,7 +1864,7 @@
                jintArray limits)
 {
     if (kLogApi) {
-        ALOGD("nScriptForEach, con(%p), s(%p), slot(%i) ains(%p) aout(%lli)", (RsContext)con, (void *)script, slot, ains, aout);
+        ALOGD("nScriptForEach, con(%p), s(%p), slot(%i) ains(%p) aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ains, aout);
     }
 
     jint   in_len = 0;
@@ -1877,7 +1874,7 @@
 
     if (ains != nullptr) {
         in_len = _env->GetArrayLength(ains);
-        if (in_len > (jint)kMaxNumberKernelArguments) {
+        if (in_len > (jint)RS_KERNEL_MAX_ARGUMENTS) {
             ALOGE("Too many arguments in kernel launch.");
             // TODO (b/20758983): Report back to Java and throw an exception
             return;
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 77662cc..49c5ea2 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -100,20 +100,13 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             if (Intent.ACTION_USER_ADDED.equals(intent.getAction())) {
+                // Notify keystore that a new user was added.
                 final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-                final int userSysUid = UserHandle.getUid(userHandle, Process.SYSTEM_UID);
                 final KeyStore ks = KeyStore.getInstance();
-
-                // Clear up keystore in case anything was left behind by previous users
-                ks.resetUid(userSysUid);
-
-                // If this user has a parent, sync with its keystore password
                 final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
                 final UserInfo parentInfo = um.getProfileParent(userHandle);
-                if (parentInfo != null) {
-                    final int parentSysUid = UserHandle.getUid(parentInfo.id, Process.SYSTEM_UID);
-                    ks.syncUid(parentSysUid, userSysUid);
-                }
+                final int parentHandle = parentInfo != null ? parentInfo.id : -1;
+                ks.onUserAdded(userHandle, parentHandle);
             } else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) {
                 final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                 mStorage.prefetchUser(userHandle);
@@ -265,28 +258,23 @@
         return mStorage.hasPattern(userId);
     }
 
-    private void maybeUpdateKeystore(String password, int userHandle) {
+    private void setKeystorePassword(String password, int userHandle) {
         final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
         final KeyStore ks = KeyStore.getInstance();
 
         final List<UserInfo> profiles = um.getProfiles(userHandle);
-        boolean shouldReset = TextUtils.isEmpty(password);
-
-        // For historical reasons, don't wipe a non-empty keystore if we have a single user with a
-        // single profile.
-        if (userHandle == UserHandle.USER_OWNER && profiles.size() == 1) {
-            if (!ks.isEmpty()) {
-                shouldReset = false;
-            }
-        }
-
         for (UserInfo pi : profiles) {
-            final int profileUid = UserHandle.getUid(pi.id, Process.SYSTEM_UID);
-            if (shouldReset) {
-                ks.resetUid(profileUid);
-            } else {
-                ks.passwordUid(password, profileUid);
-            }
+            ks.onUserPasswordChanged(pi.id, password);
+        }
+    }
+
+    private void unlockKeystore(String password, int userHandle) {
+        final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
+        final KeyStore ks = KeyStore.getInstance();
+
+        final List<UserInfo> profiles = um.getProfiles(userHandle);
+        for (UserInfo pi : profiles) {
+            ks.unlock(pi.id, password);
         }
     }
 
@@ -294,7 +282,7 @@
     public void setLockPattern(String pattern, int userId) throws RemoteException {
         checkWritePermission(userId);
 
-        maybeUpdateKeystore(pattern, userId);
+        setKeystorePassword(pattern, userId);
 
         final byte[] hash = LockPatternUtils.patternToHash(
                 LockPatternUtils.stringToPattern(pattern));
@@ -305,7 +293,7 @@
     public void setLockPassword(String password, int userId) throws RemoteException {
         checkWritePermission(userId);
 
-        maybeUpdateKeystore(password, userId);
+        setKeystorePassword(password, userId);
 
         mStorage.writePasswordHash(mLockPatternUtils.passwordToHash(password, userId), userId);
     }
@@ -322,7 +310,7 @@
 
         boolean matched = Arrays.equals(hash, storedHash);
         if (matched && !TextUtils.isEmpty(pattern)) {
-            maybeUpdateKeystore(pattern, userId);
+            unlockKeystore(pattern, userId);
         }
         return matched;
     }
@@ -340,7 +328,7 @@
 
         boolean matched = Arrays.equals(hash, storedHash);
         if (matched && !TextUtils.isEmpty(password)) {
-            maybeUpdateKeystore(password, userId);
+            unlockKeystore(password, userId);
         }
         return matched;
     }
@@ -397,8 +385,7 @@
         mStorage.removeUser(userId);
 
         final KeyStore ks = KeyStore.getInstance();
-        final int userUid = UserHandle.getUid(userId, Process.SYSTEM_UID);
-        ks.resetUid(userUid);
+        ks.onUserRemoved(userId);
     }
 
     private static final String[] VALID_SETTINGS = new String[] {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 95a0867..01858a4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -15008,7 +15008,7 @@
             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
             final boolean always = app.bad || !allowRestart;
             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
-            if ((inLaunching || always) && !cpr.connections.isEmpty()) {
+            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
                 // We left the provider in the launching list, need to
                 // restart it.
                 restart = true;
@@ -15152,7 +15152,7 @@
         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
             ContentProviderRecord cpr = mLaunchingProviders.get(i);
             if (cpr.launchingApp == app) {
-                if (!alwaysBad && !app.bad && !cpr.connections.isEmpty()) {
+                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
                     restart = true;
                 } else {
                     removeDyingProviderLocked(app, cpr, true);
diff --git a/services/core/java/com/android/server/am/ContentProviderRecord.java b/services/core/java/com/android/server/am/ContentProviderRecord.java
index a37249d..dceadf4 100644
--- a/services/core/java/com/android/server/am/ContentProviderRecord.java
+++ b/services/core/java/com/android/server/am/ContentProviderRecord.java
@@ -139,6 +139,10 @@
         return (externalProcessTokenToHandle != null || externalProcessNoHandleCount > 0);
     }
 
+    public boolean hasConnectionOrHandle() {
+        return !connections.isEmpty() || hasExternalProcessHandles();
+    }
+
     void dump(PrintWriter pw, String prefix, boolean full) {
         if (full) {
             pw.print(prefix); pw.print("package=");
diff --git a/services/core/java/com/android/server/am/ProviderMap.java b/services/core/java/com/android/server/am/ProviderMap.java
index 7da8c48..23c2dc8 100644
--- a/services/core/java/com/android/server/am/ProviderMap.java
+++ b/services/core/java/com/android/server/am/ProviderMap.java
@@ -205,8 +205,11 @@
     boolean collectForceStopProviders(String name, int appId,
             boolean doit, boolean evenPersistent, int userId,
             ArrayList<ContentProviderRecord> result) {
-        boolean didSomething = collectForceStopProvidersLocked(name, appId, doit,
-                evenPersistent, userId, mSingletonByClass, result);
+        boolean didSomething = false;
+        if (userId == UserHandle.USER_ALL || userId == UserHandle.USER_OWNER) {
+            didSomething = collectForceStopProvidersLocked(name, appId, doit,
+                    evenPersistent, userId, mSingletonByClass, result);
+        }
         if (!doit && didSomething) {
             return true;
         }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index f84cb30..c558845 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -537,6 +537,28 @@
      * Check if we've hit the limit of how many users can be created.
      */
     private boolean isUserLimitReachedLocked() {
+        return getAliveUsersExcludingGuestsCountLocked() >= UserManager.getMaxSupportedUsers();
+    }
+
+    @Override
+    public boolean canAddMoreManagedProfiles() {
+        checkManageUsersPermission("check if more managed profiles can be added.");
+        if (ActivityManager.isLowRamDeviceStatic()) {
+            return false;
+        }
+        synchronized(mPackagesLock) {
+            // Limit number of managed profiles that can be created
+            if (numberOfUsersOfTypeLocked(UserInfo.FLAG_MANAGED_PROFILE, true)
+                    >= MAX_MANAGED_PROFILES) {
+                return false;
+            }
+            int usersCount = getAliveUsersExcludingGuestsCountLocked();
+            // We allow creating a managed profile in the special case where there is only one user.
+            return usersCount == 1 || usersCount < UserManager.getMaxSupportedUsers();
+        }
+    }
+
+    private int getAliveUsersExcludingGuestsCountLocked() {
         int aliveUserCount = 0;
         final int totalUserCount = mUsers.size();
         // Skip over users being removed
@@ -547,7 +569,7 @@
                 aliveUserCount++;
             }
         }
-        return aliveUserCount >= UserManager.getMaxSupportedUsers();
+        return aliveUserCount;
     }
 
     /**
@@ -1152,7 +1174,11 @@
             Log.w(LOG_TAG, "Cannot add user. DISALLOW_ADD_USER is enabled.");
             return null;
         }
+        if (ActivityManager.isLowRamDeviceStatic()) {
+            return null;
+        }
         final boolean isGuest = (flags & UserInfo.FLAG_GUEST) != 0;
+        final boolean isManagedProfile = (flags & UserInfo.FLAG_MANAGED_PROFILE) != 0;
         final long ident = Binder.clearCallingIdentity();
         UserInfo userInfo = null;
         try {
@@ -1163,21 +1189,18 @@
                         parent = getUserInfoLocked(parentId);
                         if (parent == null) return null;
                     }
-                    // If we're not adding a guest user and the limit has been reached,
-                    // cannot add a user.
-                    if (!isGuest && isUserLimitReachedLocked()) {
+                    if (isManagedProfile && !canAddMoreManagedProfiles()) {
+                        return null;
+                    }
+                    if (!isGuest && !isManagedProfile && isUserLimitReachedLocked()) {
+                        // If we're not adding a guest user or a managed profile and the limit has
+                        // been reached, cannot add a user.
                         return null;
                     }
                     // If we're adding a guest and there already exists one, bail.
                     if (isGuest && findCurrentGuestUserLocked() != null) {
                         return null;
                     }
-                    // Limit number of managed profiles that can be created
-                    if ((flags & UserInfo.FLAG_MANAGED_PROFILE) != 0
-                            && numberOfUsersOfTypeLocked(UserInfo.FLAG_MANAGED_PROFILE, true)
-                                >= MAX_MANAGED_PROFILES) {
-                        return null;
-                    }
                     int userId = getNextAvailableIdLocked();
                     userInfo = new UserInfo(userId, name, null, flags);
                     File userPath = new File(mBaseUserPath, Integer.toString(userId));
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 8998d39..63c4461 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -9907,6 +9907,7 @@
                         winAnimator.setAnimation(a);
                         winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
                         winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
+                        winAnimator.mAnimateMove = true;
 
                         //TODO (multidisplay): Accessibility supported only for the default display.
                         if (mAccessibilityController != null
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 4cdfc41..1b5d0b8 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -131,6 +131,7 @@
     // used.
     int mAnimDw;
     int mAnimDh;
+    boolean mAnimateMove = false;
     float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
     float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
 
@@ -304,9 +305,15 @@
                         " wh=" + mWin.mFrame.height() +
                         " dw=" + mAnimDw + " dh=" + mAnimDh +
                         " scale=" + mService.getWindowAnimationScaleLocked());
-                    mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
-                            mAnimDw, mAnimDh);
                     final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+                    if (mAnimateMove) {
+                        mAnimateMove = false;
+                        mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
+                                mAnimDw, mAnimDh);
+                    } else {
+                        mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
+                                displayInfo.appWidth, displayInfo.appHeight);
+                    }
                     mAnimDw = displayInfo.appWidth;
                     mAnimDh = displayInfo.appHeight;
                     mAnimation.setStartTime(mAnimationStartTime != -1
@@ -1245,6 +1252,10 @@
             mDtDx = 0;
             mDsDy = 0;
             mDtDy = mWin.mGlobalScale;
+            if (appTransformation == null) {
+                mHasClipRect = false;
+                mClipRect.setEmpty();
+            }
         }
     }
 
@@ -1336,7 +1347,10 @@
         clipRect.bottom += attrs.surfaceInsets.bottom;
 
         // If we have an animated clip rect, intersect it with the clip rect.
-        if (mHasClipRect) {
+        // However, the clip rect animation effect should be applied on app windows that inset
+        // decor only. If applying on non-inset decor one, the top region of this window will
+        // be clipped on the end of animation, e.g. dialog activities.
+        if (mHasClipRect && (w.mAttrs.flags & LayoutParams.FLAG_LAYOUT_INSET_DECOR) != 0) {
             // NOTE: We are adding a temporary workaround due to the status bar
             // not always reporting the correct system decor rect. In such
             // cases, we take into account the specified content insets as well.
diff --git a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs
index 42b1cf1..0c177ef 100644
--- a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs
+++ b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs
@@ -116,7 +116,6 @@
     rs_allocation allMeshes = rsGetAllocation(gMeshes);
     int size = rsAllocationGetDimX(allMeshes);
     gLookAt = 0.0f;
-    float minX, minY, minZ, maxX, maxY, maxZ;
     for (int i = 0; i < size; i++) {
         MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
         rsgDrawMesh(info->mMesh);
@@ -124,7 +123,6 @@
 }
 
 static void drawDescription() {
-    uint width = rsgGetWidth();
     uint height = rsgGetHeight();
     int left = 0, right = 0, top = 0, bottom = 0;
 
@@ -196,7 +194,6 @@
 
     uint32_t w = rsAllocationGetDimX(gOffscreen);
     uint32_t h = rsAllocationGetDimY(gOffscreen);
-    uint32_t numElements = w*h;
 
     rsgAllocationSyncAll(gOffscreen, RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET);
 
diff --git a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs
index 05ef3ac..13a3c85 100644
--- a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs
+++ b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbotest.rs
@@ -115,7 +115,6 @@
     rs_allocation allMeshes = rsGetAllocation(gMeshes);
     int size = rsAllocationGetDimX(allMeshes);
     gLookAt = 0.0f;
-    float minX, minY, minZ, maxX, maxY, maxZ;
     for (int i = 0; i < size; i++) {
         MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
         rsgDrawMesh(info->mMesh);
@@ -123,7 +122,6 @@
 }
 
 static void drawDescription() {
-    uint width = rsgGetWidth();
     uint height = rsgGetHeight();
     int left = 0, right = 0, top = 0, bottom = 0;
 
diff --git a/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs
index de2a0a7..d3dd5b9 100644
--- a/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs
+++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs
@@ -123,7 +123,6 @@
     rs_allocation allMeshes = rsGetAllocation(gMeshes);
     int size = rsAllocationGetDimX(allMeshes);
     gLookAt = 0.0f;
-    float minX, minY, minZ, maxX, maxY, maxZ;
     for (int i = 0; i < size; i++) {
         MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
         rsgDrawMesh(info->mMesh);
@@ -131,7 +130,6 @@
 }
 
 void drawDescription() {
-    uint width = rsgGetWidth();
     uint height = rsgGetHeight();
     int left = 0, right = 0, top = 0, bottom = 0;
 
@@ -163,7 +161,7 @@
     rsMatrixMultiply(&matrix, &gPostureMatrix);
     rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f);
     rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f);
-    
+
     rsgProgramVertexLoadModelMatrix(&matrix);
 
     renderAllMeshes();
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
index 27e5b11..43cf4e0 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
@@ -85,7 +85,7 @@
     TestData testData;
     fillSurfaceParams(&testData);
 
-    rs_allocation null_alloc;
+    rs_allocation null_alloc = {0};
     rsForEach(gTestScripts[index].testScript,
               gTestScripts[index].testData,
               null_alloc,
@@ -125,7 +125,6 @@
 
 static int benchMode = 0;
 static bool benchmarkSingleTest = false;
-static int benchSubMode = 0;
 static int runningLoops = 0;
 static bool sendMsgFlag = false;
 
@@ -209,7 +208,6 @@
     drawOffscreenResult(0, 0, quadW, quadH);
 
     int left = 0, right = 0, top = 0, bottom = 0;
-    uint width = rsgGetWidth();
     uint height = rsgGetHeight();
     rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
     rsgBindFont(gFontSerif);
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs
index 7f10019..0f50828 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs
@@ -52,7 +52,6 @@
     fonts[3] = gFontSerif;
     fonts[4] = gFontSans;
 
-    uint width = gRenderSurfaceW;
     uint height = gRenderSurfaceH;
     int left = 0, right = 0, top = 0, bottom = 0;
     rsgMeasureText(sampleText, &left, &right, &top, &bottom);
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs
index 5089092..e87db39 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs
@@ -143,7 +143,6 @@
     float d = fabs(randomGauss()) * gGalaxyRadius * 0.5f + rsRand(64.0f);
     float id = d / gGalaxyRadius;
     float z = randomGauss() * 0.4f * (1.0f - id);
-    float p = -d * ELLIPSE_TWIST;
 
     if (d < gGalaxyRadius * 0.33f) {
         part->color.x = (uchar) (220 + id * 35);
@@ -305,7 +304,6 @@
     int left = 0, right = 0, top = 0, bottom = 0;
     rsgMeasureText(gSampleTextList100[0].item, &left, &right, &top, &bottom);
     float textHeight = (float)(top - bottom);
-    float textWidth = (float)(right - left);
 
     rs_matrix4x4 matrix;
     rsMatrixLoadScale(&matrix, size, size, 1.0);
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh
index 575794b..00793c0 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh
@@ -19,7 +19,7 @@
 #include "scenegraph_objects.rsh"
 
 //#define DEBUG_PARAMS
-static void debugParam(SgShaderParam *p, SgShaderParamData *pData) {
+static inline void debugParam(SgShaderParam *p, SgShaderParamData *pData) {
     rsDebug("____________ Param ____________", p);
     printName(pData->paramName);
     rsDebug("bufferOffset", p->bufferOffset);
@@ -44,8 +44,7 @@
     }
 }
 
-
-static void writeFloatData(float *ptr, const float4 *input, uint32_t vecSize) {
+static inline void writeFloatData(float *ptr, const float4 *input, uint32_t vecSize) {
 #ifdef DEBUG_PARAMS
     rsDebug("Writing value ", *input);
     rsDebug("Writing vec size ", vecSize);
@@ -67,7 +66,7 @@
     }
 }
 
-static bool processParam(SgShaderParam *p, SgShaderParamData *pData,
+static inline bool processParam(SgShaderParam *p, SgShaderParamData *pData,
                          uint8_t *constantBuffer,
                          const SgCamera *currentCam,
                          SgFragmentShader *shader) {
@@ -155,7 +154,7 @@
     return true;
 }
 
-static void processAllParams(rs_allocation shaderConst,
+static inline void processAllParams(rs_allocation shaderConst,
                              rs_allocation allParams,
                              const SgCamera *camera) {
     if (rsIsObject(shaderConst)) {
@@ -177,7 +176,7 @@
     }
 }
 
-static void processTextureParams(SgFragmentShader *shader) {
+static inline void processTextureParams(SgFragmentShader *shader) {
     int numParams = 0;
     if (rsIsObject(shader->shaderTextureParams)) {
         numParams = rsAllocationGetDimX(shader->shaderTextureParams);
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs
index 8a73dbd..205b2cb 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs
@@ -78,7 +78,7 @@
     if (rsIsObject(renderState->pr)) {
         rsgBindProgramRaster(renderState->pr);
     } else {
-        rs_program_raster pr;
+        rs_program_raster pr = {0};
         rsgBindProgramRaster(pr);
     }
 
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh
index bdca3ab..90ae212 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh
@@ -208,7 +208,7 @@
     rs_allocation texture;
 } SgTexture;
 
-static void printName(rs_allocation name) {
+static inline void printName(rs_allocation name) {
     if (!rsIsObject(name)) {
         rsDebug("no name", 0);
         return;
@@ -217,7 +217,7 @@
     rsDebug((const char*)rsGetElementAt(name, 0), 0);
 }
 
-static void printCameraInfo(const SgCamera *cam) {
+static inline void printCameraInfo(const SgCamera *cam) {
     rsDebug("***** Camera information. ptr:", cam);
     printName(cam->name);
     const SgTransform *camTransform = (const SgTransform *)rsGetElementAt(cam->transformMatrix, 0);
@@ -233,7 +233,7 @@
     rsDebug("View: ", &cam->view);
 }
 
-static void printLightInfo(const SgLight *light) {
+static inline void printLightInfo(const SgLight *light) {
     rsDebug("***** Light information. ptr:", light);
     printName(light->name);
     const SgTransform *lTransform = (const SgTransform *)rsGetElementAt(light->transformMatrix, 0);
@@ -246,7 +246,7 @@
     rsDebug("Type: ", light->type);
 }
 
-static void getCameraRay(const SgCamera *cam, int screenX, int screenY, float3 *pnt, float3 *vec) {
+static inline void getCameraRay(const SgCamera *cam, int screenX, int screenY, float3 *pnt, float3 *vec) {
     rsDebug("=================================", screenX);
     rsDebug("Point X", screenX);
     rsDebug("Point Y", screenY);
@@ -290,7 +290,7 @@
     *pnt = cam->position.xyz;
 }
 
-static bool intersect(const SgRenderable *obj, float3 pnt, float3 vec) {
+static inline bool intersect(const SgRenderable *obj, float3 pnt, float3 vec) {
     // Solving for t^2 + Bt + C = 0
     float3 originMinusCenter = pnt - obj->worldBoundingSphere.xyz;
     float B = dot(originMinusCenter, vec) * 2.0f;
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs
index 941b5a8..1d0b5be 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs
@@ -26,6 +26,7 @@
 } ParentData;
 
 //#define DEBUG_TRANSFORMS
+/* Unused function:
 static void debugTransform(SgTransform *data, const ParentData *parent) {
     rsDebug("****** <Transform> ******", (int)data);
     printName(data->name);
@@ -53,6 +54,7 @@
     rsDebug("timestamp", data->timestamp);
     rsDebug("****** </Transform> ******", (int)data);
 }
+*/
 
 static void appendTransformation(int type, float4 data, rs_matrix4x4 *mat) {
     rs_matrix4x4 temp;
@@ -119,7 +121,7 @@
     }
 
     if (rsIsObject(data->children)) {
-        rs_allocation nullAlloc;
+        rs_allocation nullAlloc = {0};
         rsForEach(gTransformScript, data->children, nullAlloc, &toChild, sizeof(toChild));
     }
 
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs
index 997a1a7..d94da52 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs
@@ -41,9 +41,7 @@
     gRotate = 0.0f;
 }
 
-static int pos = 50;
 static float gRotateY = 120.0f;
-static float3 gLookAt = 0;
 static float gZoom = 50.0f;
 static void displayLoading() {
     if (rsIsObject(gRobotTex) && rsIsObject(gRobotMesh)) {
diff --git a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs
index ae32e3a..735f6b9 100644
--- a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs
+++ b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs
@@ -131,7 +131,6 @@
     rs_allocation allMeshes = rsGetAllocation(gMeshes);
     int size = rsAllocationGetDimX(allMeshes);
     gLookAt = 0.0f;
-    float minX, minY, minZ, maxX, maxY, maxZ;
     for (int i = 0; i < size; i++) {
         MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
         rsgDrawMesh(info->mMesh);