android_renderscript_RenderScript.cpp revision 768bc02d815a94ad29146f1ed60c847d1af118cc
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "libRS_jni" 18 19#include <stdlib.h> 20#include <stdio.h> 21#include <fcntl.h> 22#include <unistd.h> 23#include <math.h> 24#include <utils/misc.h> 25 26#include <ui/Surface.h> 27 28#include <core/SkBitmap.h> 29#include <core/SkPixelRef.h> 30#include <core/SkStream.h> 31#include <core/SkTemplates.h> 32#include <images/SkImageDecoder.h> 33 34#include <utils/Asset.h> 35#include <utils/ResourceTypes.h> 36 37#include "jni.h" 38#include "JNIHelp.h" 39#include "android_runtime/AndroidRuntime.h" 40 41#include <RenderScript.h> 42#include <RenderScriptEnv.h> 43 44//#define LOG_API LOGE 45#define LOG_API(...) 46 47using namespace android; 48 49// --------------------------------------------------------------------------- 50 51static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL) 52{ 53 jclass npeClazz = env->FindClass(exc); 54 env->ThrowNew(npeClazz, msg); 55} 56 57static jfieldID gContextId = 0; 58static jfieldID gNativeBitmapID = 0; 59static jfieldID gTypeNativeCache = 0; 60 61static RsElement g_A_8 = NULL; 62static RsElement g_RGBA_4444 = NULL; 63static RsElement g_RGBA_8888 = NULL; 64static RsElement g_RGB_565 = NULL; 65 66static void _nInit(JNIEnv *_env, jclass _this) 67{ 68 gContextId = _env->GetFieldID(_this, "mContext", "I"); 69 70 jclass bitmapClass = _env->FindClass("android/graphics/Bitmap"); 71 gNativeBitmapID = _env->GetFieldID(bitmapClass, "mNativeBitmap", "I"); 72 73 jclass typeClass = _env->FindClass("android/renderscript/Type"); 74 gTypeNativeCache = _env->GetFieldID(typeClass, "mNativeCache", "I"); 75} 76 77static void nInitElements(JNIEnv *_env, jobject _this, jint a8, jint rgba4444, jint rgba8888, jint rgb565) 78{ 79 g_A_8 = reinterpret_cast<RsElement>(a8); 80 g_RGBA_4444 = reinterpret_cast<RsElement>(rgba4444); 81 g_RGBA_8888 = reinterpret_cast<RsElement>(rgba8888); 82 g_RGB_565 = reinterpret_cast<RsElement>(rgb565); 83} 84 85// --------------------------------------------------------------------------- 86 87static void 88nAssignName(JNIEnv *_env, jobject _this, jint obj, jbyteArray str) 89{ 90 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 91 LOG_API("nAssignName, con(%p), obj(%p)", con, (void *)obj); 92 93 jint len = _env->GetArrayLength(str); 94 jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0); 95 rsAssignName(con, (void *)obj, (const char *)cptr, len); 96 _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT); 97} 98 99static void 100nObjDestroy(JNIEnv *_env, jobject _this, jint obj) 101{ 102 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 103 LOG_API("nObjDestroy, con(%p) obj(%p)", con, (void *)obj); 104 rsObjDestroy(con, (void *)obj); 105} 106 107static void 108nObjDestroyOOB(JNIEnv *_env, jobject _this, jint obj) 109{ 110 // This function only differs from nObjDestroy in that it calls the 111 // special Out Of Band version of ObjDestroy which is thread safe. 112 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 113 LOG_API("nObjDestroyOOB, con(%p) obj(%p)", con, (void *)obj); 114 rsObjDestroyOOB(con, (void *)obj); 115} 116 117static jint 118nFileOpen(JNIEnv *_env, jobject _this, jbyteArray str) 119{ 120 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 121 LOG_API("nFileOpen, con(%p)", con); 122 123 jint len = _env->GetArrayLength(str); 124 jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0); 125 jint ret = (jint)rsFileOpen(con, (const char *)cptr, len); 126 _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT); 127 return ret; 128} 129 130// --------------------------------------------------------------------------- 131 132static jint 133nDeviceCreate(JNIEnv *_env, jobject _this) 134{ 135 LOG_API("nDeviceCreate"); 136 return (jint)rsDeviceCreate(); 137} 138 139static void 140nDeviceDestroy(JNIEnv *_env, jobject _this, jint dev) 141{ 142 LOG_API("nDeviceDestroy"); 143 return rsDeviceDestroy((RsDevice)dev); 144} 145 146static jint 147nContextCreate(JNIEnv *_env, jobject _this, jint dev, jobject wnd, jint ver, jboolean useDepth) 148{ 149 LOG_API("nContextCreate"); 150 151 if (wnd == NULL) { 152 not_valid_surface: 153 doThrow(_env, "java/lang/IllegalArgumentException", 154 "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface"); 155 return 0; 156 } 157 jclass surface_class = _env->FindClass("android/view/Surface"); 158 jfieldID surfaceFieldID = _env->GetFieldID(surface_class, "mSurface", "I"); 159 Surface * window = (Surface*)_env->GetIntField(wnd, surfaceFieldID); 160 if (window == NULL) 161 goto not_valid_surface; 162 163 return (jint)rsContextCreate((RsDevice)dev, window, ver, useDepth); 164} 165 166static void 167nContextDestroy(JNIEnv *_env, jobject _this, jint con) 168{ 169 LOG_API("nContextDestroy, con(%p)", (RsContext)con); 170 return rsContextDestroy((RsContext)con); 171} 172 173 174static void 175nElementBegin(JNIEnv *_env, jobject _this) 176{ 177 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 178 LOG_API("nElementBegin, con(%p)", con); 179 rsElementBegin(con); 180} 181 182 183static void 184nElementAdd(JNIEnv *_env, jobject _this, jint kind, jint type, jboolean norm, jint bits, jstring name) 185{ 186 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 187 const char* n = NULL; 188 if (name) { 189 n = _env->GetStringUTFChars(name, NULL); 190 } 191 LOG_API("nElementAdd, con(%p), kind(%i), type(%i), norm(%i), bits(%i)", con, kind, type, norm, bits); 192 rsElementAdd(con, (RsDataKind)kind, (RsDataType)type, norm != 0, (size_t)bits, n); 193 if (n) { 194 _env->ReleaseStringUTFChars(name, n); 195 } 196} 197 198static jint 199nElementCreate(JNIEnv *_env, jobject _this) 200{ 201 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 202 LOG_API("nElementCreate, con(%p)", con); 203 return (jint)rsElementCreate(con); 204} 205 206// ----------------------------------- 207 208static void 209nTypeBegin(JNIEnv *_env, jobject _this, jint eID) 210{ 211 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 212 LOG_API("nTypeBegin, con(%p) e(%p)", con, (RsElement)eID); 213 rsTypeBegin(con, (RsElement)eID); 214} 215 216static void 217nTypeAdd(JNIEnv *_env, jobject _this, jint dim, jint val) 218{ 219 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 220 LOG_API("nTypeAdd, con(%p) dim(%i), val(%i)", con, dim, val); 221 rsTypeAdd(con, (RsDimension)dim, val); 222} 223 224static jint 225nTypeCreate(JNIEnv *_env, jobject _this) 226{ 227 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 228 LOG_API("nTypeCreate, con(%p)", con); 229 return (jint)rsTypeCreate(con); 230} 231 232static void * SF_LoadInt(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer) 233{ 234 ((int32_t *)buffer)[0] = _env->GetIntField(_obj, _field); 235 return ((uint8_t *)buffer) + 4; 236} 237 238static void * SF_LoadShort(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer) 239{ 240 ((int16_t *)buffer)[0] = _env->GetShortField(_obj, _field); 241 return ((uint8_t *)buffer) + 2; 242} 243 244static void * SF_LoadByte(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer) 245{ 246 ((int8_t *)buffer)[0] = _env->GetByteField(_obj, _field); 247 return ((uint8_t *)buffer) + 1; 248} 249 250static void * SF_LoadFloat(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer) 251{ 252 ((float *)buffer)[0] = _env->GetFloatField(_obj, _field); 253 return ((uint8_t *)buffer) + 4; 254} 255 256static void * SF_SaveInt(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer) 257{ 258 _env->SetIntField(_obj, _field, ((int32_t *)buffer)[0]); 259 return ((uint8_t *)buffer) + 4; 260} 261 262static void * SF_SaveShort(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer) 263{ 264 _env->SetShortField(_obj, _field, ((int16_t *)buffer)[0]); 265 return ((uint8_t *)buffer) + 2; 266} 267 268static void * SF_SaveByte(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer) 269{ 270 _env->SetByteField(_obj, _field, ((int8_t *)buffer)[0]); 271 return ((uint8_t *)buffer) + 1; 272} 273 274static void * SF_SaveFloat(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer) 275{ 276 _env->SetFloatField(_obj, _field, ((float *)buffer)[0]); 277 return ((uint8_t *)buffer) + 4; 278} 279 280struct TypeFieldCache { 281 jfieldID field; 282 int bits; 283 void * (*ptr)(JNIEnv *, jobject, jfieldID, void *buffer); 284 void * (*readPtr)(JNIEnv *, jobject, jfieldID, void *buffer); 285}; 286 287struct TypeCache { 288 int fieldCount; 289 int size; 290 TypeFieldCache fields[1]; 291}; 292 293//{"nTypeFinalDestroy", "(Landroid/renderscript/Type;)V", (void*)nTypeFinalDestroy }, 294static void 295nTypeFinalDestroy(JNIEnv *_env, jobject _this, jobject _type) 296{ 297 TypeCache *tc = (TypeCache *)_env->GetIntField(_type, gTypeNativeCache); 298 free(tc); 299} 300 301// native void nTypeSetupFields(Type t, int[] types, int[] bits, Field[] IDs); 302static void 303nTypeSetupFields(JNIEnv *_env, jobject _this, jobject _type, jintArray _types, jintArray _bits, jobjectArray _IDs) 304{ 305 int fieldCount = _env->GetArrayLength(_types); 306 size_t structSize = sizeof(TypeCache) + (sizeof(TypeFieldCache) * (fieldCount-1)); 307 TypeCache *tc = (TypeCache *)malloc(structSize); 308 memset(tc, 0, structSize); 309 310 TypeFieldCache *tfc = &tc->fields[0]; 311 tc->fieldCount = fieldCount; 312 _env->SetIntField(_type, gTypeNativeCache, (jint)tc); 313 314 jint *fType = _env->GetIntArrayElements(_types, NULL); 315 jint *fBits = _env->GetIntArrayElements(_bits, NULL); 316 for (int ct=0; ct < fieldCount; ct++) { 317 jobject field = _env->GetObjectArrayElement(_IDs, ct); 318 tfc[ct].field = _env->FromReflectedField(field); 319 tfc[ct].bits = fBits[ct]; 320 321 switch(fType[ct]) { 322 case RS_TYPE_FLOAT: 323 tfc[ct].ptr = SF_LoadFloat; 324 tfc[ct].readPtr = SF_SaveFloat; 325 break; 326 case RS_TYPE_UNSIGNED: 327 case RS_TYPE_SIGNED: 328 switch(tfc[ct].bits) { 329 case 32: 330 tfc[ct].ptr = SF_LoadInt; 331 tfc[ct].readPtr = SF_SaveInt; 332 break; 333 case 16: 334 tfc[ct].ptr = SF_LoadShort; 335 tfc[ct].readPtr = SF_SaveShort; 336 break; 337 case 8: 338 tfc[ct].ptr = SF_LoadByte; 339 tfc[ct].readPtr = SF_SaveByte; 340 break; 341 } 342 break; 343 } 344 tc->size += 4; 345 } 346 347 _env->ReleaseIntArrayElements(_types, fType, JNI_ABORT); 348 _env->ReleaseIntArrayElements(_bits, fBits, JNI_ABORT); 349} 350 351 352// ----------------------------------- 353 354static jint 355nAllocationCreateTyped(JNIEnv *_env, jobject _this, jint e) 356{ 357 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 358 LOG_API("nAllocationCreateTyped, con(%p), e(%p)", con, (RsElement)e); 359 return (jint) rsAllocationCreateTyped(con, (RsElement)e); 360} 361 362static void 363nAllocationUploadToTexture(JNIEnv *_env, jobject _this, jint a, jint mip) 364{ 365 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 366 LOG_API("nAllocationUploadToTexture, con(%p), a(%p), mip(%i)", con, (RsAllocation)a, mip); 367 rsAllocationUploadToTexture(con, (RsAllocation)a, mip); 368} 369 370static void 371nAllocationUploadToBufferObject(JNIEnv *_env, jobject _this, jint a) 372{ 373 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 374 LOG_API("nAllocationUploadToBufferObject, con(%p), a(%p)", con, (RsAllocation)a); 375 rsAllocationUploadToBufferObject(con, (RsAllocation)a); 376} 377 378static RsElement SkBitmapToPredefined(SkBitmap::Config cfg) 379{ 380 switch (cfg) { 381 case SkBitmap::kA8_Config: 382 return g_A_8; 383 case SkBitmap::kARGB_4444_Config: 384 return g_RGBA_4444; 385 case SkBitmap::kARGB_8888_Config: 386 return g_RGBA_8888; 387 case SkBitmap::kRGB_565_Config: 388 return g_RGB_565; 389 390 default: 391 break; 392 } 393 // If we don't have a conversion mark it as a user type. 394 LOGE("Unsupported bitmap type"); 395 return NULL; 396} 397 398static int 399nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jobject jbitmap) 400{ 401 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 402 SkBitmap const * nativeBitmap = 403 (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID); 404 const SkBitmap& bitmap(*nativeBitmap); 405 SkBitmap::Config config = bitmap.getConfig(); 406 407 RsElement e = SkBitmapToPredefined(config); 408 if (e) { 409 bitmap.lockPixels(); 410 const int w = bitmap.width(); 411 const int h = bitmap.height(); 412 const void* ptr = bitmap.getPixels(); 413 jint id = (jint)rsAllocationCreateFromBitmap(con, w, h, (RsElement)dstFmt, e, genMips, ptr); 414 bitmap.unlockPixels(); 415 return id; 416 } 417 return 0; 418} 419 420static int 421nAllocationCreateFromAssetStream(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jint native_asset) 422{ 423 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 424 425 Asset* asset = reinterpret_cast<Asset*>(native_asset); 426 SkBitmap bitmap; 427 SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(), 428 &bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode); 429 430 SkBitmap::Config config = bitmap.getConfig(); 431 432 RsElement e = SkBitmapToPredefined(config); 433 434 if (e) { 435 bitmap.lockPixels(); 436 const int w = bitmap.width(); 437 const int h = bitmap.height(); 438 const void* ptr = bitmap.getPixels(); 439 jint id = (jint)rsAllocationCreateFromBitmap(con, w, h, (RsElement)dstFmt, e, genMips, ptr); 440 bitmap.unlockPixels(); 441 return id; 442 } 443 return 0; 444} 445 446static int 447nAllocationCreateFromBitmapBoxed(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jobject jbitmap) 448{ 449 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 450 SkBitmap const * nativeBitmap = 451 (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID); 452 const SkBitmap& bitmap(*nativeBitmap); 453 SkBitmap::Config config = bitmap.getConfig(); 454 455 RsElement e = SkBitmapToPredefined(config); 456 457 if (e) { 458 bitmap.lockPixels(); 459 const int w = bitmap.width(); 460 const int h = bitmap.height(); 461 const void* ptr = bitmap.getPixels(); 462 jint id = (jint)rsAllocationCreateFromBitmapBoxed(con, w, h, (RsElement)dstFmt, e, genMips, ptr); 463 bitmap.unlockPixels(); 464 return id; 465 } 466 return 0; 467} 468 469 470static void 471nAllocationSubData1D_i(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jintArray data, int sizeBytes) 472{ 473 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 474 jint len = _env->GetArrayLength(data); 475 LOG_API("nAllocation1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes); 476 jint *ptr = _env->GetIntArrayElements(data, NULL); 477 rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes); 478 _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT); 479} 480 481static void 482nAllocationSubData1D_s(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jshortArray data, int sizeBytes) 483{ 484 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 485 jint len = _env->GetArrayLength(data); 486 LOG_API("nAllocation1DSubData_s, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes); 487 jshort *ptr = _env->GetShortArrayElements(data, NULL); 488 rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes); 489 _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT); 490} 491 492static void 493nAllocationSubData1D_b(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jbyteArray data, int sizeBytes) 494{ 495 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 496 jint len = _env->GetArrayLength(data); 497 LOG_API("nAllocation1DSubData_b, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes); 498 jbyte *ptr = _env->GetByteArrayElements(data, NULL); 499 rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes); 500 _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT); 501} 502 503static void 504nAllocationSubData1D_f(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jfloatArray data, int sizeBytes) 505{ 506 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 507 jint len = _env->GetArrayLength(data); 508 LOG_API("nAllocation1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes); 509 jfloat *ptr = _env->GetFloatArrayElements(data, NULL); 510 rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes); 511 _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT); 512} 513 514static void 515nAllocationSubData2D_i(JNIEnv *_env, jobject _this, jint alloc, jint xoff, jint yoff, jint w, jint h, jintArray data, int sizeBytes) 516{ 517 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 518 jint len = _env->GetArrayLength(data); 519 LOG_API("nAllocation2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len); 520 jint *ptr = _env->GetIntArrayElements(data, NULL); 521 rsAllocation2DSubData(con, (RsAllocation)alloc, xoff, yoff, w, h, ptr, sizeBytes); 522 _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT); 523} 524 525static void 526nAllocationSubData2D_f(JNIEnv *_env, jobject _this, jint alloc, jint xoff, jint yoff, jint w, jint h, jfloatArray data, int sizeBytes) 527{ 528 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 529 jint len = _env->GetArrayLength(data); 530 LOG_API("nAllocation2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len); 531 jfloat *ptr = _env->GetFloatArrayElements(data, NULL); 532 rsAllocation2DSubData(con, (RsAllocation)alloc, xoff, yoff, w, h, ptr, sizeBytes); 533 _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT); 534} 535 536static void 537nAllocationRead_i(JNIEnv *_env, jobject _this, jint alloc, jintArray data) 538{ 539 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 540 jint len = _env->GetArrayLength(data); 541 LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len); 542 jint *ptr = _env->GetIntArrayElements(data, NULL); 543 rsAllocationRead(con, (RsAllocation)alloc, ptr); 544 _env->ReleaseIntArrayElements(data, ptr, 0); 545} 546 547static void 548nAllocationRead_f(JNIEnv *_env, jobject _this, jint alloc, jfloatArray data) 549{ 550 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 551 jint len = _env->GetArrayLength(data); 552 LOG_API("nAllocationRead_f, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len); 553 jfloat *ptr = _env->GetFloatArrayElements(data, NULL); 554 rsAllocationRead(con, (RsAllocation)alloc, ptr); 555 _env->ReleaseFloatArrayElements(data, ptr, 0); 556} 557 558 559//{"nAllocationDataFromObject", "(ILandroid/renderscript/Type;Ljava/lang/Object;)V", (void*)nAllocationDataFromObject }, 560static void 561nAllocationSubDataFromObject(JNIEnv *_env, jobject _this, jint alloc, jobject _type, jint offset, jobject _o) 562{ 563 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 564 LOG_API("nAllocationDataFromObject con(%p), alloc(%p)", con, (RsAllocation)alloc); 565 566 const TypeCache *tc = (TypeCache *)_env->GetIntField(_type, gTypeNativeCache); 567 568 void * bufAlloc = malloc(tc->size); 569 void * buf = bufAlloc; 570 for (int ct=0; ct < tc->fieldCount; ct++) { 571 const TypeFieldCache *tfc = &tc->fields[ct]; 572 buf = tfc->ptr(_env, _o, tfc->field, buf); 573 } 574 rsAllocation1DSubData(con, (RsAllocation)alloc, offset, 1, bufAlloc, tc->size); 575 free(bufAlloc); 576} 577 578static void 579nAllocationSubReadFromObject(JNIEnv *_env, jobject _this, jint alloc, jobject _type, jint offset, jobject _o) 580{ 581 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 582 LOG_API("nAllocationReadFromObject con(%p), alloc(%p)", con, (RsAllocation)alloc); 583 584 assert(offset == 0); 585 586 const TypeCache *tc = (TypeCache *)_env->GetIntField(_type, gTypeNativeCache); 587 588 void * bufAlloc = malloc(tc->size); 589 void * buf = bufAlloc; 590 rsAllocationRead(con, (RsAllocation)alloc, bufAlloc); 591 592 for (int ct=0; ct < tc->fieldCount; ct++) { 593 const TypeFieldCache *tfc = &tc->fields[ct]; 594 buf = tfc->readPtr(_env, _o, tfc->field, buf); 595 } 596 free(bufAlloc); 597} 598 599// ----------------------------------- 600 601static void 602nTriangleMeshBegin(JNIEnv *_env, jobject _this, jint v, jint i) 603{ 604 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 605 LOG_API("nTriangleMeshBegin, con(%p), vertex(%p), index(%p)", con, (RsElement)v, (RsElement)i); 606 rsTriangleMeshBegin(con, (RsElement)v, (RsElement)i); 607} 608 609static void 610nTriangleMeshAddVertex_XY(JNIEnv *_env, jobject _this, jfloat x, jfloat y) 611{ 612 float v[] = {x, y}; 613 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 614 LOG_API("nTriangleMeshAddVertex_XY, con(%p), x(%f), y(%f)", con, x, y); 615 rsTriangleMeshAddVertex(con, v); 616} 617 618static void 619nTriangleMeshAddVertex_XYZ(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat z) 620{ 621 float v[] = {x, y, z}; 622 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 623 LOG_API("nTriangleMeshAddVertex_XYZ, con(%p), x(%f), y(%f), z(%f)", con, x, y, z); 624 rsTriangleMeshAddVertex(con, v); 625} 626 627static void 628nTriangleMeshAddVertex_XY_ST(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat s, jfloat t) 629{ 630 float v[] = {s, t, x, y}; 631 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 632 LOG_API("nTriangleMeshAddVertex_XY_ST, con(%p), x(%f), y(%f), s(%f), t(%f)", con, x, y, s, t); 633 rsTriangleMeshAddVertex(con, v); 634} 635 636static void 637nTriangleMeshAddVertex_XYZ_ST(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat z, jfloat s, jfloat t) 638{ 639 float v[] = {s, t, x, y, z}; 640 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 641 LOG_API("nTriangleMeshAddVertex_XYZ_ST, con(%p), x(%f), y(%f), z(%f), s(%f), t(%f)", con, x, y, z, s, t); 642 rsTriangleMeshAddVertex(con, v); 643} 644 645static void 646nTriangleMeshAddVertex_XYZ_ST_NORM(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat z, jfloat s, jfloat t, jfloat nx, jfloat ny, jfloat nz) 647{ 648 float v[] = {nx, ny, nz, s, t, x, y, z}; 649 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 650 LOG_API("nTriangleMeshAddVertex_XYZ_ST, con(%p), x(%f), y(%f), z(%f), s(%f), t(%f)", con, x, y, z, s, t); 651 rsTriangleMeshAddVertex(con, v); 652} 653 654static void 655nTriangleMeshAddTriangle(JNIEnv *_env, jobject _this, jint i1, jint i2, jint i3) 656{ 657 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 658 LOG_API("nTriangleMeshAddTriangle, con(%p), i1(%i), i2(%i), i3(%i)", con, i1, i2, i3); 659 rsTriangleMeshAddTriangle(con, i1, i2, i3); 660} 661 662static jint 663nTriangleMeshCreate(JNIEnv *_env, jobject _this) 664{ 665 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 666 LOG_API("nTriangleMeshCreate, con(%p)", con); 667 return (jint) rsTriangleMeshCreate(con); 668} 669 670// ----------------------------------- 671 672static void 673nAdapter1DBindAllocation(JNIEnv *_env, jobject _this, jint adapter, jint alloc) 674{ 675 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 676 LOG_API("nAdapter1DBindAllocation, con(%p), adapter(%p), alloc(%p)", con, (RsAdapter1D)adapter, (RsAllocation)alloc); 677 rsAdapter1DBindAllocation(con, (RsAdapter1D)adapter, (RsAllocation)alloc); 678} 679 680static void 681nAdapter1DSetConstraint(JNIEnv *_env, jobject _this, jint adapter, jint dim, jint value) 682{ 683 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 684 LOG_API("nAdapter1DSetConstraint, con(%p), adapter(%p), dim(%i), value(%i)", con, (RsAdapter1D)adapter, dim, value); 685 rsAdapter1DSetConstraint(con, (RsAdapter1D)adapter, (RsDimension)dim, value); 686} 687 688static void 689nAdapter1DData_i(JNIEnv *_env, jobject _this, jint adapter, jintArray data) 690{ 691 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 692 jint len = _env->GetArrayLength(data); 693 LOG_API("nAdapter1DData_i, con(%p), adapter(%p), len(%i)", con, (RsAdapter1D)adapter, len); 694 jint *ptr = _env->GetIntArrayElements(data, NULL); 695 rsAdapter1DData(con, (RsAdapter1D)adapter, ptr); 696 _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/); 697} 698 699static void 700nAdapter1DSubData_i(JNIEnv *_env, jobject _this, jint adapter, jint offset, jint count, jintArray data) 701{ 702 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 703 jint len = _env->GetArrayLength(data); 704 LOG_API("nAdapter1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAdapter1D)adapter, offset, count, len); 705 jint *ptr = _env->GetIntArrayElements(data, NULL); 706 rsAdapter1DSubData(con, (RsAdapter1D)adapter, offset, count, ptr); 707 _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/); 708} 709 710static void 711nAdapter1DData_f(JNIEnv *_env, jobject _this, jint adapter, jfloatArray data) 712{ 713 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 714 jint len = _env->GetArrayLength(data); 715 LOG_API("nAdapter1DData_f, con(%p), adapter(%p), len(%i)", con, (RsAdapter1D)adapter, len); 716 jfloat *ptr = _env->GetFloatArrayElements(data, NULL); 717 rsAdapter1DData(con, (RsAdapter1D)adapter, ptr); 718 _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/); 719} 720 721static void 722nAdapter1DSubData_f(JNIEnv *_env, jobject _this, jint adapter, jint offset, jint count, jfloatArray data) 723{ 724 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 725 jint len = _env->GetArrayLength(data); 726 LOG_API("nAdapter1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAdapter1D)adapter, offset, count, len); 727 jfloat *ptr = _env->GetFloatArrayElements(data, NULL); 728 rsAdapter1DSubData(con, (RsAdapter1D)adapter, offset, count, ptr); 729 _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/); 730} 731 732static jint 733nAdapter1DCreate(JNIEnv *_env, jobject _this) 734{ 735 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 736 LOG_API("nAdapter1DCreate, con(%p)", con); 737 return (jint)rsAdapter1DCreate(con); 738} 739 740// ----------------------------------- 741 742static void 743nAdapter2DBindAllocation(JNIEnv *_env, jobject _this, jint adapter, jint alloc) 744{ 745 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 746 LOG_API("nAdapter2DBindAllocation, con(%p), adapter(%p), alloc(%p)", con, (RsAdapter2D)adapter, (RsAllocation)alloc); 747 rsAdapter2DBindAllocation(con, (RsAdapter2D)adapter, (RsAllocation)alloc); 748} 749 750static void 751nAdapter2DSetConstraint(JNIEnv *_env, jobject _this, jint adapter, jint dim, jint value) 752{ 753 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 754 LOG_API("nAdapter2DSetConstraint, con(%p), adapter(%p), dim(%i), value(%i)", con, (RsAdapter2D)adapter, dim, value); 755 rsAdapter2DSetConstraint(con, (RsAdapter2D)adapter, (RsDimension)dim, value); 756} 757 758static void 759nAdapter2DData_i(JNIEnv *_env, jobject _this, jint adapter, jintArray data) 760{ 761 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 762 jint len = _env->GetArrayLength(data); 763 LOG_API("nAdapter2DData_i, con(%p), adapter(%p), len(%i)", con, (RsAdapter2D)adapter, len); 764 jint *ptr = _env->GetIntArrayElements(data, NULL); 765 rsAdapter2DData(con, (RsAdapter2D)adapter, ptr); 766 _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/); 767} 768 769static void 770nAdapter2DData_f(JNIEnv *_env, jobject _this, jint adapter, jfloatArray data) 771{ 772 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 773 jint len = _env->GetArrayLength(data); 774 LOG_API("nAdapter2DData_f, con(%p), adapter(%p), len(%i)", con, (RsAdapter2D)adapter, len); 775 jfloat *ptr = _env->GetFloatArrayElements(data, NULL); 776 rsAdapter2DData(con, (RsAdapter2D)adapter, ptr); 777 _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/); 778} 779 780static void 781nAdapter2DSubData_i(JNIEnv *_env, jobject _this, jint adapter, jint xoff, jint yoff, jint w, jint h, jintArray data) 782{ 783 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 784 jint len = _env->GetArrayLength(data); 785 LOG_API("nAdapter2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", 786 con, (RsAdapter2D)adapter, xoff, yoff, w, h, len); 787 jint *ptr = _env->GetIntArrayElements(data, NULL); 788 rsAdapter2DSubData(con, (RsAdapter2D)adapter, xoff, yoff, w, h, ptr); 789 _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/); 790} 791 792static void 793nAdapter2DSubData_f(JNIEnv *_env, jobject _this, jint adapter, jint xoff, jint yoff, jint w, jint h, jfloatArray data) 794{ 795 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 796 jint len = _env->GetArrayLength(data); 797 LOG_API("nAdapter2DSubData_f, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", 798 con, (RsAdapter2D)adapter, xoff, yoff, w, h, len); 799 jfloat *ptr = _env->GetFloatArrayElements(data, NULL); 800 rsAdapter2DSubData(con, (RsAdapter1D)adapter, xoff, yoff, w, h, ptr); 801 _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/); 802} 803 804static jint 805nAdapter2DCreate(JNIEnv *_env, jobject _this) 806{ 807 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 808 LOG_API("nAdapter2DCreate, con(%p)", con); 809 return (jint)rsAdapter2DCreate(con); 810} 811 812// ----------------------------------- 813 814static void 815nScriptBindAllocation(JNIEnv *_env, jobject _this, jint script, jint alloc, jint slot) 816{ 817 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 818 LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", con, (RsScript)script, (RsAllocation)alloc, slot); 819 rsScriptBindAllocation(con, (RsScript)script, (RsAllocation)alloc, slot); 820} 821 822static void 823nScriptSetClearColor(JNIEnv *_env, jobject _this, jint script, jfloat r, jfloat g, jfloat b, jfloat a) 824{ 825 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 826 LOG_API("nScriptSetClearColor, con(%p), s(%p), r(%f), g(%f), b(%f), a(%f)", con, (void *)script, r, g, b, a); 827 rsScriptSetClearColor(con, (RsScript)script, r, g, b, a); 828} 829 830static void 831nScriptSetClearDepth(JNIEnv *_env, jobject _this, jint script, jfloat d) 832{ 833 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 834 LOG_API("nScriptCSetClearDepth, con(%p), s(%p), depth(%f)", con, (void *)script, d); 835 rsScriptSetClearDepth(con, (RsScript)script, d); 836} 837 838static void 839nScriptSetClearStencil(JNIEnv *_env, jobject _this, jint script, jint stencil) 840{ 841 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 842 LOG_API("nScriptCSetClearStencil, con(%p), s(%p), stencil(%i)", con, (void *)script, stencil); 843 rsScriptSetClearStencil(con, (RsScript)script, stencil); 844} 845 846static void 847nScriptSetTimeZone(JNIEnv *_env, jobject _this, jint script, jbyteArray timeZone) 848{ 849 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 850 LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", con, (void *)script, (const char *)timeZone); 851 852 jint length = _env->GetArrayLength(timeZone); 853 jbyte* timeZone_ptr; 854 timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0); 855 856 rsScriptSetTimeZone(con, (RsScript)script, (const char *)timeZone_ptr, length); 857 858 if (timeZone_ptr) { 859 _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0); 860 } 861} 862 863static void 864nScriptSetType(JNIEnv *_env, jobject _this, jint type, jboolean writable, jstring _str, jint slot) 865{ 866 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 867 LOG_API("nScriptCAddType, con(%p), type(%p), writable(%i), slot(%i)", con, (RsType)type, writable, slot); 868 const char* n = NULL; 869 if (_str) { 870 n = _env->GetStringUTFChars(_str, NULL); 871 } 872 rsScriptSetType(con, (RsType)type, slot, writable, n); 873 if (n) { 874 _env->ReleaseStringUTFChars(_str, n); 875 } 876} 877 878static void 879nScriptSetInvoke(JNIEnv *_env, jobject _this, jstring _str, jint slot) 880{ 881 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 882 LOG_API("nScriptSetInvoke, con(%p)", con); 883 const char* n = NULL; 884 if (_str) { 885 n = _env->GetStringUTFChars(_str, NULL); 886 } 887 rsScriptSetInvoke(con, n, slot); 888 if (n) { 889 _env->ReleaseStringUTFChars(_str, n); 890 } 891} 892 893static void 894nScriptInvoke(JNIEnv *_env, jobject _this, jint obj, jint slot) 895{ 896 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 897 LOG_API("nScriptInvoke, con(%p), script(%p)", con, (void *)obj); 898 rsScriptInvoke(con, (RsScript)obj, slot); 899} 900 901static void 902nScriptSetRoot(JNIEnv *_env, jobject _this, jboolean isRoot) 903{ 904 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 905 LOG_API("nScriptCSetRoot, con(%p), isRoot(%i)", con, isRoot); 906 rsScriptSetRoot(con, isRoot); 907} 908 909// ----------------------------------- 910 911static void 912nScriptCBegin(JNIEnv *_env, jobject _this) 913{ 914 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 915 LOG_API("nScriptCBegin, con(%p)", con); 916 rsScriptCBegin(con); 917} 918 919static void 920nScriptCSetScript(JNIEnv *_env, jobject _this, jbyteArray scriptRef, 921 jint offset, jint length) 922{ 923 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 924 LOG_API("!!! nScriptCSetScript, con(%p)", con); 925 jint _exception = 0; 926 jint remaining; 927 jbyte* script_base = 0; 928 jbyte* script_ptr; 929 if (!scriptRef) { 930 _exception = 1; 931 //_env->ThrowNew(IAEClass, "script == null"); 932 goto exit; 933 } 934 if (offset < 0) { 935 _exception = 1; 936 //_env->ThrowNew(IAEClass, "offset < 0"); 937 goto exit; 938 } 939 if (length < 0) { 940 _exception = 1; 941 //_env->ThrowNew(IAEClass, "length < 0"); 942 goto exit; 943 } 944 remaining = _env->GetArrayLength(scriptRef) - offset; 945 if (remaining < length) { 946 _exception = 1; 947 //_env->ThrowNew(IAEClass, "length > script.length - offset"); 948 goto exit; 949 } 950 script_base = (jbyte *) 951 _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0); 952 script_ptr = script_base + offset; 953 954 rsScriptCSetText(con, (const char *)script_ptr, length); 955 956exit: 957 if (script_base) { 958 _env->ReleasePrimitiveArrayCritical(scriptRef, script_base, 959 _exception ? JNI_ABORT: 0); 960 } 961} 962 963static jint 964nScriptCCreate(JNIEnv *_env, jobject _this) 965{ 966 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 967 LOG_API("nScriptCCreate, con(%p)", con); 968 return (jint)rsScriptCCreate(con); 969} 970 971static void 972nScriptCAddDefineI32(JNIEnv *_env, jobject _this, jstring name, jint value) 973{ 974 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 975 const char* n = _env->GetStringUTFChars(name, NULL); 976 LOG_API("nScriptCAddDefineI32, con(%p) name(%s) value(%d)", con, n, value); 977 rsScriptCSetDefineI32(con, n, value); 978 _env->ReleaseStringUTFChars(name, n); 979} 980 981static void 982nScriptCAddDefineF(JNIEnv *_env, jobject _this, jstring name, jfloat value) 983{ 984 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 985 const char* n = _env->GetStringUTFChars(name, NULL); 986 LOG_API("nScriptCAddDefineF, con(%p) name(%s) value(%f)", con, n, value); 987 rsScriptCSetDefineF(con, n, value); 988 _env->ReleaseStringUTFChars(name, n); 989} 990 991// --------------------------------------------------------------------------- 992 993static void 994nProgramFragmentStoreBegin(JNIEnv *_env, jobject _this, jint in, jint out) 995{ 996 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 997 LOG_API("nProgramFragmentStoreBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out); 998 rsProgramFragmentStoreBegin(con, (RsElement)in, (RsElement)out); 999} 1000 1001static void 1002nProgramFragmentStoreDepthFunc(JNIEnv *_env, jobject _this, jint func) 1003{ 1004 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1005 LOG_API("nProgramFragmentStoreDepthFunc, con(%p), func(%i)", con, func); 1006 rsProgramFragmentStoreDepthFunc(con, (RsDepthFunc)func); 1007} 1008 1009static void 1010nProgramFragmentStoreDepthMask(JNIEnv *_env, jobject _this, jboolean enable) 1011{ 1012 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1013 LOG_API("nProgramFragmentStoreDepthMask, con(%p), enable(%i)", con, enable); 1014 rsProgramFragmentStoreDepthMask(con, enable); 1015} 1016 1017static void 1018nProgramFragmentStoreColorMask(JNIEnv *_env, jobject _this, jboolean r, jboolean g, jboolean b, jboolean a) 1019{ 1020 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1021 LOG_API("nProgramFragmentStoreColorMask, con(%p), r(%i), g(%i), b(%i), a(%i)", con, r, g, b, a); 1022 rsProgramFragmentStoreColorMask(con, r, g, b, a); 1023} 1024 1025static void 1026nProgramFragmentStoreBlendFunc(JNIEnv *_env, jobject _this, int src, int dst) 1027{ 1028 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1029 LOG_API("nProgramFragmentStoreBlendFunc, con(%p), src(%i), dst(%i)", con, src, dst); 1030 rsProgramFragmentStoreBlendFunc(con, (RsBlendSrcFunc)src, (RsBlendDstFunc)dst); 1031} 1032 1033static void 1034nProgramFragmentStoreDither(JNIEnv *_env, jobject _this, jboolean enable) 1035{ 1036 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1037 LOG_API("nProgramFragmentStoreDither, con(%p), enable(%i)", con, enable); 1038 rsProgramFragmentStoreDither(con, enable); 1039} 1040 1041static jint 1042nProgramFragmentStoreCreate(JNIEnv *_env, jobject _this) 1043{ 1044 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1045 LOG_API("nProgramFragmentStoreCreate, con(%p)", con); 1046 1047 return (jint)rsProgramFragmentStoreCreate(con); 1048} 1049 1050// --------------------------------------------------------------------------- 1051 1052static void 1053nProgramFragmentBegin(JNIEnv *_env, jobject _this, jint in, jint out, jboolean pointSpriteEnable) 1054{ 1055 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1056 LOG_API("nProgramFragmentBegin, con(%p), in(%p), out(%p) PointSprite(%i)", con, (RsElement)in, (RsElement)out, pointSpriteEnable); 1057 rsProgramFragmentBegin(con, (RsElement)in, (RsElement)out, pointSpriteEnable); 1058} 1059 1060static void 1061nProgramFragmentBindTexture(JNIEnv *_env, jobject _this, jint vpf, jint slot, jint a) 1062{ 1063 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1064 LOG_API("nProgramFragmentBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsAllocation)a); 1065 rsProgramFragmentBindTexture(con, (RsProgramFragment)vpf, slot, (RsAllocation)a); 1066} 1067 1068static void 1069nProgramFragmentBindSampler(JNIEnv *_env, jobject _this, jint vpf, jint slot, jint a) 1070{ 1071 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1072 LOG_API("nProgramFragmentBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsSampler)a); 1073 rsProgramFragmentBindSampler(con, (RsProgramFragment)vpf, slot, (RsSampler)a); 1074} 1075 1076static void 1077nProgramFragmentSetSlot(JNIEnv *_env, jobject _this, jint slot, jboolean enable, jint env, jint vt) 1078{ 1079 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1080 LOG_API("nProgramFragmentSetType, con(%p), slot(%i), enable(%i), env(%i), vt(%p)", con, slot, enable, env, (RsType)vt); 1081 rsProgramFragmentSetSlot(con, slot, enable, (RsTexEnvMode)env, (RsType)vt); 1082} 1083 1084static jint 1085nProgramFragmentCreate(JNIEnv *_env, jobject _this, jint slot, jboolean enable) 1086{ 1087 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1088 LOG_API("nProgramFragmentCreate, con(%p)", con); 1089 return (jint)rsProgramFragmentCreate(con); 1090} 1091 1092// --------------------------------------------------------------------------- 1093 1094static void 1095nProgramVertexBegin(JNIEnv *_env, jobject _this, jint in, jint out) 1096{ 1097 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1098 LOG_API("nProgramVertexBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out); 1099 rsProgramVertexBegin(con, (RsElement)in, (RsElement)out); 1100} 1101 1102static void 1103nProgramVertexBindAllocation(JNIEnv *_env, jobject _this, jint vpv, jint a) 1104{ 1105 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1106 LOG_API("nProgramVertexBindAllocation, con(%p), vpf(%p), a(%p)", con, (RsProgramVertex)vpv, (RsAllocation)a); 1107 rsProgramVertexBindAllocation(con, (RsProgramFragment)vpv, (RsAllocation)a); 1108} 1109 1110static void 1111nProgramVertexSetTextureMatrixEnable(JNIEnv *_env, jobject _this, jboolean enable) 1112{ 1113 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1114 LOG_API("nProgramVertexSetTextureMatrixEnable, con(%p), enable(%i)", con, enable); 1115 rsProgramVertexSetTextureMatrixEnable(con, enable); 1116} 1117 1118static void 1119nProgramVertexAddLight(JNIEnv *_env, jobject _this, jint light) 1120{ 1121 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1122 LOG_API("nProgramVertexAddLight, con(%p), light(%p)", con, (RsLight)light); 1123 rsProgramVertexAddLight(con, (RsLight)light); 1124} 1125 1126static jint 1127nProgramVertexCreate(JNIEnv *_env, jobject _this) 1128{ 1129 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1130 LOG_API("nProgramVertexCreate, con(%p)", con); 1131 return (jint)rsProgramVertexCreate(con); 1132} 1133 1134 1135 1136// --------------------------------------------------------------------------- 1137 1138static void 1139nContextBindRootScript(JNIEnv *_env, jobject _this, jint script) 1140{ 1141 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1142 LOG_API("nContextBindRootScript, con(%p), script(%p)", con, (RsScript)script); 1143 rsContextBindRootScript(con, (RsScript)script); 1144} 1145 1146static void 1147nContextBindProgramFragmentStore(JNIEnv *_env, jobject _this, jint pfs) 1148{ 1149 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1150 LOG_API("nContextBindProgramFragmentStore, con(%p), pfs(%p)", con, (RsProgramFragmentStore)pfs); 1151 rsContextBindProgramFragmentStore(con, (RsProgramFragmentStore)pfs); 1152} 1153 1154static void 1155nContextBindProgramFragment(JNIEnv *_env, jobject _this, jint pf) 1156{ 1157 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1158 LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", con, (RsProgramFragment)pf); 1159 rsContextBindProgramFragment(con, (RsProgramFragment)pf); 1160} 1161 1162static void 1163nContextBindProgramVertex(JNIEnv *_env, jobject _this, jint pf) 1164{ 1165 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1166 LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", con, (RsProgramVertex)pf); 1167 rsContextBindProgramVertex(con, (RsProgramVertex)pf); 1168} 1169 1170static void 1171nContextAddDefineI32(JNIEnv *_env, jobject _this, jstring name, jint value) 1172{ 1173 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1174 const char* n = _env->GetStringUTFChars(name, NULL); 1175 LOG_API("nScriptCAddDefineI32, con(%p) name(%s) value(%d)", con, n, value); 1176 rsContextSetDefineI32(con, n, value); 1177 _env->ReleaseStringUTFChars(name, n); 1178} 1179 1180static void 1181nContextAddDefineF(JNIEnv *_env, jobject _this, jstring name, jfloat value) 1182{ 1183 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1184 const char* n = _env->GetStringUTFChars(name, NULL); 1185 LOG_API("nScriptCAddDefineF, con(%p) name(%s) value(%f)", con, n, value); 1186 rsContextSetDefineF(con, n, value); 1187 _env->ReleaseStringUTFChars(name, n); 1188} 1189 1190 1191// --------------------------------------------------------------------------- 1192 1193static void 1194nSamplerBegin(JNIEnv *_env, jobject _this) 1195{ 1196 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1197 LOG_API("nSamplerBegin, con(%p)", con); 1198 rsSamplerBegin(con); 1199} 1200 1201static void 1202nSamplerSet(JNIEnv *_env, jobject _this, jint p, jint v) 1203{ 1204 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1205 LOG_API("nSamplerSet, con(%p), param(%i), value(%i)", con, p, v); 1206 rsSamplerSet(con, (RsSamplerParam)p, (RsSamplerValue)v); 1207} 1208 1209static jint 1210nSamplerCreate(JNIEnv *_env, jobject _this) 1211{ 1212 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1213 LOG_API("nSamplerCreate, con(%p)", con); 1214 return (jint)rsSamplerCreate(con); 1215} 1216 1217// --------------------------------------------------------------------------- 1218 1219static void 1220nLightBegin(JNIEnv *_env, jobject _this) 1221{ 1222 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1223 LOG_API("nLightBegin, con(%p)", con); 1224 rsLightBegin(con); 1225} 1226 1227static void 1228nLightSetIsMono(JNIEnv *_env, jobject _this, jboolean isMono) 1229{ 1230 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1231 LOG_API("nLightSetIsMono, con(%p), isMono(%i)", con, isMono); 1232 rsLightSetMonochromatic(con, isMono); 1233} 1234 1235static void 1236nLightSetIsLocal(JNIEnv *_env, jobject _this, jboolean isLocal) 1237{ 1238 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1239 LOG_API("nLightSetIsLocal, con(%p), isLocal(%i)", con, isLocal); 1240 rsLightSetLocal(con, isLocal); 1241} 1242 1243static jint 1244nLightCreate(JNIEnv *_env, jobject _this) 1245{ 1246 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1247 LOG_API("nLightCreate, con(%p)", con); 1248 return (jint)rsLightCreate(con); 1249} 1250 1251static void 1252nLightSetColor(JNIEnv *_env, jobject _this, jint light, float r, float g, float b) 1253{ 1254 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1255 LOG_API("nLightSetColor, con(%p), light(%p), r(%f), g(%f), b(%f)", con, (RsLight)light, r, g, b); 1256 rsLightSetColor(con, (RsLight)light, r, g, b); 1257} 1258 1259static void 1260nLightSetPosition(JNIEnv *_env, jobject _this, jint light, float x, float y, float z) 1261{ 1262 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1263 LOG_API("nLightSetPosition, con(%p), light(%p), x(%f), y(%f), z(%f)", con, (RsLight)light, x, y, z); 1264 rsLightSetPosition(con, (RsLight)light, x, y, z); 1265} 1266 1267// --------------------------------------------------------------------------- 1268 1269static jint 1270nSimpleMeshCreate(JNIEnv *_env, jobject _this, jint batchID, jint indexID, jintArray vtxIDs, jint primID) 1271{ 1272 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1273 jint len = _env->GetArrayLength(vtxIDs); 1274 LOG_API("nSimpleMeshCreate, con(%p), batchID(%i), indexID(%i), vtxIDs.len(%i), primID(%i)", 1275 con, batchID, indexID, len, primID); 1276 jint *ptr = _env->GetIntArrayElements(vtxIDs, NULL); 1277 int id = (int)rsSimpleMeshCreate(con, (void *)batchID, (void *)indexID, (void **)ptr, len, primID); 1278 _env->ReleaseIntArrayElements(vtxIDs, ptr, 0/*JNI_ABORT*/); 1279 return id; 1280} 1281 1282static void 1283nSimpleMeshBindVertex(JNIEnv *_env, jobject _this, jint s, jint alloc, jint slot) 1284{ 1285 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1286 LOG_API("nSimpleMeshBindVertex, con(%p), SimpleMesh(%p), Alloc(%p), slot(%i)", con, (RsSimpleMesh)s, (RsAllocation)alloc, slot); 1287 rsSimpleMeshBindVertex(con, (RsSimpleMesh)s, (RsAllocation)alloc, slot); 1288} 1289 1290static void 1291nSimpleMeshBindIndex(JNIEnv *_env, jobject _this, jint s, jint alloc) 1292{ 1293 RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); 1294 LOG_API("nSimpleMeshBindIndex, con(%p), SimpleMesh(%p), Alloc(%p)", con, (RsSimpleMesh)s, (RsAllocation)alloc); 1295 rsSimpleMeshBindIndex(con, (RsSimpleMesh)s, (RsAllocation)alloc); 1296} 1297 1298// --------------------------------------------------------------------------- 1299 1300 1301static const char *classPathName = "android/renderscript/RenderScript"; 1302 1303static JNINativeMethod methods[] = { 1304{"_nInit", "()V", (void*)_nInit }, 1305{"nInitElements", "(IIII)V", (void*)nInitElements }, 1306 1307{"nDeviceCreate", "()I", (void*)nDeviceCreate }, 1308{"nDeviceDestroy", "(I)V", (void*)nDeviceDestroy }, 1309{"nContextCreate", "(ILandroid/view/Surface;IZ)I", (void*)nContextCreate }, 1310{"nContextDestroy", "(I)V", (void*)nContextDestroy }, 1311{"nAssignName", "(I[B)V", (void*)nAssignName }, 1312{"nObjDestroy", "(I)V", (void*)nObjDestroy }, 1313{"nObjDestroyOOB", "(I)V", (void*)nObjDestroyOOB }, 1314 1315{"nFileOpen", "([B)I", (void*)nFileOpen }, 1316 1317{"nElementBegin", "()V", (void*)nElementBegin }, 1318{"nElementAdd", "(IIZILjava/lang/String;)V", (void*)nElementAdd }, 1319{"nElementCreate", "()I", (void*)nElementCreate }, 1320 1321{"nTypeBegin", "(I)V", (void*)nTypeBegin }, 1322{"nTypeAdd", "(II)V", (void*)nTypeAdd }, 1323{"nTypeCreate", "()I", (void*)nTypeCreate }, 1324{"nTypeFinalDestroy", "(Landroid/renderscript/Type;)V", (void*)nTypeFinalDestroy }, 1325{"nTypeSetupFields", "(Landroid/renderscript/Type;[I[I[Ljava/lang/reflect/Field;)V", (void*)nTypeSetupFields }, 1326 1327{"nAllocationCreateTyped", "(I)I", (void*)nAllocationCreateTyped }, 1328{"nAllocationCreateFromBitmap", "(IZLandroid/graphics/Bitmap;)I", (void*)nAllocationCreateFromBitmap }, 1329{"nAllocationCreateFromBitmapBoxed","(IZLandroid/graphics/Bitmap;)I", (void*)nAllocationCreateFromBitmapBoxed }, 1330{"nAllocationCreateFromAssetStream","(IZI)I", (void*)nAllocationCreateFromAssetStream }, 1331{"nAllocationUploadToTexture", "(II)V", (void*)nAllocationUploadToTexture }, 1332{"nAllocationUploadToBufferObject","(I)V", (void*)nAllocationUploadToBufferObject }, 1333{"nAllocationSubData1D", "(III[II)V", (void*)nAllocationSubData1D_i }, 1334{"nAllocationSubData1D", "(III[SI)V", (void*)nAllocationSubData1D_s }, 1335{"nAllocationSubData1D", "(III[BI)V", (void*)nAllocationSubData1D_b }, 1336{"nAllocationSubData1D", "(III[FI)V", (void*)nAllocationSubData1D_f }, 1337{"nAllocationSubData2D", "(IIIII[II)V", (void*)nAllocationSubData2D_i }, 1338{"nAllocationSubData2D", "(IIIII[FI)V", (void*)nAllocationSubData2D_f }, 1339{"nAllocationRead", "(I[I)V", (void*)nAllocationRead_i }, 1340{"nAllocationRead", "(I[F)V", (void*)nAllocationRead_f }, 1341{"nAllocationSubDataFromObject", "(ILandroid/renderscript/Type;ILjava/lang/Object;)V", (void*)nAllocationSubDataFromObject }, 1342{"nAllocationSubReadFromObject", "(ILandroid/renderscript/Type;ILjava/lang/Object;)V", (void*)nAllocationSubReadFromObject }, 1343 1344{"nTriangleMeshBegin", "(II)V", (void*)nTriangleMeshBegin }, 1345{"nTriangleMeshAddVertex_XY", "(FF)V", (void*)nTriangleMeshAddVertex_XY }, 1346{"nTriangleMeshAddVertex_XYZ", "(FFF)V", (void*)nTriangleMeshAddVertex_XYZ }, 1347{"nTriangleMeshAddVertex_XY_ST", "(FFFF)V", (void*)nTriangleMeshAddVertex_XY_ST }, 1348{"nTriangleMeshAddVertex_XYZ_ST", "(FFFFF)V", (void*)nTriangleMeshAddVertex_XYZ_ST }, 1349{"nTriangleMeshAddVertex_XYZ_ST_NORM", "(FFFFFFFF)V", (void*)nTriangleMeshAddVertex_XYZ_ST_NORM }, 1350{"nTriangleMeshAddTriangle", "(III)V", (void*)nTriangleMeshAddTriangle }, 1351{"nTriangleMeshCreate", "()I", (void*)nTriangleMeshCreate }, 1352 1353{"nAdapter1DBindAllocation", "(II)V", (void*)nAdapter1DBindAllocation }, 1354{"nAdapter1DSetConstraint", "(III)V", (void*)nAdapter1DSetConstraint }, 1355{"nAdapter1DData", "(I[I)V", (void*)nAdapter1DData_i }, 1356{"nAdapter1DData", "(I[F)V", (void*)nAdapter1DData_f }, 1357{"nAdapter1DSubData", "(III[I)V", (void*)nAdapter1DSubData_i }, 1358{"nAdapter1DSubData", "(III[F)V", (void*)nAdapter1DSubData_f }, 1359{"nAdapter1DCreate", "()I", (void*)nAdapter1DCreate }, 1360 1361{"nAdapter2DBindAllocation", "(II)V", (void*)nAdapter2DBindAllocation }, 1362{"nAdapter2DSetConstraint", "(III)V", (void*)nAdapter2DSetConstraint }, 1363{"nAdapter2DData", "(I[I)V", (void*)nAdapter2DData_i }, 1364{"nAdapter2DData", "(I[F)V", (void*)nAdapter2DData_f }, 1365{"nAdapter2DSubData", "(IIIII[I)V", (void*)nAdapter2DSubData_i }, 1366{"nAdapter2DSubData", "(IIIII[F)V", (void*)nAdapter2DSubData_f }, 1367{"nAdapter2DCreate", "()I", (void*)nAdapter2DCreate }, 1368 1369{"nScriptBindAllocation", "(III)V", (void*)nScriptBindAllocation }, 1370{"nScriptSetClearColor", "(IFFFF)V", (void*)nScriptSetClearColor }, 1371{"nScriptSetClearDepth", "(IF)V", (void*)nScriptSetClearDepth }, 1372{"nScriptSetClearStencil", "(II)V", (void*)nScriptSetClearStencil }, 1373{"nScriptSetTimeZone", "(I[B)V", (void*)nScriptSetTimeZone }, 1374{"nScriptSetType", "(IZLjava/lang/String;I)V", (void*)nScriptSetType }, 1375{"nScriptSetRoot", "(Z)V", (void*)nScriptSetRoot }, 1376{"nScriptSetInvokable", "(Ljava/lang/String;I)V", (void*)nScriptSetInvoke }, 1377{"nScriptInvoke", "(II)V", (void*)nScriptInvoke }, 1378 1379{"nScriptCBegin", "()V", (void*)nScriptCBegin }, 1380{"nScriptCSetScript", "([BII)V", (void*)nScriptCSetScript }, 1381{"nScriptCCreate", "()I", (void*)nScriptCCreate }, 1382{"nScriptCAddDefineI32", "(Ljava/lang/String;I)V", (void*)nScriptCAddDefineI32 }, 1383{"nScriptCAddDefineF", "(Ljava/lang/String;F)V", (void*)nScriptCAddDefineF }, 1384 1385{"nProgramFragmentStoreBegin", "(II)V", (void*)nProgramFragmentStoreBegin }, 1386{"nProgramFragmentStoreDepthFunc", "(I)V", (void*)nProgramFragmentStoreDepthFunc }, 1387{"nProgramFragmentStoreDepthMask", "(Z)V", (void*)nProgramFragmentStoreDepthMask }, 1388{"nProgramFragmentStoreColorMask", "(ZZZZ)V", (void*)nProgramFragmentStoreColorMask }, 1389{"nProgramFragmentStoreBlendFunc", "(II)V", (void*)nProgramFragmentStoreBlendFunc }, 1390{"nProgramFragmentStoreDither", "(Z)V", (void*)nProgramFragmentStoreDither }, 1391{"nProgramFragmentStoreCreate", "()I", (void*)nProgramFragmentStoreCreate }, 1392 1393{"nProgramFragmentBegin", "(IIZ)V", (void*)nProgramFragmentBegin }, 1394{"nProgramFragmentBindTexture", "(III)V", (void*)nProgramFragmentBindTexture }, 1395{"nProgramFragmentBindSampler", "(III)V", (void*)nProgramFragmentBindSampler }, 1396{"nProgramFragmentSetSlot", "(IZII)V", (void*)nProgramFragmentSetSlot }, 1397{"nProgramFragmentCreate", "()I", (void*)nProgramFragmentCreate }, 1398 1399{"nProgramVertexBindAllocation", "(II)V", (void*)nProgramVertexBindAllocation }, 1400{"nProgramVertexBegin", "(II)V", (void*)nProgramVertexBegin }, 1401{"nProgramVertexSetTextureMatrixEnable", "(Z)V", (void*)nProgramVertexSetTextureMatrixEnable }, 1402{"nProgramVertexAddLight", "(I)V", (void*)nProgramVertexAddLight }, 1403{"nProgramVertexCreate", "()I", (void*)nProgramVertexCreate }, 1404 1405{"nLightBegin", "()V", (void*)nLightBegin }, 1406{"nLightSetIsMono", "(Z)V", (void*)nLightSetIsMono }, 1407{"nLightSetIsLocal", "(Z)V", (void*)nLightSetIsLocal }, 1408{"nLightCreate", "()I", (void*)nLightCreate }, 1409{"nLightSetColor", "(IFFF)V", (void*)nLightSetColor }, 1410{"nLightSetPosition", "(IFFF)V", (void*)nLightSetPosition }, 1411 1412{"nContextBindRootScript", "(I)V", (void*)nContextBindRootScript }, 1413{"nContextBindProgramFragmentStore","(I)V", (void*)nContextBindProgramFragmentStore }, 1414{"nContextBindProgramFragment", "(I)V", (void*)nContextBindProgramFragment }, 1415{"nContextBindProgramVertex", "(I)V", (void*)nContextBindProgramVertex }, 1416 1417{"nSamplerBegin", "()V", (void*)nSamplerBegin }, 1418{"nSamplerSet", "(II)V", (void*)nSamplerSet }, 1419{"nSamplerCreate", "()I", (void*)nSamplerCreate }, 1420 1421{"nSimpleMeshCreate", "(II[II)I", (void*)nSimpleMeshCreate }, 1422{"nSimpleMeshBindVertex", "(III)V", (void*)nSimpleMeshBindVertex }, 1423{"nSimpleMeshBindIndex", "(II)V", (void*)nSimpleMeshBindIndex }, 1424 1425}; 1426 1427static int registerFuncs(JNIEnv *_env) 1428{ 1429 return android::AndroidRuntime::registerNativeMethods( 1430 _env, classPathName, methods, NELEM(methods)); 1431} 1432 1433// --------------------------------------------------------------------------- 1434 1435jint JNI_OnLoad(JavaVM* vm, void* reserved) 1436{ 1437 JNIEnv* env = NULL; 1438 jint result = -1; 1439 1440 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { 1441 LOGE("ERROR: GetEnv failed\n"); 1442 goto bail; 1443 } 1444 assert(env != NULL); 1445 1446 if (registerFuncs(env) < 0) { 1447 LOGE("ERROR: MediaPlayer native registration failed\n"); 1448 goto bail; 1449 } 1450 1451 /* success -- return valid version number */ 1452 result = JNI_VERSION_1_4; 1453 1454bail: 1455 return result; 1456} 1457