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