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