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