1/* 2 * Copyright (C) 2012 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; 21 22import android.content.Context; 23import android.content.pm.ApplicationInfo; 24import android.content.pm.PackageManager; 25import android.content.res.AssetManager; 26import android.graphics.Bitmap; 27import android.graphics.BitmapFactory; 28import android.os.Process; 29import android.util.Log; 30import android.view.Surface; 31 32 33 34/** 35 * Renderscript base master class. An instance of this class creates native 36 * worker threads for processing commands from this object. This base class 37 * does not provide any extended capabilities beyond simple data processing. 38 * For extended capabilities use derived classes such as RenderScriptGL. 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/graphics/renderscript.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 boolean mUseNativeRS; 54 55 static class NRS { 56 android.renderscript.RenderScript mRS; 57 58 android.renderscript.RenderScript getRS() { 59 return mRS; 60 } 61 } 62 NRS mNRS; 63 64 /* 65 * We use a class initializer to allow the native code to cache some 66 * field offsets. 67 */ 68 @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) 69 static boolean sInitialized; 70 native static void _nInit(); 71 72 73 static { 74 sInitialized = false; 75 try { 76 System.loadLibrary("rsjni"); 77 _nInit(); 78 sInitialized = true; 79 } catch (UnsatisfiedLinkError e) { 80 Log.e(LOG_TAG, "Error loading RS jni library: " + e); 81 throw new RSRuntimeException("Error loading RS jni library: " + e); 82 } 83 } 84 85 // Non-threadsafe functions. 86 native int nDeviceCreate(); 87 native void nDeviceDestroy(int dev); 88 native void nDeviceSetConfig(int dev, int param, int value); 89 native int nContextGetUserMessage(int con, int[] data); 90 native String nContextGetErrorMessage(int con); 91 native int nContextPeekMessage(int con, int[] subID); 92 native void nContextInitToClient(int con); 93 native void nContextDeinitToClient(int con); 94 95 /** 96 * Name of the file that holds the object cache. 97 */ 98 private static final String CACHE_PATH = "com.android.renderscript.cache"; 99 static String mCachePath; 100 101 /** 102 * Sets the directory to use as a persistent storage for the 103 * renderscript object file cache. 104 * 105 * @hide 106 * @param cacheDir A directory the current process can write to 107 */ 108 public static void setupDiskCache(File cacheDir) { 109 File f = new File(cacheDir, CACHE_PATH); 110 mCachePath = f.getAbsolutePath(); 111 f.mkdirs(); 112 } 113 114 115 // Methods below are wrapped to protect the non-threadsafe 116 // lockless fifo. 117 native int rsnContextCreate(int dev, int ver, int sdkVer); 118 synchronized int nContextCreate(int dev, int ver, int sdkVer) { 119 return rsnContextCreate(dev, ver, sdkVer); 120 } 121 native void rsnContextDestroy(int con); 122 synchronized void nContextDestroy() { 123 validate(); 124 rsnContextDestroy(mContext); 125 } 126 native void rsnContextSetPriority(int con, int p); 127 synchronized void nContextSetPriority(int p) { 128 validate(); 129 rsnContextSetPriority(mContext, p); 130 } 131 native void rsnContextDump(int con, int bits); 132 synchronized void nContextDump(int bits) { 133 validate(); 134 rsnContextDump(mContext, bits); 135 } 136 native void rsnContextFinish(int con); 137 synchronized void nContextFinish() { 138 validate(); 139 rsnContextFinish(mContext); 140 } 141 142 native void rsnObjDestroy(int con, int id); 143 synchronized void nObjDestroy(int id) { 144 // There is a race condition here. The calling code may be run 145 // by the gc while teardown is occuring. This protects againts 146 // deleting dead objects. 147 if (mContext != 0) { 148 rsnObjDestroy(mContext, id); 149 } 150 } 151 152 native int rsnElementCreate(int con, int type, int kind, boolean norm, int vecSize); 153 synchronized int nElementCreate(int type, int kind, boolean norm, int vecSize) { 154 validate(); 155 return rsnElementCreate(mContext, type, kind, norm, vecSize); 156 } 157 native int rsnElementCreate2(int con, int[] elements, String[] names, int[] arraySizes); 158 synchronized int nElementCreate2(int[] elements, String[] names, int[] arraySizes) { 159 validate(); 160 return rsnElementCreate2(mContext, elements, names, arraySizes); 161 } 162 native void rsnElementGetNativeData(int con, int id, int[] elementData); 163 synchronized void nElementGetNativeData(int id, int[] elementData) { 164 validate(); 165 rsnElementGetNativeData(mContext, id, elementData); 166 } 167 native void rsnElementGetSubElements(int con, int id, 168 int[] IDs, String[] names, int[] arraySizes); 169 synchronized void nElementGetSubElements(int id, int[] IDs, String[] names, int[] arraySizes) { 170 validate(); 171 rsnElementGetSubElements(mContext, id, IDs, names, arraySizes); 172 } 173 174 native int rsnTypeCreate(int con, int eid, int x, int y, int z, boolean mips, boolean faces); 175 synchronized int nTypeCreate(int eid, int x, int y, int z, boolean mips, boolean faces) { 176 validate(); 177 return rsnTypeCreate(mContext, eid, x, y, z, mips, faces); 178 } 179 native void rsnTypeGetNativeData(int con, int id, int[] typeData); 180 synchronized void nTypeGetNativeData(int id, int[] typeData) { 181 validate(); 182 rsnTypeGetNativeData(mContext, id, typeData); 183 } 184 185 native int rsnAllocationCreateTyped(int con, int type, int mip, int usage, int pointer); 186 synchronized int nAllocationCreateTyped(int type, int mip, int usage, int pointer) { 187 validate(); 188 return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer); 189 } 190 native int rsnAllocationCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage); 191 synchronized int nAllocationCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) { 192 validate(); 193 return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage); 194 } 195 native int rsnAllocationCubeCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage); 196 synchronized int nAllocationCubeCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) { 197 validate(); 198 return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage); 199 } 200 native int rsnAllocationCreateBitmapRef(int con, int type, Bitmap bmp); 201 synchronized int nAllocationCreateBitmapRef(int type, Bitmap bmp) { 202 validate(); 203 return rsnAllocationCreateBitmapRef(mContext, type, bmp); 204 } 205 native int rsnAllocationCreateFromAssetStream(int con, int mips, int assetStream, int usage); 206 synchronized int nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) { 207 validate(); 208 return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage); 209 } 210 211 native void rsnAllocationCopyToBitmap(int con, int alloc, Bitmap bmp); 212 synchronized void nAllocationCopyToBitmap(int alloc, Bitmap bmp) { 213 validate(); 214 rsnAllocationCopyToBitmap(mContext, alloc, bmp); 215 } 216 217 218 native void rsnAllocationSyncAll(int con, int alloc, int src); 219 synchronized void nAllocationSyncAll(int alloc, int src) { 220 validate(); 221 rsnAllocationSyncAll(mContext, alloc, src); 222 } 223 224 225 native void rsnAllocationGenerateMipmaps(int con, int alloc); 226 synchronized void nAllocationGenerateMipmaps(int alloc) { 227 validate(); 228 rsnAllocationGenerateMipmaps(mContext, alloc); 229 } 230 native void rsnAllocationCopyFromBitmap(int con, int alloc, Bitmap bmp); 231 synchronized void nAllocationCopyFromBitmap(int alloc, Bitmap bmp) { 232 validate(); 233 rsnAllocationCopyFromBitmap(mContext, alloc, bmp); 234 } 235 236 237 native void rsnAllocationData1D(int con, int id, int off, int mip, int count, int[] d, int sizeBytes); 238 synchronized void nAllocationData1D(int id, int off, int mip, int count, int[] d, int sizeBytes) { 239 validate(); 240 rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes); 241 } 242 native void rsnAllocationData1D(int con, int id, int off, int mip, int count, short[] d, int sizeBytes); 243 synchronized void nAllocationData1D(int id, int off, int mip, int count, short[] d, int sizeBytes) { 244 validate(); 245 rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes); 246 } 247 native void rsnAllocationData1D(int con, int id, int off, int mip, int count, byte[] d, int sizeBytes); 248 synchronized void nAllocationData1D(int id, int off, int mip, int count, byte[] d, int sizeBytes) { 249 validate(); 250 rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes); 251 } 252 native void rsnAllocationData1D(int con, int id, int off, int mip, int count, float[] d, int sizeBytes); 253 synchronized void nAllocationData1D(int id, int off, int mip, int count, float[] d, int sizeBytes) { 254 validate(); 255 rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes); 256 } 257 258 native void rsnAllocationElementData1D(int con, int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes); 259 synchronized void nAllocationElementData1D(int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) { 260 validate(); 261 rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes); 262 } 263 264 native void rsnAllocationData2D(int con, 265 int dstAlloc, int dstXoff, int dstYoff, 266 int dstMip, int dstFace, 267 int width, int height, 268 int srcAlloc, int srcXoff, int srcYoff, 269 int srcMip, int srcFace); 270 synchronized void nAllocationData2D(int dstAlloc, int dstXoff, int dstYoff, 271 int dstMip, int dstFace, 272 int width, int height, 273 int srcAlloc, int srcXoff, int srcYoff, 274 int srcMip, int srcFace) { 275 validate(); 276 rsnAllocationData2D(mContext, 277 dstAlloc, dstXoff, dstYoff, 278 dstMip, dstFace, 279 width, height, 280 srcAlloc, srcXoff, srcYoff, 281 srcMip, srcFace); 282 } 283 284 native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes); 285 synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes) { 286 validate(); 287 rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes); 288 } 289 native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes); 290 synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes) { 291 validate(); 292 rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes); 293 } 294 native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes); 295 synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes) { 296 validate(); 297 rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes); 298 } 299 native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes); 300 synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes) { 301 validate(); 302 rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes); 303 } 304 native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, Bitmap b); 305 synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, Bitmap b) { 306 validate(); 307 rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b); 308 } 309 310 native void rsnAllocationRead(int con, int id, byte[] d); 311 synchronized void nAllocationRead(int id, byte[] d) { 312 validate(); 313 rsnAllocationRead(mContext, id, d); 314 } 315 native void rsnAllocationRead(int con, int id, short[] d); 316 synchronized void nAllocationRead(int id, short[] d) { 317 validate(); 318 rsnAllocationRead(mContext, id, d); 319 } 320 native void rsnAllocationRead(int con, int id, int[] d); 321 synchronized void nAllocationRead(int id, int[] d) { 322 validate(); 323 rsnAllocationRead(mContext, id, d); 324 } 325 native void rsnAllocationRead(int con, int id, float[] d); 326 synchronized void nAllocationRead(int id, float[] d) { 327 validate(); 328 rsnAllocationRead(mContext, id, d); 329 } 330 native int rsnAllocationGetType(int con, int id); 331 synchronized int nAllocationGetType(int id) { 332 validate(); 333 return rsnAllocationGetType(mContext, id); 334 } 335 336 native void rsnAllocationResize1D(int con, int id, int dimX); 337 synchronized void nAllocationResize1D(int id, int dimX) { 338 validate(); 339 rsnAllocationResize1D(mContext, id, dimX); 340 } 341 native void rsnAllocationResize2D(int con, int id, int dimX, int dimY); 342 synchronized void nAllocationResize2D(int id, int dimX, int dimY) { 343 validate(); 344 rsnAllocationResize2D(mContext, id, dimX, dimY); 345 } 346 347 native void rsnScriptBindAllocation(int con, int script, int alloc, int slot); 348 synchronized void nScriptBindAllocation(int script, int alloc, int slot) { 349 validate(); 350 rsnScriptBindAllocation(mContext, script, alloc, slot); 351 } 352 native void rsnScriptSetTimeZone(int con, int script, byte[] timeZone); 353 synchronized void nScriptSetTimeZone(int script, byte[] timeZone) { 354 validate(); 355 rsnScriptSetTimeZone(mContext, script, timeZone); 356 } 357 native void rsnScriptInvoke(int con, int id, int slot); 358 synchronized void nScriptInvoke(int id, int slot) { 359 validate(); 360 rsnScriptInvoke(mContext, id, slot); 361 } 362 native void rsnScriptForEach(int con, int id, int slot, int ain, int aout, byte[] params); 363 native void rsnScriptForEach(int con, int id, int slot, int ain, int aout); 364 synchronized void nScriptForEach(int id, int slot, int ain, int aout, byte[] params) { 365 validate(); 366 if (params == null) { 367 rsnScriptForEach(mContext, id, slot, ain, aout); 368 } else { 369 rsnScriptForEach(mContext, id, slot, ain, aout, params); 370 } 371 } 372 native void rsnScriptInvokeV(int con, int id, int slot, byte[] params); 373 synchronized void nScriptInvokeV(int id, int slot, byte[] params) { 374 validate(); 375 rsnScriptInvokeV(mContext, id, slot, params); 376 } 377 native void rsnScriptSetVarI(int con, int id, int slot, int val); 378 synchronized void nScriptSetVarI(int id, int slot, int val) { 379 validate(); 380 rsnScriptSetVarI(mContext, id, slot, val); 381 } 382 native void rsnScriptSetVarJ(int con, int id, int slot, long val); 383 synchronized void nScriptSetVarJ(int id, int slot, long val) { 384 validate(); 385 rsnScriptSetVarJ(mContext, id, slot, val); 386 } 387 native void rsnScriptSetVarF(int con, int id, int slot, float val); 388 synchronized void nScriptSetVarF(int id, int slot, float val) { 389 validate(); 390 rsnScriptSetVarF(mContext, id, slot, val); 391 } 392 native void rsnScriptSetVarD(int con, int id, int slot, double val); 393 synchronized void nScriptSetVarD(int id, int slot, double val) { 394 validate(); 395 rsnScriptSetVarD(mContext, id, slot, val); 396 } 397 native void rsnScriptSetVarV(int con, int id, int slot, byte[] val); 398 synchronized void nScriptSetVarV(int id, int slot, byte[] val) { 399 validate(); 400 rsnScriptSetVarV(mContext, id, slot, val); 401 } 402 native void rsnScriptSetVarVE(int con, int id, int slot, byte[] val, 403 int e, int[] dims); 404 synchronized void nScriptSetVarVE(int id, int slot, byte[] val, 405 int e, int[] dims) { 406 validate(); 407 rsnScriptSetVarVE(mContext, id, slot, val, e, dims); 408 } 409 native void rsnScriptSetVarObj(int con, int id, int slot, int val); 410 synchronized void nScriptSetVarObj(int id, int slot, int val) { 411 validate(); 412 rsnScriptSetVarObj(mContext, id, slot, val); 413 } 414 415 native int rsnScriptCCreate(int con, String resName, String cacheDir, 416 byte[] script, int length); 417 synchronized int nScriptCCreate(String resName, String cacheDir, byte[] script, int length) { 418 validate(); 419 return rsnScriptCCreate(mContext, resName, cacheDir, script, length); 420 } 421 422 native int rsnScriptIntrinsicCreate(int con, int id, int eid); 423 synchronized int nScriptIntrinsicCreate(int id, int eid) { 424 validate(); 425 return rsnScriptIntrinsicCreate(mContext, id, eid); 426 } 427 428 native int rsnScriptKernelIDCreate(int con, int sid, int slot, int sig); 429 synchronized int nScriptKernelIDCreate(int sid, int slot, int sig) { 430 validate(); 431 return rsnScriptKernelIDCreate(mContext, sid, slot, sig); 432 } 433 434 native int rsnScriptFieldIDCreate(int con, int sid, int slot); 435 synchronized int nScriptFieldIDCreate(int sid, int slot) { 436 validate(); 437 return rsnScriptFieldIDCreate(mContext, sid, slot); 438 } 439 440 native int rsnScriptGroupCreate(int con, int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types); 441 synchronized int nScriptGroupCreate(int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types) { 442 validate(); 443 return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types); 444 } 445 446 native void rsnScriptGroupSetInput(int con, int group, int kernel, int alloc); 447 synchronized void nScriptGroupSetInput(int group, int kernel, int alloc) { 448 validate(); 449 rsnScriptGroupSetInput(mContext, group, kernel, alloc); 450 } 451 452 native void rsnScriptGroupSetOutput(int con, int group, int kernel, int alloc); 453 synchronized void nScriptGroupSetOutput(int group, int kernel, int alloc) { 454 validate(); 455 rsnScriptGroupSetOutput(mContext, group, kernel, alloc); 456 } 457 458 native void rsnScriptGroupExecute(int con, int group); 459 synchronized void nScriptGroupExecute(int group) { 460 validate(); 461 rsnScriptGroupExecute(mContext, group); 462 } 463 464 native int rsnSamplerCreate(int con, int magFilter, int minFilter, 465 int wrapS, int wrapT, int wrapR, float aniso); 466 synchronized int nSamplerCreate(int magFilter, int minFilter, 467 int wrapS, int wrapT, int wrapR, float aniso) { 468 validate(); 469 return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso); 470 } 471 472 473 474 int mDev; 475 int mContext; 476 @SuppressWarnings({"FieldCanBeLocal"}) 477 MessageThread mMessageThread; 478 479 Element mElement_U8; 480 Element mElement_I8; 481 Element mElement_U16; 482 Element mElement_I16; 483 Element mElement_U32; 484 Element mElement_I32; 485 Element mElement_U64; 486 Element mElement_I64; 487 Element mElement_F32; 488 Element mElement_F64; 489 Element mElement_BOOLEAN; 490 491 Element mElement_ELEMENT; 492 Element mElement_TYPE; 493 Element mElement_ALLOCATION; 494 Element mElement_SAMPLER; 495 Element mElement_SCRIPT; 496 497 Element mElement_A_8; 498 Element mElement_RGB_565; 499 Element mElement_RGB_888; 500 Element mElement_RGBA_5551; 501 Element mElement_RGBA_4444; 502 Element mElement_RGBA_8888; 503 504 Element mElement_FLOAT_2; 505 Element mElement_FLOAT_3; 506 Element mElement_FLOAT_4; 507 508 Element mElement_DOUBLE_2; 509 Element mElement_DOUBLE_3; 510 Element mElement_DOUBLE_4; 511 512 Element mElement_UCHAR_2; 513 Element mElement_UCHAR_3; 514 Element mElement_UCHAR_4; 515 516 Element mElement_CHAR_2; 517 Element mElement_CHAR_3; 518 Element mElement_CHAR_4; 519 520 Element mElement_USHORT_2; 521 Element mElement_USHORT_3; 522 Element mElement_USHORT_4; 523 524 Element mElement_SHORT_2; 525 Element mElement_SHORT_3; 526 Element mElement_SHORT_4; 527 528 Element mElement_UINT_2; 529 Element mElement_UINT_3; 530 Element mElement_UINT_4; 531 532 Element mElement_INT_2; 533 Element mElement_INT_3; 534 Element mElement_INT_4; 535 536 Element mElement_ULONG_2; 537 Element mElement_ULONG_3; 538 Element mElement_ULONG_4; 539 540 Element mElement_LONG_2; 541 Element mElement_LONG_3; 542 Element mElement_LONG_4; 543 544 Element mElement_MATRIX_4X4; 545 Element mElement_MATRIX_3X3; 546 Element mElement_MATRIX_2X2; 547 548 Sampler mSampler_CLAMP_NEAREST; 549 Sampler mSampler_CLAMP_LINEAR; 550 Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR; 551 Sampler mSampler_WRAP_NEAREST; 552 Sampler mSampler_WRAP_LINEAR; 553 Sampler mSampler_WRAP_LINEAR_MIP_LINEAR; 554 555 /////////////////////////////////////////////////////////////////////////////////// 556 // 557 558 /** 559 * Base class application should derive from for handling RS messages 560 * coming from their scripts. When a script calls sendToClient the data 561 * fields will be filled in and then the run method called by a message 562 * handling thread. This will occur some time after sendToClient completes 563 * in the script. 564 * 565 */ 566 public static class RSMessageHandler implements Runnable { 567 protected int[] mData; 568 protected int mID; 569 protected int mLength; 570 public void run() { 571 } 572 } 573 /** 574 * If an application is expecting messages it should set this field to an 575 * instance of RSMessage. This instance will receive all the user messages 576 * sent from sendToClient by scripts from this context. 577 * 578 */ 579 RSMessageHandler mMessageCallback = null; 580 581 public void setMessageHandler(RSMessageHandler msg) { 582 mMessageCallback = msg; 583 } 584 public RSMessageHandler getMessageHandler() { 585 return mMessageCallback; 586 } 587 588 /** 589 * Runtime error base class. An application should derive from this class 590 * if it wishes to install an error handler. When errors occur at runtime 591 * the fields in this class will be filled and the run method called. 592 * 593 */ 594 public static class RSErrorHandler implements Runnable { 595 protected String mErrorMessage; 596 protected int mErrorNum; 597 public void run() { 598 } 599 } 600 601 /** 602 * Application Error handler. All runtime errors will be dispatched to the 603 * instance of RSAsyncError set here. If this field is null a 604 * RSRuntimeException will instead be thrown with details about the error. 605 * This will cause program termaination. 606 * 607 */ 608 RSErrorHandler mErrorCallback = null; 609 610 public void setErrorHandler(RSErrorHandler msg) { 611 mErrorCallback = msg; 612 } 613 public RSErrorHandler getErrorHandler() { 614 return mErrorCallback; 615 } 616 617 /** 618 * RenderScript worker threads priority enumeration. The default value is 619 * NORMAL. Applications wishing to do background processing such as 620 * wallpapers should set their priority to LOW to avoid starving forground 621 * processes. 622 */ 623 public enum Priority { 624 LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)), 625 NORMAL (Process.THREAD_PRIORITY_DISPLAY); 626 627 int mID; 628 Priority(int id) { 629 mID = id; 630 } 631 } 632 633 void validate() { 634 if (mContext == 0) { 635 throw new RSInvalidStateException("Calling RS with no Context active."); 636 } 637 } 638 639 640 /** 641 * Change the priority of the worker threads for this context. 642 * 643 * @param p New priority to be set. 644 */ 645 public void setPriority(Priority p) { 646 validate(); 647 nContextSetPriority(p.mID); 648 } 649 650 static class MessageThread extends Thread { 651 RenderScript mRS; 652 boolean mRun = true; 653 int[] mAuxData = new int[2]; 654 655 static final int RS_MESSAGE_TO_CLIENT_NONE = 0; 656 static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1; 657 static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2; 658 static final int RS_MESSAGE_TO_CLIENT_ERROR = 3; 659 static final int RS_MESSAGE_TO_CLIENT_USER = 4; 660 661 static final int RS_ERROR_FATAL_UNKNOWN = 0x1000; 662 663 MessageThread(RenderScript rs) { 664 super("RSMessageThread"); 665 mRS = rs; 666 667 } 668 669 public void run() { 670 // This function is a temporary solution. The final solution will 671 // used typed allocations where the message id is the type indicator. 672 int[] rbuf = new int[16]; 673 mRS.nContextInitToClient(mRS.mContext); 674 while(mRun) { 675 rbuf[0] = 0; 676 int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData); 677 int size = mAuxData[1]; 678 int subID = mAuxData[0]; 679 680 if (msg == RS_MESSAGE_TO_CLIENT_USER) { 681 if ((size>>2) >= rbuf.length) { 682 rbuf = new int[(size + 3) >> 2]; 683 } 684 if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) != 685 RS_MESSAGE_TO_CLIENT_USER) { 686 throw new RSDriverException("Error processing message from Renderscript."); 687 } 688 689 if(mRS.mMessageCallback != null) { 690 mRS.mMessageCallback.mData = rbuf; 691 mRS.mMessageCallback.mID = subID; 692 mRS.mMessageCallback.mLength = size; 693 mRS.mMessageCallback.run(); 694 } else { 695 throw new RSInvalidStateException("Received a message from the script with no message handler installed."); 696 } 697 continue; 698 } 699 700 if (msg == RS_MESSAGE_TO_CLIENT_ERROR) { 701 String e = mRS.nContextGetErrorMessage(mRS.mContext); 702 703 if (subID >= RS_ERROR_FATAL_UNKNOWN) { 704 throw new RSRuntimeException("Fatal error " + subID + ", details: " + e); 705 } 706 707 if(mRS.mErrorCallback != null) { 708 mRS.mErrorCallback.mErrorMessage = e; 709 mRS.mErrorCallback.mErrorNum = subID; 710 mRS.mErrorCallback.run(); 711 } else { 712 // Do not throw here. In these cases, we do not have 713 // a fatal error. 714 } 715 continue; 716 } 717 718 // 2: teardown. 719 // But we want to avoid starving other threads during 720 // teardown by yielding until the next line in the destructor 721 // can execute to set mRun = false 722 try { 723 sleep(1, 0); 724 } catch(InterruptedException e) { 725 } 726 } 727 Log.d(LOG_TAG, "MessageThread exiting."); 728 } 729 } 730 731 RenderScript(Context ctx) { 732 if (ctx != null) { 733 mApplicationContext = ctx.getApplicationContext(); 734 } 735 } 736 737 /** 738 * Gets the application context associated with the RenderScript context. 739 * 740 * @return The application context. 741 */ 742 public final Context getApplicationContext() { 743 return mApplicationContext; 744 } 745 746 /** 747 * Create a basic RenderScript context. 748 * 749 * @hide 750 * @param ctx The context. 751 * @return RenderScript 752 */ 753 public static RenderScript create(Context ctx, int sdkVersion) { 754 RenderScript rs = new RenderScript(ctx); 755 756 rs.mDev = rs.nDeviceCreate(); 757 rs.mContext = rs.nContextCreate(rs.mDev, 0, sdkVersion); 758 if (rs.mContext == 0) { 759 throw new RSDriverException("Failed to create RS context."); 760 } 761 rs.mMessageThread = new MessageThread(rs); 762 rs.mMessageThread.start(); 763 return rs; 764 } 765 766 /** 767 * Create a basic RenderScript context. 768 * 769 * @param ctx The context. 770 * @return RenderScript 771 */ 772 public static RenderScript create(Context ctx) { 773 int v = ctx.getApplicationInfo().targetSdkVersion; 774 return create(ctx, v); 775 } 776 777 /** 778 * Print the currently available debugging information about the state of 779 * the RS context to the log. 780 * 781 */ 782 public void contextDump() { 783 validate(); 784 nContextDump(0); 785 } 786 787 /** 788 * Wait for any commands in the fifo between the java bindings and native to 789 * be processed. 790 * 791 */ 792 public void finish() { 793 nContextFinish(); 794 } 795 796 /** 797 * Destroy this renderscript context. Once this function is called its no 798 * longer legal to use this or any objects created by this context. 799 * 800 */ 801 public void destroy() { 802 validate(); 803 nContextDeinitToClient(mContext); 804 mMessageThread.mRun = false; 805 try { 806 mMessageThread.join(); 807 } catch(InterruptedException e) { 808 } 809 810 nContextDestroy(); 811 mContext = 0; 812 813 nDeviceDestroy(mDev); 814 mDev = 0; 815 } 816 817 boolean isAlive() { 818 return mContext != 0; 819 } 820 821 int safeID(BaseObj o) { 822 if(o != null) { 823 return o.getID(this); 824 } 825 return 0; 826 } 827} 828