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