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