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