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