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