Allocation.java revision 355707e4f665904e31d9f5fcff1e3921f7db8cdd
1/* 2 * Copyright (C) 2008-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.renderscript; 18 19import java.io.IOException; 20import java.io.InputStream; 21import java.util.HashMap; 22import android.content.res.Resources; 23import android.content.res.AssetManager; 24import android.graphics.Bitmap; 25import android.graphics.BitmapFactory; 26import android.view.Surface; 27import android.util.Log; 28import android.util.TypedValue; 29import android.graphics.Canvas; 30import android.os.Trace; 31 32/** 33 * <p> This class provides the primary method through which data is passed to 34 * and from RenderScript kernels. An Allocation provides the backing store for 35 * a given {@link android.renderscript.Type}. </p> 36 * 37 * <p>An Allocation also contains a set of usage flags that denote how the 38 * Allocation could be used. For example, an Allocation may have usage flags 39 * specifying that it can be used from a script as well as input to a {@link 40 * android.renderscript.Sampler}. A developer must synchronize across these 41 * different usages using {@link android.renderscript.Allocation#syncAll} in 42 * order to ensure that different users of the Allocation have a consistent view 43 * of memory. For example, in the case where an Allocation is used as the output 44 * of one kernel and as Sampler input in a later kernel, a developer must call 45 * {@link #syncAll syncAll(Allocation.USAGE_SCRIPT)} prior to launching the 46 * second kernel to ensure correctness. 47 * 48 * <p>An Allocation can be populated with the {@link #copyFrom} routines. For 49 * more complex Element types, the {@link #copyFromUnchecked} methods can be 50 * used to copy from byte arrays or similar constructs.</p> 51 * 52 * <div class="special reference"> 53 * <h3>Developer Guides</h3> 54 * <p>For more information about creating an application that uses RenderScript, read the 55 * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p> 56 * </div> 57 **/ 58public class Allocation extends BaseObj { 59 Type mType; 60 Bitmap mBitmap; 61 int mUsage; 62 Allocation mAdaptedAllocation; 63 int mSize; 64 65 boolean mConstrainedLOD; 66 boolean mConstrainedFace; 67 boolean mConstrainedY; 68 boolean mConstrainedZ; 69 boolean mReadAllowed = true; 70 boolean mWriteAllowed = true; 71 int mSelectedY; 72 int mSelectedZ; 73 int mSelectedLOD; 74 Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X; 75 76 int mCurrentDimX; 77 int mCurrentDimY; 78 int mCurrentDimZ; 79 int mCurrentCount; 80 static HashMap<Long, Allocation> mAllocationMap = 81 new HashMap<Long, Allocation>(); 82 OnBufferAvailableListener mBufferNotifier; 83 84 /** 85 * The usage of the Allocation. These signal to RenderScript where to place 86 * the Allocation in memory. 87 * 88 */ 89 90 /** 91 * The Allocation will be bound to and accessed by scripts. 92 */ 93 public static final int USAGE_SCRIPT = 0x0001; 94 95 /** 96 * The Allocation will be used as a texture source by one or more graphics 97 * programs. 98 * 99 */ 100 public static final int USAGE_GRAPHICS_TEXTURE = 0x0002; 101 102 /** 103 * The Allocation will be used as a graphics mesh. 104 * 105 * This was deprecated in API level 16. 106 * 107 */ 108 public static final int USAGE_GRAPHICS_VERTEX = 0x0004; 109 110 111 /** 112 * The Allocation will be used as the source of shader constants by one or 113 * more programs. 114 * 115 * This was deprecated in API level 16. 116 * 117 */ 118 public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008; 119 120 /** 121 * The Allocation will be used as a target for offscreen rendering 122 * 123 * This was deprecated in API level 16. 124 * 125 */ 126 public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010; 127 128 /** 129 * The Allocation will be used as a {@link android.view.Surface} 130 * consumer. This usage will cause the Allocation to be created 131 * as read-only. 132 * 133 */ 134 public static final int USAGE_IO_INPUT = 0x0020; 135 136 /** 137 * The Allocation will be used as a {@link android.view.Surface} 138 * producer. The dimensions and format of the {@link 139 * android.view.Surface} will be forced to those of the 140 * Allocation. 141 * 142 */ 143 public static final int USAGE_IO_OUTPUT = 0x0040; 144 145 /** 146 * The Allocation's backing store will be inherited from another object 147 * (usually a {@link android.graphics.Bitmap}); copying to or from the 148 * original source Bitmap will cause a synchronization rather than a full 149 * copy. {@link #syncAll} may also be used to synchronize the Allocation 150 * and the source Bitmap. 151 * 152 * <p>This is set by default for allocations created with {@link 153 * #createFromBitmap} in API version 18 and higher.</p> 154 * 155 */ 156 public static final int USAGE_SHARED = 0x0080; 157 158 /** 159 * Controls mipmap behavior when using the bitmap creation and update 160 * functions. 161 */ 162 public enum MipmapControl { 163 /** 164 * No mipmaps will be generated and the type generated from the incoming 165 * bitmap will not contain additional LODs. 166 */ 167 MIPMAP_NONE(0), 168 169 /** 170 * A full mipmap chain will be created in script memory. The Type of 171 * the Allocation will contain a full mipmap chain. On upload, the full 172 * chain will be transferred. 173 */ 174 MIPMAP_FULL(1), 175 176 /** 177 * The Type of the Allocation will be the same as MIPMAP_NONE. It will 178 * not contain mipmaps. On upload, the allocation data will contain a 179 * full mipmap chain generated from the top level in script memory. 180 */ 181 MIPMAP_ON_SYNC_TO_TEXTURE(2); 182 183 int mID; 184 MipmapControl(int id) { 185 mID = id; 186 } 187 } 188 189 190 private long getIDSafe() { 191 if (mAdaptedAllocation != null) { 192 return mAdaptedAllocation.getID(mRS); 193 } 194 return getID(mRS); 195 } 196 197 198 /** 199 * Get the {@link android.renderscript.Element} of the {@link 200 * android.renderscript.Type} of the Allocation. 201 * 202 * @return Element 203 * 204 */ 205 public Element getElement() { 206 return mType.getElement(); 207 } 208 209 /** 210 * Get the usage flags of the Allocation. 211 * 212 * @return usage this Allocation's set of the USAGE_* flags OR'd together 213 * 214 */ 215 public int getUsage() { 216 return mUsage; 217 } 218 219 /** 220 * Get the size of the Allocation in bytes. 221 * 222 * @return size of the Allocation in bytes. 223 * 224 */ 225 public int getBytesSize() { 226 return mType.getCount() * mType.getElement().getBytesSize(); 227 } 228 229 private void updateCacheInfo(Type t) { 230 mCurrentDimX = t.getX(); 231 mCurrentDimY = t.getY(); 232 mCurrentDimZ = t.getZ(); 233 mCurrentCount = mCurrentDimX; 234 if (mCurrentDimY > 1) { 235 mCurrentCount *= mCurrentDimY; 236 } 237 if (mCurrentDimZ > 1) { 238 mCurrentCount *= mCurrentDimZ; 239 } 240 } 241 242 private void setBitmap(Bitmap b) { 243 mBitmap = b; 244 } 245 246 Allocation(long id, RenderScript rs, Type t, int usage) { 247 super(id, rs); 248 if ((usage & ~(USAGE_SCRIPT | 249 USAGE_GRAPHICS_TEXTURE | 250 USAGE_GRAPHICS_VERTEX | 251 USAGE_GRAPHICS_CONSTANTS | 252 USAGE_GRAPHICS_RENDER_TARGET | 253 USAGE_IO_INPUT | 254 USAGE_IO_OUTPUT | 255 USAGE_SHARED)) != 0) { 256 throw new RSIllegalArgumentException("Unknown usage specified."); 257 } 258 259 if ((usage & USAGE_IO_INPUT) != 0) { 260 mWriteAllowed = false; 261 262 if ((usage & ~(USAGE_IO_INPUT | 263 USAGE_GRAPHICS_TEXTURE | 264 USAGE_SCRIPT)) != 0) { 265 throw new RSIllegalArgumentException("Invalid usage combination."); 266 } 267 } 268 269 mType = t; 270 mUsage = usage; 271 272 if (t != null) { 273 // TODO: A3D doesn't have Type info during creation, so we can't 274 // calculate the size ahead of time. We can possibly add a method 275 // to update the size in the future if it seems reasonable. 276 mSize = mType.getCount() * mType.getElement().getBytesSize(); 277 updateCacheInfo(t); 278 } 279 try { 280 RenderScript.registerNativeAllocation.invoke(RenderScript.sRuntime, mSize); 281 } catch (Exception e) { 282 Log.e(RenderScript.LOG_TAG, "Couldn't invoke registerNativeAllocation:" + e); 283 throw new RSRuntimeException("Couldn't invoke registerNativeAllocation:" + e); 284 } 285 } 286 287 protected void finalize() throws Throwable { 288 RenderScript.registerNativeFree.invoke(RenderScript.sRuntime, mSize); 289 super.finalize(); 290 } 291 292 private void validateIsInt32() { 293 if ((mType.mElement.mType == Element.DataType.SIGNED_32) || 294 (mType.mElement.mType == Element.DataType.UNSIGNED_32)) { 295 return; 296 } 297 throw new RSIllegalArgumentException( 298 "32 bit integer source does not match allocation type " + mType.mElement.mType); 299 } 300 301 private void validateIsInt16() { 302 if ((mType.mElement.mType == Element.DataType.SIGNED_16) || 303 (mType.mElement.mType == Element.DataType.UNSIGNED_16)) { 304 return; 305 } 306 throw new RSIllegalArgumentException( 307 "16 bit integer source does not match allocation type " + mType.mElement.mType); 308 } 309 310 private void validateIsInt8() { 311 if ((mType.mElement.mType == Element.DataType.SIGNED_8) || 312 (mType.mElement.mType == Element.DataType.UNSIGNED_8)) { 313 return; 314 } 315 throw new RSIllegalArgumentException( 316 "8 bit integer source does not match allocation type " + mType.mElement.mType); 317 } 318 319 private void validateIsFloat32() { 320 if (mType.mElement.mType == Element.DataType.FLOAT_32) { 321 return; 322 } 323 throw new RSIllegalArgumentException( 324 "32 bit float source does not match allocation type " + mType.mElement.mType); 325 } 326 327 private void validateIsObject() { 328 if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) || 329 (mType.mElement.mType == Element.DataType.RS_TYPE) || 330 (mType.mElement.mType == Element.DataType.RS_ALLOCATION) || 331 (mType.mElement.mType == Element.DataType.RS_SAMPLER) || 332 (mType.mElement.mType == Element.DataType.RS_SCRIPT) || 333 (mType.mElement.mType == Element.DataType.RS_MESH) || 334 (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) || 335 (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) || 336 (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) || 337 (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) { 338 return; 339 } 340 throw new RSIllegalArgumentException( 341 "Object source does not match allocation type " + mType.mElement.mType); 342 } 343 344 @Override 345 void updateFromNative() { 346 super.updateFromNative(); 347 long typeID = mRS.nAllocationGetType(getID(mRS)); 348 if(typeID != 0) { 349 mType = new Type(typeID, mRS); 350 mType.updateFromNative(); 351 updateCacheInfo(mType); 352 } 353 } 354 355 /** 356 * Get the {@link android.renderscript.Type} of the Allocation. 357 * 358 * @return Type 359 * 360 */ 361 public Type getType() { 362 return mType; 363 } 364 365 /** 366 * Propagate changes from one usage of the Allocation to the 367 * other usages of the Allocation. 368 * 369 */ 370 public void syncAll(int srcLocation) { 371 Trace.traceBegin(RenderScript.TRACE_TAG, "syncAll"); 372 switch (srcLocation) { 373 case USAGE_GRAPHICS_TEXTURE: 374 case USAGE_SCRIPT: 375 if ((mUsage & USAGE_SHARED) != 0) { 376 copyFrom(mBitmap); 377 } 378 break; 379 case USAGE_GRAPHICS_CONSTANTS: 380 case USAGE_GRAPHICS_VERTEX: 381 break; 382 case USAGE_SHARED: 383 if ((mUsage & USAGE_SHARED) != 0) { 384 copyTo(mBitmap); 385 } 386 break; 387 default: 388 throw new RSIllegalArgumentException("Source must be exactly one usage type."); 389 } 390 mRS.validate(); 391 mRS.nAllocationSyncAll(getIDSafe(), srcLocation); 392 Trace.traceEnd(RenderScript.TRACE_TAG); 393 } 394 395 /** 396 * Send a buffer to the output stream. The contents of the Allocation will 397 * be undefined after this operation. This operation is only valid if {@link 398 * #USAGE_IO_OUTPUT} is set on the Allocation. 399 * 400 * 401 */ 402 public void ioSend() { 403 Trace.traceBegin(RenderScript.TRACE_TAG, "ioSend"); 404 if ((mUsage & USAGE_IO_OUTPUT) == 0) { 405 throw new RSIllegalArgumentException( 406 "Can only send buffer if IO_OUTPUT usage specified."); 407 } 408 mRS.validate(); 409 mRS.nAllocationIoSend(getID(mRS)); 410 Trace.traceEnd(RenderScript.TRACE_TAG); 411 } 412 413 /** 414 * Receive the latest input into the Allocation. This operation 415 * is only valid if {@link #USAGE_IO_INPUT} is set on the Allocation. 416 * 417 */ 418 public void ioReceive() { 419 Trace.traceBegin(RenderScript.TRACE_TAG, "ioReceive"); 420 if ((mUsage & USAGE_IO_INPUT) == 0) { 421 throw new RSIllegalArgumentException( 422 "Can only receive if IO_INPUT usage specified."); 423 } 424 mRS.validate(); 425 mRS.nAllocationIoReceive(getID(mRS)); 426 Trace.traceEnd(RenderScript.TRACE_TAG); 427 } 428 429 /** 430 * Copy an array of RS objects to the Allocation. 431 * 432 * @param d Source array. 433 */ 434 public void copyFrom(BaseObj[] d) { 435 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); 436 mRS.validate(); 437 validateIsObject(); 438 if (d.length != mCurrentCount) { 439 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " + 440 mCurrentCount + ", array length = " + d.length); 441 } 442 // FIXME: requires 64-bit path 443 444 int i[] = new int[d.length]; 445 for (int ct=0; ct < d.length; ct++) { 446 i[ct] = (int)d[ct].getID(mRS); 447 } 448 copy1DRangeFromUnchecked(0, mCurrentCount, i); 449 Trace.traceEnd(RenderScript.TRACE_TAG); 450 } 451 452 private void validateBitmapFormat(Bitmap b) { 453 Bitmap.Config bc = b.getConfig(); 454 if (bc == null) { 455 throw new RSIllegalArgumentException("Bitmap has an unsupported format for this operation"); 456 } 457 switch (bc) { 458 case ALPHA_8: 459 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) { 460 throw new RSIllegalArgumentException("Allocation kind is " + 461 mType.getElement().mKind + ", type " + 462 mType.getElement().mType + 463 " of " + mType.getElement().getBytesSize() + 464 " bytes, passed bitmap was " + bc); 465 } 466 break; 467 case ARGB_8888: 468 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) || 469 (mType.getElement().getBytesSize() != 4)) { 470 throw new RSIllegalArgumentException("Allocation kind is " + 471 mType.getElement().mKind + ", type " + 472 mType.getElement().mType + 473 " of " + mType.getElement().getBytesSize() + 474 " bytes, passed bitmap was " + bc); 475 } 476 break; 477 case RGB_565: 478 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) || 479 (mType.getElement().getBytesSize() != 2)) { 480 throw new RSIllegalArgumentException("Allocation kind is " + 481 mType.getElement().mKind + ", type " + 482 mType.getElement().mType + 483 " of " + mType.getElement().getBytesSize() + 484 " bytes, passed bitmap was " + bc); 485 } 486 break; 487 case ARGB_4444: 488 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) || 489 (mType.getElement().getBytesSize() != 2)) { 490 throw new RSIllegalArgumentException("Allocation kind is " + 491 mType.getElement().mKind + ", type " + 492 mType.getElement().mType + 493 " of " + mType.getElement().getBytesSize() + 494 " bytes, passed bitmap was " + bc); 495 } 496 break; 497 498 } 499 } 500 501 private void validateBitmapSize(Bitmap b) { 502 if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) { 503 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch"); 504 } 505 } 506 507 /** 508 * Copy into this Allocation from an array. This method does not guarantee 509 * that the Allocation is compatible with the input buffer; it copies memory 510 * without reinterpretation. 511 * 512 * @param d the source data array 513 */ 514 public void copyFromUnchecked(int[] d) { 515 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked"); 516 mRS.validate(); 517 if (mCurrentDimZ > 0) { 518 copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d); 519 } else if (mCurrentDimY > 0) { 520 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d); 521 } else { 522 copy1DRangeFromUnchecked(0, mCurrentCount, d); 523 } 524 Trace.traceEnd(RenderScript.TRACE_TAG); 525 } 526 527 /** 528 * Copy into this Allocation from an array. This method does not guarantee 529 * that the Allocation is compatible with the input buffer; it copies memory 530 * without reinterpretation. 531 * 532 * @param d the source data array 533 */ 534 public void copyFromUnchecked(short[] d) { 535 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked"); 536 mRS.validate(); 537 if (mCurrentDimZ > 0) { 538 copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d); 539 } else if (mCurrentDimY > 0) { 540 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d); 541 } else { 542 copy1DRangeFromUnchecked(0, mCurrentCount, d); 543 } 544 Trace.traceEnd(RenderScript.TRACE_TAG); 545 } 546 547 /** 548 * Copy into this Allocation from an array. This method does not guarantee 549 * that the Allocation is compatible with the input buffer; it copies memory 550 * without reinterpretation. 551 * 552 * @param d the source data array 553 */ 554 public void copyFromUnchecked(byte[] d) { 555 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked"); 556 mRS.validate(); 557 if (mCurrentDimZ > 0) { 558 copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d); 559 } else if (mCurrentDimY > 0) { 560 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d); 561 } else { 562 copy1DRangeFromUnchecked(0, mCurrentCount, d); 563 } 564 Trace.traceEnd(RenderScript.TRACE_TAG); 565 } 566 567 /** 568 * Copy into this Allocation from an array. This method does not guarantee 569 * that the Allocation is compatible with the input buffer; it copies memory 570 * without reinterpretation. 571 * 572 * @param d the source data array 573 */ 574 public void copyFromUnchecked(float[] d) { 575 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked"); 576 mRS.validate(); 577 if (mCurrentDimZ > 0) { 578 copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d); 579 } else if (mCurrentDimY > 0) { 580 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d); 581 } else { 582 copy1DRangeFromUnchecked(0, mCurrentCount, d); 583 } 584 Trace.traceEnd(RenderScript.TRACE_TAG); 585 } 586 587 588 /** 589 * Copy into this Allocation from an array. This variant is type checked 590 * and will generate exceptions if the Allocation's {@link 591 * android.renderscript.Element} is not a 32 bit integer type. 592 * 593 * @param d the source data array 594 */ 595 public void copyFrom(int[] d) { 596 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); 597 mRS.validate(); 598 if (mCurrentDimZ > 0) { 599 copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d); 600 } else if (mCurrentDimY > 0) { 601 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d); 602 } else { 603 copy1DRangeFrom(0, mCurrentCount, d); 604 } 605 Trace.traceEnd(RenderScript.TRACE_TAG); 606 } 607 608 /** 609 * Copy into this Allocation from an array. This variant is type checked 610 * and will generate exceptions if the Allocation's {@link 611 * android.renderscript.Element} is not a 16 bit integer type. 612 * 613 * @param d the source data array 614 */ 615 public void copyFrom(short[] d) { 616 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); 617 mRS.validate(); 618 if (mCurrentDimZ > 0) { 619 copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d); 620 } else if (mCurrentDimY > 0) { 621 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d); 622 } else { 623 copy1DRangeFrom(0, mCurrentCount, d); 624 } 625 Trace.traceEnd(RenderScript.TRACE_TAG); 626 } 627 628 /** 629 * Copy into this Allocation from an array. This variant is type checked 630 * and will generate exceptions if the Allocation's {@link 631 * android.renderscript.Element} is not an 8 bit integer type. 632 * 633 * @param d the source data array 634 */ 635 public void copyFrom(byte[] d) { 636 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); 637 mRS.validate(); 638 if (mCurrentDimZ > 0) { 639 copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d); 640 } else if (mCurrentDimY > 0) { 641 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d); 642 } else { 643 copy1DRangeFrom(0, mCurrentCount, d); 644 } 645 Trace.traceEnd(RenderScript.TRACE_TAG); 646 } 647 648 /** 649 * Copy into this Allocation from an array. This variant is type checked 650 * and will generate exceptions if the Allocation's {@link 651 * android.renderscript.Element} is not a 32 bit float type. 652 * 653 * @param d the source data array 654 */ 655 public void copyFrom(float[] d) { 656 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); 657 mRS.validate(); 658 if (mCurrentDimZ > 0) { 659 copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d); 660 } else if (mCurrentDimY > 0) { 661 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d); 662 } else { 663 copy1DRangeFrom(0, mCurrentCount, d); 664 } 665 Trace.traceEnd(RenderScript.TRACE_TAG); 666 } 667 668 /** 669 * Copy into an Allocation from a {@link android.graphics.Bitmap}. The 670 * height, width, and format of the bitmap must match the existing 671 * allocation. 672 * 673 * <p>If the {@link android.graphics.Bitmap} is the same as the {@link 674 * android.graphics.Bitmap} used to create the Allocation with {@link 675 * #createFromBitmap} and {@link #USAGE_SHARED} is set on the Allocation, 676 * this will synchronize the Allocation with the latest data from the {@link 677 * android.graphics.Bitmap}, potentially avoiding the actual copy.</p> 678 * 679 * @param b the source bitmap 680 */ 681 public void copyFrom(Bitmap b) { 682 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); 683 mRS.validate(); 684 if (b.getConfig() == null) { 685 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888); 686 Canvas c = new Canvas(newBitmap); 687 c.drawBitmap(b, 0, 0, null); 688 copyFrom(newBitmap); 689 return; 690 } 691 validateBitmapSize(b); 692 validateBitmapFormat(b); 693 mRS.nAllocationCopyFromBitmap(getID(mRS), b); 694 Trace.traceEnd(RenderScript.TRACE_TAG); 695 } 696 697 /** 698 * Copy an Allocation from an Allocation. The types of both allocations 699 * must be identical. 700 * 701 * @param a the source allocation 702 */ 703 public void copyFrom(Allocation a) { 704 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); 705 mRS.validate(); 706 if (!mType.equals(a.getType())) { 707 throw new RSIllegalArgumentException("Types of allocations must match."); 708 } 709 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0); 710 Trace.traceEnd(RenderScript.TRACE_TAG); 711 } 712 713 /** 714 * This is only intended to be used by auto-generated code reflected from 715 * the RenderScript script files and should not be used by developers. 716 * 717 * @param xoff 718 * @param fp 719 */ 720 public void setFromFieldPacker(int xoff, FieldPacker fp) { 721 mRS.validate(); 722 int eSize = mType.mElement.getBytesSize(); 723 final byte[] data = fp.getData(); 724 725 int count = data.length / eSize; 726 if ((eSize * count) != data.length) { 727 throw new RSIllegalArgumentException("Field packer length " + data.length + 728 " not divisible by element size " + eSize + "."); 729 } 730 copy1DRangeFromUnchecked(xoff, count, data); 731 } 732 733 /** 734 * This is only intended to be used by auto-generated code reflected from 735 * the RenderScript script files. 736 * 737 * @param xoff 738 * @param component_number 739 * @param fp 740 */ 741 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) { 742 mRS.validate(); 743 if (component_number >= mType.mElement.mElements.length) { 744 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range."); 745 } 746 if(xoff < 0) { 747 throw new RSIllegalArgumentException("Offset must be >= 0."); 748 } 749 750 final byte[] data = fp.getData(); 751 int eSize = mType.mElement.mElements[component_number].getBytesSize(); 752 eSize *= mType.mElement.mArraySizes[component_number]; 753 754 if (data.length != eSize) { 755 throw new RSIllegalArgumentException("Field packer sizelength " + data.length + 756 " does not match component size " + eSize + "."); 757 } 758 759 mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD, 760 component_number, data, data.length); 761 } 762 763 private void data1DChecks(int off, int count, int len, int dataSize) { 764 mRS.validate(); 765 if(off < 0) { 766 throw new RSIllegalArgumentException("Offset must be >= 0."); 767 } 768 if(count < 1) { 769 throw new RSIllegalArgumentException("Count must be >= 1."); 770 } 771 if((off + count) > mCurrentCount) { 772 throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount + 773 ", got " + count + " at offset " + off + "."); 774 } 775 if(len < dataSize) { 776 throw new RSIllegalArgumentException("Array too small for allocation type."); 777 } 778 } 779 780 /** 781 * Generate a mipmap chain. This is only valid if the Type of the Allocation 782 * includes mipmaps. 783 * 784 * <p>This function will generate a complete set of mipmaps from the top 785 * level LOD and place them into the script memory space.</p> 786 * 787 * <p>If the Allocation is also using other memory spaces, a call to {@link 788 * #syncAll syncAll(Allocation.USAGE_SCRIPT)} is required.</p> 789 */ 790 public void generateMipmaps() { 791 mRS.nAllocationGenerateMipmaps(getID(mRS)); 792 } 793 794 /** 795 * Copy an array into part of this Allocation. This method does not 796 * guarantee that the Allocation is compatible with the input buffer. 797 * 798 * @param off The offset of the first element to be copied. 799 * @param count The number of elements to be copied. 800 * @param d the source data array 801 */ 802 public void copy1DRangeFromUnchecked(int off, int count, int[] d) { 803 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked"); 804 int dataSize = mType.mElement.getBytesSize() * count; 805 data1DChecks(off, count, d.length * 4, dataSize); 806 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize, Element.DataType.SIGNED_32); 807 Trace.traceEnd(RenderScript.TRACE_TAG); 808 } 809 810 /** 811 * Copy an array into part of this Allocation. This method does not 812 * guarantee that the Allocation is compatible with the input buffer. 813 * 814 * @param off The offset of the first element to be copied. 815 * @param count The number of elements to be copied. 816 * @param d the source data array 817 */ 818 public void copy1DRangeFromUnchecked(int off, int count, short[] d) { 819 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked"); 820 int dataSize = mType.mElement.getBytesSize() * count; 821 data1DChecks(off, count, d.length * 2, dataSize); 822 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize, Element.DataType.SIGNED_16); 823 Trace.traceEnd(RenderScript.TRACE_TAG); 824 } 825 826 /** 827 * Copy an array into part of this Allocation. This method does not 828 * guarantee that the Allocation is compatible with the input buffer. 829 * 830 * @param off The offset of the first element to be copied. 831 * @param count The number of elements to be copied. 832 * @param d the source data array 833 */ 834 public void copy1DRangeFromUnchecked(int off, int count, byte[] d) { 835 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked"); 836 int dataSize = mType.mElement.getBytesSize() * count; 837 data1DChecks(off, count, d.length, dataSize); 838 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize, Element.DataType.SIGNED_8); 839 Trace.traceEnd(RenderScript.TRACE_TAG); 840 } 841 842 /** 843 * Copy an array into part of this Allocation. This method does not 844 * guarantee that the Allocation is compatible with the input buffer. 845 * 846 * @param off The offset of the first element to be copied. 847 * @param count The number of elements to be copied. 848 * @param d the source data array 849 */ 850 public void copy1DRangeFromUnchecked(int off, int count, float[] d) { 851 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked"); 852 int dataSize = mType.mElement.getBytesSize() * count; 853 data1DChecks(off, count, d.length * 4, dataSize); 854 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize, Element.DataType.FLOAT_32); 855 Trace.traceEnd(RenderScript.TRACE_TAG); 856 } 857 858 /** 859 * Copy an array into part of this Allocation. This variant is type checked 860 * and will generate exceptions if the Allocation type is not a 32 bit 861 * integer type. 862 * 863 * @param off The offset of the first element to be copied. 864 * @param count The number of elements to be copied. 865 * @param d the source data array 866 */ 867 public void copy1DRangeFrom(int off, int count, int[] d) { 868 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom"); 869 validateIsInt32(); 870 copy1DRangeFromUnchecked(off, count, d); 871 Trace.traceEnd(RenderScript.TRACE_TAG); 872 } 873 874 /** 875 * Copy an array into part of this Allocation. This variant is type checked 876 * and will generate exceptions if the Allocation type is not a 16 bit 877 * integer type. 878 * 879 * @param off The offset of the first element to be copied. 880 * @param count The number of elements to be copied. 881 * @param d the source data array 882 */ 883 public void copy1DRangeFrom(int off, int count, short[] d) { 884 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom"); 885 validateIsInt16(); 886 copy1DRangeFromUnchecked(off, count, d); 887 Trace.traceEnd(RenderScript.TRACE_TAG); 888 } 889 890 /** 891 * Copy an array into part of this Allocation. This variant is type checked 892 * and will generate exceptions if the Allocation type is not an 8 bit 893 * integer type. 894 * 895 * @param off The offset of the first element to be copied. 896 * @param count The number of elements to be copied. 897 * @param d the source data array 898 */ 899 public void copy1DRangeFrom(int off, int count, byte[] d) { 900 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom"); 901 validateIsInt8(); 902 copy1DRangeFromUnchecked(off, count, d); 903 Trace.traceEnd(RenderScript.TRACE_TAG); 904 } 905 906 /** 907 * Copy an array into part of this Allocation. This variant is type checked 908 * and will generate exceptions if the Allocation type is not a 32 bit float 909 * type. 910 * 911 * @param off The offset of the first element to be copied. 912 * @param count The number of elements to be copied. 913 * @param d the source data array. 914 */ 915 public void copy1DRangeFrom(int off, int count, float[] d) { 916 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom"); 917 validateIsFloat32(); 918 copy1DRangeFromUnchecked(off, count, d); 919 Trace.traceEnd(RenderScript.TRACE_TAG); 920 } 921 /** 922 * Copy part of an Allocation into this Allocation. 923 * 924 * @param off The offset of the first element to be copied. 925 * @param count The number of elements to be copied. 926 * @param data the source data allocation. 927 * @param dataOff off The offset of the first element in data to 928 * be copied. 929 */ 930 public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) { 931 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom"); 932 mRS.nAllocationData2D(getIDSafe(), off, 0, 933 mSelectedLOD, mSelectedFace.mID, 934 count, 1, data.getID(mRS), dataOff, 0, 935 data.mSelectedLOD, data.mSelectedFace.mID); 936 } 937 938 private void validate2DRange(int xoff, int yoff, int w, int h) { 939 if (mAdaptedAllocation != null) { 940 941 } else { 942 943 if (xoff < 0 || yoff < 0) { 944 throw new RSIllegalArgumentException("Offset cannot be negative."); 945 } 946 if (h < 0 || w < 0) { 947 throw new RSIllegalArgumentException("Height or width cannot be negative."); 948 } 949 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) { 950 throw new RSIllegalArgumentException("Updated region larger than allocation."); 951 } 952 } 953 } 954 955 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, byte[] data) { 956 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked"); 957 mRS.validate(); 958 validate2DRange(xoff, yoff, w, h); 959 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, 960 w, h, data, data.length, Element.DataType.SIGNED_8); 961 Trace.traceEnd(RenderScript.TRACE_TAG); 962 } 963 964 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, short[] data) { 965 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked"); 966 mRS.validate(); 967 validate2DRange(xoff, yoff, w, h); 968 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, 969 w, h, data, data.length * 2, Element.DataType.SIGNED_16); 970 Trace.traceEnd(RenderScript.TRACE_TAG); 971 } 972 973 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, int[] data) { 974 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked"); 975 mRS.validate(); 976 validate2DRange(xoff, yoff, w, h); 977 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, 978 w, h, data, data.length * 4, Element.DataType.SIGNED_32); 979 Trace.traceEnd(RenderScript.TRACE_TAG); 980 } 981 982 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, float[] data) { 983 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked"); 984 mRS.validate(); 985 validate2DRange(xoff, yoff, w, h); 986 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, 987 w, h, data, data.length * 4, Element.DataType.FLOAT_32); 988 Trace.traceEnd(RenderScript.TRACE_TAG); 989 } 990 991 /** 992 * Copy from an array into a rectangular region in this Allocation. The 993 * array is assumed to be tightly packed. 994 * 995 * @param xoff X offset of the region to update in this Allocation 996 * @param yoff Y offset of the region to update in this Allocation 997 * @param w Width of the region to update 998 * @param h Height of the region to update 999 * @param data to be placed into the Allocation 1000 */ 1001 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) { 1002 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom"); 1003 validateIsInt8(); 1004 copy2DRangeFromUnchecked(xoff, yoff, w, h, data); 1005 Trace.traceEnd(RenderScript.TRACE_TAG); 1006 } 1007 1008 /** 1009 * Copy from an array into a rectangular region in this Allocation. The 1010 * array is assumed to be tightly packed. 1011 * 1012 * @param xoff X offset of the region to update in this Allocation 1013 * @param yoff Y offset of the region to update in this Allocation 1014 * @param w Width of the region to update 1015 * @param h Height of the region to update 1016 * @param data to be placed into the Allocation 1017 */ 1018 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) { 1019 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom"); 1020 validateIsInt16(); 1021 copy2DRangeFromUnchecked(xoff, yoff, w, h, data); 1022 Trace.traceEnd(RenderScript.TRACE_TAG); 1023 } 1024 1025 /** 1026 * Copy from an array into a rectangular region in this Allocation. The 1027 * array is assumed to be tightly packed. 1028 * 1029 * @param xoff X offset of the region to update in this Allocation 1030 * @param yoff Y offset of the region to update in this Allocation 1031 * @param w Width of the region to update 1032 * @param h Height of the region to update 1033 * @param data to be placed into the Allocation 1034 */ 1035 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) { 1036 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom"); 1037 validateIsInt32(); 1038 copy2DRangeFromUnchecked(xoff, yoff, w, h, data); 1039 Trace.traceEnd(RenderScript.TRACE_TAG); 1040 } 1041 1042 /** 1043 * Copy from an array into a rectangular region in this Allocation. The 1044 * array is assumed to be tightly packed. 1045 * 1046 * @param xoff X offset of the region to update in this Allocation 1047 * @param yoff Y offset of the region to update in this Allocation 1048 * @param w Width of the region to update 1049 * @param h Height of the region to update 1050 * @param data to be placed into the Allocation 1051 */ 1052 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) { 1053 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom"); 1054 validateIsFloat32(); 1055 copy2DRangeFromUnchecked(xoff, yoff, w, h, data); 1056 Trace.traceEnd(RenderScript.TRACE_TAG); 1057 } 1058 1059 /** 1060 * Copy a rectangular region from an Allocation into a rectangular region in 1061 * this Allocation. 1062 * 1063 * @param xoff X offset of the region in this Allocation 1064 * @param yoff Y offset of the region in this Allocation 1065 * @param w Width of the region to update. 1066 * @param h Height of the region to update. 1067 * @param data source Allocation. 1068 * @param dataXoff X offset in source Allocation 1069 * @param dataYoff Y offset in source Allocation 1070 */ 1071 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, 1072 Allocation data, int dataXoff, int dataYoff) { 1073 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom"); 1074 mRS.validate(); 1075 validate2DRange(xoff, yoff, w, h); 1076 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, 1077 mSelectedLOD, mSelectedFace.mID, 1078 w, h, data.getID(mRS), dataXoff, dataYoff, 1079 data.mSelectedLOD, data.mSelectedFace.mID); 1080 Trace.traceEnd(RenderScript.TRACE_TAG); 1081 } 1082 1083 /** 1084 * Copy a {@link android.graphics.Bitmap} into an Allocation. The height 1085 * and width of the update will use the height and width of the {@link 1086 * android.graphics.Bitmap}. 1087 * 1088 * @param xoff X offset of the region to update in this Allocation 1089 * @param yoff Y offset of the region to update in this Allocation 1090 * @param data the Bitmap to be copied 1091 */ 1092 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) { 1093 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom"); 1094 mRS.validate(); 1095 if (data.getConfig() == null) { 1096 Bitmap newBitmap = Bitmap.createBitmap(data.getWidth(), data.getHeight(), Bitmap.Config.ARGB_8888); 1097 Canvas c = new Canvas(newBitmap); 1098 c.drawBitmap(data, 0, 0, null); 1099 copy2DRangeFrom(xoff, yoff, newBitmap); 1100 return; 1101 } 1102 validateBitmapFormat(data); 1103 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight()); 1104 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data); 1105 Trace.traceEnd(RenderScript.TRACE_TAG); 1106 } 1107 1108 private void validate3DRange(int xoff, int yoff, int zoff, int w, int h, int d) { 1109 if (mAdaptedAllocation != null) { 1110 1111 } else { 1112 1113 if (xoff < 0 || yoff < 0 || zoff < 0) { 1114 throw new RSIllegalArgumentException("Offset cannot be negative."); 1115 } 1116 if (h < 0 || w < 0 || d < 0) { 1117 throw new RSIllegalArgumentException("Height or width cannot be negative."); 1118 } 1119 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY) || ((zoff + d) > mCurrentDimZ)) { 1120 throw new RSIllegalArgumentException("Updated region larger than allocation."); 1121 } 1122 } 1123 } 1124 1125 /** 1126 * @hide 1127 * 1128 */ 1129 void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, byte[] data) { 1130 mRS.validate(); 1131 validate3DRange(xoff, yoff, zoff, w, h, d); 1132 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, 1133 w, h, d, data, data.length, Element.DataType.SIGNED_8); 1134 } 1135 1136 /** 1137 * @hide 1138 * 1139 */ 1140 void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, short[] data) { 1141 mRS.validate(); 1142 validate3DRange(xoff, yoff, zoff, w, h, d); 1143 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, 1144 w, h, d, data, data.length * 2, Element.DataType.SIGNED_16); 1145 } 1146 1147 /** 1148 * @hide 1149 * 1150 */ 1151 void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, int[] data) { 1152 mRS.validate(); 1153 validate3DRange(xoff, yoff, zoff, w, h, d); 1154 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, 1155 w, h, d, data, data.length * 4, Element.DataType.SIGNED_32); 1156 } 1157 1158 /** 1159 * @hide 1160 * 1161 */ 1162 void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, float[] data) { 1163 mRS.validate(); 1164 validate3DRange(xoff, yoff, zoff, w, h, d); 1165 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, 1166 w, h, d, data, data.length * 4, Element.DataType.FLOAT_32); 1167 } 1168 1169 1170 /** 1171 * @hide 1172 * Copy a rectangular region from the array into the allocation. 1173 * The array is assumed to be tightly packed. 1174 * 1175 * @param xoff X offset of the region to update in this Allocation 1176 * @param yoff Y offset of the region to update in this Allocation 1177 * @param zoff Z offset of the region to update in this Allocation 1178 * @param w Width of the region to update 1179 * @param h Height of the region to update 1180 * @param d Depth of the region to update 1181 * @param data to be placed into the allocation 1182 */ 1183 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, byte[] data) { 1184 validateIsInt8(); 1185 copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, data); 1186 } 1187 1188 /** 1189 * @hide 1190 * 1191 */ 1192 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, short[] data) { 1193 validateIsInt16(); 1194 copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, data); 1195 } 1196 1197 /** 1198 * @hide 1199 * 1200 */ 1201 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, int[] data) { 1202 validateIsInt32(); 1203 copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, data); 1204 } 1205 1206 /** 1207 * @hide 1208 * 1209 */ 1210 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, float[] data) { 1211 validateIsFloat32(); 1212 copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, data); 1213 } 1214 1215 /** 1216 * @hide 1217 * Copy a rectangular region into the allocation from another 1218 * allocation. 1219 * 1220 * @param xoff X offset of the region to update in this Allocation 1221 * @param yoff Y offset of the region to update in this Allocation 1222 * @param zoff Z offset of the region to update in this Allocation 1223 * @param w Width of the region to update. 1224 * @param h Height of the region to update. 1225 * @param d Depth of the region to update. 1226 * @param data source allocation. 1227 * @param dataXoff X offset of the region in the source Allocation 1228 * @param dataYoff Y offset of the region in the source Allocation 1229 * @param dataZoff Z offset of the region in the source Allocation 1230 */ 1231 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, 1232 Allocation data, int dataXoff, int dataYoff, int dataZoff) { 1233 mRS.validate(); 1234 validate3DRange(xoff, yoff, zoff, w, h, d); 1235 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, 1236 w, h, d, data.getID(mRS), dataXoff, dataYoff, dataZoff, 1237 data.mSelectedLOD); 1238 } 1239 1240 1241 /** 1242 * Copy from the Allocation into a {@link android.graphics.Bitmap}. The 1243 * bitmap must match the dimensions of the Allocation. 1244 * 1245 * @param b The bitmap to be set from the Allocation. 1246 */ 1247 public void copyTo(Bitmap b) { 1248 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo"); 1249 mRS.validate(); 1250 validateBitmapFormat(b); 1251 validateBitmapSize(b); 1252 mRS.nAllocationCopyToBitmap(getID(mRS), b); 1253 Trace.traceEnd(RenderScript.TRACE_TAG); 1254 } 1255 1256 /** 1257 * Copy from the Allocation into a byte array. The array must be at least 1258 * as large as the Allocation. The allocation must be of an 8 bit integer 1259 * {@link android.renderscript.Element} type. 1260 * 1261 * @param d The array to be set from the Allocation. 1262 */ 1263 public void copyTo(byte[] d) { 1264 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo"); 1265 validateIsInt8(); 1266 mRS.validate(); 1267 mRS.nAllocationRead(getID(mRS), d, Element.DataType.SIGNED_8); 1268 Trace.traceEnd(RenderScript.TRACE_TAG); 1269 } 1270 1271 /** 1272 * Copy from the Allocation into a short array. The array must be at least 1273 * as large as the Allocation. The allocation must be of an 16 bit integer 1274 * {@link android.renderscript.Element} type. 1275 * 1276 * @param d The array to be set from the Allocation. 1277 */ 1278 public void copyTo(short[] d) { 1279 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo"); 1280 validateIsInt16(); 1281 mRS.validate(); 1282 mRS.nAllocationRead(getID(mRS), d, Element.DataType.SIGNED_16); 1283 Trace.traceEnd(RenderScript.TRACE_TAG); 1284 } 1285 1286 /** 1287 * Copy from the Allocation into a int array. The array must be at least as 1288 * large as the Allocation. The allocation must be of an 32 bit integer 1289 * {@link android.renderscript.Element} type. 1290 * 1291 * @param d The array to be set from the Allocation. 1292 */ 1293 public void copyTo(int[] d) { 1294 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo"); 1295 validateIsInt32(); 1296 mRS.validate(); 1297 mRS.nAllocationRead(getID(mRS), d, Element.DataType.SIGNED_32); 1298 Trace.traceEnd(RenderScript.TRACE_TAG); 1299 } 1300 1301 /** 1302 * Copy from the Allocation into a float array. The array must be at least 1303 * as large as the Allocation. The allocation must be of an 32 bit float 1304 * {@link android.renderscript.Element} type. 1305 * 1306 * @param d The array to be set from the Allocation. 1307 */ 1308 public void copyTo(float[] d) { 1309 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo"); 1310 validateIsFloat32(); 1311 mRS.validate(); 1312 mRS.nAllocationRead(getID(mRS), d, Element.DataType.FLOAT_32); 1313 Trace.traceEnd(RenderScript.TRACE_TAG); 1314 } 1315 1316 /** 1317 * Resize a 1D allocation. The contents of the allocation are preserved. 1318 * If new elements are allocated objects are created with null contents and 1319 * the new region is otherwise undefined. 1320 * 1321 * <p>If the new region is smaller the references of any objects outside the 1322 * new region will be released.</p> 1323 * 1324 * <p>A new type will be created with the new dimension.</p> 1325 * 1326 * @param dimX The new size of the allocation. 1327 * 1328 * @deprecated RenderScript objects should be immutable once created. The 1329 * replacement is to create a new allocation and copy the contents. 1330 */ 1331 public synchronized void resize(int dimX) { 1332 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) { 1333 throw new RSInvalidStateException("Resize only support for 1D allocations at this time."); 1334 } 1335 mRS.nAllocationResize1D(getID(mRS), dimX); 1336 mRS.finish(); // Necessary because resize is fifoed and update is async. 1337 1338 long typeID = mRS.nAllocationGetType(getID(mRS)); 1339 mType = new Type(typeID, mRS); 1340 mType.updateFromNative(); 1341 updateCacheInfo(mType); 1342 } 1343 1344 1345 // creation 1346 1347 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options(); 1348 static { 1349 mBitmapOptions.inScaled = false; 1350 } 1351 1352 /** 1353 * Creates a new Allocation with the given {@link 1354 * android.renderscript.Type}, mipmap flag, and usage flags. 1355 * 1356 * @param type RenderScript type describing data layout 1357 * @param mips specifies desired mipmap behaviour for the 1358 * allocation 1359 * @param usage bit field specifying how the Allocation is 1360 * utilized 1361 */ 1362 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) { 1363 Trace.traceBegin(RenderScript.TRACE_TAG, "createTyped"); 1364 rs.validate(); 1365 if (type.getID(rs) == 0) { 1366 throw new RSInvalidStateException("Bad Type"); 1367 } 1368 long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0); 1369 if (id == 0) { 1370 throw new RSRuntimeException("Allocation creation failed."); 1371 } 1372 Trace.traceEnd(RenderScript.TRACE_TAG); 1373 return new Allocation(id, rs, type, usage); 1374 } 1375 1376 /** 1377 * Creates an Allocation with the size specified by the type and no mipmaps 1378 * generated by default 1379 * 1380 * @param rs Context to which the allocation will belong. 1381 * @param type renderscript type describing data layout 1382 * @param usage bit field specifying how the allocation is 1383 * utilized 1384 * 1385 * @return allocation 1386 */ 1387 static public Allocation createTyped(RenderScript rs, Type type, int usage) { 1388 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage); 1389 } 1390 1391 /** 1392 * Creates an Allocation for use by scripts with a given {@link 1393 * android.renderscript.Type} and no mipmaps 1394 * 1395 * @param rs Context to which the Allocation will belong. 1396 * @param type RenderScript Type describing data layout 1397 * 1398 * @return allocation 1399 */ 1400 static public Allocation createTyped(RenderScript rs, Type type) { 1401 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT); 1402 } 1403 1404 /** 1405 * Creates an Allocation with a specified number of given elements 1406 * 1407 * @param rs Context to which the Allocation will belong. 1408 * @param e Element to use in the Allocation 1409 * @param count the number of Elements in the Allocation 1410 * @param usage bit field specifying how the Allocation is 1411 * utilized 1412 * 1413 * @return allocation 1414 */ 1415 static public Allocation createSized(RenderScript rs, Element e, 1416 int count, int usage) { 1417 Trace.traceBegin(RenderScript.TRACE_TAG, "createSized"); 1418 rs.validate(); 1419 Type.Builder b = new Type.Builder(rs, e); 1420 b.setX(count); 1421 Type t = b.create(); 1422 1423 long id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0); 1424 if (id == 0) { 1425 throw new RSRuntimeException("Allocation creation failed."); 1426 } 1427 Trace.traceEnd(RenderScript.TRACE_TAG); 1428 return new Allocation(id, rs, t, usage); 1429 } 1430 1431 /** 1432 * Creates an Allocation with a specified number of given elements 1433 * 1434 * @param rs Context to which the Allocation will belong. 1435 * @param e Element to use in the Allocation 1436 * @param count the number of Elements in the Allocation 1437 * 1438 * @return allocation 1439 */ 1440 static public Allocation createSized(RenderScript rs, Element e, int count) { 1441 return createSized(rs, e, count, USAGE_SCRIPT); 1442 } 1443 1444 static Element elementFromBitmap(RenderScript rs, Bitmap b) { 1445 final Bitmap.Config bc = b.getConfig(); 1446 if (bc == Bitmap.Config.ALPHA_8) { 1447 return Element.A_8(rs); 1448 } 1449 if (bc == Bitmap.Config.ARGB_4444) { 1450 return Element.RGBA_4444(rs); 1451 } 1452 if (bc == Bitmap.Config.ARGB_8888) { 1453 return Element.RGBA_8888(rs); 1454 } 1455 if (bc == Bitmap.Config.RGB_565) { 1456 return Element.RGB_565(rs); 1457 } 1458 throw new RSInvalidStateException("Bad bitmap type: " + bc); 1459 } 1460 1461 static Type typeFromBitmap(RenderScript rs, Bitmap b, 1462 MipmapControl mip) { 1463 Element e = elementFromBitmap(rs, b); 1464 Type.Builder tb = new Type.Builder(rs, e); 1465 tb.setX(b.getWidth()); 1466 tb.setY(b.getHeight()); 1467 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL); 1468 return tb.create(); 1469 } 1470 1471 /** 1472 * Creates an Allocation from a {@link android.graphics.Bitmap}. 1473 * 1474 * @param rs Context to which the allocation will belong. 1475 * @param b Bitmap source for the allocation data 1476 * @param mips specifies desired mipmap behaviour for the 1477 * allocation 1478 * @param usage bit field specifying how the allocation is 1479 * utilized 1480 * 1481 * @return Allocation containing bitmap data 1482 * 1483 */ 1484 static public Allocation createFromBitmap(RenderScript rs, Bitmap b, 1485 MipmapControl mips, 1486 int usage) { 1487 Trace.traceBegin(RenderScript.TRACE_TAG, "createFromBitmap"); 1488 rs.validate(); 1489 1490 // WAR undocumented color formats 1491 if (b.getConfig() == null) { 1492 if ((usage & USAGE_SHARED) != 0) { 1493 throw new RSIllegalArgumentException("USAGE_SHARED cannot be used with a Bitmap that has a null config."); 1494 } 1495 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888); 1496 Canvas c = new Canvas(newBitmap); 1497 c.drawBitmap(b, 0, 0, null); 1498 return createFromBitmap(rs, newBitmap, mips, usage); 1499 } 1500 1501 Type t = typeFromBitmap(rs, b, mips); 1502 1503 // enable optimized bitmap path only with no mipmap and script-only usage 1504 if (mips == MipmapControl.MIPMAP_NONE && 1505 t.getElement().isCompatible(Element.RGBA_8888(rs)) && 1506 usage == (USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE)) { 1507 long id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage); 1508 if (id == 0) { 1509 throw new RSRuntimeException("Load failed."); 1510 } 1511 1512 // keep a reference to the Bitmap around to prevent GC 1513 Allocation alloc = new Allocation(id, rs, t, usage); 1514 alloc.setBitmap(b); 1515 return alloc; 1516 } 1517 1518 1519 long id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage); 1520 if (id == 0) { 1521 throw new RSRuntimeException("Load failed."); 1522 } 1523 Trace.traceEnd(RenderScript.TRACE_TAG); 1524 return new Allocation(id, rs, t, usage); 1525 } 1526 1527 /** 1528 * Returns the handle to a raw buffer that is being managed by the screen 1529 * compositor. This operation is only valid for Allocations with {@link 1530 * #USAGE_IO_INPUT}. 1531 * 1532 * @return Surface object associated with allocation 1533 * 1534 */ 1535 public Surface getSurface() { 1536 if ((mUsage & USAGE_IO_INPUT) == 0) { 1537 throw new RSInvalidStateException("Allocation is not a surface texture."); 1538 } 1539 return mRS.nAllocationGetSurface(getID(mRS)); 1540 } 1541 1542 /** 1543 * Associate a {@link android.view.Surface} with this Allocation. This 1544 * operation is only valid for Allocations with {@link #USAGE_IO_OUTPUT}. 1545 * 1546 * @param sur Surface to associate with allocation 1547 */ 1548 public void setSurface(Surface sur) { 1549 mRS.validate(); 1550 if ((mUsage & USAGE_IO_OUTPUT) == 0) { 1551 throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT."); 1552 } 1553 1554 mRS.nAllocationSetSurface(getID(mRS), sur); 1555 } 1556 1557 /** 1558 * Creates an Allocation from a {@link android.graphics.Bitmap}. 1559 * 1560 * <p>With target API version 18 or greater, this Allocation will be created 1561 * with {@link #USAGE_SHARED}, {@link #USAGE_SCRIPT}, and {@link 1562 * #USAGE_GRAPHICS_TEXTURE}. With target API version 17 or lower, this 1563 * Allocation will be created with {@link #USAGE_GRAPHICS_TEXTURE}.</p> 1564 * 1565 * @param rs Context to which the allocation will belong. 1566 * @param b bitmap source for the allocation data 1567 * 1568 * @return Allocation containing bitmap data 1569 * 1570 */ 1571 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) { 1572 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) { 1573 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, 1574 USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE); 1575 } 1576 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, 1577 USAGE_GRAPHICS_TEXTURE); 1578 } 1579 1580 /** 1581 * Creates a cubemap Allocation from a {@link android.graphics.Bitmap} 1582 * containing the horizontal list of cube faces. Each face must be a square, 1583 * have the same size as all other faces, and have a width that is a power 1584 * of 2. 1585 * 1586 * @param rs Context to which the allocation will belong. 1587 * @param b Bitmap with cubemap faces layed out in the following 1588 * format: right, left, top, bottom, front, back 1589 * @param mips specifies desired mipmap behaviour for the cubemap 1590 * @param usage bit field specifying how the cubemap is utilized 1591 * 1592 * @return allocation containing cubemap data 1593 * 1594 */ 1595 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b, 1596 MipmapControl mips, 1597 int usage) { 1598 rs.validate(); 1599 1600 int height = b.getHeight(); 1601 int width = b.getWidth(); 1602 1603 if (width % 6 != 0) { 1604 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6"); 1605 } 1606 if (width / 6 != height) { 1607 throw new RSIllegalArgumentException("Only square cube map faces supported"); 1608 } 1609 boolean isPow2 = (height & (height - 1)) == 0; 1610 if (!isPow2) { 1611 throw new RSIllegalArgumentException("Only power of 2 cube faces supported"); 1612 } 1613 1614 Element e = elementFromBitmap(rs, b); 1615 Type.Builder tb = new Type.Builder(rs, e); 1616 tb.setX(height); 1617 tb.setY(height); 1618 tb.setFaces(true); 1619 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL); 1620 Type t = tb.create(); 1621 1622 long id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage); 1623 if(id == 0) { 1624 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e); 1625 } 1626 return new Allocation(id, rs, t, usage); 1627 } 1628 1629 /** 1630 * Creates a non-mipmapped cubemap Allocation for use as a graphics texture 1631 * from a {@link android.graphics.Bitmap} containing the horizontal list of 1632 * cube faces. Each face must be a square, have the same size as all other 1633 * faces, and have a width that is a power of 2. 1634 * 1635 * @param rs Context to which the allocation will belong. 1636 * @param b bitmap with cubemap faces layed out in the following 1637 * format: right, left, top, bottom, front, back 1638 * 1639 * @return allocation containing cubemap data 1640 * 1641 */ 1642 static public Allocation createCubemapFromBitmap(RenderScript rs, 1643 Bitmap b) { 1644 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, 1645 USAGE_GRAPHICS_TEXTURE); 1646 } 1647 1648 /** 1649 * Creates a cubemap Allocation from 6 {@link android.graphics.Bitmap} 1650 * objects containing the cube faces. Each face must be a square, have the 1651 * same size as all other faces, and have a width that is a power of 2. 1652 * 1653 * @param rs Context to which the allocation will belong. 1654 * @param xpos cubemap face in the positive x direction 1655 * @param xneg cubemap face in the negative x direction 1656 * @param ypos cubemap face in the positive y direction 1657 * @param yneg cubemap face in the negative y direction 1658 * @param zpos cubemap face in the positive z direction 1659 * @param zneg cubemap face in the negative z direction 1660 * @param mips specifies desired mipmap behaviour for the cubemap 1661 * @param usage bit field specifying how the cubemap is utilized 1662 * 1663 * @return allocation containing cubemap data 1664 * 1665 */ 1666 static public Allocation createCubemapFromCubeFaces(RenderScript rs, 1667 Bitmap xpos, 1668 Bitmap xneg, 1669 Bitmap ypos, 1670 Bitmap yneg, 1671 Bitmap zpos, 1672 Bitmap zneg, 1673 MipmapControl mips, 1674 int usage) { 1675 int height = xpos.getHeight(); 1676 if (xpos.getWidth() != height || 1677 xneg.getWidth() != height || xneg.getHeight() != height || 1678 ypos.getWidth() != height || ypos.getHeight() != height || 1679 yneg.getWidth() != height || yneg.getHeight() != height || 1680 zpos.getWidth() != height || zpos.getHeight() != height || 1681 zneg.getWidth() != height || zneg.getHeight() != height) { 1682 throw new RSIllegalArgumentException("Only square cube map faces supported"); 1683 } 1684 boolean isPow2 = (height & (height - 1)) == 0; 1685 if (!isPow2) { 1686 throw new RSIllegalArgumentException("Only power of 2 cube faces supported"); 1687 } 1688 1689 Element e = elementFromBitmap(rs, xpos); 1690 Type.Builder tb = new Type.Builder(rs, e); 1691 tb.setX(height); 1692 tb.setY(height); 1693 tb.setFaces(true); 1694 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL); 1695 Type t = tb.create(); 1696 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage); 1697 1698 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap); 1699 adapter.setFace(Type.CubemapFace.POSITIVE_X); 1700 adapter.copyFrom(xpos); 1701 adapter.setFace(Type.CubemapFace.NEGATIVE_X); 1702 adapter.copyFrom(xneg); 1703 adapter.setFace(Type.CubemapFace.POSITIVE_Y); 1704 adapter.copyFrom(ypos); 1705 adapter.setFace(Type.CubemapFace.NEGATIVE_Y); 1706 adapter.copyFrom(yneg); 1707 adapter.setFace(Type.CubemapFace.POSITIVE_Z); 1708 adapter.copyFrom(zpos); 1709 adapter.setFace(Type.CubemapFace.NEGATIVE_Z); 1710 adapter.copyFrom(zneg); 1711 1712 return cubemap; 1713 } 1714 1715 /** 1716 * Creates a non-mipmapped cubemap Allocation for use as a sampler input 1717 * from 6 {@link android.graphics.Bitmap} objects containing the cube 1718 * faces. Each face must be a square, have the same size as all other faces, 1719 * and have a width that is a power of 2. 1720 * 1721 * @param rs Context to which the allocation will belong. 1722 * @param xpos cubemap face in the positive x direction 1723 * @param xneg cubemap face in the negative x direction 1724 * @param ypos cubemap face in the positive y direction 1725 * @param yneg cubemap face in the negative y direction 1726 * @param zpos cubemap face in the positive z direction 1727 * @param zneg cubemap face in the negative z direction 1728 * 1729 * @return allocation containing cubemap data 1730 * 1731 */ 1732 static public Allocation createCubemapFromCubeFaces(RenderScript rs, 1733 Bitmap xpos, 1734 Bitmap xneg, 1735 Bitmap ypos, 1736 Bitmap yneg, 1737 Bitmap zpos, 1738 Bitmap zneg) { 1739 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg, 1740 zpos, zneg, MipmapControl.MIPMAP_NONE, 1741 USAGE_GRAPHICS_TEXTURE); 1742 } 1743 1744 /** 1745 * Creates an Allocation from the Bitmap referenced 1746 * by resource ID. 1747 * 1748 * @param rs Context to which the allocation will belong. 1749 * @param res application resources 1750 * @param id resource id to load the data from 1751 * @param mips specifies desired mipmap behaviour for the 1752 * allocation 1753 * @param usage bit field specifying how the allocation is 1754 * utilized 1755 * 1756 * @return Allocation containing resource data 1757 * 1758 */ 1759 static public Allocation createFromBitmapResource(RenderScript rs, 1760 Resources res, 1761 int id, 1762 MipmapControl mips, 1763 int usage) { 1764 1765 rs.validate(); 1766 if ((usage & (USAGE_SHARED | USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) { 1767 throw new RSIllegalArgumentException("Unsupported usage specified."); 1768 } 1769 Bitmap b = BitmapFactory.decodeResource(res, id); 1770 Allocation alloc = createFromBitmap(rs, b, mips, usage); 1771 b.recycle(); 1772 return alloc; 1773 } 1774 1775 /** 1776 * Creates a non-mipmapped Allocation to use as a graphics texture from the 1777 * {@link android.graphics.Bitmap} referenced by resource ID. 1778 * 1779 * <p>With target API version 18 or greater, this allocation will be created 1780 * with {@link #USAGE_SCRIPT} and {@link #USAGE_GRAPHICS_TEXTURE}. With 1781 * target API version 17 or lower, this allocation will be created with 1782 * {@link #USAGE_GRAPHICS_TEXTURE}.</p> 1783 * 1784 * @param rs Context to which the allocation will belong. 1785 * @param res application resources 1786 * @param id resource id to load the data from 1787 * 1788 * @return Allocation containing resource data 1789 * 1790 */ 1791 static public Allocation createFromBitmapResource(RenderScript rs, 1792 Resources res, 1793 int id) { 1794 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) { 1795 return createFromBitmapResource(rs, res, id, 1796 MipmapControl.MIPMAP_NONE, 1797 USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE); 1798 } 1799 return createFromBitmapResource(rs, res, id, 1800 MipmapControl.MIPMAP_NONE, 1801 USAGE_GRAPHICS_TEXTURE); 1802 } 1803 1804 /** 1805 * Creates an Allocation containing string data encoded in UTF-8 format. 1806 * 1807 * @param rs Context to which the allocation will belong. 1808 * @param str string to create the allocation from 1809 * @param usage bit field specifying how the allocaiton is 1810 * utilized 1811 * 1812 */ 1813 static public Allocation createFromString(RenderScript rs, 1814 String str, 1815 int usage) { 1816 rs.validate(); 1817 byte[] allocArray = null; 1818 try { 1819 allocArray = str.getBytes("UTF-8"); 1820 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage); 1821 alloc.copyFrom(allocArray); 1822 return alloc; 1823 } 1824 catch (Exception e) { 1825 throw new RSRuntimeException("Could not convert string to utf-8."); 1826 } 1827 } 1828 1829 /** 1830 * Interface to handle notification when new buffers are available via 1831 * {@link #USAGE_IO_INPUT}. An application will receive one notification 1832 * when a buffer is available. Additional buffers will not trigger new 1833 * notifications until a buffer is processed. 1834 */ 1835 public interface OnBufferAvailableListener { 1836 public void onBufferAvailable(Allocation a); 1837 } 1838 1839 /** 1840 * Set a notification handler for {@link #USAGE_IO_INPUT}. 1841 * 1842 * @param callback instance of the OnBufferAvailableListener 1843 * class to be called when buffer arrive. 1844 */ 1845 public void setOnBufferAvailableListener(OnBufferAvailableListener callback) { 1846 synchronized(mAllocationMap) { 1847 mAllocationMap.put(new Long(getID(mRS)), this); 1848 mBufferNotifier = callback; 1849 } 1850 } 1851 1852 static void sendBufferNotification(int id) { 1853 synchronized(mAllocationMap) { 1854 Allocation a = mAllocationMap.get(new Long(id)); 1855 1856 if ((a != null) && (a.mBufferNotifier != null)) { 1857 a.mBufferNotifier.onBufferAvailable(a); 1858 } 1859 } 1860 } 1861 1862} 1863 1864