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 #include <GLES/gl.h>
     21 #include <GLES/glext.h>
     22 
     23 #include <jni.h>
     24 #include <JNIHelp.h>
     25 #include <android_runtime/AndroidRuntime.h>
     26 #include <utils/misc.h>
     27 #include <assert.h>
     28 
     29 static int initialized = 0;
     30 
     31 static jclass nioAccessClass;
     32 static jclass bufferClass;
     33 static jmethodID getBasePointerID;
     34 static jmethodID getBaseArrayID;
     35 static jmethodID getBaseArrayOffsetID;
     36 static jfieldID positionID;
     37 static jfieldID limitID;
     38 static jfieldID elementSizeShiftID;
     39 
     40 
     41 /* special calls implemented in Android's GLES wrapper used to more
     42  * efficiently bound-check passed arrays */
     43 extern "C" {
     44 #ifdef GL_VERSION_ES_CM_1_1
     45 GL_API void GL_APIENTRY glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
     46         const GLvoid *ptr, GLsizei count);
     47 GL_API void GL_APIENTRY glNormalPointerBounds(GLenum type, GLsizei stride,
     48         const GLvoid *pointer, GLsizei count);
     49 GL_API void GL_APIENTRY glTexCoordPointerBounds(GLint size, GLenum type,
     50         GLsizei stride, const GLvoid *pointer, GLsizei count);
     51 GL_API void GL_APIENTRY glVertexPointerBounds(GLint size, GLenum type,
     52         GLsizei stride, const GLvoid *pointer, GLsizei count);
     53 GL_API void GL_APIENTRY glPointSizePointerOESBounds(GLenum type,
     54         GLsizei stride, const GLvoid *pointer, GLsizei count);
     55 GL_API void GL_APIENTRY glMatrixIndexPointerOESBounds(GLint size, GLenum type,
     56         GLsizei stride, const GLvoid *pointer, GLsizei count);
     57 GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type,
     58         GLsizei stride, const GLvoid *pointer, GLsizei count);
     59 #endif
     60 #ifdef GL_ES_VERSION_2_0
     61 static void glVertexAttribPointerBounds(GLuint indx, GLint size, GLenum type,
     62         GLboolean normalized, GLsizei stride, const GLvoid *pointer, GLsizei count) {
     63     glVertexAttribPointer(indx, size, type, normalized, stride, pointer);
     64 }
     65 #endif
     66 #ifdef GL_ES_VERSION_3_0
     67 static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type,
     68         GLsizei stride, const GLvoid *pointer, GLsizei count) {
     69     glVertexAttribIPointer(indx, size, type, stride, pointer);
     70 }
     71 #endif
     72 }
     73 
     74 /* Cache method IDs each time the class is loaded. */
     75 
     76 static void
     77 nativeClassInit(JNIEnv *_env, jclass glImplClass)
     78 {
     79     jclass nioAccessClassLocal = _env->FindClass("java/nio/NIOAccess");
     80     nioAccessClass = (jclass) _env->NewGlobalRef(nioAccessClassLocal);
     81 
     82     jclass bufferClassLocal = _env->FindClass("java/nio/Buffer");
     83     bufferClass = (jclass) _env->NewGlobalRef(bufferClassLocal);
     84 
     85     getBasePointerID = _env->GetStaticMethodID(nioAccessClass,
     86             "getBasePointer", "(Ljava/nio/Buffer;)J");
     87     getBaseArrayID = _env->GetStaticMethodID(nioAccessClass,
     88             "getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;");
     89     getBaseArrayOffsetID = _env->GetStaticMethodID(nioAccessClass,
     90             "getBaseArrayOffset", "(Ljava/nio/Buffer;)I");
     91 
     92     positionID = _env->GetFieldID(bufferClass, "position", "I");
     93     limitID = _env->GetFieldID(bufferClass, "limit", "I");
     94     elementSizeShiftID =
     95         _env->GetFieldID(bufferClass, "_elementSizeShift", "I");
     96 }
     97 
     98 static void *
     99 getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *offset)
    100 {
    101     jint position;
    102     jint limit;
    103     jint elementSizeShift;
    104     jlong pointer;
    105 
    106     position = _env->GetIntField(buffer, positionID);
    107     limit = _env->GetIntField(buffer, limitID);
    108     elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
    109     *remaining = (limit - position) << elementSizeShift;
    110     pointer = _env->CallStaticLongMethod(nioAccessClass,
    111             getBasePointerID, buffer);
    112     if (pointer != 0L) {
    113         *array = NULL;
    114         return reinterpret_cast<void*>(pointer);
    115     }
    116 
    117     *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
    118             getBaseArrayID, buffer);
    119     *offset = _env->CallStaticIntMethod(nioAccessClass,
    120             getBaseArrayOffsetID, buffer);
    121 
    122     return NULL;
    123 }
    124 
    125 static void
    126 releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
    127 {
    128     _env->ReleasePrimitiveArrayCritical(array, data,
    129                        commit ? 0 : JNI_ABORT);
    130 }
    131 
    132 static void *
    133 getDirectBufferPointer(JNIEnv *_env, jobject buffer) {
    134     char* buf = (char*) _env->GetDirectBufferAddress(buffer);
    135     if (buf) {
    136         jint position = _env->GetIntField(buffer, positionID);
    137         jint elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
    138         buf += position << elementSizeShift;
    139     } else {
    140         jniThrowException(_env, "java/lang/IllegalArgumentException",
    141                           "Must use a native order direct Buffer");
    142     }
    143     return (void*) buf;
    144 }
    145 
    146 // --------------------------------------------------------------------------
    147 
    148 /*
    149  * returns the number of values glGet returns for a given pname.
    150  *
    151  * The code below is written such that pnames requiring only one values
    152  * are the default (and are not explicitely tested for). This makes the
    153  * checking code much shorter/readable/efficient.
    154  *
    155  * This means that unknown pnames (e.g.: extensions) will default to 1. If
    156  * that unknown pname needs more than 1 value, then the validation check
    157  * is incomplete and the app may crash if it passed the wrong number params.
    158  */
    159 static int getNeededCount(GLint pname) {
    160     int needed = 1;
    161 #ifdef GL_ES_VERSION_2_0
    162     // GLES 2.x pnames
    163     switch (pname) {
    164         case GL_ALIASED_LINE_WIDTH_RANGE:
    165         case GL_ALIASED_POINT_SIZE_RANGE:
    166             needed = 2;
    167             break;
    168 
    169         case GL_BLEND_COLOR:
    170         case GL_COLOR_CLEAR_VALUE:
    171         case GL_COLOR_WRITEMASK:
    172         case GL_SCISSOR_BOX:
    173         case GL_VIEWPORT:
    174             needed = 4;
    175             break;
    176 
    177         case GL_COMPRESSED_TEXTURE_FORMATS:
    178             glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &needed);
    179             break;
    180 
    181         case GL_SHADER_BINARY_FORMATS:
    182             glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &needed);
    183             break;
    184     }
    185 #endif
    186 
    187 #ifdef GL_VERSION_ES_CM_1_1
    188     // GLES 1.x pnames
    189     switch (pname) {
    190         case GL_ALIASED_LINE_WIDTH_RANGE:
    191         case GL_ALIASED_POINT_SIZE_RANGE:
    192         case GL_DEPTH_RANGE:
    193         case GL_SMOOTH_LINE_WIDTH_RANGE:
    194         case GL_SMOOTH_POINT_SIZE_RANGE:
    195             needed = 2;
    196             break;
    197 
    198         case GL_CURRENT_NORMAL:
    199         case GL_POINT_DISTANCE_ATTENUATION:
    200             needed = 3;
    201             break;
    202 
    203         case GL_COLOR_CLEAR_VALUE:
    204         case GL_COLOR_WRITEMASK:
    205         case GL_CURRENT_COLOR:
    206         case GL_CURRENT_TEXTURE_COORDS:
    207         case GL_FOG_COLOR:
    208         case GL_LIGHT_MODEL_AMBIENT:
    209         case GL_SCISSOR_BOX:
    210         case GL_VIEWPORT:
    211             needed = 4;
    212             break;
    213 
    214         case GL_MODELVIEW_MATRIX:
    215         case GL_PROJECTION_MATRIX:
    216         case GL_TEXTURE_MATRIX:
    217             needed = 16;
    218             break;
    219 
    220         case GL_COMPRESSED_TEXTURE_FORMATS:
    221             glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &needed);
    222             break;
    223     }
    224 #endif
    225     return needed;
    226 }
    227 
    228 template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
    229 static void
    230 get
    231   (JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
    232     jint _exception = 0;
    233     const char * _exceptionType;
    234     const char * _exceptionMessage;
    235     CTYPE *params_base = (CTYPE *) 0;
    236     jint _remaining;
    237     CTYPE *params = (CTYPE *) 0;
    238     int _needed = 0;
    239 
    240     if (!params_ref) {
    241         _exception = 1;
    242         _exceptionType = "java/lang/IllegalArgumentException";
    243         _exceptionMessage = "params == null";
    244         goto exit;
    245     }
    246     if (offset < 0) {
    247         _exception = 1;
    248         _exceptionType = "java/lang/IllegalArgumentException";
    249         _exceptionMessage = "offset < 0";
    250         goto exit;
    251     }
    252     _remaining = _env->GetArrayLength(params_ref) - offset;
    253     _needed = getNeededCount(pname);
    254     // if we didn't find this pname, we just assume the user passed
    255     // an array of the right size -- this might happen with extensions
    256     // or if we forget an enum here.
    257     if (_remaining < _needed) {
    258         _exception = 1;
    259         _exceptionType = "java/lang/IllegalArgumentException";
    260         _exceptionMessage = "length - offset < needed";
    261         goto exit;
    262     }
    263     params_base = (CTYPE *)
    264         _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
    265     params = params_base + offset;
    266 
    267     GET(
    268         (GLenum)pname,
    269         (CTYPE *)params
    270     );
    271 
    272 exit:
    273     if (params_base) {
    274         _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
    275             _exception ? JNI_ABORT: 0);
    276     }
    277     if (_exception) {
    278         jniThrowException(_env, _exceptionType, _exceptionMessage);
    279     }
    280 }
    281 
    282 
    283 template <typename CTYPE, void GET(GLenum, CTYPE*)>
    284 static void
    285 getarray
    286   (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
    287     jint _exception = 0;
    288     const char * _exceptionType;
    289     const char * _exceptionMessage;
    290     jarray _array = (jarray) 0;
    291     jint _bufferOffset = (jint) 0;
    292     jint _remaining;
    293     CTYPE *params = (CTYPE *) 0;
    294     int _needed = 0;
    295 
    296     params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
    297     _remaining /= sizeof(CTYPE);    // convert from bytes to item count
    298     _needed = getNeededCount(pname);
    299     // if we didn't find this pname, we just assume the user passed
    300     // an array of the right size -- this might happen with extensions
    301     // or if we forget an enum here.
    302     if (_needed>0 && _remaining < _needed) {
    303         _exception = 1;
    304         _exceptionType = "java/lang/IllegalArgumentException";
    305         _exceptionMessage = "remaining() < needed";
    306         goto exit;
    307     }
    308     if (params == NULL) {
    309         char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
    310         params = (CTYPE *) (_paramsBase + _bufferOffset);
    311     }
    312     GET(
    313         (GLenum)pname,
    314         (CTYPE *)params
    315     );
    316 
    317 exit:
    318     if (_array) {
    319         releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
    320     }
    321     if (_exception) {
    322         jniThrowException(_env, _exceptionType, _exceptionMessage);
    323     }
    324 }
    325 
    326 // --------------------------------------------------------------------------
    327 /* GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent ) */
    328 static jint
    329 android_glQueryMatrixxOES___3II_3II
    330   (JNIEnv *_env, jobject _this, jintArray mantissa_ref, jint mantissaOffset, jintArray exponent_ref, jint exponentOffset) {
    331     jint _exception = 0;
    332     const char * _exceptionType = NULL;
    333     const char * _exceptionMessage = NULL;
    334     GLbitfield _returnValue = -1;
    335     GLfixed *mantissa_base = (GLfixed *) 0;
    336     jint _mantissaRemaining;
    337     GLfixed *mantissa = (GLfixed *) 0;
    338     GLint *exponent_base = (GLint *) 0;
    339     jint _exponentRemaining;
    340     GLint *exponent = (GLint *) 0;
    341 
    342     if (!mantissa_ref) {
    343         _exception = 1;
    344         _exceptionType = "java/lang/IllegalArgumentException";
    345         _exceptionMessage = "mantissa == null";
    346         goto exit;
    347     }
    348     if (mantissaOffset < 0) {
    349         _exception = 1;
    350         _exceptionType = "java/lang/IllegalArgumentException";
    351         _exceptionMessage = "mantissaOffset < 0";
    352         goto exit;
    353     }
    354     _mantissaRemaining = _env->GetArrayLength(mantissa_ref) - mantissaOffset;
    355     if (_mantissaRemaining < 16) {
    356         _exception = 1;
    357         _exceptionType = "java/lang/IllegalArgumentException";
    358         _exceptionMessage = "length - mantissaOffset < 16 < needed";
    359         goto exit;
    360     }
    361     mantissa_base = (GLfixed *)
    362         _env->GetPrimitiveArrayCritical(mantissa_ref, (jboolean *)0);
    363     mantissa = mantissa_base + mantissaOffset;
    364 
    365     if (!exponent_ref) {
    366         _exception = 1;
    367         _exceptionType = "java/lang/IllegalArgumentException";
    368         _exceptionMessage = "exponent == null";
    369         goto exit;
    370     }
    371     if (exponentOffset < 0) {
    372         _exception = 1;
    373         _exceptionType = "java/lang/IllegalArgumentException";
    374         _exceptionMessage = "exponentOffset < 0";
    375         goto exit;
    376     }
    377     _exponentRemaining = _env->GetArrayLength(exponent_ref) - exponentOffset;
    378     if (_exponentRemaining < 16) {
    379         _exception = 1;
    380         _exceptionType = "java/lang/IllegalArgumentException";
    381         _exceptionMessage = "length - exponentOffset < 16 < needed";
    382         goto exit;
    383     }
    384     exponent_base = (GLint *)
    385         _env->GetPrimitiveArrayCritical(exponent_ref, (jboolean *)0);
    386     exponent = exponent_base + exponentOffset;
    387 
    388     _returnValue = glQueryMatrixxOES(
    389         (GLfixed *)mantissa,
    390         (GLint *)exponent
    391     );
    392 
    393 exit:
    394     if (exponent_base) {
    395         _env->ReleasePrimitiveArrayCritical(exponent_ref, exponent_base,
    396             _exception ? JNI_ABORT: 0);
    397     }
    398     if (mantissa_base) {
    399         _env->ReleasePrimitiveArrayCritical(mantissa_ref, mantissa_base,
    400             _exception ? JNI_ABORT: 0);
    401     }
    402     if (_exception) {
    403         jniThrowException(_env, _exceptionType, _exceptionMessage);
    404     }
    405     return (jint)_returnValue;
    406 }
    407 
    408 /* GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent ) */
    409 static jint
    410 android_glQueryMatrixxOES__Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2
    411   (JNIEnv *_env, jobject _this, jobject mantissa_buf, jobject exponent_buf) {
    412     jint _exception = 0;
    413     const char * _exceptionType = NULL;
    414     const char * _exceptionMessage = NULL;
    415     jarray _mantissaArray = (jarray) 0;
    416     jint _mantissaBufferOffset = (jint) 0;
    417     jarray _exponentArray = (jarray) 0;
    418     jint _exponentBufferOffset = (jint) 0;
    419     GLbitfield _returnValue = -1;
    420     jint _mantissaRemaining;
    421     GLfixed *mantissa = (GLfixed *) 0;
    422     jint _exponentRemaining;
    423     GLint *exponent = (GLint *) 0;
    424 
    425     mantissa = (GLfixed *)getPointer(_env, mantissa_buf, &_mantissaArray, &_mantissaRemaining, &_mantissaBufferOffset);
    426     if (_mantissaRemaining < 16) {
    427         _exception = 1;
    428         _exceptionType = "java/lang/IllegalArgumentException";
    429         _exceptionMessage = "remaining() < 16 < needed";
    430         goto exit;
    431     }
    432     exponent = (GLint *)getPointer(_env, exponent_buf, &_exponentArray, &_exponentRemaining, &_exponentBufferOffset);
    433     if (_exponentRemaining < 16) {
    434         _exception = 1;
    435         _exceptionType = "java/lang/IllegalArgumentException";
    436         _exceptionMessage = "remaining() < 16 < needed";
    437         goto exit;
    438     }
    439     if (mantissa == NULL) {
    440         char * _mantissaBase = (char *)_env->GetPrimitiveArrayCritical(_mantissaArray, (jboolean *) 0);
    441         mantissa = (GLfixed *) (_mantissaBase + _mantissaBufferOffset);
    442     }
    443     if (exponent == NULL) {
    444         char * _exponentBase = (char *)_env->GetPrimitiveArrayCritical(_exponentArray, (jboolean *) 0);
    445         exponent = (GLint *) (_exponentBase + _exponentBufferOffset);
    446     }
    447     _returnValue = glQueryMatrixxOES(
    448         (GLfixed *)mantissa,
    449         (GLint *)exponent
    450     );
    451 
    452 exit:
    453     if (_exponentArray) {
    454         releasePointer(_env, _exponentArray, exponent, _exception ? JNI_FALSE : JNI_TRUE);
    455     }
    456     if (_mantissaArray) {
    457         releasePointer(_env, _mantissaArray, mantissa, _exception ? JNI_FALSE : JNI_TRUE);
    458     }
    459     if (_exception) {
    460         jniThrowException(_env, _exceptionType, _exceptionMessage);
    461     }
    462     return (jint)_returnValue;
    463 }
    464 
    465 static const char *classPathName = "android/opengl/GLES10Ext";
    466 
    467 static JNINativeMethod methods[] = {
    468 {"_nativeClassInit", "()V", (void*)nativeClassInit },
    469 {"glQueryMatrixxOES", "([II[II)I", (void *) android_glQueryMatrixxOES___3II_3II },
    470 {"glQueryMatrixxOES", "(Ljava/nio/IntBuffer;Ljava/nio/IntBuffer;)I", (void *) android_glQueryMatrixxOES__Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2 },
    471 };
    472 
    473 int register_android_opengl_jni_GLES10Ext(JNIEnv *_env)
    474 {
    475     int err;
    476     err = android::AndroidRuntime::registerNativeMethods(_env, classPathName, methods, NELEM(methods));
    477     return err;
    478 }
    479