Home | History | Annotate | Download | only in jni
      1 /*
      2 **
      3 ** Copyright 2009, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 // This source file is automatically generated
     19 
     20 #pragma GCC diagnostic ignored "-Wunused-variable"
     21 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
     22 #pragma GCC diagnostic ignored "-Wunused-function"
     23 
     24 #include <GLES/gl.h>
     25 #include <GLES/glext.h>
     26 
     27 #include <jni.h>
     28 #include <JNIHelp.h>
     29 #include <android_runtime/AndroidRuntime.h>
     30 #include <utils/misc.h>
     31 #include <assert.h>
     32 
     33 static int initialized = 0;
     34 
     35 static jclass nioAccessClass;
     36 static jclass bufferClass;
     37 static jmethodID getBasePointerID;
     38 static jmethodID getBaseArrayID;
     39 static jmethodID getBaseArrayOffsetID;
     40 static jfieldID positionID;
     41 static jfieldID limitID;
     42 static jfieldID elementSizeShiftID;
     43 
     44 
     45 /* special calls implemented in Android's GLES wrapper used to more
     46  * efficiently bound-check passed arrays */
     47 extern "C" {
     48 #ifdef GL_VERSION_ES_CM_1_1
     49 GL_API void GL_APIENTRY glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
     50         const GLvoid *ptr, GLsizei count);
     51 GL_API void GL_APIENTRY glNormalPointerBounds(GLenum type, GLsizei stride,
     52         const GLvoid *pointer, GLsizei count);
     53 GL_API void GL_APIENTRY glTexCoordPointerBounds(GLint size, GLenum type,
     54         GLsizei stride, const GLvoid *pointer, GLsizei count);
     55 GL_API void GL_APIENTRY glVertexPointerBounds(GLint size, GLenum type,
     56         GLsizei stride, const GLvoid *pointer, GLsizei count);
     57 GL_API void GL_APIENTRY glPointSizePointerOESBounds(GLenum type,
     58         GLsizei stride, const GLvoid *pointer, GLsizei count);
     59 GL_API void GL_APIENTRY glMatrixIndexPointerOESBounds(GLint size, GLenum type,
     60         GLsizei stride, const GLvoid *pointer, GLsizei count);
     61 GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type,
     62         GLsizei stride, const GLvoid *pointer, GLsizei count);
     63 #endif
     64 #ifdef GL_ES_VERSION_2_0
     65 static void glVertexAttribPointerBounds(GLuint indx, GLint size, GLenum type,
     66         GLboolean normalized, GLsizei stride, const GLvoid *pointer, GLsizei count) {
     67     glVertexAttribPointer(indx, size, type, normalized, stride, pointer);
     68 }
     69 #endif
     70 #ifdef GL_ES_VERSION_3_0
     71 static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type,
     72         GLsizei stride, const GLvoid *pointer, GLsizei count) {
     73     glVertexAttribIPointer(indx, size, type, stride, pointer);
     74 }
     75 #endif
     76 }
     77 
     78 /* Cache method IDs each time the class is loaded. */
     79 
     80 static void
     81 nativeClassInit(JNIEnv *_env, jclass glImplClass)
     82 {
     83     jclass nioAccessClassLocal = _env->FindClass("java/nio/NIOAccess");
     84     nioAccessClass = (jclass) _env->NewGlobalRef(nioAccessClassLocal);
     85 
     86     jclass bufferClassLocal = _env->FindClass("java/nio/Buffer");
     87     bufferClass = (jclass) _env->NewGlobalRef(bufferClassLocal);
     88 
     89     getBasePointerID = _env->GetStaticMethodID(nioAccessClass,
     90             "getBasePointer", "(Ljava/nio/Buffer;)J");
     91     getBaseArrayID = _env->GetStaticMethodID(nioAccessClass,
     92             "getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;");
     93     getBaseArrayOffsetID = _env->GetStaticMethodID(nioAccessClass,
     94             "getBaseArrayOffset", "(Ljava/nio/Buffer;)I");
     95 
     96     positionID = _env->GetFieldID(bufferClass, "position", "I");
     97     limitID = _env->GetFieldID(bufferClass, "limit", "I");
     98     elementSizeShiftID =
     99         _env->GetFieldID(bufferClass, "_elementSizeShift", "I");
    100 }
    101 
    102 static void *
    103 getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *offset)
    104 {
    105     jint position;
    106     jint limit;
    107     jint elementSizeShift;
    108     jlong pointer;
    109 
    110     position = _env->GetIntField(buffer, positionID);
    111     limit = _env->GetIntField(buffer, limitID);
    112     elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
    113     *remaining = (limit - position) << elementSizeShift;
    114     pointer = _env->CallStaticLongMethod(nioAccessClass,
    115             getBasePointerID, buffer);
    116     if (pointer != 0L) {
    117         *array = NULL;
    118         return reinterpret_cast<void*>(pointer);
    119     }
    120 
    121     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
    122             getBaseArrayID, buffer);
    123     *offset = _env->CallStaticIntMethod(nioAccessClass,
    124             getBaseArrayOffsetID, buffer);
    125 
    126     return NULL;
    127 }
    128 
    129 class ByteArrayGetter {
    130 public:
    131     static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
    132         return _env->GetByteArrayElements(array, is_copy);
    133     }
    134 };
    135 class BooleanArrayGetter {
    136 public:
    137     static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
    138         return _env->GetBooleanArrayElements(array, is_copy);
    139     }
    140 };
    141 class CharArrayGetter {
    142 public:
    143     static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
    144         return _env->GetCharArrayElements(array, is_copy);
    145     }
    146 };
    147 class ShortArrayGetter {
    148 public:
    149     static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
    150         return _env->GetShortArrayElements(array, is_copy);
    151     }
    152 };
    153 class IntArrayGetter {
    154 public:
    155     static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
    156         return _env->GetIntArrayElements(array, is_copy);
    157     }
    158 };
    159 class LongArrayGetter {
    160 public:
    161     static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
    162         return _env->GetLongArrayElements(array, is_copy);
    163     }
    164 };
    165 class FloatArrayGetter {
    166 public:
    167     static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
    168         return _env->GetFloatArrayElements(array, is_copy);
    169     }
    170 };
    171 class DoubleArrayGetter {
    172 public:
    173     static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
    174         return _env->GetDoubleArrayElements(array, is_copy);
    175     }
    176 };
    177 
    178 template<typename JTYPEARRAY, typename ARRAYGETTER>
    179 static void*
    180 getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
    181     return ARRAYGETTER::Get(_env, array, is_copy);
    182 }
    183 
    184 class ByteArrayReleaser {
    185 public:
    186     static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
    187         _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
    188     }
    189 };
    190 class BooleanArrayReleaser {
    191 public:
    192     static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
    193         _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
    194     }
    195 };
    196 class CharArrayReleaser {
    197 public:
    198     static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
    199         _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
    200     }
    201 };
    202 class ShortArrayReleaser {
    203 public:
    204     static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
    205         _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
    206     }
    207 };
    208 class IntArrayReleaser {
    209 public:
    210     static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
    211         _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
    212     }
    213 };
    214 class LongArrayReleaser {
    215 public:
    216     static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
    217         _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
    218     }
    219 };
    220 class FloatArrayReleaser {
    221 public:
    222     static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
    223         _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
    224     }
    225 };
    226 class DoubleArrayReleaser {
    227 public:
    228     static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
    229         _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
    230     }
    231 };
    232 
    233 template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
    234 static void
    235 releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
    236     ARRAYRELEASER::Release(_env, array, data, commit);
    237 }
    238 
    239 static void
    240 releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
    241 {
    242     _env->ReleasePrimitiveArrayCritical(array, data,
    243                        commit ? 0 : JNI_ABORT);
    244 }
    245 
    246 static void *
    247 getDirectBufferPointer(JNIEnv *_env, jobject buffer) {
    248     char* buf = (char*) _env->GetDirectBufferAddress(buffer);
    249     if (buf) {
    250         jint position = _env->GetIntField(buffer, positionID);
    251         jint elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
    252         buf += position << elementSizeShift;
    253     } else {
    254         jniThrowException(_env, "java/lang/IllegalArgumentException",
    255                           "Must use a native order direct Buffer");
    256     }
    257     return (void*) buf;
    258 }
    259 
    260 // --------------------------------------------------------------------------
    261 
    262 /*
    263  * returns the number of values glGet returns for a given pname.
    264  *
    265  * The code below is written such that pnames requiring only one values
    266  * are the default (and are not explicitely tested for). This makes the
    267  * checking code much shorter/readable/efficient.
    268  *
    269  * This means that unknown pnames (e.g.: extensions) will default to 1. If
    270  * that unknown pname needs more than 1 value, then the validation check
    271  * is incomplete and the app may crash if it passed the wrong number params.
    272  */
    273 static int getNeededCount(GLint pname) {
    274     int needed = 1;
    275 #ifdef GL_ES_VERSION_2_0
    276     // GLES 2.x pnames
    277     switch (pname) {
    278         case GL_ALIASED_LINE_WIDTH_RANGE:
    279         case GL_ALIASED_POINT_SIZE_RANGE:
    280             needed = 2;
    281             break;
    282 
    283         case GL_BLEND_COLOR:
    284         case GL_COLOR_CLEAR_VALUE:
    285         case GL_COLOR_WRITEMASK:
    286         case GL_SCISSOR_BOX:
    287         case GL_VIEWPORT:
    288             needed = 4;
    289             break;
    290 
    291         case GL_COMPRESSED_TEXTURE_FORMATS:
    292             glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &needed);
    293             break;
    294 
    295         case GL_SHADER_BINARY_FORMATS:
    296             glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &needed);
    297             break;
    298     }
    299 #endif
    300 
    301 #ifdef GL_VERSION_ES_CM_1_1
    302     // GLES 1.x pnames
    303     switch (pname) {
    304         case GL_ALIASED_LINE_WIDTH_RANGE:
    305         case GL_ALIASED_POINT_SIZE_RANGE:
    306         case GL_DEPTH_RANGE:
    307         case GL_SMOOTH_LINE_WIDTH_RANGE:
    308         case GL_SMOOTH_POINT_SIZE_RANGE:
    309             needed = 2;
    310             break;
    311 
    312         case GL_CURRENT_NORMAL:
    313         case GL_POINT_DISTANCE_ATTENUATION:
    314             needed = 3;
    315             break;
    316 
    317         case GL_COLOR_CLEAR_VALUE:
    318         case GL_COLOR_WRITEMASK:
    319         case GL_CURRENT_COLOR:
    320         case GL_CURRENT_TEXTURE_COORDS:
    321         case GL_FOG_COLOR:
    322         case GL_LIGHT_MODEL_AMBIENT:
    323         case GL_SCISSOR_BOX:
    324         case GL_VIEWPORT:
    325             needed = 4;
    326             break;
    327 
    328         case GL_MODELVIEW_MATRIX:
    329         case GL_PROJECTION_MATRIX:
    330         case GL_TEXTURE_MATRIX:
    331             needed = 16;
    332             break;
    333 
    334         case GL_COMPRESSED_TEXTURE_FORMATS:
    335             glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &needed);
    336             break;
    337     }
    338 #endif
    339     return needed;
    340 }
    341 
    342 template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
    343           typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
    344 static void
    345 get
    346   (JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
    347     jint _exception = 0;
    348     const char * _exceptionType;
    349     const char * _exceptionMessage;
    350     CTYPE *params_base = (CTYPE *) 0;
    351     jint _remaining;
    352     CTYPE *params = (CTYPE *) 0;
    353     int _needed = 0;
    354 
    355     if (!params_ref) {
    356         _exception = 1;
    357         _exceptionType = "java/lang/IllegalArgumentException";
    358         _exceptionMessage = "params == null";
    359         goto exit;
    360     }
    361     if (offset < 0) {
    362         _exception = 1;
    363         _exceptionType = "java/lang/IllegalArgumentException";
    364         _exceptionMessage = "offset < 0";
    365         goto exit;
    366     }
    367     _remaining = _env->GetArrayLength(params_ref) - offset;
    368     _needed = getNeededCount(pname);
    369     // if we didn't find this pname, we just assume the user passed
    370     // an array of the right size -- this might happen with extensions
    371     // or if we forget an enum here.
    372     if (_remaining < _needed) {
    373         _exception = 1;
    374         _exceptionType = "java/lang/IllegalArgumentException";
    375         _exceptionMessage = "length - offset < needed";
    376         goto exit;
    377     }
    378     params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
    379         _env, params_ref, (jboolean *)0);
    380     params = params_base + offset;
    381 
    382     GET(
    383         (GLenum)pname,
    384         (CTYPE *)params
    385     );
    386 
    387 exit:
    388     if (params_base) {
    389         releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
    390             _env, params_ref, params_base, !_exception);
    391     }
    392     if (_exception) {
    393         jniThrowException(_env, _exceptionType, _exceptionMessage);
    394     }
    395 }
    396 
    397 
    398 template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
    399           typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
    400 static void
    401 getarray
    402   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
    403     jint _exception = 0;
    404     const char * _exceptionType;
    405     const char * _exceptionMessage;
    406     JTYPEARRAY _array = (JTYPEARRAY) 0;
    407     jint _bufferOffset = (jint) 0;
    408     jint _remaining;
    409     CTYPE *params = (CTYPE *) 0;
    410     int _needed = 0;
    411 
    412     params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
    413     _remaining /= sizeof(CTYPE);    // convert from bytes to item count
    414     _needed = getNeededCount(pname);
    415     // if we didn't find this pname, we just assume the user passed
    416     // an array of the right size -- this might happen with extensions
    417     // or if we forget an enum here.
    418     if (_needed>0 && _remaining < _needed) {
    419         _exception = 1;
    420         _exceptionType = "java/lang/IllegalArgumentException";
    421         _exceptionMessage = "remaining() < needed";
    422         goto exit;
    423     }
    424     if (params == NULL) {
    425         char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
    426             _env, _array, (jboolean *) 0);
    427         params = (CTYPE *) (_paramsBase + _bufferOffset);
    428     }
    429     GET(
    430         (GLenum)pname,
    431         (CTYPE *)params
    432     );
    433 
    434 exit:
    435     if (_array) {
    436         releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
    437             _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
    438     }
    439     if (_exception) {
    440         jniThrowException(_env, _exceptionType, _exceptionMessage);
    441     }
    442 }
    443 
    444 // --------------------------------------------------------------------------
    445 /* GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent ) */
    446 static jint
    447 android_glQueryMatrixxOES___3II_3II
    448   (JNIEnv *_env, jobject _this, jintArray mantissa_ref, jint mantissaOffset, jintArray exponent_ref, jint exponentOffset) {
    449     jint _exception = 0;
    450     const char * _exceptionType = NULL;
    451     const char * _exceptionMessage = NULL;
    452     GLbitfield _returnValue = -1;
    453     GLfixed *mantissa_base = (GLfixed *) 0;
    454     jint _mantissaRemaining;
    455     GLfixed *mantissa = (GLfixed *) 0;
    456     GLint *exponent_base = (GLint *) 0;
    457     jint _exponentRemaining;
    458     GLint *exponent = (GLint *) 0;
    459 
    460     if (!mantissa_ref) {
    461         _exception = 1;
    462         _exceptionType = "java/lang/IllegalArgumentException";
    463         _exceptionMessage = "mantissa == null";
    464         goto exit;
    465     }
    466     if (mantissaOffset < 0) {
    467         _exception = 1;
    468         _exceptionType = "java/lang/IllegalArgumentException";
    469         _exceptionMessage = "mantissaOffset < 0";
    470         goto exit;
    471     }
    472     _mantissaRemaining = _env->GetArrayLength(mantissa_ref) - mantissaOffset;
    473     if (_mantissaRemaining < 16) {
    474         _exception = 1;
    475         _exceptionType = "java/lang/IllegalArgumentException";
    476         _exceptionMessage = "length - mantissaOffset < 16 < needed";
    477         goto exit;
    478     }
    479     mantissa_base = (GLfixed *)
    480         _env->GetIntArrayElements(mantissa_ref, (jboolean *)0);
    481     mantissa = mantissa_base + mantissaOffset;
    482 
    483     if (!exponent_ref) {
    484         _exception = 1;
    485         _exceptionType = "java/lang/IllegalArgumentException";
    486         _exceptionMessage = "exponent == null";
    487         goto exit;
    488     }
    489     if (exponentOffset < 0) {
    490         _exception = 1;
    491         _exceptionType = "java/lang/IllegalArgumentException";
    492         _exceptionMessage = "exponentOffset < 0";
    493         goto exit;
    494     }
    495     _exponentRemaining = _env->GetArrayLength(exponent_ref) - exponentOffset;
    496     if (_exponentRemaining < 16) {
    497         _exception = 1;
    498         _exceptionType = "java/lang/IllegalArgumentException";
    499         _exceptionMessage = "length - exponentOffset < 16 < needed";
    500         goto exit;
    501     }
    502     exponent_base = (GLint *)
    503         _env->GetIntArrayElements(exponent_ref, (jboolean *)0);
    504     exponent = exponent_base + exponentOffset;
    505 
    506     _returnValue = glQueryMatrixxOES(
    507         (GLfixed *)mantissa,
    508         (GLint *)exponent
    509     );
    510 
    511 exit:
    512     if (exponent_base) {
    513         _env->ReleaseIntArrayElements(exponent_ref, (jint*)exponent_base,
    514             _exception ? JNI_ABORT: 0);
    515     }
    516     if (mantissa_base) {
    517         _env->ReleaseIntArrayElements(mantissa_ref, (jint*)mantissa_base,
    518             _exception ? JNI_ABORT: 0);
    519     }
    520     if (_exception) {
    521         jniThrowException(_env, _exceptionType, _exceptionMessage);
    522     }
    523     return (jint)_returnValue;
    524 }
    525 
    526 /* GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent ) */
    527 static jint
    528 android_glQueryMatrixxOES__Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2
    529   (JNIEnv *_env, jobject _this, jobject mantissa_buf, jobject exponent_buf) {
    530     jint _exception = 0;
    531     const char * _exceptionType = NULL;
    532     const char * _exceptionMessage = NULL;
    533     jintArray _mantissaArray = (jintArray) 0;
    534     jint _mantissaBufferOffset = (jint) 0;
    535     jintArray _exponentArray = (jintArray) 0;
    536     jint _exponentBufferOffset = (jint) 0;
    537     GLbitfield _returnValue = -1;
    538     jint _mantissaRemaining;
    539     GLfixed *mantissa = (GLfixed *) 0;
    540     jint _exponentRemaining;
    541     GLint *exponent = (GLint *) 0;
    542 
    543     mantissa = (GLfixed *)getPointer(_env, mantissa_buf, (jarray*)&_mantissaArray, &_mantissaRemaining, &_mantissaBufferOffset);
    544     if (_mantissaRemaining < 16) {
    545         _exception = 1;
    546         _exceptionType = "java/lang/IllegalArgumentException";
    547         _exceptionMessage = "remaining() < 16 < needed";
    548         goto exit;
    549     }
    550     exponent = (GLint *)getPointer(_env, exponent_buf, (jarray*)&_exponentArray, &_exponentRemaining, &_exponentBufferOffset);
    551     if (_exponentRemaining < 16) {
    552         _exception = 1;
    553         _exceptionType = "java/lang/IllegalArgumentException";
    554         _exceptionMessage = "remaining() < 16 < needed";
    555         goto exit;
    556     }
    557     if (mantissa == NULL) {
    558         char * _mantissaBase = (char *)_env->GetIntArrayElements(_mantissaArray, (jboolean *) 0);
    559         mantissa = (GLfixed *) (_mantissaBase + _mantissaBufferOffset);
    560     }
    561     if (exponent == NULL) {
    562         char * _exponentBase = (char *)_env->GetIntArrayElements(_exponentArray, (jboolean *) 0);
    563         exponent = (GLint *) (_exponentBase + _exponentBufferOffset);
    564     }
    565     _returnValue = glQueryMatrixxOES(
    566         (GLfixed *)mantissa,
    567         (GLint *)exponent
    568     );
    569 
    570 exit:
    571     if (_exponentArray) {
    572         _env->ReleaseIntArrayElements(_exponentArray, (jint*)exponent, _exception ? JNI_ABORT : 0);
    573     }
    574     if (_mantissaArray) {
    575         _env->ReleaseIntArrayElements(_mantissaArray, (jint*)mantissa, _exception ? JNI_ABORT : 0);
    576     }
    577     if (_exception) {
    578         jniThrowException(_env, _exceptionType, _exceptionMessage);
    579     }
    580     return (jint)_returnValue;
    581 }
    582 
    583 static const char *classPathName = "android/opengl/GLES10Ext";
    584 
    585 static const JNINativeMethod methods[] = {
    586 {"_nativeClassInit", "()V", (void*)nativeClassInit },
    587 {"glQueryMatrixxOES", "([II[II)I", (void *) android_glQueryMatrixxOES___3II_3II },
    588 {"glQueryMatrixxOES", "(Ljava/nio/IntBuffer;Ljava/nio/IntBuffer;)I", (void *) android_glQueryMatrixxOES__Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2 },
    589 };
    590 
    591 int register_android_opengl_jni_GLES10Ext(JNIEnv *_env)
    592 {
    593     int err;
    594     err = android::AndroidRuntime::registerNativeMethods(_env, classPathName, methods, NELEM(methods));
    595     return err;
    596 }
    597