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