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