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