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