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