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