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