RenderScript.java revision 9cc2e8df196039de183aa1e1cc0ff443b474154d
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; 33 34import android.os.SystemProperties; 35 36/** 37 * This class provides access to a RenderScript context, which controls RenderScript 38 * initialization, resource management, and teardown. An instance of the RenderScript 39 * class must be created before any other RS objects can be created. 40 * 41 * <div class="special reference"> 42 * <h3>Developer Guides</h3> 43 * <p>For more information about creating an application that uses RenderScript, read the 44 * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p> 45 * </div> 46 **/ 47public class RenderScript { 48 static final String LOG_TAG = "RenderScript_jni"; 49 static final boolean DEBUG = false; 50 @SuppressWarnings({"UnusedDeclaration", "deprecation"}) 51 static final boolean LOG_ENABLED = false; 52 53 private Context mApplicationContext; 54 55 /* 56 * We use a class initializer to allow the native code to cache some 57 * field offsets. 58 */ 59 @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) 60 static boolean sInitialized; 61 static boolean sUseGCHooks; 62 static Object sRuntime; 63 static Method registerNativeAllocation; 64 static Method registerNativeFree; 65 66 static Object lock = new Object(); 67 68 // Non-threadsafe functions. 69 native int nDeviceCreate(); 70 native void nDeviceDestroy(int dev); 71 native void nDeviceSetConfig(int dev, int param, int value); 72 native int nContextGetUserMessage(int con, int[] data); 73 native String nContextGetErrorMessage(int con); 74 native int nContextPeekMessage(int con, int[] subID); 75 native void nContextInitToClient(int con); 76 native void nContextDeinitToClient(int con); 77 78 static boolean isNative = false; 79 80 static private int sThunk = -1; 81 static private int sSdkVersion = -1; 82 83 static boolean shouldThunk() { 84 if (sThunk == -1) { 85 throw new RSRuntimeException("Can't use RS classes before setting up a RenderScript context"); 86 } else if (sThunk == 1) { 87 return true; 88 } 89 return false; 90 } 91 92 /** 93 * Determines whether or not we should be thunking into the native 94 * RenderScript layer or actually using the compatibility library. 95 */ 96 static private boolean setupThunk(int sdkVersion, Context ctx) { 97 if (sThunk == -1) { 98 // use compat on Jelly Bean MR2 if we're requesting SDK 19+ 99 if (android.os.Build.VERSION.SDK_INT == 18 && sdkVersion >= 19) { 100 sThunk = 0; 101 } 102 else if ((android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) 103 && (SystemProperties.getInt("debug.rs.forcecompat", 0) == 0)) { 104 sThunk = 1; 105 } else { 106 sThunk = 0; 107 } 108 109 110 if (sThunk == 1) { 111 // Workarounds that may disable thunking go here 112 ApplicationInfo info; 113 try { 114 info = ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(), 115 PackageManager.GET_META_DATA); 116 } catch (PackageManager.NameNotFoundException e) { 117 // assume no workarounds needed 118 return true; 119 } 120 long minorVersion = 0; 121 122 // load minorID from reflection 123 try { 124 Class<?> javaRS = Class.forName("android.renderscript.RenderScript"); 125 Method getMinorID = javaRS.getDeclaredMethod("getMinorID"); 126 minorVersion = ((java.lang.Long)getMinorID.invoke(null)).longValue(); 127 } catch (Exception e) { 128 // minor version remains 0 on devices with no possible WARs 129 } 130 131 if (info.metaData != null) { 132 // asynchronous teardown: minor version 1+ 133 if (info.metaData.getBoolean("com.android.support.v8.renderscript.EnableAsyncTeardown") == true) { 134 if (minorVersion == 0) { 135 sThunk = 0; 136 } 137 } 138 139 } 140 // end of workarounds 141 } 142 } 143 144 if (sThunk == 1) { 145 return true; 146 } 147 return false; 148 } 149 150 /** 151 * Name of the file that holds the object cache. 152 */ 153 private static final String CACHE_PATH = "com.android.renderscript.cache"; 154 static String mCachePath; 155 156 /** 157 * Sets the directory to use as a persistent storage for the 158 * renderscript object file cache. 159 * 160 * @hide 161 * @param cacheDir A directory the current process can write to 162 */ 163 public static void setupDiskCache(File cacheDir) { 164 File f = new File(cacheDir, CACHE_PATH); 165 mCachePath = f.getAbsolutePath(); 166 f.mkdirs(); 167 } 168 169 /** 170 * ContextType specifies the specific type of context to be created. 171 * 172 */ 173 public enum ContextType { 174 /** 175 * NORMAL context, this is the default and what shipping apps should 176 * use. 177 */ 178 NORMAL (0), 179 180 /** 181 * DEBUG context, perform extra runtime checks to validate the 182 * kernels and APIs are being used as intended. Get and SetElementAt 183 * will be bounds checked in this mode. 184 */ 185 DEBUG (1), 186 187 /** 188 * PROFILE context, Intended to be used once the first time an 189 * application is run on a new device. This mode allows the runtime to 190 * do additional testing and performance tuning. 191 */ 192 PROFILE (2); 193 194 int mID; 195 ContextType(int id) { 196 mID = id; 197 } 198 } 199 200 // Methods below are wrapped to protect the non-threadsafe 201 // lockless fifo. 202 native int rsnContextCreate(int dev, int ver, int sdkVer, int contextType); 203 synchronized int nContextCreate(int dev, int ver, int sdkVer, int contextType) { 204 return rsnContextCreate(dev, ver, sdkVer, contextType); 205 } 206 native void rsnContextDestroy(int con); 207 synchronized void nContextDestroy() { 208 validate(); 209 210 // take teardown lock 211 // teardown lock can only be taken when no objects are being destroyed 212 ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock(); 213 wlock.lock(); 214 215 int curCon = mContext; 216 // context is considered dead as of this point 217 mContext = 0; 218 219 wlock.unlock(); 220 rsnContextDestroy(curCon); 221 } 222 native void rsnContextSetPriority(int con, int p); 223 synchronized void nContextSetPriority(int p) { 224 validate(); 225 rsnContextSetPriority(mContext, p); 226 } 227 native void rsnContextDump(int con, int bits); 228 synchronized void nContextDump(int bits) { 229 validate(); 230 rsnContextDump(mContext, bits); 231 } 232 native void rsnContextFinish(int con); 233 synchronized void nContextFinish() { 234 validate(); 235 rsnContextFinish(mContext); 236 } 237 238 native void rsnContextSendMessage(int con, int id, int[] data); 239 synchronized void nContextSendMessage(int id, int[] data) { 240 validate(); 241 rsnContextSendMessage(mContext, id, data); 242 } 243 244 // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers 245 native void rsnObjDestroy(int con, int id); 246 void nObjDestroy(int id) { 247 // There is a race condition here. The calling code may be run 248 // by the gc while teardown is occuring. This protects againts 249 // deleting dead objects. 250 if (mContext != 0) { 251 rsnObjDestroy(mContext, id); 252 } 253 } 254 255 native int rsnElementCreate(int con, int type, int kind, boolean norm, int vecSize); 256 synchronized int nElementCreate(int type, int kind, boolean norm, int vecSize) { 257 validate(); 258 return rsnElementCreate(mContext, type, kind, norm, vecSize); 259 } 260 native int rsnElementCreate2(int con, int[] elements, String[] names, int[] arraySizes); 261 synchronized int nElementCreate2(int[] elements, String[] names, int[] arraySizes) { 262 validate(); 263 return rsnElementCreate2(mContext, elements, names, arraySizes); 264 } 265 native void rsnElementGetNativeData(int con, int id, int[] elementData); 266 synchronized void nElementGetNativeData(int id, int[] elementData) { 267 validate(); 268 rsnElementGetNativeData(mContext, id, elementData); 269 } 270 native void rsnElementGetSubElements(int con, int id, 271 int[] IDs, String[] names, int[] arraySizes); 272 synchronized void nElementGetSubElements(int id, int[] IDs, String[] names, int[] arraySizes) { 273 validate(); 274 rsnElementGetSubElements(mContext, id, IDs, names, arraySizes); 275 } 276 277 native int rsnTypeCreate(int con, int eid, int x, int y, int z, boolean mips, boolean faces, int yuv); 278 synchronized int nTypeCreate(int eid, int x, int y, int z, boolean mips, boolean faces, int yuv) { 279 validate(); 280 return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv); 281 } 282 native void rsnTypeGetNativeData(int con, int id, int[] typeData); 283 synchronized void nTypeGetNativeData(int id, int[] typeData) { 284 validate(); 285 rsnTypeGetNativeData(mContext, id, typeData); 286 } 287 288 native int rsnAllocationCreateTyped(int con, int type, int mip, int usage, int pointer); 289 synchronized int nAllocationCreateTyped(int type, int mip, int usage, int pointer) { 290 validate(); 291 return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer); 292 } 293 native int rsnAllocationCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage); 294 synchronized int nAllocationCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) { 295 validate(); 296 return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage); 297 } 298 299 native int rsnAllocationCreateBitmapBackedAllocation(int con, int type, int mip, Bitmap bmp, int usage); 300 synchronized int nAllocationCreateBitmapBackedAllocation(int type, int mip, Bitmap bmp, int usage) { 301 validate(); 302 return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage); 303 } 304 305 306 native int rsnAllocationCubeCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage); 307 synchronized int nAllocationCubeCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) { 308 validate(); 309 return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage); 310 } 311 native int rsnAllocationCreateBitmapRef(int con, int type, Bitmap bmp); 312 synchronized int nAllocationCreateBitmapRef(int type, Bitmap bmp) { 313 validate(); 314 return rsnAllocationCreateBitmapRef(mContext, type, bmp); 315 } 316 native int rsnAllocationCreateFromAssetStream(int con, int mips, int assetStream, int usage); 317 synchronized int nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) { 318 validate(); 319 return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage); 320 } 321 322 native void rsnAllocationCopyToBitmap(int con, int alloc, Bitmap bmp); 323 synchronized void nAllocationCopyToBitmap(int alloc, Bitmap bmp) { 324 validate(); 325 rsnAllocationCopyToBitmap(mContext, alloc, bmp); 326 } 327 328 329 native void rsnAllocationSyncAll(int con, int alloc, int src); 330 synchronized void nAllocationSyncAll(int alloc, int src) { 331 validate(); 332 rsnAllocationSyncAll(mContext, alloc, src); 333 } 334 native void rsnAllocationIoSend(int con, int alloc); 335 synchronized void nAllocationIoSend(int alloc) { 336 validate(); 337 rsnAllocationIoSend(mContext, alloc); 338 } 339 native void rsnAllocationIoReceive(int con, int alloc); 340 synchronized void nAllocationIoReceive(int alloc) { 341 validate(); 342 rsnAllocationIoReceive(mContext, alloc); 343 } 344 345 346 native void rsnAllocationGenerateMipmaps(int con, int alloc); 347 synchronized void nAllocationGenerateMipmaps(int alloc) { 348 validate(); 349 rsnAllocationGenerateMipmaps(mContext, alloc); 350 } 351 native void rsnAllocationCopyFromBitmap(int con, int alloc, Bitmap bmp); 352 synchronized void nAllocationCopyFromBitmap(int alloc, Bitmap bmp) { 353 validate(); 354 rsnAllocationCopyFromBitmap(mContext, alloc, bmp); 355 } 356 357 358 native void rsnAllocationData1D(int con, int id, int off, int mip, int count, int[] d, int sizeBytes); 359 synchronized void nAllocationData1D(int id, int off, int mip, int count, int[] d, int sizeBytes) { 360 validate(); 361 rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes); 362 } 363 native void rsnAllocationData1D(int con, int id, int off, int mip, int count, short[] d, int sizeBytes); 364 synchronized void nAllocationData1D(int id, int off, int mip, int count, short[] d, int sizeBytes) { 365 validate(); 366 rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes); 367 } 368 native void rsnAllocationData1D(int con, int id, int off, int mip, int count, byte[] d, int sizeBytes); 369 synchronized void nAllocationData1D(int id, int off, int mip, int count, byte[] d, int sizeBytes) { 370 validate(); 371 rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes); 372 } 373 native void rsnAllocationData1D(int con, int id, int off, int mip, int count, float[] d, int sizeBytes); 374 synchronized void nAllocationData1D(int id, int off, int mip, int count, float[] d, int sizeBytes) { 375 validate(); 376 rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes); 377 } 378 379 native void rsnAllocationElementData1D(int con, int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes); 380 synchronized void nAllocationElementData1D(int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) { 381 validate(); 382 rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes); 383 } 384 385 native void rsnAllocationData2D(int con, 386 int dstAlloc, int dstXoff, int dstYoff, 387 int dstMip, int dstFace, 388 int width, int height, 389 int srcAlloc, int srcXoff, int srcYoff, 390 int srcMip, int srcFace); 391 synchronized void nAllocationData2D(int dstAlloc, int dstXoff, int dstYoff, 392 int dstMip, int dstFace, 393 int width, int height, 394 int srcAlloc, int srcXoff, int srcYoff, 395 int srcMip, int srcFace) { 396 validate(); 397 rsnAllocationData2D(mContext, 398 dstAlloc, dstXoff, dstYoff, 399 dstMip, dstFace, 400 width, height, 401 srcAlloc, srcXoff, srcYoff, 402 srcMip, srcFace); 403 } 404 405 native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes); 406 synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes) { 407 validate(); 408 rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes); 409 } 410 native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes); 411 synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes) { 412 validate(); 413 rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes); 414 } 415 native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes); 416 synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes) { 417 validate(); 418 rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes); 419 } 420 native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes); 421 synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes) { 422 validate(); 423 rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes); 424 } 425 native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, Bitmap b); 426 synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, Bitmap b) { 427 validate(); 428 rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b); 429 } 430 431 native void rsnAllocationData3D(int con, 432 int dstAlloc, int dstXoff, int dstYoff, int dstZoff, 433 int dstMip, 434 int width, int height, int depth, 435 int srcAlloc, int srcXoff, int srcYoff, int srcZoff, 436 int srcMip); 437 synchronized void nAllocationData3D(int dstAlloc, int dstXoff, int dstYoff, int dstZoff, 438 int dstMip, 439 int width, int height, int depth, 440 int srcAlloc, int srcXoff, int srcYoff, int srcZoff, 441 int srcMip) { 442 validate(); 443 rsnAllocationData3D(mContext, 444 dstAlloc, dstXoff, dstYoff, dstZoff, 445 dstMip, width, height, depth, 446 srcAlloc, srcXoff, srcYoff, srcZoff, srcMip); 447 } 448 449 native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, byte[] d, int sizeBytes); 450 synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, byte[] d, int sizeBytes) { 451 validate(); 452 rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes); 453 } 454 native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, short[] d, int sizeBytes); 455 synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, short[] d, int sizeBytes) { 456 validate(); 457 rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes); 458 } 459 native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, int[] d, int sizeBytes); 460 synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, int[] d, int sizeBytes) { 461 validate(); 462 rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes); 463 } 464 native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, float[] d, int sizeBytes); 465 synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, float[] d, int sizeBytes) { 466 validate(); 467 rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes); 468 } 469 470 471 native void rsnAllocationRead(int con, int id, byte[] d); 472 synchronized void nAllocationRead(int id, byte[] d) { 473 validate(); 474 rsnAllocationRead(mContext, id, d); 475 } 476 native void rsnAllocationRead(int con, int id, short[] d); 477 synchronized void nAllocationRead(int id, short[] d) { 478 validate(); 479 rsnAllocationRead(mContext, id, d); 480 } 481 native void rsnAllocationRead(int con, int id, int[] d); 482 synchronized void nAllocationRead(int id, int[] d) { 483 validate(); 484 rsnAllocationRead(mContext, id, d); 485 } 486 native void rsnAllocationRead(int con, int id, float[] d); 487 synchronized void nAllocationRead(int id, float[] d) { 488 validate(); 489 rsnAllocationRead(mContext, id, d); 490 } 491 native int rsnAllocationGetType(int con, int id); 492 synchronized int nAllocationGetType(int id) { 493 validate(); 494 return rsnAllocationGetType(mContext, id); 495 } 496 497 native void rsnAllocationResize1D(int con, int id, int dimX); 498 synchronized void nAllocationResize1D(int id, int dimX) { 499 validate(); 500 rsnAllocationResize1D(mContext, id, dimX); 501 } 502 native void rsnAllocationResize2D(int con, int id, int dimX, int dimY); 503 synchronized void nAllocationResize2D(int id, int dimX, int dimY) { 504 validate(); 505 rsnAllocationResize2D(mContext, id, dimX, dimY); 506 } 507 508 native void rsnScriptBindAllocation(int con, int script, int alloc, int slot); 509 synchronized void nScriptBindAllocation(int script, int alloc, int slot) { 510 validate(); 511 rsnScriptBindAllocation(mContext, script, alloc, slot); 512 } 513 native void rsnScriptSetTimeZone(int con, int script, byte[] timeZone); 514 synchronized void nScriptSetTimeZone(int script, byte[] timeZone) { 515 validate(); 516 rsnScriptSetTimeZone(mContext, script, timeZone); 517 } 518 native void rsnScriptInvoke(int con, int id, int slot); 519 synchronized void nScriptInvoke(int id, int slot) { 520 validate(); 521 rsnScriptInvoke(mContext, id, slot); 522 } 523 native void rsnScriptForEach(int con, int id, int slot, int ain, int aout, byte[] params); 524 native void rsnScriptForEach(int con, int id, int slot, int ain, int aout); 525 native void rsnScriptForEachClipped(int con, int id, int slot, int ain, int aout, byte[] params, 526 int xstart, int xend, int ystart, int yend, int zstart, int zend); 527 native void rsnScriptForEachClipped(int con, int id, int slot, int ain, int aout, 528 int xstart, int xend, int ystart, int yend, int zstart, int zend); 529 synchronized void nScriptForEach(int id, int slot, int ain, int aout, byte[] params) { 530 validate(); 531 if (params == null) { 532 rsnScriptForEach(mContext, id, slot, ain, aout); 533 } else { 534 rsnScriptForEach(mContext, id, slot, ain, aout, params); 535 } 536 } 537 538 synchronized void nScriptForEachClipped(int id, int slot, int ain, int aout, byte[] params, 539 int xstart, int xend, int ystart, int yend, int zstart, int zend) { 540 validate(); 541 if (params == null) { 542 rsnScriptForEachClipped(mContext, id, slot, ain, aout, xstart, xend, ystart, yend, zstart, zend); 543 } else { 544 rsnScriptForEachClipped(mContext, id, slot, ain, aout, params, xstart, xend, ystart, yend, zstart, zend); 545 } 546 } 547 548 native void rsnScriptInvokeV(int con, int id, int slot, byte[] params); 549 synchronized void nScriptInvokeV(int id, int slot, byte[] params) { 550 validate(); 551 rsnScriptInvokeV(mContext, id, slot, params); 552 } 553 native void rsnScriptSetVarI(int con, int id, int slot, int val); 554 synchronized void nScriptSetVarI(int id, int slot, int val) { 555 validate(); 556 rsnScriptSetVarI(mContext, id, slot, val); 557 } 558 native void rsnScriptSetVarJ(int con, int id, int slot, long val); 559 synchronized void nScriptSetVarJ(int id, int slot, long val) { 560 validate(); 561 rsnScriptSetVarJ(mContext, id, slot, val); 562 } 563 native void rsnScriptSetVarF(int con, int id, int slot, float val); 564 synchronized void nScriptSetVarF(int id, int slot, float val) { 565 validate(); 566 rsnScriptSetVarF(mContext, id, slot, val); 567 } 568 native void rsnScriptSetVarD(int con, int id, int slot, double val); 569 synchronized void nScriptSetVarD(int id, int slot, double val) { 570 validate(); 571 rsnScriptSetVarD(mContext, id, slot, val); 572 } 573 native void rsnScriptSetVarV(int con, int id, int slot, byte[] val); 574 synchronized void nScriptSetVarV(int id, int slot, byte[] val) { 575 validate(); 576 rsnScriptSetVarV(mContext, id, slot, val); 577 } 578 native void rsnScriptSetVarVE(int con, int id, int slot, byte[] val, 579 int e, int[] dims); 580 synchronized void nScriptSetVarVE(int id, int slot, byte[] val, 581 int e, int[] dims) { 582 validate(); 583 rsnScriptSetVarVE(mContext, id, slot, val, e, dims); 584 } 585 native void rsnScriptSetVarObj(int con, int id, int slot, int val); 586 synchronized void nScriptSetVarObj(int id, int slot, int val) { 587 validate(); 588 rsnScriptSetVarObj(mContext, id, slot, val); 589 } 590 591 native int rsnScriptCCreate(int con, String resName, String cacheDir, 592 byte[] script, int length); 593 synchronized int nScriptCCreate(String resName, String cacheDir, byte[] script, int length) { 594 validate(); 595 return rsnScriptCCreate(mContext, resName, cacheDir, script, length); 596 } 597 598 native int rsnScriptIntrinsicCreate(int con, int id, int eid); 599 synchronized int nScriptIntrinsicCreate(int id, int eid) { 600 validate(); 601 return rsnScriptIntrinsicCreate(mContext, id, eid); 602 } 603 604 native int rsnScriptKernelIDCreate(int con, int sid, int slot, int sig); 605 synchronized int nScriptKernelIDCreate(int sid, int slot, int sig) { 606 validate(); 607 return rsnScriptKernelIDCreate(mContext, sid, slot, sig); 608 } 609 610 native int rsnScriptFieldIDCreate(int con, int sid, int slot); 611 synchronized int nScriptFieldIDCreate(int sid, int slot) { 612 validate(); 613 return rsnScriptFieldIDCreate(mContext, sid, slot); 614 } 615 616 native int rsnScriptGroupCreate(int con, int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types); 617 synchronized int nScriptGroupCreate(int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types) { 618 validate(); 619 return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types); 620 } 621 622 native void rsnScriptGroupSetInput(int con, int group, int kernel, int alloc); 623 synchronized void nScriptGroupSetInput(int group, int kernel, int alloc) { 624 validate(); 625 rsnScriptGroupSetInput(mContext, group, kernel, alloc); 626 } 627 628 native void rsnScriptGroupSetOutput(int con, int group, int kernel, int alloc); 629 synchronized void nScriptGroupSetOutput(int group, int kernel, int alloc) { 630 validate(); 631 rsnScriptGroupSetOutput(mContext, group, kernel, alloc); 632 } 633 634 native void rsnScriptGroupExecute(int con, int group); 635 synchronized void nScriptGroupExecute(int group) { 636 validate(); 637 rsnScriptGroupExecute(mContext, group); 638 } 639 640 native int rsnSamplerCreate(int con, int magFilter, int minFilter, 641 int wrapS, int wrapT, int wrapR, float aniso); 642 synchronized int nSamplerCreate(int magFilter, int minFilter, 643 int wrapS, int wrapT, int wrapR, float aniso) { 644 validate(); 645 return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso); 646 } 647 648 649 650 651 int mDev; 652 int mContext; 653 ReentrantReadWriteLock mRWLock; 654 @SuppressWarnings({"FieldCanBeLocal"}) 655 MessageThread mMessageThread; 656 657 Element mElement_U8; 658 Element mElement_I8; 659 Element mElement_U16; 660 Element mElement_I16; 661 Element mElement_U32; 662 Element mElement_I32; 663 Element mElement_U64; 664 Element mElement_I64; 665 Element mElement_F32; 666 Element mElement_F64; 667 Element mElement_BOOLEAN; 668 669 Element mElement_ELEMENT; 670 Element mElement_TYPE; 671 Element mElement_ALLOCATION; 672 Element mElement_SAMPLER; 673 Element mElement_SCRIPT; 674 675 Element mElement_A_8; 676 Element mElement_RGB_565; 677 Element mElement_RGB_888; 678 Element mElement_RGBA_5551; 679 Element mElement_RGBA_4444; 680 Element mElement_RGBA_8888; 681 682 Element mElement_FLOAT_2; 683 Element mElement_FLOAT_3; 684 Element mElement_FLOAT_4; 685 686 Element mElement_DOUBLE_2; 687 Element mElement_DOUBLE_3; 688 Element mElement_DOUBLE_4; 689 690 Element mElement_UCHAR_2; 691 Element mElement_UCHAR_3; 692 Element mElement_UCHAR_4; 693 694 Element mElement_CHAR_2; 695 Element mElement_CHAR_3; 696 Element mElement_CHAR_4; 697 698 Element mElement_USHORT_2; 699 Element mElement_USHORT_3; 700 Element mElement_USHORT_4; 701 702 Element mElement_SHORT_2; 703 Element mElement_SHORT_3; 704 Element mElement_SHORT_4; 705 706 Element mElement_UINT_2; 707 Element mElement_UINT_3; 708 Element mElement_UINT_4; 709 710 Element mElement_INT_2; 711 Element mElement_INT_3; 712 Element mElement_INT_4; 713 714 Element mElement_ULONG_2; 715 Element mElement_ULONG_3; 716 Element mElement_ULONG_4; 717 718 Element mElement_LONG_2; 719 Element mElement_LONG_3; 720 Element mElement_LONG_4; 721 722 Element mElement_MATRIX_4X4; 723 Element mElement_MATRIX_3X3; 724 Element mElement_MATRIX_2X2; 725 726 Sampler mSampler_CLAMP_NEAREST; 727 Sampler mSampler_CLAMP_LINEAR; 728 Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR; 729 Sampler mSampler_WRAP_NEAREST; 730 Sampler mSampler_WRAP_LINEAR; 731 Sampler mSampler_WRAP_LINEAR_MIP_LINEAR; 732 Sampler mSampler_MIRRORED_REPEAT_NEAREST; 733 Sampler mSampler_MIRRORED_REPEAT_LINEAR; 734 Sampler mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR; 735 736 737 /////////////////////////////////////////////////////////////////////////////////// 738 // 739 740 /** 741 * The base class from which an application should derive in order 742 * to receive RS messages from scripts. When a script calls {@code 743 * rsSendToClient}, the data fields will be filled, and the run 744 * method will be called on a separate thread. This will occur 745 * some time after {@code rsSendToClient} completes in the script, 746 * as {@code rsSendToClient} is asynchronous. Message handlers are 747 * not guaranteed to have completed when {@link 748 * android.support.v8.renderscript.RenderScript#finish} returns. 749 * 750 */ 751 public static class RSMessageHandler implements Runnable { 752 protected int[] mData; 753 protected int mID; 754 protected int mLength; 755 public void run() { 756 } 757 } 758 /** 759 * If an application is expecting messages, it should set this 760 * field to an instance of {@link RSMessageHandler}. This 761 * instance will receive all the user messages sent from {@code 762 * sendToClient} by scripts from this context. 763 * 764 */ 765 RSMessageHandler mMessageCallback = null; 766 767 public void setMessageHandler(RSMessageHandler msg) { 768 mMessageCallback = msg; 769 if (isNative) { 770 RenderScriptThunker rst = (RenderScriptThunker) this; 771 rst.setMessageHandler(msg); 772 } 773 } 774 public RSMessageHandler getMessageHandler() { 775 return mMessageCallback; 776 } 777 778 /** 779 * Place a message into the message queue to be sent back to the message 780 * handler once all previous commands have been executed. 781 * 782 * @hide 783 * 784 * @param id 785 * @param data 786 */ 787 public void sendMessage(int id, int[] data) { 788 nContextSendMessage(id, data); 789 } 790 791 /** 792 * The runtime error handler base class. An application should derive from this class 793 * if it wishes to install an error handler. When errors occur at runtime, 794 * the fields in this class will be filled, and the run method will be called. 795 * 796 */ 797 public static class RSErrorHandler implements Runnable { 798 protected String mErrorMessage; 799 protected int mErrorNum; 800 public void run() { 801 } 802 } 803 804 /** 805 * Application Error handler. All runtime errors will be dispatched to the 806 * instance of RSAsyncError set here. If this field is null a 807 * {@link RSRuntimeException} will instead be thrown with details about the error. 808 * This will cause program termaination. 809 * 810 */ 811 RSErrorHandler mErrorCallback = null; 812 813 public void setErrorHandler(RSErrorHandler msg) { 814 mErrorCallback = msg; 815 if (isNative) { 816 RenderScriptThunker rst = (RenderScriptThunker) this; 817 rst.setErrorHandler(msg); 818 } 819 } 820 public RSErrorHandler getErrorHandler() { 821 return mErrorCallback; 822 } 823 824 /** 825 * RenderScript worker thread priority enumeration. The default value is 826 * NORMAL. Applications wishing to do background processing should set 827 * their priority to LOW to avoid starving forground processes. 828 */ 829 public enum Priority { 830 LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)), 831 NORMAL (Process.THREAD_PRIORITY_DISPLAY); 832 833 int mID; 834 Priority(int id) { 835 mID = id; 836 } 837 } 838 839 void validate() { 840 if (mContext == 0) { 841 throw new RSInvalidStateException("Calling RS with no Context active."); 842 } 843 } 844 845 846 /** 847 * Change the priority of the worker threads for this context. 848 * 849 * @param p New priority to be set. 850 */ 851 public void setPriority(Priority p) { 852 validate(); 853 nContextSetPriority(p.mID); 854 } 855 856 static class MessageThread extends Thread { 857 RenderScript mRS; 858 boolean mRun = true; 859 int[] mAuxData = new int[2]; 860 861 static final int RS_MESSAGE_TO_CLIENT_NONE = 0; 862 static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1; 863 static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2; 864 static final int RS_MESSAGE_TO_CLIENT_ERROR = 3; 865 static final int RS_MESSAGE_TO_CLIENT_USER = 4; 866 867 static final int RS_ERROR_FATAL_UNKNOWN = 0x1000; 868 869 MessageThread(RenderScript rs) { 870 super("RSMessageThread"); 871 mRS = rs; 872 873 } 874 875 public void run() { 876 // This function is a temporary solution. The final solution will 877 // used typed allocations where the message id is the type indicator. 878 int[] rbuf = new int[16]; 879 mRS.nContextInitToClient(mRS.mContext); 880 while(mRun) { 881 rbuf[0] = 0; 882 int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData); 883 int size = mAuxData[1]; 884 int subID = mAuxData[0]; 885 886 if (msg == RS_MESSAGE_TO_CLIENT_USER) { 887 if ((size>>2) >= rbuf.length) { 888 rbuf = new int[(size + 3) >> 2]; 889 } 890 if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) != 891 RS_MESSAGE_TO_CLIENT_USER) { 892 throw new RSDriverException("Error processing message from RenderScript."); 893 } 894 895 if(mRS.mMessageCallback != null) { 896 mRS.mMessageCallback.mData = rbuf; 897 mRS.mMessageCallback.mID = subID; 898 mRS.mMessageCallback.mLength = size; 899 mRS.mMessageCallback.run(); 900 } else { 901 throw new RSInvalidStateException("Received a message from the script with no message handler installed."); 902 } 903 continue; 904 } 905 906 if (msg == RS_MESSAGE_TO_CLIENT_ERROR) { 907 String e = mRS.nContextGetErrorMessage(mRS.mContext); 908 909 if (subID >= RS_ERROR_FATAL_UNKNOWN) { 910 throw new RSRuntimeException("Fatal error " + subID + ", details: " + e); 911 } 912 913 if(mRS.mErrorCallback != null) { 914 mRS.mErrorCallback.mErrorMessage = e; 915 mRS.mErrorCallback.mErrorNum = subID; 916 mRS.mErrorCallback.run(); 917 } else { 918 android.util.Log.e(LOG_TAG, "non fatal RS error, " + e); 919 // Do not throw here. In these cases, we do not have 920 // a fatal error. 921 } 922 continue; 923 } 924 925 // 2: teardown. 926 // But we want to avoid starving other threads during 927 // teardown by yielding until the next line in the destructor 928 // can execute to set mRun = false 929 try { 930 sleep(1, 0); 931 } catch(InterruptedException e) { 932 } 933 } 934 //Log.d(LOG_TAG, "MessageThread exiting."); 935 } 936 } 937 938 RenderScript(Context ctx) { 939 if (ctx != null) { 940 mApplicationContext = ctx.getApplicationContext(); 941 } 942 mRWLock = new ReentrantReadWriteLock(); 943 } 944 945 /** 946 * Gets the application context associated with the RenderScript context. 947 * 948 * @return The application context. 949 */ 950 public final Context getApplicationContext() { 951 return mApplicationContext; 952 } 953 954 /** 955 * @hide 956 */ 957 public static RenderScript create(Context ctx, int sdkVersion) { 958 return create(ctx, sdkVersion, ContextType.NORMAL); 959 } 960 961 /** 962 * Create a RenderScript context. 963 * 964 * @hide 965 * @param ctx The context. 966 * @return RenderScript 967 */ 968 public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) { 969 RenderScript rs = new RenderScript(ctx); 970 971 if (sSdkVersion == -1) { 972 sSdkVersion = sdkVersion; 973 } else if (sSdkVersion != sdkVersion) { 974 throw new RSRuntimeException("Can't have two contexts with different SDK versions in support lib"); 975 } 976 977 if (setupThunk(sSdkVersion, ctx)) { 978 android.util.Log.v(LOG_TAG, "RS native mode"); 979 return RenderScriptThunker.create(ctx, sSdkVersion); 980 } 981 synchronized(lock) { 982 if (sInitialized == false) { 983 try { 984 Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime"); 985 Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime"); 986 sRuntime = get_runtime.invoke(null); 987 registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", Integer.TYPE); 988 registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", Integer.TYPE); 989 sUseGCHooks = true; 990 } catch (Exception e) { 991 Log.e(LOG_TAG, "No GC methods"); 992 sUseGCHooks = false; 993 } 994 try { 995 System.loadLibrary("RSSupport"); 996 System.loadLibrary("rsjni"); 997 sInitialized = true; 998 } catch (UnsatisfiedLinkError e) { 999 Log.e(LOG_TAG, "Error loading RS jni library: " + e); 1000 throw new RSRuntimeException("Error loading RS jni library: " + e); 1001 } 1002 } 1003 } 1004 1005 android.util.Log.v(LOG_TAG, "RS compat mode"); 1006 rs.mDev = rs.nDeviceCreate(); 1007 rs.mContext = rs.nContextCreate(rs.mDev, 0, sdkVersion, ct.mID); 1008 if (rs.mContext == 0) { 1009 throw new RSDriverException("Failed to create RS context."); 1010 } 1011 rs.mMessageThread = new MessageThread(rs); 1012 rs.mMessageThread.start(); 1013 return rs; 1014 } 1015 1016 /** 1017 * Create a RenderScript context. 1018 * 1019 * @param ctx The context. 1020 * @return RenderScript 1021 */ 1022 public static RenderScript create(Context ctx) { 1023 return create(ctx, ContextType.NORMAL); 1024 } 1025 1026 /** 1027 * Create a RenderScript context. 1028 * 1029 * @hide 1030 * 1031 * @param ctx The context. 1032 * @param ct The type of context to be created. 1033 * @return RenderScript 1034 */ 1035 public static RenderScript create(Context ctx, ContextType ct) { 1036 int v = ctx.getApplicationInfo().targetSdkVersion; 1037 return create(ctx, v, ct); 1038 } 1039 1040 /** 1041 * Print the currently available debugging information about the state of 1042 * the RS context to the log. 1043 * 1044 */ 1045 public void contextDump() { 1046 validate(); 1047 nContextDump(0); 1048 } 1049 1050 /** 1051 * Wait for any pending asynchronous opeations (such as copies to a RS 1052 * allocation or RS script executions) to complete. 1053 * 1054 */ 1055 public void finish() { 1056 nContextFinish(); 1057 } 1058 1059 /** 1060 * Destroys this RenderScript context. Once this function is called, 1061 * using this context or any objects belonging to this context is 1062 * illegal. 1063 * 1064 */ 1065 public void destroy() { 1066 validate(); 1067 nContextFinish(); 1068 nContextDeinitToClient(mContext); 1069 mMessageThread.mRun = false; 1070 try { 1071 mMessageThread.join(); 1072 } catch(InterruptedException e) { 1073 } 1074 1075 nContextDestroy(); 1076 nDeviceDestroy(mDev); 1077 mDev = 0; 1078 } 1079 1080 boolean isAlive() { 1081 return mContext != 0; 1082 } 1083 1084 int safeID(BaseObj o) { 1085 if(o != null) { 1086 return o.getID(this); 1087 } 1088 return 0; 1089 } 1090} 1091