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