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 17 package android.support.v8.renderscript; 18 19 import java.io.File; 20 import java.lang.reflect.Field; 21 import java.lang.reflect.Method; 22 import java.util.concurrent.locks.ReentrantReadWriteLock; 23 import java.util.ArrayList; 24 import java.nio.ByteBuffer; 25 26 import android.content.Context; 27 import android.content.pm.ApplicationInfo; 28 import android.content.pm.PackageManager; 29 import android.content.res.AssetManager; 30 import android.graphics.Bitmap; 31 import android.graphics.BitmapFactory; 32 import android.os.Process; 33 import android.util.Log; 34 import 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 **/ 47 public 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 */ setBlackList(String blackList)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 */ forceCompat()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. nLoadSO(boolean useNative, int deviceApi, String libPath)104 native boolean nLoadSO(boolean useNative, int deviceApi, String libPath); nLoadIOSO()105 native boolean nLoadIOSO(); nDeviceCreate()106 native long nDeviceCreate(); nDeviceDestroy(long dev)107 native void nDeviceDestroy(long dev); nDeviceSetConfig(long dev, int param, int value)108 native void nDeviceSetConfig(long dev, int param, int value); nContextGetUserMessage(long con, int[] data)109 native int nContextGetUserMessage(long con, int[] data); nContextGetErrorMessage(long con)110 native String nContextGetErrorMessage(long con); nContextPeekMessage(long con, int[] subID)111 native int nContextPeekMessage(long con, int[] subID); nContextInitToClient(long con)112 native void nContextInitToClient(long con); nContextDeinitToClient(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 getDispatchAPILevel()126 int getDispatchAPILevel() { 127 return mDispatchAPILevel; 128 } 129 isUseNative()130 boolean isUseNative() { 131 return useNative; 132 } 133 /* 134 * Detect the bitness of the VM to allow FieldPacker to do the right thing. 135 */ rsnSystemGetPointerSize()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 */ setupNative(int sdkVersion, Context ctx)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 */ setupDiskCache(File cacheDir)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; ContextType(int id)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 rsnContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir)288 native long rsnContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir); nContextCreate(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 } rsnContextDestroy(long con)292 native void rsnContextDestroy(long con); nContextDestroy()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 } rsnContextSetPriority(long con, int p)308 native void rsnContextSetPriority(long con, int p); nContextSetPriority(int p)309 synchronized void nContextSetPriority(int p) { 310 validate(); 311 rsnContextSetPriority(mContext, p); 312 } rsnContextDump(long con, int bits)313 native void rsnContextDump(long con, int bits); nContextDump(int bits)314 synchronized void nContextDump(int bits) { 315 validate(); 316 rsnContextDump(mContext, bits); 317 } rsnContextFinish(long con)318 native void rsnContextFinish(long con); nContextFinish()319 synchronized void nContextFinish() { 320 validate(); 321 rsnContextFinish(mContext); 322 } 323 rsnContextSendMessage(long con, int id, int[] data)324 native void rsnContextSendMessage(long con, int id, int[] data); nContextSendMessage(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 rsnObjDestroy(long con, long id)331 native void rsnObjDestroy(long con, long id); nObjDestroy(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 rsnElementCreate(long con, long type, int kind, boolean norm, int vecSize)341 native long rsnElementCreate(long con, long type, int kind, boolean norm, int vecSize); nElementCreate(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 } rsnElementCreate2(long con, long[] elements, String[] names, int[] arraySizes)346 native long rsnElementCreate2(long con, long[] elements, String[] names, int[] arraySizes); nElementCreate2(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 } rsnElementGetNativeData(long con, long id, int[] elementData)351 native void rsnElementGetNativeData(long con, long id, int[] elementData); nElementGetNativeData(long id, int[] elementData)352 synchronized void nElementGetNativeData(long id, int[] elementData) { 353 validate(); 354 rsnElementGetNativeData(mContext, id, elementData); 355 } rsnElementGetSubElements(long con, long id, long[] IDs, String[] names, int[] arraySizes)356 native void rsnElementGetSubElements(long con, long id, 357 long[] IDs, String[] names, int[] arraySizes); nElementGetSubElements(long id, 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 rsnTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv)363 native long rsnTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv); nTypeCreate(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 rsnTypeGetNativeData(long con, long id, long[] typeData)369 native void rsnTypeGetNativeData(long con, long id, long[] typeData); nTypeGetNativeData(long id, long[] typeData)370 synchronized void nTypeGetNativeData(long id, long[] typeData) { 371 validate(); 372 rsnTypeGetNativeData(mContext, id, typeData); 373 } 374 rsnAllocationCreateTyped(long con, long type, int mip, int usage, long pointer)375 native long rsnAllocationCreateTyped(long con, long type, int mip, int usage, long pointer); nAllocationCreateTyped(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 } rsnAllocationCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage)380 native long rsnAllocationCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage); nAllocationCreateFromBitmap(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 rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, Bitmap bmp, int usage)386 native long rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, Bitmap bmp, int usage); nAllocationCreateBitmapBackedAllocation(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 rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage)393 native long rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage); nAllocationCubeCreateFromBitmap(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 } rsnAllocationCreateBitmapRef(long con, long type, Bitmap bmp)398 native long rsnAllocationCreateBitmapRef(long con, long type, Bitmap bmp); nAllocationCreateBitmapRef(long type, Bitmap bmp)399 synchronized long nAllocationCreateBitmapRef(long type, Bitmap bmp) { 400 validate(); 401 return rsnAllocationCreateBitmapRef(mContext, type, bmp); 402 } rsnAllocationCreateFromAssetStream(long con, int mips, int assetStream, int usage)403 native long rsnAllocationCreateFromAssetStream(long con, int mips, int assetStream, int usage); nAllocationCreateFromAssetStream(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 rsnAllocationCopyToBitmap(long con, long alloc, Bitmap bmp)409 native void rsnAllocationCopyToBitmap(long con, long alloc, Bitmap bmp); nAllocationCopyToBitmap(long alloc, Bitmap bmp)410 synchronized void nAllocationCopyToBitmap(long alloc, Bitmap bmp) { 411 validate(); 412 rsnAllocationCopyToBitmap(mContext, alloc, bmp); 413 } 414 415 rsnAllocationSyncAll(long con, long alloc, int src)416 native void rsnAllocationSyncAll(long con, long alloc, int src); nAllocationSyncAll(long alloc, int src)417 synchronized void nAllocationSyncAll(long alloc, int src) { 418 validate(); 419 rsnAllocationSyncAll(mContext, alloc, src); 420 } 421 rsnAllocationSetSurface(long con, long alloc, Surface sur)422 native void rsnAllocationSetSurface(long con, long alloc, Surface sur); nAllocationSetSurface(long alloc, Surface sur)423 synchronized void nAllocationSetSurface(long alloc, Surface sur) { 424 validate(); 425 rsnAllocationSetSurface(mContext, alloc, sur); 426 } 427 rsnAllocationIoSend(long con, long alloc)428 native void rsnAllocationIoSend(long con, long alloc); nAllocationIoSend(long alloc)429 synchronized void nAllocationIoSend(long alloc) { 430 validate(); 431 rsnAllocationIoSend(mContext, alloc); 432 } rsnAllocationIoReceive(long con, long alloc)433 native void rsnAllocationIoReceive(long con, long alloc); nAllocationIoReceive(long alloc)434 synchronized void nAllocationIoReceive(long alloc) { 435 validate(); 436 rsnAllocationIoReceive(mContext, alloc); 437 } rsnAllocationGetByteBuffer(long con, long alloc, int xBytesSize, int dimY, int dimZ)438 native ByteBuffer rsnAllocationGetByteBuffer(long con, long alloc, int xBytesSize, int dimY, int dimZ); nAllocationGetByteBuffer(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 } rsnAllocationGetStride(long con, long alloc)443 native long rsnAllocationGetStride(long con, long alloc); nAllocationGetStride(long alloc)444 synchronized long nAllocationGetStride(long alloc) { 445 validate(); 446 return rsnAllocationGetStride(mContext, alloc); 447 } 448 rsnAllocationGenerateMipmaps(long con, long alloc)449 native void rsnAllocationGenerateMipmaps(long con, long alloc); nAllocationGenerateMipmaps(long alloc)450 synchronized void nAllocationGenerateMipmaps(long alloc) { 451 validate(); 452 rsnAllocationGenerateMipmaps(mContext, alloc); 453 } rsnAllocationCopyFromBitmap(long con, long alloc, Bitmap bmp)454 native void rsnAllocationCopyFromBitmap(long con, long alloc, Bitmap bmp); nAllocationCopyFromBitmap(long alloc, Bitmap bmp)455 synchronized void nAllocationCopyFromBitmap(long alloc, Bitmap bmp) { 456 validate(); 457 rsnAllocationCopyFromBitmap(mContext, alloc, bmp); 458 } 459 460 rsnAllocationData1D(long con, long id, int off, int mip, int count, Object d, int sizeBytes, int dt, int mSize, boolean usePadding)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); nAllocationData1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType dt, 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 rsnAllocationElementData1D(long con,long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes)469 native void rsnAllocationElementData1D(long con,long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes); nAllocationElementData1D(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 rsnAllocationData2D(long con, long dstAlloc, int dstXoff, int dstYoff, int dstMip, int dstFace, int width, int height, long srcAlloc, int srcXoff, int srcYoff, int srcMip, int srcFace)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); nAllocationData2D(long dstAlloc, int dstXoff, int dstYoff, int dstMip, int dstFace, int width, int height, long srcAlloc, int srcXoff, int srcYoff, 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 rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, int w, int h, Object d, int sizeBytes, int dt, int mSize, boolean usePadding)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); nAllocationData2D(long id, int xoff, int yoff, int mip, int face, int w, int h, Object d, int sizeBytes, Element.DataType dt, 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 rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, Bitmap b)512 native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, Bitmap b); nAllocationData2D(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 rsnAllocationData3D(long con, long dstAlloc, int dstXoff, int dstYoff, int dstZoff, int dstMip, int width, int height, int depth, long srcAlloc, int srcXoff, int srcYoff, int srcZoff, int srcMip)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); nAllocationData3D(long dstAlloc, int dstXoff, int dstYoff, int dstZoff, int dstMip, int width, int height, int depth, long srcAlloc, int srcXoff, int srcYoff, int srcZoff, 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 rsnAllocationData3D(long con, long id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, Object d, int sizeBytes, int dt, int mSize, boolean usePadding)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); nAllocationData3D(long id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt, 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 rsnAllocationRead(long con, long id, Object d, int dt, int mSize, boolean usePadding)548 native void rsnAllocationRead(long con, long id, Object d, int dt, int mSize, boolean usePadding); nAllocationRead(long id, Object d, Element.DataType 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 rsnAllocationRead1D(long con, long id, int off, int mip, int count, Object d, int sizeBytes, int dt, int mSize, boolean usePadding)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); nAllocationRead1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType 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 rsnAllocationRead2D(long con, long id, int xoff, int yoff, int mip, int face, int w, int h, Object d, int sizeBytes, int dt, int mSize, boolean usePadding)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); nAllocationRead2D(long id, int xoff, int yoff, int mip, int face, int w, int h, Object d, int sizeBytes, Element.DataType dt, 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 rsnAllocationGetType(long con, long id)594 native long rsnAllocationGetType(long con, long id); nAllocationGetType(long id)595 synchronized long nAllocationGetType(long id) { 596 validate(); 597 return rsnAllocationGetType(mContext, id); 598 } 599 rsnAllocationResize1D(long con, long id, int dimX)600 native void rsnAllocationResize1D(long con, long id, int dimX); nAllocationResize1D(long id, int dimX)601 synchronized void nAllocationResize1D(long id, int dimX) { 602 validate(); 603 rsnAllocationResize1D(mContext, id, dimX); 604 } rsnAllocationResize2D(long con, long id, int dimX, int dimY)605 native void rsnAllocationResize2D(long con, long id, int dimX, int dimY); nAllocationResize2D(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 rsnScriptBindAllocation(long con, long script, long alloc, int slot, boolean mUseInc)611 native void rsnScriptBindAllocation(long con, long script, long alloc, int slot, boolean mUseInc); nScriptBindAllocation(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 } rsnScriptSetTimeZone(long con, long script, byte[] timeZone, boolean mUseInc)620 native void rsnScriptSetTimeZone(long con, long script, byte[] timeZone, boolean mUseInc); nScriptSetTimeZone(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 } rsnScriptInvoke(long con, long id, int slot, boolean mUseInc)629 native void rsnScriptInvoke(long con, long id, int slot, boolean mUseInc); nScriptInvoke(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 } rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, byte[] params, boolean mUseInc)638 native void rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, byte[] params, boolean mUseInc); rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, boolean mUseInc)639 native void rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, boolean mUseInc); rsnScriptForEachClipped(long con, long incCon, long id, int slot, long ain, long aout, byte[] params, int xstart, int xend, int ystart, int yend, int zstart, int zend, 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); rsnScriptForEachClipped(long con, long incCon, long id, int slot, long ain, long aout, 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); nScriptForEach(long id, int slot, long ain, long aout, byte[] params, 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 nScriptForEachClipped(long id, int slot, long ain, long aout, byte[] params, int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc)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 rsnScriptForEach(long con, long id, int slot, long[] ains, long aout, byte[] params, int[] limits)663 native void rsnScriptForEach(long con, long id, int slot, long[] ains, 664 long aout, byte[] params, int[] limits); 665 nScriptForEach(long id, int slot, long[] ains, long aout, byte[] params, int[] limits)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 rsnScriptReduce(long con, long id, int slot, long[] ains, long aout, int[] limits)676 native void rsnScriptReduce(long con, long id, int slot, long[] ains, 677 long aout, int[] limits); nScriptReduce(long id, int slot, long ains[], 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 rsnScriptInvokeV(long con, long id, int slot, byte[] params, boolean mUseInc)684 native void rsnScriptInvokeV(long con, long id, int slot, byte[] params, boolean mUseInc); nScriptInvokeV(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 } rsnScriptSetVarI(long con, long id, int slot, int val, boolean mUseInc)693 native void rsnScriptSetVarI(long con, long id, int slot, int val, boolean mUseInc); nScriptSetVarI(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 } rsnScriptSetVarJ(long con, long id, int slot, long val, boolean mUseInc)702 native void rsnScriptSetVarJ(long con, long id, int slot, long val, boolean mUseInc); nScriptSetVarJ(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 } rsnScriptSetVarF(long con, long id, int slot, float val, boolean mUseInc)711 native void rsnScriptSetVarF(long con, long id, int slot, float val, boolean mUseInc); nScriptSetVarF(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 } rsnScriptSetVarD(long con, long id, int slot, double val, boolean mUseInc)720 native void rsnScriptSetVarD(long con, long id, int slot, double val, boolean mUseInc); nScriptSetVarD(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 } rsnScriptSetVarV(long con, long id, int slot, byte[] val, boolean mUseInc)729 native void rsnScriptSetVarV(long con, long id, int slot, byte[] val, boolean mUseInc); nScriptSetVarV(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 } rsnScriptSetVarVE(long con, long id, int slot, byte[] val, long e, int[] dims, boolean mUseInc)738 native void rsnScriptSetVarVE(long con, long id, int slot, byte[] val, 739 long e, int[] dims, boolean mUseInc); nScriptSetVarVE(long id, int slot, byte[] val, 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 } rsnScriptSetVarObj(long con, long id, int slot, long val, boolean mUseInc)749 native void rsnScriptSetVarObj(long con, long id, int slot, long val, boolean mUseInc); nScriptSetVarObj(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 rsnScriptCCreate(long con, String resName, String cacheDir, byte[] script, int length)759 native long rsnScriptCCreate(long con, String resName, String cacheDir, 760 byte[] script, int length); nScriptCCreate(String resName, String cacheDir, 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 rsnScriptIntrinsicCreate(long con, int id, long eid, boolean mUseInc)766 native long rsnScriptIntrinsicCreate(long con, int id, long eid, boolean mUseInc); nScriptIntrinsicCreate(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 rsnScriptKernelIDCreate(long con, long sid, int slot, int sig, boolean mUseInc)798 native long rsnScriptKernelIDCreate(long con, long sid, int slot, int sig, boolean mUseInc); nScriptKernelIDCreate(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 rsnScriptInvokeIDCreate(long con, long sid, int slot)808 native long rsnScriptInvokeIDCreate(long con, long sid, int slot); nScriptInvokeIDCreate(long sid, int slot)809 synchronized long nScriptInvokeIDCreate(long sid, int slot) { 810 validate(); 811 return rsnScriptInvokeIDCreate(mContext, sid, slot); 812 } 813 rsnScriptFieldIDCreate(long con, long sid, int slot, boolean mUseInc)814 native long rsnScriptFieldIDCreate(long con, long sid, int slot, boolean mUseInc); nScriptFieldIDCreate(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 rsnScriptGroupCreate(long con, long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types)824 native long rsnScriptGroupCreate(long con, long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types); nScriptGroupCreate(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 rsnScriptGroupSetInput(long con, long group, long kernel, long alloc)830 native void rsnScriptGroupSetInput(long con, long group, long kernel, long alloc); nScriptGroupSetInput(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 rsnScriptGroupSetOutput(long con, long group, long kernel, long alloc)836 native void rsnScriptGroupSetOutput(long con, long group, long kernel, long alloc); nScriptGroupSetOutput(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 rsnScriptGroupExecute(long con, long group)842 native void rsnScriptGroupExecute(long con, long group); nScriptGroupExecute(long group)843 synchronized void nScriptGroupExecute(long group) { 844 validate(); 845 rsnScriptGroupExecute(mContext, group); 846 } 847 rsnSamplerCreate(long con, int magFilter, int minFilter, int wrapS, int wrapT, int wrapR, float aniso)848 native long rsnSamplerCreate(long con, int magFilter, int minFilter, 849 int wrapS, int wrapT, int wrapR, float aniso); nSamplerCreate(int magFilter, int minFilter, 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 rsnClosureCreate(long con, long kernelID, long returnValue, long[] fieldIDs, long[] values, int[] sizes, long[] depClosures, long[] depFieldIDs)857 native long rsnClosureCreate(long con, long kernelID, long returnValue, 858 long[] fieldIDs, long[] values, int[] sizes, long[] depClosures, 859 long[] depFieldIDs); nClosureCreate(long kernelID, long returnValue, long[] fieldIDs, long[] values, int[] sizes, long[] depClosures, 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 rsnInvokeClosureCreate(long con, long invokeID, byte[] params, long[] fieldIDs, long[] values, int[] sizes)872 native long rsnInvokeClosureCreate(long con, long invokeID, byte[] params, 873 long[] fieldIDs, long[] values, int[] sizes); nInvokeClosureCreate(long invokeID, byte[] params, 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 rsnClosureSetArg(long con, long closureID, int index, long value, int size)885 native void rsnClosureSetArg(long con, long closureID, int index, 886 long value, int size); nClosureSetArg(long closureID, int index, 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 rsnClosureSetGlobal(long con, long closureID, long fieldID, long value, int size)893 native void rsnClosureSetGlobal(long con, long closureID, long fieldID, 894 long value, int size); 895 // Does this have to be synchronized? nClosureSetGlobal(long closureID, long fieldID, long value, int size)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 rsnScriptGroup2Create(long con, String name, String cachePath, long[] closures)902 native long rsnScriptGroup2Create(long con, String name, String cachePath, 903 long[] closures); nScriptGroup2Create(String name, String cachePath, long[] closures)904 synchronized long nScriptGroup2Create(String name, String cachePath, 905 long[] closures) { 906 validate(); 907 return rsnScriptGroup2Create(mContext, name, cachePath, closures); 908 } 909 rsnScriptGroup2Execute(long con, long groupID)910 native void rsnScriptGroup2Execute(long con, long groupID); nScriptGroup2Execute(long groupID)911 synchronized void nScriptGroup2Execute(long groupID) { 912 validate(); 913 rsnScriptGroup2Execute(mContext, groupID); 914 } 915 rsnScriptIntrinsicBLAS_Single(long con, long incCon, long id, int func, int TransA, int TransB, int Side, int Uplo, int Diag, int M, int N, int K, float alpha, long A, long B, float beta, long C, int incX, int incY, int KL, int KU, boolean mUseInc)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); nScriptIntrinsicBLAS_Single(long id, int func, int TransA, int TransB, int Side, int Uplo, int Diag, int M, int N, int K, float alpha, long A, long B, float beta, long C, int incX, int incY, 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 rsnScriptIntrinsicBLAS_Double(long con, long incCon, long id, int func, int TransA, int TransB, int Side, int Uplo, int Diag, int M, int N, int K, double alpha, long A, long B, double beta, long C, int incX, int incY, int KL, int KU, boolean mUseInc)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); nScriptIntrinsicBLAS_Double(long id, int func, int TransA, int TransB, int Side, int Uplo, int Diag, int M, int N, int K, double alpha, long A, long B, double beta, long C, int incX, int incY, 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 rsnScriptIntrinsicBLAS_Complex(long con, long incCon, long id, int func, int TransA, int TransB, int Side, int Uplo, int Diag, int M, int N, int K, float alphaX, float alphaY, long A, long B, float betaX, float betaY, long C, int incX, int incY, int KL, int KU, boolean mUseInc)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); nScriptIntrinsicBLAS_Complex(long id, int func, int TransA, int TransB, int Side, int Uplo, int Diag, int M, int N, int K, float alphaX, float alphaY, long A, long B, float betaX, float betaY, long C, int incX, int incY, 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 rsnScriptIntrinsicBLAS_Z(long con, long incCon, long id, int func, int TransA, int TransB, int Side, int Uplo, int Diag, int M, int N, int K, double alphaX, double alphaY, long A, long B, double betaX, double betaY, long C, int incX, int incY, int KL, int KU, boolean mUseInc)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); nScriptIntrinsicBLAS_Z(long id, int func, int TransA, int TransB, int Side, int Uplo, int Diag, int M, int N, int K, double alphaX, double alphaY, long A, long B, double betaX, double betaY, long C, int incX, int incY, 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 rsnScriptIntrinsicBLAS_BNNM(long con, long incCon, long id, int M, int N, int K, long A, int a_offset, long B, int b_offset, long C, int c_offset, int c_mult_int, boolean mUseInc)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); nScriptIntrinsicBLAS_BNNM(long id, int M, int N, int K, long A, int a_offset, long B, int b_offset, long C, int c_offset, 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 nIncLoadSO(int deviceApi, String libPath)976 native boolean nIncLoadSO(int deviceApi, String libPath); nIncDeviceCreate()977 native long nIncDeviceCreate(); nIncDeviceDestroy(long dev)978 native void nIncDeviceDestroy(long dev); 979 // Methods below are wrapped to protect the non-threadsafe 980 // lockless fifo. rsnIncContextCreate(long dev, int ver, int sdkVer, int contextType)981 native long rsnIncContextCreate(long dev, int ver, int sdkVer, int contextType); nIncContextCreate(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 } rsnIncContextDestroy(long con)985 native void rsnIncContextDestroy(long con); nIncContextDestroy()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 rsnIncContextFinish(long con)1002 native void rsnIncContextFinish(long con); nIncContextFinish()1003 synchronized void nIncContextFinish() { 1004 validate(); 1005 rsnIncContextFinish(mIncCon); 1006 } 1007 rsnIncObjDestroy(long con, long id)1008 native void rsnIncObjDestroy(long con, long id); nIncObjDestroy(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 } rsnIncElementCreate(long con, long type, int kind, boolean norm, int vecSize)1017 native long rsnIncElementCreate(long con, long type, int kind, boolean norm, int vecSize); nIncElementCreate(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 } rsnIncTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv)1022 native long rsnIncTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv); nIncTypeCreate(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 } rsnIncAllocationCreateTyped(long con, long incCon, long alloc, long type, int xBytesSize)1027 native long rsnIncAllocationCreateTyped(long con, long incCon, long alloc, long type, int xBytesSize); nIncAllocationCreateTyped(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; run()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 setMessageHandler(RSMessageHandler msg)1153 public void setMessageHandler(RSMessageHandler msg) { 1154 mMessageCallback = msg; 1155 } getMessageHandler()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 */ sendMessage(int id, int[] data)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; run()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 setErrorHandler(RSErrorHandler msg)1193 public void setErrorHandler(RSErrorHandler msg) { 1194 mErrorCallback = msg; 1195 } getErrorHandler()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; Priority(int id)1210 Priority(int id) { 1211 mID = id; 1212 } 1213 } 1214 validateObject(BaseObj o)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 validate()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 */ usingIO()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 */ setPriority(Priority p)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 MessageThread(RenderScript rs)1258 MessageThread(RenderScript rs) { 1259 super("RSMessageThread"); 1260 mRS = rs; 1261 1262 } 1263 run()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 RenderScript(Context ctx)1327 RenderScript(Context ctx) { 1328 mContextType = ContextType.NORMAL; 1329 if (ctx != null) { 1330 mApplicationContext = ctx.getApplicationContext(); 1331 // Only set mNativeLibDir for API 9+. 1332 mNativeLibDir = mApplicationContext.getApplicationInfo().nativeLibraryDir; 1333 } 1334 mIncCon = 0; 1335 mIncLoaded = false; 1336 mRWLock = new ReentrantReadWriteLock(); 1337 } 1338 1339 /** 1340 * Gets the application context associated with the RenderScript context. 1341 * 1342 * @return The application context. 1343 */ getApplicationContext()1344 public final Context getApplicationContext() { 1345 return mApplicationContext; 1346 } 1347 1348 /** 1349 * Create a RenderScript context. 1350 * 1351 * @param ctx The context. 1352 * @return RenderScript 1353 */ internalCreate(Context ctx, int sdkVersion, ContextType ct, int flags)1354 private static RenderScript internalCreate(Context ctx, int sdkVersion, ContextType ct, int flags) { 1355 RenderScript rs = new RenderScript(ctx); 1356 1357 if (sSdkVersion == -1) { 1358 sSdkVersion = sdkVersion; 1359 } else if (sSdkVersion != sdkVersion) { 1360 throw new RSRuntimeException("Can't have two contexts with different SDK versions in support lib"); 1361 } 1362 useNative = setupNative(sSdkVersion, ctx); 1363 synchronized(lock) { 1364 if (sInitialized == false) { 1365 try { 1366 Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime"); 1367 Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime"); 1368 sRuntime = get_runtime.invoke(null); 1369 registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", Integer.TYPE); 1370 registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", Integer.TYPE); 1371 sUseGCHooks = true; 1372 } catch (Exception e) { 1373 Log.e(LOG_TAG, "No GC methods"); 1374 sUseGCHooks = false; 1375 } 1376 try { 1377 // For API 9 - 22, always use the absolute path of librsjni.so 1378 // http://b/25226912 1379 if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M && 1380 rs.mNativeLibDir != null) { 1381 System.load(rs.mNativeLibDir + "/librsjni.so"); 1382 } else { 1383 System.loadLibrary("rsjni"); 1384 } 1385 sInitialized = true; 1386 sPointerSize = rsnSystemGetPointerSize(); 1387 } catch (UnsatisfiedLinkError e) { 1388 Log.e(LOG_TAG, "Error loading RS jni library: " + e); 1389 throw new RSRuntimeException("Error loading RS jni library: " + e + " Support lib API: " + SUPPORT_LIB_VERSION); 1390 } 1391 } 1392 } 1393 1394 if (useNative) { 1395 android.util.Log.v(LOG_TAG, "RS native mode"); 1396 } else { 1397 android.util.Log.v(LOG_TAG, "RS compat mode"); 1398 } 1399 1400 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 1401 useIOlib = true; 1402 } 1403 1404 // The target API level used to init dispatchTable. 1405 int dispatchAPI = sdkVersion; 1406 if (sdkVersion < android.os.Build.VERSION.SDK_INT) { 1407 // If the device API is higher than target API level, init dispatch table based on device API. 1408 dispatchAPI = android.os.Build.VERSION.SDK_INT; 1409 } 1410 1411 String rssupportPath = null; 1412 // For API 9 - 22, always use the absolute path of libRSSupport.so 1413 // http://b/25226912 1414 if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M && 1415 rs.mNativeLibDir != null) { 1416 rssupportPath = rs.mNativeLibDir + "/libRSSupport.so"; 1417 } 1418 if (!rs.nLoadSO(useNative, dispatchAPI, rssupportPath)) { 1419 if (useNative) { 1420 android.util.Log.v(LOG_TAG, "Unable to load libRS.so, falling back to compat mode"); 1421 useNative = false; 1422 } 1423 try { 1424 if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M && 1425 rs.mNativeLibDir != null) { 1426 System.load(rssupportPath); 1427 } else { 1428 System.loadLibrary("RSSupport"); 1429 } 1430 } catch (UnsatisfiedLinkError e) { 1431 Log.e(LOG_TAG, "Error loading RS Compat library: " + e + " Support lib version: " + SUPPORT_LIB_VERSION); 1432 throw new RSRuntimeException("Error loading RS Compat library: " + e + " Support lib version: " + SUPPORT_LIB_VERSION); 1433 } 1434 if (!rs.nLoadSO(false, dispatchAPI, rssupportPath)) { 1435 Log.e(LOG_TAG, "Error loading RS Compat library: nLoadSO() failed; Support lib version: " + SUPPORT_LIB_VERSION); 1436 throw new RSRuntimeException("Error loading libRSSupport library, Support lib version: " + SUPPORT_LIB_VERSION); 1437 } 1438 } 1439 1440 if (useIOlib) { 1441 try { 1442 System.loadLibrary("RSSupportIO"); 1443 } catch (UnsatisfiedLinkError e) { 1444 useIOlib = false; 1445 } 1446 if (!useIOlib || !rs.nLoadIOSO()) { 1447 android.util.Log.v(LOG_TAG, "Unable to load libRSSupportIO.so, USAGE_IO not supported"); 1448 useIOlib = false; 1449 } 1450 } 1451 1452 // For old APIs with dlopen bug, need to load blas lib in Java first. 1453 // Only try load to blasV8 when the desired API level includes IntrinsicBLAS. 1454 if (dispatchAPI >= 23) { 1455 // Enable multi-input kernels only when diapatchAPI is M+. 1456 rs.mEnableMultiInput = true; 1457 try { 1458 System.loadLibrary("blasV8"); 1459 } catch (UnsatisfiedLinkError e) { 1460 Log.v(LOG_TAG, "Unable to load BLAS lib, ONLY BNNM will be supported: " + e); 1461 } 1462 } 1463 1464 long device = rs.nDeviceCreate(); 1465 rs.mContext = rs.nContextCreate(device, 0, sdkVersion, ct.mID, rs.mNativeLibDir); 1466 rs.mContextType = ct; 1467 rs.mContextFlags = flags; 1468 rs.mContextSdkVersion = sdkVersion; 1469 rs.mDispatchAPILevel = dispatchAPI; 1470 if (rs.mContext == 0) { 1471 throw new RSDriverException("Failed to create RS context."); 1472 } 1473 rs.mMessageThread = new MessageThread(rs); 1474 rs.mMessageThread.start(); 1475 return rs; 1476 } 1477 1478 /** 1479 * Create a RenderScript context. 1480 * 1481 * See documentation for @create for details 1482 * 1483 * @param ctx The context. 1484 * @return RenderScript 1485 */ create(Context ctx)1486 public static RenderScript create(Context ctx) { 1487 return create(ctx, ContextType.NORMAL); 1488 } 1489 1490 /** 1491 * calls create(ctx, ct, CREATE_FLAG_NONE) 1492 * 1493 * See documentation for @create for details 1494 * 1495 * @param ctx The context. 1496 * @param ct The type of context to be created. 1497 * @return RenderScript 1498 */ create(Context ctx, ContextType ct)1499 public static RenderScript create(Context ctx, ContextType ct) { 1500 return create(ctx, ct, CREATE_FLAG_NONE); 1501 } 1502 1503 /** 1504 * Gets or creates a RenderScript context of the specified type. 1505 * 1506 * The returned context will be cached for future reuse within 1507 * the process. When an application is finished using 1508 * RenderScript it should call releaseAllContexts() 1509 * 1510 * A process context is a context designed for easy creation and 1511 * lifecycle management. Multiple calls to this function will 1512 * return the same object provided they are called with the same 1513 * options. This allows it to be used any time a RenderScript 1514 * context is needed. 1515 * 1516 * 1517 * @param ctx The context. 1518 * @param ct The type of context to be created. 1519 * @param flags The OR of the CREATE_FLAG_* options desired 1520 * @return RenderScript 1521 */ create(Context ctx, ContextType ct, int flags)1522 public static RenderScript create(Context ctx, ContextType ct, int flags) { 1523 int v = ctx.getApplicationInfo().targetSdkVersion; 1524 return create(ctx, v, ct, flags); 1525 } 1526 1527 /** 1528 * calls create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE) 1529 * 1530 * Used by the RenderScriptThunker to maintain backward compatibility. 1531 * 1532 * @hide 1533 * @param ctx The context. 1534 * @param sdkVersion The target SDK Version. 1535 * @return RenderScript 1536 */ create(Context ctx, int sdkVersion)1537 public static RenderScript create(Context ctx, int sdkVersion) { 1538 return create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE); 1539 } 1540 1541 1542 /** 1543 * calls create(ctx, sdkVersion, ct, CREATE_FLAG_NONE) 1544 * Create a RenderScript context. 1545 * 1546 * @hide 1547 * @param ctx The context. 1548 * @return RenderScript 1549 */ create(Context ctx, int sdkVersion, ContextType ct)1550 public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) { 1551 return create(ctx, sdkVersion, ct, CREATE_FLAG_NONE); 1552 } 1553 1554 /** 1555 * Gets or creates a RenderScript context of the specified type. 1556 * 1557 * @param ctx The context. 1558 * @param ct The type of context to be created. 1559 * @param sdkVersion The target SDK Version. 1560 * @param flags The OR of the CREATE_FLAG_* options desired 1561 * @return RenderScript 1562 */ create(Context ctx, int sdkVersion, ContextType ct, int flags)1563 public static RenderScript create(Context ctx, int sdkVersion, ContextType ct, int flags) { 1564 synchronized (mProcessContextList) { 1565 for (RenderScript prs : mProcessContextList) { 1566 if ((prs.mContextType == ct) && 1567 (prs.mContextFlags == flags) && 1568 (prs.mContextSdkVersion == sdkVersion)) { 1569 1570 return prs; 1571 } 1572 } 1573 1574 RenderScript prs = internalCreate(ctx, sdkVersion, ct, flags); 1575 prs.mIsProcessContext = true; 1576 mProcessContextList.add(prs); 1577 return prs; 1578 } 1579 } 1580 1581 /** 1582 * 1583 * Releases all the process contexts. This is the same as 1584 * calling .destroy() on each unique context retreived with 1585 * create(...). If no contexts have been created this 1586 * function does nothing. 1587 * 1588 * Typically you call this when your application is losing focus 1589 * and will not be using a context for some time. 1590 * 1591 * This has no effect on a context created with 1592 * createMultiContext() 1593 */ releaseAllContexts()1594 public static void releaseAllContexts() { 1595 ArrayList<RenderScript> oldList; 1596 synchronized (mProcessContextList) { 1597 oldList = mProcessContextList; 1598 mProcessContextList = new ArrayList<RenderScript>(); 1599 } 1600 1601 for (RenderScript prs : oldList) { 1602 prs.mIsProcessContext = false; 1603 prs.destroy(); 1604 } 1605 oldList.clear(); 1606 } 1607 1608 1609 1610 /** 1611 * Create a RenderScript context. 1612 * 1613 * This is an advanced function intended for applications which 1614 * need to create more than one RenderScript context to be used 1615 * at the same time. 1616 * 1617 * If you need a single context please use create() 1618 * 1619 * @param ctx The context. 1620 * @return RenderScript 1621 */ createMultiContext(Context ctx, ContextType ct, int flags, int API_number)1622 public static RenderScript createMultiContext(Context ctx, ContextType ct, int flags, int API_number) { 1623 return internalCreate(ctx, API_number, ct, flags); 1624 } 1625 1626 /** 1627 * Print the currently available debugging information about the state of 1628 * the RS context to the log. 1629 * 1630 */ contextDump()1631 public void contextDump() { 1632 validate(); 1633 nContextDump(0); 1634 } 1635 1636 /** 1637 * Wait for any pending asynchronous opeations (such as copies to a RS 1638 * allocation or RS script executions) to complete. 1639 * 1640 */ finish()1641 public void finish() { 1642 nContextFinish(); 1643 } 1644 helpDestroy()1645 private void helpDestroy() { 1646 boolean shouldDestroy = false; 1647 synchronized(this) { 1648 if (!mDestroyed) { 1649 shouldDestroy = true; 1650 mDestroyed = true; 1651 } 1652 } 1653 1654 if (shouldDestroy) { 1655 nContextFinish(); 1656 if (mIncCon != 0) { 1657 nIncContextFinish(); 1658 nIncContextDestroy(); 1659 mIncCon = 0; 1660 } 1661 nContextDeinitToClient(mContext); 1662 mMessageThread.mRun = false; 1663 // Interrupt mMessageThread so it gets to see immediately that mRun is false 1664 // and exit rightaway. 1665 mMessageThread.interrupt(); 1666 1667 // Wait for mMessageThread to join. Try in a loop, in case this thread gets interrupted 1668 // during the wait. If interrupted, set the "interrupted" status of the current thread. 1669 boolean hasJoined = false, interrupted = false; 1670 while (!hasJoined) { 1671 try { 1672 mMessageThread.join(); 1673 hasJoined = true; 1674 } catch (InterruptedException e) { 1675 interrupted = true; 1676 } 1677 } 1678 if (interrupted) { 1679 Log.v(LOG_TAG, "Interrupted during wait for MessageThread to join"); 1680 Thread.currentThread().interrupt(); 1681 } 1682 1683 nContextDestroy(); 1684 } 1685 } 1686 1687 @Override finalize()1688 protected void finalize() throws Throwable { 1689 helpDestroy(); 1690 super.finalize(); 1691 } 1692 1693 /** 1694 * Destroys this RenderScript context. Once this function is called, 1695 * using this context or any objects belonging to this context is 1696 * illegal. 1697 * 1698 * This function is a NOP if the context was created 1699 * with create(). Please use releaseAllContexts() to clean up 1700 * contexts created with the create function. 1701 */ destroy()1702 public void destroy() { 1703 if (mIsProcessContext) { 1704 // users cannot destroy a process context 1705 return; 1706 } 1707 validate(); 1708 helpDestroy(); 1709 } 1710 isAlive()1711 boolean isAlive() { 1712 return mContext != 0; 1713 } 1714 safeID(BaseObj o)1715 long safeID(BaseObj o) { 1716 if(o != null) { 1717 return o.getID(this); 1718 } 1719 return 0; 1720 } 1721 } 1722