RenderScript.java revision be7b1defb6b11920703b241ba5815fb09487bb02
1/* 2 * Copyright (C) 2008-2012 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 17package android.renderscript; 18 19import java.io.File; 20import java.lang.reflect.Field; 21import java.lang.reflect.Method; 22import java.util.concurrent.locks.ReentrantReadWriteLock; 23 24import android.content.Context; 25import android.content.pm.ApplicationInfo; 26import android.content.pm.PackageManager; 27import android.content.res.AssetManager; 28import android.graphics.Bitmap; 29import android.graphics.BitmapFactory; 30import android.graphics.SurfaceTexture; 31import android.os.Process; 32import android.util.Log; 33import android.view.Surface; 34import android.os.SystemProperties; 35import android.os.Trace; 36 37/** 38 * This class provides access to a RenderScript context, which controls RenderScript 39 * initialization, resource management, and teardown. An instance of the RenderScript 40 * class must be created before any other RS objects can be created. 41 * 42 * <div class="special reference"> 43 * <h3>Developer Guides</h3> 44 * <p>For more information about creating an application that uses RenderScript, read the 45 * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p> 46 * </div> 47 **/ 48public class RenderScript { 49 static final long TRACE_TAG = Trace.TRACE_TAG_RS; 50 51 static final String LOG_TAG = "RenderScript_jni"; 52 static final boolean DEBUG = false; 53 @SuppressWarnings({"UnusedDeclaration", "deprecation"}) 54 static final boolean LOG_ENABLED = false; 55 56 private Context mApplicationContext; 57 58 /* 59 * We use a class initializer to allow the native code to cache some 60 * field offsets. 61 */ 62 @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // TODO: now used locally; remove? 63 static boolean sInitialized; 64 native static void _nInit(); 65 66 static Object sRuntime; 67 static Method registerNativeAllocation; 68 static Method registerNativeFree; 69 70 /* 71 * Detect the bitness of the VM to allow FieldPacker to do the right thing. 72 */ 73 static native int rsnSystemGetPointerSize(); 74 static int sPointerSize; 75 76 static { 77 sInitialized = false; 78 if (!SystemProperties.getBoolean("config.disable_renderscript", false)) { 79 try { 80 Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime"); 81 Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime"); 82 sRuntime = get_runtime.invoke(null); 83 registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", Integer.TYPE); 84 registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", Integer.TYPE); 85 } catch (Exception e) { 86 Log.e(LOG_TAG, "Error loading GC methods: " + e); 87 throw new RSRuntimeException("Error loading GC methods: " + e); 88 } 89 try { 90 System.loadLibrary("rs_jni"); 91 _nInit(); 92 sInitialized = true; 93 sPointerSize = rsnSystemGetPointerSize(); 94 } catch (UnsatisfiedLinkError e) { 95 Log.e(LOG_TAG, "Error loading RS jni library: " + e); 96 throw new RSRuntimeException("Error loading RS jni library: " + e); 97 } 98 } 99 } 100 101 // Non-threadsafe functions. 102 native long nDeviceCreate(); 103 native void nDeviceDestroy(long dev); 104 native void nDeviceSetConfig(long dev, int param, int value); 105 native int nContextGetUserMessage(long con, int[] data); 106 native String nContextGetErrorMessage(long con); 107 native int nContextPeekMessage(long con, int[] subID); 108 native void nContextInitToClient(long con); 109 native void nContextDeinitToClient(long con); 110 111 static File mCacheDir; 112 113 // this should be a monotonically increasing ID 114 // used in conjunction with the API version of a device 115 static final long sMinorID = 1; 116 117 /** 118 * Returns an identifier that can be used to identify a particular 119 * minor version of RS. 120 * 121 * @hide 122 */ 123 public static long getMinorID() { 124 return sMinorID; 125 } 126 127 /** 128 * Sets the directory to use as a persistent storage for the 129 * renderscript object file cache. 130 * 131 * @hide 132 * @param cacheDir A directory the current process can write to 133 */ 134 public static void setupDiskCache(File cacheDir) { 135 if (!sInitialized) { 136 Log.e(LOG_TAG, "RenderScript.setupDiskCache() called when disabled"); 137 return; 138 } 139 140 // Defer creation of cache path to nScriptCCreate(). 141 mCacheDir = cacheDir; 142 } 143 144 /** 145 * ContextType specifies the specific type of context to be created. 146 * 147 */ 148 public enum ContextType { 149 /** 150 * NORMAL context, this is the default and what shipping apps should 151 * use. 152 */ 153 NORMAL (0), 154 155 /** 156 * DEBUG context, perform extra runtime checks to validate the 157 * kernels and APIs are being used as intended. Get and SetElementAt 158 * will be bounds checked in this mode. 159 */ 160 DEBUG (1), 161 162 /** 163 * PROFILE context, Intended to be used once the first time an 164 * application is run on a new device. This mode allows the runtime to 165 * do additional testing and performance tuning. 166 */ 167 PROFILE (2); 168 169 int mID; 170 ContextType(int id) { 171 mID = id; 172 } 173 } 174 175 ContextType mContextType; 176 ReentrantReadWriteLock mRWLock; 177 178 // Methods below are wrapped to protect the non-threadsafe 179 // lockless fifo. 180 native long rsnContextCreateGL(long dev, int ver, int sdkVer, 181 int colorMin, int colorPref, 182 int alphaMin, int alphaPref, 183 int depthMin, int depthPref, 184 int stencilMin, int stencilPref, 185 int samplesMin, int samplesPref, float samplesQ, int dpi); 186 synchronized long nContextCreateGL(long dev, int ver, int sdkVer, 187 int colorMin, int colorPref, 188 int alphaMin, int alphaPref, 189 int depthMin, int depthPref, 190 int stencilMin, int stencilPref, 191 int samplesMin, int samplesPref, float samplesQ, int dpi) { 192 return rsnContextCreateGL(dev, ver, sdkVer, colorMin, colorPref, 193 alphaMin, alphaPref, depthMin, depthPref, 194 stencilMin, stencilPref, 195 samplesMin, samplesPref, samplesQ, dpi); 196 } 197 native long rsnContextCreate(long dev, int ver, int sdkVer, int contextType); 198 synchronized long nContextCreate(long dev, int ver, int sdkVer, int contextType) { 199 return rsnContextCreate(dev, ver, sdkVer, contextType); 200 } 201 native void rsnContextDestroy(long con); 202 synchronized void nContextDestroy() { 203 validate(); 204 205 // take teardown lock 206 // teardown lock can only be taken when no objects are being destroyed 207 ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock(); 208 wlock.lock(); 209 210 long curCon = mContext; 211 // context is considered dead as of this point 212 mContext = 0; 213 214 wlock.unlock(); 215 rsnContextDestroy(curCon); 216 } 217 native void rsnContextSetSurface(long con, int w, int h, Surface sur); 218 synchronized void nContextSetSurface(int w, int h, Surface sur) { 219 validate(); 220 rsnContextSetSurface(mContext, w, h, sur); 221 } 222 native void rsnContextSetSurfaceTexture(long con, int w, int h, SurfaceTexture sur); 223 synchronized void nContextSetSurfaceTexture(int w, int h, SurfaceTexture sur) { 224 validate(); 225 rsnContextSetSurfaceTexture(mContext, w, h, sur); 226 } 227 native void rsnContextSetPriority(long con, int p); 228 synchronized void nContextSetPriority(int p) { 229 validate(); 230 rsnContextSetPriority(mContext, p); 231 } 232 native void rsnContextDump(long con, int bits); 233 synchronized void nContextDump(int bits) { 234 validate(); 235 rsnContextDump(mContext, bits); 236 } 237 native void rsnContextFinish(long con); 238 synchronized void nContextFinish() { 239 validate(); 240 rsnContextFinish(mContext); 241 } 242 243 native void rsnContextSendMessage(long con, int id, int[] data); 244 synchronized void nContextSendMessage(int id, int[] data) { 245 validate(); 246 rsnContextSendMessage(mContext, id, data); 247 } 248 249 native void rsnContextBindRootScript(long con, long script); 250 synchronized void nContextBindRootScript(long script) { 251 validate(); 252 rsnContextBindRootScript(mContext, script); 253 } 254 native void rsnContextBindSampler(long con, int sampler, int slot); 255 synchronized void nContextBindSampler(int sampler, int slot) { 256 validate(); 257 rsnContextBindSampler(mContext, sampler, slot); 258 } 259 native void rsnContextBindProgramStore(long con, long pfs); 260 synchronized void nContextBindProgramStore(long pfs) { 261 validate(); 262 rsnContextBindProgramStore(mContext, pfs); 263 } 264 native void rsnContextBindProgramFragment(long con, long pf); 265 synchronized void nContextBindProgramFragment(long pf) { 266 validate(); 267 rsnContextBindProgramFragment(mContext, pf); 268 } 269 native void rsnContextBindProgramVertex(long con, long pv); 270 synchronized void nContextBindProgramVertex(long pv) { 271 validate(); 272 rsnContextBindProgramVertex(mContext, pv); 273 } 274 native void rsnContextBindProgramRaster(long con, long pr); 275 synchronized void nContextBindProgramRaster(long pr) { 276 validate(); 277 rsnContextBindProgramRaster(mContext, pr); 278 } 279 native void rsnContextPause(long con); 280 synchronized void nContextPause() { 281 validate(); 282 rsnContextPause(mContext); 283 } 284 native void rsnContextResume(long con); 285 synchronized void nContextResume() { 286 validate(); 287 rsnContextResume(mContext); 288 } 289 290 native void rsnAssignName(long con, long obj, byte[] name); 291 synchronized void nAssignName(long obj, byte[] name) { 292 validate(); 293 rsnAssignName(mContext, obj, name); 294 } 295 native String rsnGetName(long con, long obj); 296 synchronized String nGetName(long obj) { 297 validate(); 298 return rsnGetName(mContext, obj); 299 } 300 301 // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers 302 native void rsnObjDestroy(long con, long id); 303 void nObjDestroy(long id) { 304 // There is a race condition here. The calling code may be run 305 // by the gc while teardown is occuring. This protects againts 306 // deleting dead objects. 307 if (mContext != 0) { 308 rsnObjDestroy(mContext, id); 309 } 310 } 311 312 native long rsnElementCreate(long con, long type, int kind, boolean norm, int vecSize); 313 synchronized long nElementCreate(long type, int kind, boolean norm, int vecSize) { 314 validate(); 315 return rsnElementCreate(mContext, type, kind, norm, vecSize); 316 } 317 native long rsnElementCreate2(long con, long[] elements, String[] names, int[] arraySizes); 318 synchronized long nElementCreate2(long[] elements, String[] names, int[] arraySizes) { 319 validate(); 320 return rsnElementCreate2(mContext, elements, names, arraySizes); 321 } 322 native void rsnElementGetNativeData(long con, long id, int[] elementData); 323 synchronized void nElementGetNativeData(long id, int[] elementData) { 324 validate(); 325 rsnElementGetNativeData(mContext, id, elementData); 326 } 327 native void rsnElementGetSubElements(long con, long id, 328 long[] IDs, String[] names, int[] arraySizes); 329 synchronized void nElementGetSubElements(long id, long[] IDs, String[] names, int[] arraySizes) { 330 validate(); 331 rsnElementGetSubElements(mContext, id, IDs, names, arraySizes); 332 } 333 334 native long rsnTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv); 335 synchronized long nTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) { 336 validate(); 337 return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv); 338 } 339 native void rsnTypeGetNativeData(long con, long id, long[] typeData); 340 synchronized void nTypeGetNativeData(long id, long[] typeData) { 341 validate(); 342 rsnTypeGetNativeData(mContext, id, typeData); 343 } 344 345 native long rsnAllocationCreateTyped(long con, long type, int mip, int usage, long pointer); 346 synchronized long nAllocationCreateTyped(long type, int mip, int usage, long pointer) { 347 validate(); 348 return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer); 349 } 350 native long rsnAllocationCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage); 351 synchronized long nAllocationCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) { 352 validate(); 353 return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage); 354 } 355 356 native long rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, Bitmap bmp, int usage); 357 synchronized long nAllocationCreateBitmapBackedAllocation(long type, int mip, Bitmap bmp, int usage) { 358 validate(); 359 return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage); 360 } 361 362 native long rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage); 363 synchronized long nAllocationCubeCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) { 364 validate(); 365 return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage); 366 } 367 native long rsnAllocationCreateBitmapRef(long con, long type, Bitmap bmp); 368 synchronized long nAllocationCreateBitmapRef(long type, Bitmap bmp) { 369 validate(); 370 return rsnAllocationCreateBitmapRef(mContext, type, bmp); 371 } 372 native long rsnAllocationCreateFromAssetStream(long con, int mips, int assetStream, int usage); 373 synchronized long nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) { 374 validate(); 375 return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage); 376 } 377 378 native void rsnAllocationCopyToBitmap(long con, long alloc, Bitmap bmp); 379 synchronized void nAllocationCopyToBitmap(long alloc, Bitmap bmp) { 380 validate(); 381 rsnAllocationCopyToBitmap(mContext, alloc, bmp); 382 } 383 384 385 native void rsnAllocationSyncAll(long con, long alloc, int src); 386 synchronized void nAllocationSyncAll(long alloc, int src) { 387 validate(); 388 rsnAllocationSyncAll(mContext, alloc, src); 389 } 390 native Surface rsnAllocationGetSurface(long con, long alloc); 391 synchronized Surface nAllocationGetSurface(long alloc) { 392 validate(); 393 return rsnAllocationGetSurface(mContext, alloc); 394 } 395 native void rsnAllocationSetSurface(long con, long alloc, Surface sur); 396 synchronized void nAllocationSetSurface(long alloc, Surface sur) { 397 validate(); 398 rsnAllocationSetSurface(mContext, alloc, sur); 399 } 400 native void rsnAllocationIoSend(long con, long alloc); 401 synchronized void nAllocationIoSend(long alloc) { 402 validate(); 403 rsnAllocationIoSend(mContext, alloc); 404 } 405 native void rsnAllocationIoReceive(long con, long alloc); 406 synchronized void nAllocationIoReceive(long alloc) { 407 validate(); 408 rsnAllocationIoReceive(mContext, alloc); 409 } 410 411 412 native void rsnAllocationGenerateMipmaps(long con, long alloc); 413 synchronized void nAllocationGenerateMipmaps(long alloc) { 414 validate(); 415 rsnAllocationGenerateMipmaps(mContext, alloc); 416 } 417 native void rsnAllocationCopyFromBitmap(long con, long alloc, Bitmap bmp); 418 synchronized void nAllocationCopyFromBitmap(long alloc, Bitmap bmp) { 419 validate(); 420 rsnAllocationCopyFromBitmap(mContext, alloc, bmp); 421 } 422 423 424 native void rsnAllocationData1D(long con, long id, int off, int mip, int count, Object d, int sizeBytes, int dt); 425 synchronized void nAllocationData1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType dt) { 426 validate(); 427 rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID); 428 } 429 430 native void rsnAllocationElementData1D(long con,long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes); 431 synchronized void nAllocationElementData1D(long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) { 432 validate(); 433 rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes); 434 } 435 436 native void rsnAllocationData2D(long con, 437 long dstAlloc, int dstXoff, int dstYoff, 438 int dstMip, int dstFace, 439 int width, int height, 440 long srcAlloc, int srcXoff, int srcYoff, 441 int srcMip, int srcFace); 442 synchronized void nAllocationData2D(long dstAlloc, int dstXoff, int dstYoff, 443 int dstMip, int dstFace, 444 int width, int height, 445 long srcAlloc, int srcXoff, int srcYoff, 446 int srcMip, int srcFace) { 447 validate(); 448 rsnAllocationData2D(mContext, 449 dstAlloc, dstXoff, dstYoff, 450 dstMip, dstFace, 451 width, height, 452 srcAlloc, srcXoff, srcYoff, 453 srcMip, srcFace); 454 } 455 456 native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, 457 int w, int h, Object d, int sizeBytes, int dt); 458 synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face, 459 int w, int h, Object d, int sizeBytes, Element.DataType dt) { 460 validate(); 461 rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID); 462 } 463 464 native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, Bitmap b); 465 synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face, Bitmap b) { 466 validate(); 467 rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b); 468 } 469 470 native void rsnAllocationData3D(long con, 471 long dstAlloc, int dstXoff, int dstYoff, int dstZoff, 472 int dstMip, 473 int width, int height, int depth, 474 long srcAlloc, int srcXoff, int srcYoff, int srcZoff, 475 int srcMip); 476 synchronized void nAllocationData3D(long dstAlloc, int dstXoff, int dstYoff, int dstZoff, 477 int dstMip, 478 int width, int height, int depth, 479 long srcAlloc, int srcXoff, int srcYoff, int srcZoff, 480 int srcMip) { 481 validate(); 482 rsnAllocationData3D(mContext, 483 dstAlloc, dstXoff, dstYoff, dstZoff, 484 dstMip, width, height, depth, 485 srcAlloc, srcXoff, srcYoff, srcZoff, srcMip); 486 } 487 488 native void rsnAllocationData3D(long con, long id, int xoff, int yoff, int zoff, int mip, 489 int w, int h, int depth, Object d, int sizeBytes, int dt); 490 synchronized void nAllocationData3D(long id, int xoff, int yoff, int zoff, int mip, 491 int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt) { 492 validate(); 493 rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes, dt.mID); 494 } 495 496 native void rsnAllocationRead(long con, long id, Object d, int dt); 497 synchronized void nAllocationRead(long id, Object d, Element.DataType dt) { 498 validate(); 499 rsnAllocationRead(mContext, id, d, dt.mID); 500 } 501 502 native void rsnAllocationRead1D(long con, long id, int off, int mip, int count, Object d, 503 int sizeBytes, int dt); 504 synchronized void nAllocationRead1D(long id, int off, int mip, int count, Object d, 505 int sizeBytes, Element.DataType dt) { 506 validate(); 507 rsnAllocationRead1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID); 508 } 509 510 native void rsnAllocationRead2D(long con, long id, int xoff, int yoff, int mip, int face, 511 int w, int h, Object d, int sizeBytes, int dt); 512 synchronized void nAllocationRead2D(long id, int xoff, int yoff, int mip, int face, 513 int w, int h, Object d, int sizeBytes, Element.DataType dt) { 514 validate(); 515 rsnAllocationRead2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID); 516 } 517 518 native long rsnAllocationGetType(long con, long id); 519 synchronized long nAllocationGetType(long id) { 520 validate(); 521 return rsnAllocationGetType(mContext, id); 522 } 523 524 native void rsnAllocationResize1D(long con, long id, int dimX); 525 synchronized void nAllocationResize1D(long id, int dimX) { 526 validate(); 527 rsnAllocationResize1D(mContext, id, dimX); 528 } 529 530 native long rsnFileA3DCreateFromAssetStream(long con, long assetStream); 531 synchronized long nFileA3DCreateFromAssetStream(long assetStream) { 532 validate(); 533 return rsnFileA3DCreateFromAssetStream(mContext, assetStream); 534 } 535 native long rsnFileA3DCreateFromFile(long con, String path); 536 synchronized long nFileA3DCreateFromFile(String path) { 537 validate(); 538 return rsnFileA3DCreateFromFile(mContext, path); 539 } 540 native long rsnFileA3DCreateFromAsset(long con, AssetManager mgr, String path); 541 synchronized long nFileA3DCreateFromAsset(AssetManager mgr, String path) { 542 validate(); 543 return rsnFileA3DCreateFromAsset(mContext, mgr, path); 544 } 545 native int rsnFileA3DGetNumIndexEntries(long con, long fileA3D); 546 synchronized int nFileA3DGetNumIndexEntries(long fileA3D) { 547 validate(); 548 return rsnFileA3DGetNumIndexEntries(mContext, fileA3D); 549 } 550 native void rsnFileA3DGetIndexEntries(long con, long fileA3D, int numEntries, int[] IDs, String[] names); 551 synchronized void nFileA3DGetIndexEntries(long fileA3D, int numEntries, int[] IDs, String[] names) { 552 validate(); 553 rsnFileA3DGetIndexEntries(mContext, fileA3D, numEntries, IDs, names); 554 } 555 native long rsnFileA3DGetEntryByIndex(long con, long fileA3D, int index); 556 synchronized long nFileA3DGetEntryByIndex(long fileA3D, int index) { 557 validate(); 558 return rsnFileA3DGetEntryByIndex(mContext, fileA3D, index); 559 } 560 561 native long rsnFontCreateFromFile(long con, String fileName, float size, int dpi); 562 synchronized long nFontCreateFromFile(String fileName, float size, int dpi) { 563 validate(); 564 return rsnFontCreateFromFile(mContext, fileName, size, dpi); 565 } 566 native long rsnFontCreateFromAssetStream(long con, String name, float size, int dpi, long assetStream); 567 synchronized long nFontCreateFromAssetStream(String name, float size, int dpi, long assetStream) { 568 validate(); 569 return rsnFontCreateFromAssetStream(mContext, name, size, dpi, assetStream); 570 } 571 native long rsnFontCreateFromAsset(long con, AssetManager mgr, String path, float size, int dpi); 572 synchronized long nFontCreateFromAsset(AssetManager mgr, String path, float size, int dpi) { 573 validate(); 574 return rsnFontCreateFromAsset(mContext, mgr, path, size, dpi); 575 } 576 577 578 native void rsnScriptBindAllocation(long con, long script, long alloc, int slot); 579 synchronized void nScriptBindAllocation(long script, long alloc, int slot) { 580 validate(); 581 rsnScriptBindAllocation(mContext, script, alloc, slot); 582 } 583 native void rsnScriptSetTimeZone(long con, long script, byte[] timeZone); 584 synchronized void nScriptSetTimeZone(long script, byte[] timeZone) { 585 validate(); 586 rsnScriptSetTimeZone(mContext, script, timeZone); 587 } 588 native void rsnScriptInvoke(long con, long id, int slot); 589 synchronized void nScriptInvoke(long id, int slot) { 590 validate(); 591 rsnScriptInvoke(mContext, id, slot); 592 } 593 594 native void rsnScriptForEach(long con, long id, int slot, long[] ains, 595 long aout, byte[] params, int[] limits); 596 597 synchronized void nScriptForEach(long id, int slot, long[] ains, long aout, 598 byte[] params, int[] limits) { 599 validate(); 600 rsnScriptForEach(mContext, id, slot, ains, aout, params, limits); 601 } 602 603 native void rsnScriptInvokeV(long con, long id, int slot, byte[] params); 604 synchronized void nScriptInvokeV(long id, int slot, byte[] params) { 605 validate(); 606 rsnScriptInvokeV(mContext, id, slot, params); 607 } 608 609 native void rsnScriptSetVarI(long con, long id, int slot, int val); 610 synchronized void nScriptSetVarI(long id, int slot, int val) { 611 validate(); 612 rsnScriptSetVarI(mContext, id, slot, val); 613 } 614 native int rsnScriptGetVarI(long con, long id, int slot); 615 synchronized int nScriptGetVarI(long id, int slot) { 616 validate(); 617 return rsnScriptGetVarI(mContext, id, slot); 618 } 619 620 native void rsnScriptSetVarJ(long con, long id, int slot, long val); 621 synchronized void nScriptSetVarJ(long id, int slot, long val) { 622 validate(); 623 rsnScriptSetVarJ(mContext, id, slot, val); 624 } 625 native long rsnScriptGetVarJ(long con, long id, int slot); 626 synchronized long nScriptGetVarJ(long id, int slot) { 627 validate(); 628 return rsnScriptGetVarJ(mContext, id, slot); 629 } 630 631 native void rsnScriptSetVarF(long con, long id, int slot, float val); 632 synchronized void nScriptSetVarF(long id, int slot, float val) { 633 validate(); 634 rsnScriptSetVarF(mContext, id, slot, val); 635 } 636 native float rsnScriptGetVarF(long con, long id, int slot); 637 synchronized float nScriptGetVarF(long id, int slot) { 638 validate(); 639 return rsnScriptGetVarF(mContext, id, slot); 640 } 641 native void rsnScriptSetVarD(long con, long id, int slot, double val); 642 synchronized void nScriptSetVarD(long id, int slot, double val) { 643 validate(); 644 rsnScriptSetVarD(mContext, id, slot, val); 645 } 646 native double rsnScriptGetVarD(long con, long id, int slot); 647 synchronized double nScriptGetVarD(long id, int slot) { 648 validate(); 649 return rsnScriptGetVarD(mContext, id, slot); 650 } 651 native void rsnScriptSetVarV(long con, long id, int slot, byte[] val); 652 synchronized void nScriptSetVarV(long id, int slot, byte[] val) { 653 validate(); 654 rsnScriptSetVarV(mContext, id, slot, val); 655 } 656 native void rsnScriptGetVarV(long con, long id, int slot, byte[] val); 657 synchronized void nScriptGetVarV(long id, int slot, byte[] val) { 658 validate(); 659 rsnScriptGetVarV(mContext, id, slot, val); 660 } 661 native void rsnScriptSetVarVE(long con, long id, int slot, byte[] val, 662 long e, int[] dims); 663 synchronized void nScriptSetVarVE(long id, int slot, byte[] val, 664 long e, int[] dims) { 665 validate(); 666 rsnScriptSetVarVE(mContext, id, slot, val, e, dims); 667 } 668 native void rsnScriptSetVarObj(long con, long id, int slot, long val); 669 synchronized void nScriptSetVarObj(long id, int slot, long val) { 670 validate(); 671 rsnScriptSetVarObj(mContext, id, slot, val); 672 } 673 674 native long rsnScriptCCreate(long con, String resName, String cacheDir, 675 byte[] script, int length); 676 synchronized long nScriptCCreate(String resName, String cacheDir, byte[] script, int length) { 677 validate(); 678 return rsnScriptCCreate(mContext, resName, cacheDir, script, length); 679 } 680 681 native long rsnScriptIntrinsicCreate(long con, int id, long eid); 682 synchronized long nScriptIntrinsicCreate(int id, long eid) { 683 validate(); 684 return rsnScriptIntrinsicCreate(mContext, id, eid); 685 } 686 687 native long rsnScriptKernelIDCreate(long con, long sid, int slot, int sig); 688 synchronized long nScriptKernelIDCreate(long sid, int slot, int sig) { 689 validate(); 690 return rsnScriptKernelIDCreate(mContext, sid, slot, sig); 691 } 692 693 native long rsnScriptFieldIDCreate(long con, long sid, int slot); 694 synchronized long nScriptFieldIDCreate(long sid, int slot) { 695 validate(); 696 return rsnScriptFieldIDCreate(mContext, sid, slot); 697 } 698 699 native long rsnScriptGroupCreate(long con, long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types); 700 synchronized long nScriptGroupCreate(long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types) { 701 validate(); 702 return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types); 703 } 704 705 native void rsnScriptGroupSetInput(long con, long group, long kernel, long alloc); 706 synchronized void nScriptGroupSetInput(long group, long kernel, long alloc) { 707 validate(); 708 rsnScriptGroupSetInput(mContext, group, kernel, alloc); 709 } 710 711 native void rsnScriptGroupSetOutput(long con, long group, long kernel, long alloc); 712 synchronized void nScriptGroupSetOutput(long group, long kernel, long alloc) { 713 validate(); 714 rsnScriptGroupSetOutput(mContext, group, kernel, alloc); 715 } 716 717 native void rsnScriptGroupExecute(long con, long group); 718 synchronized void nScriptGroupExecute(long group) { 719 validate(); 720 rsnScriptGroupExecute(mContext, group); 721 } 722 723 native long rsnSamplerCreate(long con, int magFilter, int minFilter, 724 int wrapS, int wrapT, int wrapR, float aniso); 725 synchronized long nSamplerCreate(int magFilter, int minFilter, 726 int wrapS, int wrapT, int wrapR, float aniso) { 727 validate(); 728 return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso); 729 } 730 731 native long rsnProgramStoreCreate(long con, boolean r, boolean g, boolean b, boolean a, 732 boolean depthMask, boolean dither, 733 int srcMode, int dstMode, int depthFunc); 734 synchronized long nProgramStoreCreate(boolean r, boolean g, boolean b, boolean a, 735 boolean depthMask, boolean dither, 736 int srcMode, int dstMode, int depthFunc) { 737 validate(); 738 return rsnProgramStoreCreate(mContext, r, g, b, a, depthMask, dither, srcMode, 739 dstMode, depthFunc); 740 } 741 742 native long rsnProgramRasterCreate(long con, boolean pointSprite, int cullMode); 743 synchronized long nProgramRasterCreate(boolean pointSprite, int cullMode) { 744 validate(); 745 return rsnProgramRasterCreate(mContext, pointSprite, cullMode); 746 } 747 748 native void rsnProgramBindConstants(long con, long pv, int slot, long mID); 749 synchronized void nProgramBindConstants(long pv, int slot, long mID) { 750 validate(); 751 rsnProgramBindConstants(mContext, pv, slot, mID); 752 } 753 native void rsnProgramBindTexture(long con, long vpf, int slot, long a); 754 synchronized void nProgramBindTexture(long vpf, int slot, long a) { 755 validate(); 756 rsnProgramBindTexture(mContext, vpf, slot, a); 757 } 758 native void rsnProgramBindSampler(long con, long vpf, int slot, long s); 759 synchronized void nProgramBindSampler(long vpf, int slot, long s) { 760 validate(); 761 rsnProgramBindSampler(mContext, vpf, slot, s); 762 } 763 native long rsnProgramFragmentCreate(long con, String shader, String[] texNames, long[] params); 764 synchronized long nProgramFragmentCreate(String shader, String[] texNames, long[] params) { 765 validate(); 766 return rsnProgramFragmentCreate(mContext, shader, texNames, params); 767 } 768 native long rsnProgramVertexCreate(long con, String shader, String[] texNames, long[] params); 769 synchronized long nProgramVertexCreate(String shader, String[] texNames, long[] params) { 770 validate(); 771 return rsnProgramVertexCreate(mContext, shader, texNames, params); 772 } 773 774 native long rsnMeshCreate(long con, long[] vtx, long[] idx, int[] prim); 775 synchronized long nMeshCreate(long[] vtx, long[] idx, int[] prim) { 776 validate(); 777 return rsnMeshCreate(mContext, vtx, idx, prim); 778 } 779 native int rsnMeshGetVertexBufferCount(long con, long id); 780 synchronized int nMeshGetVertexBufferCount(long id) { 781 validate(); 782 return rsnMeshGetVertexBufferCount(mContext, id); 783 } 784 native int rsnMeshGetIndexCount(long con, long id); 785 synchronized int nMeshGetIndexCount(long id) { 786 validate(); 787 return rsnMeshGetIndexCount(mContext, id); 788 } 789 native void rsnMeshGetVertices(long con, long id, long[] vtxIds, int vtxIdCount); 790 synchronized void nMeshGetVertices(long id, long[] vtxIds, int vtxIdCount) { 791 validate(); 792 rsnMeshGetVertices(mContext, id, vtxIds, vtxIdCount); 793 } 794 native void rsnMeshGetIndices(long con, long id, long[] idxIds, int[] primitives, int vtxIdCount); 795 synchronized void nMeshGetIndices(long id, long[] idxIds, int[] primitives, int vtxIdCount) { 796 validate(); 797 rsnMeshGetIndices(mContext, id, idxIds, primitives, vtxIdCount); 798 } 799 800 native long rsnPathCreate(long con, int prim, boolean isStatic, long vtx, long loop, float q); 801 synchronized long nPathCreate(int prim, boolean isStatic, long vtx, long loop, float q) { 802 validate(); 803 return rsnPathCreate(mContext, prim, isStatic, vtx, loop, q); 804 } 805 806 long mDev; 807 long mContext; 808 @SuppressWarnings({"FieldCanBeLocal"}) 809 MessageThread mMessageThread; 810 811 Element mElement_U8; 812 Element mElement_I8; 813 Element mElement_U16; 814 Element mElement_I16; 815 Element mElement_U32; 816 Element mElement_I32; 817 Element mElement_U64; 818 Element mElement_I64; 819 Element mElement_F32; 820 Element mElement_F64; 821 Element mElement_BOOLEAN; 822 823 Element mElement_ELEMENT; 824 Element mElement_TYPE; 825 Element mElement_ALLOCATION; 826 Element mElement_SAMPLER; 827 Element mElement_SCRIPT; 828 Element mElement_MESH; 829 Element mElement_PROGRAM_FRAGMENT; 830 Element mElement_PROGRAM_VERTEX; 831 Element mElement_PROGRAM_RASTER; 832 Element mElement_PROGRAM_STORE; 833 Element mElement_FONT; 834 835 Element mElement_A_8; 836 Element mElement_RGB_565; 837 Element mElement_RGB_888; 838 Element mElement_RGBA_5551; 839 Element mElement_RGBA_4444; 840 Element mElement_RGBA_8888; 841 842 Element mElement_FLOAT_2; 843 Element mElement_FLOAT_3; 844 Element mElement_FLOAT_4; 845 846 Element mElement_DOUBLE_2; 847 Element mElement_DOUBLE_3; 848 Element mElement_DOUBLE_4; 849 850 Element mElement_UCHAR_2; 851 Element mElement_UCHAR_3; 852 Element mElement_UCHAR_4; 853 854 Element mElement_CHAR_2; 855 Element mElement_CHAR_3; 856 Element mElement_CHAR_4; 857 858 Element mElement_USHORT_2; 859 Element mElement_USHORT_3; 860 Element mElement_USHORT_4; 861 862 Element mElement_SHORT_2; 863 Element mElement_SHORT_3; 864 Element mElement_SHORT_4; 865 866 Element mElement_UINT_2; 867 Element mElement_UINT_3; 868 Element mElement_UINT_4; 869 870 Element mElement_INT_2; 871 Element mElement_INT_3; 872 Element mElement_INT_4; 873 874 Element mElement_ULONG_2; 875 Element mElement_ULONG_3; 876 Element mElement_ULONG_4; 877 878 Element mElement_LONG_2; 879 Element mElement_LONG_3; 880 Element mElement_LONG_4; 881 882 Element mElement_YUV; 883 884 Element mElement_MATRIX_4X4; 885 Element mElement_MATRIX_3X3; 886 Element mElement_MATRIX_2X2; 887 888 Sampler mSampler_CLAMP_NEAREST; 889 Sampler mSampler_CLAMP_LINEAR; 890 Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR; 891 Sampler mSampler_WRAP_NEAREST; 892 Sampler mSampler_WRAP_LINEAR; 893 Sampler mSampler_WRAP_LINEAR_MIP_LINEAR; 894 Sampler mSampler_MIRRORED_REPEAT_NEAREST; 895 Sampler mSampler_MIRRORED_REPEAT_LINEAR; 896 Sampler mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR; 897 898 ProgramStore mProgramStore_BLEND_NONE_DEPTH_TEST; 899 ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH; 900 ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_TEST; 901 ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH; 902 903 ProgramRaster mProgramRaster_CULL_BACK; 904 ProgramRaster mProgramRaster_CULL_FRONT; 905 ProgramRaster mProgramRaster_CULL_NONE; 906 907 /////////////////////////////////////////////////////////////////////////////////// 908 // 909 910 /** 911 * The base class from which an application should derive in order 912 * to receive RS messages from scripts. When a script calls {@code 913 * rsSendToClient}, the data fields will be filled, and the run 914 * method will be called on a separate thread. This will occur 915 * some time after {@code rsSendToClient} completes in the script, 916 * as {@code rsSendToClient} is asynchronous. Message handlers are 917 * not guaranteed to have completed when {@link 918 * android.renderscript.RenderScript#finish} returns. 919 * 920 */ 921 public static class RSMessageHandler implements Runnable { 922 protected int[] mData; 923 protected int mID; 924 protected int mLength; 925 public void run() { 926 } 927 } 928 /** 929 * If an application is expecting messages, it should set this 930 * field to an instance of {@link RSMessageHandler}. This 931 * instance will receive all the user messages sent from {@code 932 * sendToClient} by scripts from this context. 933 * 934 */ 935 RSMessageHandler mMessageCallback = null; 936 937 public void setMessageHandler(RSMessageHandler msg) { 938 mMessageCallback = msg; 939 } 940 public RSMessageHandler getMessageHandler() { 941 return mMessageCallback; 942 } 943 944 /** 945 * Place a message into the message queue to be sent back to the message 946 * handler once all previous commands have been executed. 947 * 948 * @param id 949 * @param data 950 */ 951 public void sendMessage(int id, int[] data) { 952 nContextSendMessage(id, data); 953 } 954 955 /** 956 * The runtime error handler base class. An application should derive from this class 957 * if it wishes to install an error handler. When errors occur at runtime, 958 * the fields in this class will be filled, and the run method will be called. 959 * 960 */ 961 public static class RSErrorHandler implements Runnable { 962 protected String mErrorMessage; 963 protected int mErrorNum; 964 public void run() { 965 } 966 } 967 968 /** 969 * Application Error handler. All runtime errors will be dispatched to the 970 * instance of RSAsyncError set here. If this field is null a 971 * {@link RSRuntimeException} will instead be thrown with details about the error. 972 * This will cause program termaination. 973 * 974 */ 975 RSErrorHandler mErrorCallback = null; 976 977 public void setErrorHandler(RSErrorHandler msg) { 978 mErrorCallback = msg; 979 } 980 public RSErrorHandler getErrorHandler() { 981 return mErrorCallback; 982 } 983 984 /** 985 * RenderScript worker thread priority enumeration. The default value is 986 * NORMAL. Applications wishing to do background processing should set 987 * their priority to LOW to avoid starving forground processes. 988 */ 989 public enum Priority { 990 LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)), 991 NORMAL (Process.THREAD_PRIORITY_DISPLAY); 992 993 int mID; 994 Priority(int id) { 995 mID = id; 996 } 997 } 998 999 void validateObject(BaseObj o) { 1000 if (o != null) { 1001 if (o.mRS != this) { 1002 throw new RSIllegalArgumentException("Attempting to use an object across contexts."); 1003 } 1004 } 1005 } 1006 1007 void validate() { 1008 if (mContext == 0) { 1009 throw new RSInvalidStateException("Calling RS with no Context active."); 1010 } 1011 } 1012 1013 1014 /** 1015 * Change the priority of the worker threads for this context. 1016 * 1017 * @param p New priority to be set. 1018 */ 1019 public void setPriority(Priority p) { 1020 validate(); 1021 nContextSetPriority(p.mID); 1022 } 1023 1024 static class MessageThread extends Thread { 1025 RenderScript mRS; 1026 boolean mRun = true; 1027 int[] mAuxData = new int[2]; 1028 1029 static final int RS_MESSAGE_TO_CLIENT_NONE = 0; 1030 static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1; 1031 static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2; 1032 static final int RS_MESSAGE_TO_CLIENT_ERROR = 3; 1033 static final int RS_MESSAGE_TO_CLIENT_USER = 4; 1034 static final int RS_MESSAGE_TO_CLIENT_NEW_BUFFER = 5; 1035 1036 static final int RS_ERROR_FATAL_DEBUG = 0x0800; 1037 static final int RS_ERROR_FATAL_UNKNOWN = 0x1000; 1038 1039 MessageThread(RenderScript rs) { 1040 super("RSMessageThread"); 1041 mRS = rs; 1042 1043 } 1044 1045 public void run() { 1046 // This function is a temporary solution. The final solution will 1047 // used typed allocations where the message id is the type indicator. 1048 int[] rbuf = new int[16]; 1049 mRS.nContextInitToClient(mRS.mContext); 1050 while(mRun) { 1051 rbuf[0] = 0; 1052 int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData); 1053 int size = mAuxData[1]; 1054 int subID = mAuxData[0]; 1055 1056 if (msg == RS_MESSAGE_TO_CLIENT_USER) { 1057 if ((size>>2) >= rbuf.length) { 1058 rbuf = new int[(size + 3) >> 2]; 1059 } 1060 if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) != 1061 RS_MESSAGE_TO_CLIENT_USER) { 1062 throw new RSDriverException("Error processing message from RenderScript."); 1063 } 1064 1065 if(mRS.mMessageCallback != null) { 1066 mRS.mMessageCallback.mData = rbuf; 1067 mRS.mMessageCallback.mID = subID; 1068 mRS.mMessageCallback.mLength = size; 1069 mRS.mMessageCallback.run(); 1070 } else { 1071 throw new RSInvalidStateException("Received a message from the script with no message handler installed."); 1072 } 1073 continue; 1074 } 1075 1076 if (msg == RS_MESSAGE_TO_CLIENT_ERROR) { 1077 String e = mRS.nContextGetErrorMessage(mRS.mContext); 1078 1079 // Throw RSRuntimeException under the following conditions: 1080 // 1081 // 1) It is an unknown fatal error. 1082 // 2) It is a debug fatal error, and we are not in a 1083 // debug context. 1084 // 3) It is a debug fatal error, and we do not have an 1085 // error callback. 1086 if (subID >= RS_ERROR_FATAL_UNKNOWN || 1087 (subID >= RS_ERROR_FATAL_DEBUG && 1088 (mRS.mContextType != ContextType.DEBUG || 1089 mRS.mErrorCallback == null))) { 1090 throw new RSRuntimeException("Fatal error " + subID + ", details: " + e); 1091 } 1092 1093 if(mRS.mErrorCallback != null) { 1094 mRS.mErrorCallback.mErrorMessage = e; 1095 mRS.mErrorCallback.mErrorNum = subID; 1096 mRS.mErrorCallback.run(); 1097 } else { 1098 android.util.Log.e(LOG_TAG, "non fatal RS error, " + e); 1099 // Do not throw here. In these cases, we do not have 1100 // a fatal error. 1101 } 1102 continue; 1103 } 1104 1105 if (msg == RS_MESSAGE_TO_CLIENT_NEW_BUFFER) { 1106 Allocation.sendBufferNotification(subID); 1107 continue; 1108 } 1109 1110 // 2: teardown. 1111 // But we want to avoid starving other threads during 1112 // teardown by yielding until the next line in the destructor 1113 // can execute to set mRun = false 1114 try { 1115 sleep(1, 0); 1116 } catch(InterruptedException e) { 1117 } 1118 } 1119 //Log.d(LOG_TAG, "MessageThread exiting."); 1120 } 1121 } 1122 1123 RenderScript(Context ctx) { 1124 mContextType = ContextType.NORMAL; 1125 if (ctx != null) { 1126 mApplicationContext = ctx.getApplicationContext(); 1127 } 1128 mRWLock = new ReentrantReadWriteLock(); 1129 } 1130 1131 /** 1132 * Gets the application context associated with the RenderScript context. 1133 * 1134 * @return The application context. 1135 */ 1136 public final Context getApplicationContext() { 1137 return mApplicationContext; 1138 } 1139 1140 /** 1141 * @hide 1142 */ 1143 public static RenderScript create(Context ctx, int sdkVersion) { 1144 return create(ctx, sdkVersion, ContextType.NORMAL); 1145 } 1146 1147 /** 1148 * Create a RenderScript context. 1149 * 1150 * @hide 1151 * @param ctx The context. 1152 * @return RenderScript 1153 */ 1154 public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) { 1155 if (!sInitialized) { 1156 Log.e(LOG_TAG, "RenderScript.create() called when disabled; someone is likely to crash"); 1157 return null; 1158 } 1159 1160 RenderScript rs = new RenderScript(ctx); 1161 1162 rs.mDev = rs.nDeviceCreate(); 1163 rs.mContext = rs.nContextCreate(rs.mDev, 0, sdkVersion, ct.mID); 1164 rs.mContextType = ct; 1165 if (rs.mContext == 0) { 1166 throw new RSDriverException("Failed to create RS context."); 1167 } 1168 rs.mMessageThread = new MessageThread(rs); 1169 rs.mMessageThread.start(); 1170 return rs; 1171 } 1172 1173 /** 1174 * Create a RenderScript context. 1175 * 1176 * @param ctx The context. 1177 * @return RenderScript 1178 */ 1179 public static RenderScript create(Context ctx) { 1180 return create(ctx, ContextType.NORMAL); 1181 } 1182 1183 /** 1184 * Create a RenderScript context. 1185 * 1186 * 1187 * @param ctx The context. 1188 * @param ct The type of context to be created. 1189 * @return RenderScript 1190 */ 1191 public static RenderScript create(Context ctx, ContextType ct) { 1192 int v = ctx.getApplicationInfo().targetSdkVersion; 1193 return create(ctx, v, ct); 1194 } 1195 1196 /** 1197 * Print the currently available debugging information about the state of 1198 * the RS context to the log. 1199 * 1200 */ 1201 public void contextDump() { 1202 validate(); 1203 nContextDump(0); 1204 } 1205 1206 /** 1207 * Wait for any pending asynchronous opeations (such as copies to a RS 1208 * allocation or RS script executions) to complete. 1209 * 1210 */ 1211 public void finish() { 1212 nContextFinish(); 1213 } 1214 1215 /** 1216 * Destroys this RenderScript context. Once this function is called, 1217 * using this context or any objects belonging to this context is 1218 * illegal. 1219 * 1220 */ 1221 public void destroy() { 1222 validate(); 1223 nContextFinish(); 1224 1225 nContextDeinitToClient(mContext); 1226 mMessageThread.mRun = false; 1227 try { 1228 mMessageThread.join(); 1229 } catch(InterruptedException e) { 1230 } 1231 1232 nContextDestroy(); 1233 1234 nDeviceDestroy(mDev); 1235 mDev = 0; 1236 } 1237 1238 boolean isAlive() { 1239 return mContext != 0; 1240 } 1241 1242 long safeID(BaseObj o) { 1243 if(o != null) { 1244 return o.getID(this); 1245 } 1246 return 0; 1247 } 1248} 1249