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