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