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 17 package android.renderscript; 18 19 import java.nio.ByteBuffer; 20 import java.util.HashMap; 21 22 import android.content.res.Resources; 23 import android.graphics.Bitmap; 24 import android.graphics.BitmapFactory; 25 import android.graphics.Canvas; 26 import android.os.Trace; 27 import android.util.Log; 28 import android.view.Surface; 29 30 /** 31 * <p> This class provides the primary method through which data is passed to 32 * and from RenderScript kernels. An Allocation provides the backing store for 33 * a given {@link android.renderscript.Type}. </p> 34 * 35 * <p>An Allocation also contains a set of usage flags that denote how the 36 * Allocation could be used. For example, an Allocation may have usage flags 37 * specifying that it can be used from a script as well as input to a {@link 38 * android.renderscript.Sampler}. A developer must synchronize across these 39 * different usages using {@link android.renderscript.Allocation#syncAll} in 40 * order to ensure that different users of the Allocation have a consistent view 41 * of memory. For example, in the case where an Allocation is used as the output 42 * of one kernel and as Sampler input in a later kernel, a developer must call 43 * {@link #syncAll syncAll(Allocation.USAGE_SCRIPT)} prior to launching the 44 * second kernel to ensure correctness. 45 * 46 * <p>An Allocation can be populated with the {@link #copyFrom} routines. For 47 * more complex Element types, the {@link #copyFromUnchecked} methods can be 48 * used to copy from byte arrays or similar constructs.</p> 49 * 50 * <div class="special reference"> 51 * <h3>Developer Guides</h3> 52 * <p>For more information about creating an application that uses RenderScript, read the 53 * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p> 54 * </div> 55 **/ 56 57 public class Allocation extends BaseObj { 58 private static final int MAX_NUMBER_IO_INPUT_ALLOC = 16; 59 60 Type mType; 61 boolean mOwningType = false; 62 Bitmap mBitmap; 63 int mUsage; 64 Allocation mAdaptedAllocation; 65 int mSize; 66 MipmapControl mMipmapControl; 67 68 long mTimeStamp = -1; 69 boolean mReadAllowed = true; 70 boolean mWriteAllowed = true; 71 boolean mAutoPadding = false; 72 int mSelectedX; 73 int mSelectedY; 74 int mSelectedZ; 75 int mSelectedLOD; 76 int mSelectedArray[]; 77 Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X; 78 79 int mCurrentDimX; 80 int mCurrentDimY; 81 int mCurrentDimZ; 82 int mCurrentCount; 83 static HashMap<Long, Allocation> mAllocationMap = 84 new HashMap<Long, Allocation>(); 85 OnBufferAvailableListener mBufferNotifier; 86 87 private Surface mGetSurfaceSurface = null; 88 private ByteBuffer mByteBuffer = null; 89 private long mByteBufferStride = -1; 90 91 private Element.DataType validateObjectIsPrimitiveArray(Object d, boolean checkType) { 92 final Class c = d.getClass(); 93 if (!c.isArray()) { 94 throw new RSIllegalArgumentException("Object passed is not an array of primitives."); 95 } 96 final Class cmp = c.getComponentType(); 97 if (!cmp.isPrimitive()) { 98 throw new RSIllegalArgumentException("Object passed is not an Array of primitives."); 99 } 100 101 if (cmp == Long.TYPE) { 102 if (checkType) { 103 validateIsInt64(); 104 return mType.mElement.mType; 105 } 106 return Element.DataType.SIGNED_64; 107 } 108 109 if (cmp == Integer.TYPE) { 110 if (checkType) { 111 validateIsInt32(); 112 return mType.mElement.mType; 113 } 114 return Element.DataType.SIGNED_32; 115 } 116 117 if (cmp == Short.TYPE) { 118 if (checkType) { 119 validateIsInt16OrFloat16(); 120 return mType.mElement.mType; 121 } 122 return Element.DataType.SIGNED_16; 123 } 124 125 if (cmp == Byte.TYPE) { 126 if (checkType) { 127 validateIsInt8(); 128 return mType.mElement.mType; 129 } 130 return Element.DataType.SIGNED_8; 131 } 132 133 if (cmp == Float.TYPE) { 134 if (checkType) { 135 validateIsFloat32(); 136 } 137 return Element.DataType.FLOAT_32; 138 } 139 140 if (cmp == Double.TYPE) { 141 if (checkType) { 142 validateIsFloat64(); 143 } 144 return Element.DataType.FLOAT_64; 145 } 146 147 throw new RSIllegalArgumentException("Parameter of type " + cmp.getSimpleName() + 148 "[] is not compatible with data type " + mType.mElement.mType.name() + 149 " of allocation"); 150 } 151 152 153 /** 154 * The usage of the Allocation. These signal to RenderScript where to place 155 * the Allocation in memory. 156 * 157 */ 158 159 /** 160 * The Allocation will be bound to and accessed by scripts. 161 */ 162 public static final int USAGE_SCRIPT = 0x0001; 163 164 /** 165 * The Allocation will be used as a texture source by one or more graphics 166 * programs. 167 * 168 */ 169 public static final int USAGE_GRAPHICS_TEXTURE = 0x0002; 170 171 /** 172 * The Allocation will be used as a graphics mesh. 173 * 174 * This was deprecated in API level 16. 175 * 176 */ 177 public static final int USAGE_GRAPHICS_VERTEX = 0x0004; 178 179 180 /** 181 * The Allocation will be used as the source of shader constants by one or 182 * more programs. 183 * 184 * This was deprecated in API level 16. 185 * 186 */ 187 public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008; 188 189 /** 190 * The Allocation will be used as a target for offscreen rendering 191 * 192 * This was deprecated in API level 16. 193 * 194 */ 195 public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010; 196 197 /** 198 * The Allocation will be used as a {@link android.view.Surface} 199 * consumer. This usage will cause the Allocation to be created 200 * as read-only. 201 * 202 */ 203 public static final int USAGE_IO_INPUT = 0x0020; 204 205 /** 206 * The Allocation will be used as a {@link android.view.Surface} 207 * producer. The dimensions and format of the {@link 208 * android.view.Surface} will be forced to those of the 209 * Allocation. 210 * 211 */ 212 public static final int USAGE_IO_OUTPUT = 0x0040; 213 214 /** 215 * The Allocation's backing store will be inherited from another object 216 * (usually a {@link android.graphics.Bitmap}); copying to or from the 217 * original source Bitmap will cause a synchronization rather than a full 218 * copy. {@link #syncAll} may also be used to synchronize the Allocation 219 * and the source Bitmap. 220 * 221 * <p>This is set by default for allocations created with {@link 222 * #createFromBitmap} in API version 18 and higher.</p> 223 * 224 */ 225 public static final int USAGE_SHARED = 0x0080; 226 227 /** 228 * Controls mipmap behavior when using the bitmap creation and update 229 * functions. 230 */ 231 public enum MipmapControl { 232 /** 233 * No mipmaps will be generated and the type generated from the incoming 234 * bitmap will not contain additional LODs. 235 */ 236 MIPMAP_NONE(0), 237 238 /** 239 * A full mipmap chain will be created in script memory. The Type of 240 * the Allocation will contain a full mipmap chain. On upload, the full 241 * chain will be transferred. 242 */ 243 MIPMAP_FULL(1), 244 245 /** 246 * The Type of the Allocation will be the same as MIPMAP_NONE. It will 247 * not contain mipmaps. On upload, the allocation data will contain a 248 * full mipmap chain generated from the top level in script memory. 249 */ 250 MIPMAP_ON_SYNC_TO_TEXTURE(2); 251 252 int mID; 253 MipmapControl(int id) { 254 mID = id; 255 } 256 } 257 258 259 private long getIDSafe() { 260 if (mAdaptedAllocation != null) { 261 return mAdaptedAllocation.getID(mRS); 262 } 263 return getID(mRS); 264 } 265 266 267 /** 268 * Get the {@link android.renderscript.Element} of the {@link 269 * android.renderscript.Type} of the Allocation. 270 * 271 * @return Element 272 * 273 */ 274 public Element getElement() { 275 return mType.getElement(); 276 } 277 278 /** 279 * Get the usage flags of the Allocation. 280 * 281 * @return usage this Allocation's set of the USAGE_* flags OR'd together 282 * 283 */ 284 public int getUsage() { 285 return mUsage; 286 } 287 288 /** 289 * @hide 290 * Get the Mipmap control flag of the Allocation. 291 * 292 * @return the Mipmap control flag of the Allocation 293 * 294 */ 295 public MipmapControl getMipmap() { 296 return mMipmapControl; 297 } 298 299 /** 300 * Specifies the mapping between the Allocation's cells and an array's elements 301 * when data is copied from the Allocation to the array, or vice-versa. 302 * 303 * Only applies to an Allocation whose Element is a vector of length 3 (such as 304 * {@link Element#U8_3} or {@link Element#RGB_888}). Enabling this feature may make 305 * copying data from the Allocation to an array or vice-versa less efficient. 306 * 307 * <p> Vec3 Element cells are stored in an Allocation as Vec4 Element cells with 308 * the same {@link android.renderscript.Element.DataType}, with the fourth vector 309 * component treated as padding. When this feature is enabled, only the data components, 310 * i.e. the first 3 vector components of each cell, will be mapped between the array 311 * and the Allocation. When disabled, explicit mapping of the padding components 312 * is required, as described in the following example. 313 * 314 * <p> For example, when copying an integer array to an Allocation of two {@link 315 * Element#I32_3} cells using {@link #copyFrom(int[])}: 316 * <p> When disabled: 317 * The array must have at least 8 integers, with the first 4 integers copied 318 * to the first cell of the Allocation, and the next 4 integers copied to 319 * the second cell. The 4th and 8th integers are mapped as the padding components. 320 * 321 * <p> When enabled: 322 * The array just needs to have at least 6 integers, with the first 3 integers 323 * copied to the the first cell as data components, and the next 3 copied to 324 * the second cell. There is no mapping for the padding components. 325 * 326 * <p> Similarly, when copying a byte array to an Allocation of two {@link 327 * Element#I32_3} cells, using {@link #copyFromUnchecked(int[])}: 328 * <p> When disabled: 329 * The array must have at least 32 bytes, with the first 16 bytes copied 330 * to the first cell of the Allocation, and the next 16 bytes copied to 331 * the second cell. The 13th-16th and 29th-32nd bytes are mapped as padding 332 * components. 333 * 334 * <p> When enabled: 335 * The array just needs to have at least 24 bytes, with the first 12 bytes copied 336 * to the first cell of the Allocation, and the next 12 bytes copied to 337 * the second cell. There is no mapping for the padding components. 338 * 339 * <p> Similar to copying data to an Allocation from an array, when copying data from an 340 * Allocation to an array, the padding components for Vec3 Element cells will not be 341 * copied/mapped to the array if AutoPadding is enabled. 342 * 343 * <p> Default: Disabled. 344 * 345 * @param useAutoPadding True: enable AutoPadding; False: disable AutoPadding 346 * 347 */ 348 public void setAutoPadding(boolean useAutoPadding) { 349 mAutoPadding = useAutoPadding; 350 } 351 352 /** 353 * Get the size of the Allocation in bytes. 354 * 355 * @return size of the Allocation in bytes. 356 * 357 */ 358 public int getBytesSize() { 359 if (mType.mDimYuv != 0) { 360 return (int)Math.ceil(mType.getCount() * mType.getElement().getBytesSize() * 1.5); 361 } 362 return mType.getCount() * mType.getElement().getBytesSize(); 363 } 364 365 private void updateCacheInfo(Type t) { 366 mCurrentDimX = t.getX(); 367 mCurrentDimY = t.getY(); 368 mCurrentDimZ = t.getZ(); 369 mCurrentCount = mCurrentDimX; 370 if (mCurrentDimY > 1) { 371 mCurrentCount *= mCurrentDimY; 372 } 373 if (mCurrentDimZ > 1) { 374 mCurrentCount *= mCurrentDimZ; 375 } 376 } 377 378 private void setBitmap(Bitmap b) { 379 mBitmap = b; 380 } 381 382 Allocation(long id, RenderScript rs, Type t, int usage) { 383 super(id, rs); 384 if ((usage & ~(USAGE_SCRIPT | 385 USAGE_GRAPHICS_TEXTURE | 386 USAGE_GRAPHICS_VERTEX | 387 USAGE_GRAPHICS_CONSTANTS | 388 USAGE_GRAPHICS_RENDER_TARGET | 389 USAGE_IO_INPUT | 390 USAGE_IO_OUTPUT | 391 USAGE_SHARED)) != 0) { 392 throw new RSIllegalArgumentException("Unknown usage specified."); 393 } 394 395 if ((usage & USAGE_IO_INPUT) != 0) { 396 mWriteAllowed = false; 397 398 if ((usage & ~(USAGE_IO_INPUT | 399 USAGE_GRAPHICS_TEXTURE | 400 USAGE_SCRIPT)) != 0) { 401 throw new RSIllegalArgumentException("Invalid usage combination."); 402 } 403 } 404 405 mType = t; 406 mUsage = usage; 407 408 if (t != null) { 409 // TODO: A3D doesn't have Type info during creation, so we can't 410 // calculate the size ahead of time. We can possibly add a method 411 // to update the size in the future if it seems reasonable. 412 mSize = mType.getCount() * mType.getElement().getBytesSize(); 413 updateCacheInfo(t); 414 } 415 try { 416 RenderScript.registerNativeAllocation.invoke(RenderScript.sRuntime, mSize); 417 } catch (Exception e) { 418 Log.e(RenderScript.LOG_TAG, "Couldn't invoke registerNativeAllocation:" + e); 419 throw new RSRuntimeException("Couldn't invoke registerNativeAllocation:" + e); 420 } 421 guard.open("destroy"); 422 } 423 424 Allocation(long id, RenderScript rs, Type t, boolean owningType, int usage, MipmapControl mips) { 425 this(id, rs, t, usage); 426 mOwningType = owningType; 427 mMipmapControl = mips; 428 } 429 430 protected void finalize() throws Throwable { 431 RenderScript.registerNativeFree.invoke(RenderScript.sRuntime, mSize); 432 super.finalize(); 433 } 434 435 private void validateIsInt64() { 436 if ((mType.mElement.mType == Element.DataType.SIGNED_64) || 437 (mType.mElement.mType == Element.DataType.UNSIGNED_64)) { 438 return; 439 } 440 throw new RSIllegalArgumentException( 441 "64 bit integer source does not match allocation type " + mType.mElement.mType); 442 } 443 444 private void validateIsInt32() { 445 if ((mType.mElement.mType == Element.DataType.SIGNED_32) || 446 (mType.mElement.mType == Element.DataType.UNSIGNED_32)) { 447 return; 448 } 449 throw new RSIllegalArgumentException( 450 "32 bit integer source does not match allocation type " + mType.mElement.mType); 451 } 452 453 private void validateIsInt16OrFloat16() { 454 if ((mType.mElement.mType == Element.DataType.SIGNED_16) || 455 (mType.mElement.mType == Element.DataType.UNSIGNED_16) || 456 (mType.mElement.mType == Element.DataType.FLOAT_16)) { 457 return; 458 } 459 throw new RSIllegalArgumentException( 460 "16 bit integer source does not match allocation type " + mType.mElement.mType); 461 } 462 463 private void validateIsInt8() { 464 if ((mType.mElement.mType == Element.DataType.SIGNED_8) || 465 (mType.mElement.mType == Element.DataType.UNSIGNED_8)) { 466 return; 467 } 468 throw new RSIllegalArgumentException( 469 "8 bit integer source does not match allocation type " + mType.mElement.mType); 470 } 471 472 private void validateIsFloat32() { 473 if (mType.mElement.mType == Element.DataType.FLOAT_32) { 474 return; 475 } 476 throw new RSIllegalArgumentException( 477 "32 bit float source does not match allocation type " + mType.mElement.mType); 478 } 479 480 private void validateIsFloat64() { 481 if (mType.mElement.mType == Element.DataType.FLOAT_64) { 482 return; 483 } 484 throw new RSIllegalArgumentException( 485 "64 bit float source does not match allocation type " + mType.mElement.mType); 486 } 487 488 private void validateIsObject() { 489 if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) || 490 (mType.mElement.mType == Element.DataType.RS_TYPE) || 491 (mType.mElement.mType == Element.DataType.RS_ALLOCATION) || 492 (mType.mElement.mType == Element.DataType.RS_SAMPLER) || 493 (mType.mElement.mType == Element.DataType.RS_SCRIPT) || 494 (mType.mElement.mType == Element.DataType.RS_MESH) || 495 (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) || 496 (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) || 497 (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) || 498 (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) { 499 return; 500 } 501 throw new RSIllegalArgumentException( 502 "Object source does not match allocation type " + mType.mElement.mType); 503 } 504 505 @Override 506 void updateFromNative() { 507 super.updateFromNative(); 508 long typeID = mRS.nAllocationGetType(getID(mRS)); 509 if(typeID != 0) { 510 mType = new Type(typeID, mRS); 511 mType.updateFromNative(); 512 updateCacheInfo(mType); 513 } 514 } 515 516 /** 517 * Get the {@link android.renderscript.Type} of the Allocation. 518 * 519 * @return Type 520 * 521 */ 522 public Type getType() { 523 return mType; 524 } 525 526 /** 527 * Propagate changes from one usage of the Allocation to the 528 * other usages of the Allocation. 529 * 530 */ 531 public void syncAll(int srcLocation) { 532 try { 533 Trace.traceBegin(RenderScript.TRACE_TAG, "syncAll"); 534 switch (srcLocation) { 535 case USAGE_GRAPHICS_TEXTURE: 536 case USAGE_SCRIPT: 537 if ((mUsage & USAGE_SHARED) != 0) { 538 copyFrom(mBitmap); 539 } 540 break; 541 case USAGE_GRAPHICS_CONSTANTS: 542 case USAGE_GRAPHICS_VERTEX: 543 break; 544 case USAGE_SHARED: 545 if ((mUsage & USAGE_SHARED) != 0) { 546 copyTo(mBitmap); 547 } 548 break; 549 default: 550 throw new RSIllegalArgumentException("Source must be exactly one usage type."); 551 } 552 mRS.validate(); 553 mRS.nAllocationSyncAll(getIDSafe(), srcLocation); 554 } finally { 555 Trace.traceEnd(RenderScript.TRACE_TAG); 556 } 557 } 558 559 /** 560 * Send a buffer to the output stream. The contents of the Allocation will 561 * be undefined after this operation. This operation is only valid if {@link 562 * #USAGE_IO_OUTPUT} is set on the Allocation. 563 * 564 * 565 */ 566 public void ioSend() { 567 try { 568 Trace.traceBegin(RenderScript.TRACE_TAG, "ioSend"); 569 if ((mUsage & USAGE_IO_OUTPUT) == 0) { 570 throw new RSIllegalArgumentException( 571 "Can only send buffer if IO_OUTPUT usage specified."); 572 } 573 mRS.validate(); 574 mRS.nAllocationIoSend(getID(mRS)); 575 } finally { 576 Trace.traceEnd(RenderScript.TRACE_TAG); 577 } 578 } 579 580 /** 581 * Receive the latest input into the Allocation. This operation 582 * is only valid if {@link #USAGE_IO_INPUT} is set on the Allocation. 583 * 584 */ 585 public void ioReceive() { 586 try { 587 Trace.traceBegin(RenderScript.TRACE_TAG, "ioReceive"); 588 if ((mUsage & USAGE_IO_INPUT) == 0) { 589 throw new RSIllegalArgumentException( 590 "Can only receive if IO_INPUT usage specified."); 591 } 592 mRS.validate(); 593 mTimeStamp = mRS.nAllocationIoReceive(getID(mRS)); 594 } finally { 595 Trace.traceEnd(RenderScript.TRACE_TAG); 596 } 597 } 598 599 /** 600 * Copy an array of RS objects to the Allocation. 601 * 602 * @param d Source array. 603 */ 604 public void copyFrom(BaseObj[] d) { 605 try { 606 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); 607 mRS.validate(); 608 validateIsObject(); 609 if (d.length != mCurrentCount) { 610 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " + 611 mCurrentCount + ", array length = " + d.length); 612 } 613 614 if (RenderScript.sPointerSize == 8) { 615 long i[] = new long[d.length * 4]; 616 for (int ct=0; ct < d.length; ct++) { 617 i[ct * 4] = d[ct].getID(mRS); 618 } 619 copy1DRangeFromUnchecked(0, mCurrentCount, i); 620 } else { 621 int i[] = new int[d.length]; 622 for (int ct=0; ct < d.length; ct++) { 623 i[ct] = (int) d[ct].getID(mRS); 624 } 625 copy1DRangeFromUnchecked(0, mCurrentCount, i); 626 } 627 } finally { 628 Trace.traceEnd(RenderScript.TRACE_TAG); 629 } 630 } 631 632 private void validateBitmapFormat(Bitmap b) { 633 Bitmap.Config bc = b.getConfig(); 634 if (bc == null) { 635 throw new RSIllegalArgumentException("Bitmap has an unsupported format for this operation"); 636 } 637 switch (bc) { 638 case ALPHA_8: 639 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) { 640 throw new RSIllegalArgumentException("Allocation kind is " + 641 mType.getElement().mKind + ", type " + 642 mType.getElement().mType + 643 " of " + mType.getElement().getBytesSize() + 644 " bytes, passed bitmap was " + bc); 645 } 646 break; 647 case ARGB_8888: 648 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) || 649 (mType.getElement().getBytesSize() != 4)) { 650 throw new RSIllegalArgumentException("Allocation kind is " + 651 mType.getElement().mKind + ", type " + 652 mType.getElement().mType + 653 " of " + mType.getElement().getBytesSize() + 654 " bytes, passed bitmap was " + bc); 655 } 656 break; 657 case RGB_565: 658 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) || 659 (mType.getElement().getBytesSize() != 2)) { 660 throw new RSIllegalArgumentException("Allocation kind is " + 661 mType.getElement().mKind + ", type " + 662 mType.getElement().mType + 663 " of " + mType.getElement().getBytesSize() + 664 " bytes, passed bitmap was " + bc); 665 } 666 break; 667 case ARGB_4444: 668 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) || 669 (mType.getElement().getBytesSize() != 2)) { 670 throw new RSIllegalArgumentException("Allocation kind is " + 671 mType.getElement().mKind + ", type " + 672 mType.getElement().mType + 673 " of " + mType.getElement().getBytesSize() + 674 " bytes, passed bitmap was " + bc); 675 } 676 break; 677 678 } 679 } 680 681 private void validateBitmapSize(Bitmap b) { 682 if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) { 683 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch"); 684 } 685 } 686 687 private void copyFromUnchecked(Object array, Element.DataType dt, int arrayLen) { 688 try { 689 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked"); 690 mRS.validate(); 691 if (mCurrentDimZ > 0) { 692 copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, array, dt, arrayLen); 693 } else if (mCurrentDimY > 0) { 694 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, array, dt, arrayLen); 695 } else { 696 copy1DRangeFromUnchecked(0, mCurrentCount, array, dt, arrayLen); 697 } 698 } finally { 699 Trace.traceEnd(RenderScript.TRACE_TAG); 700 } 701 } 702 703 704 /** 705 * Copy into this Allocation from an array. This method does not guarantee 706 * that the Allocation is compatible with the input buffer; it copies memory 707 * without reinterpretation. 708 * 709 * <p> If the Allocation does not have Vec3 Elements, then the size of the 710 * array in bytes must be at least the size of the Allocation {@link 711 * #getBytesSize getBytesSize()}. 712 * 713 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 714 * is disabled, then the size of the array in bytes must be at least the size 715 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 716 * the cells must be part of the array. 717 * 718 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 719 * is enabled, then the size of the array in bytes must be at least 3/4 the size 720 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 721 * the cells must not be part of the array. 722 * 723 * @param array The source array 724 */ 725 public void copyFromUnchecked(Object array) { 726 try { 727 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked"); 728 copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, false), 729 java.lang.reflect.Array.getLength(array)); 730 } finally { 731 Trace.traceEnd(RenderScript.TRACE_TAG); 732 } 733 } 734 735 /** 736 * Copy into this Allocation from an array. This method does not guarantee 737 * that the Allocation is compatible with the input buffer; it copies memory 738 * without reinterpretation. 739 * 740 * <p> If the Allocation does not have Vec3 Elements, then the size of the 741 * array in bytes must be at least the size of the Allocation {@link 742 * #getBytesSize getBytesSize()}. 743 * 744 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 745 * is disabled, then the size of the array in bytes must be at least the size 746 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 747 * the cells must be part of the array. 748 * 749 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 750 * is enabled, then the size of the array in bytes must be at least 3/4 the size 751 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 752 * the cells must not be part of the array. 753 * 754 * @param d the source array 755 */ 756 public void copyFromUnchecked(int[] d) { 757 copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length); 758 } 759 760 /** 761 * Copy into this Allocation from an array. This method does not guarantee 762 * that the Allocation is compatible with the input buffer; it copies memory 763 * without reinterpretation. 764 * 765 * <p> If the Allocation does not have Vec3 Elements, then the size of the 766 * array in bytes must be at least the size of the Allocation {@link 767 * #getBytesSize getBytesSize()}. 768 * 769 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 770 * is disabled, then the size of the array in bytes must be at least the size 771 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 772 * the cells must be part of the array. 773 * 774 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 775 * is enabled, then the size of the array in bytes must be at least 3/4 the size 776 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 777 * the cells must not be part of the array. 778 * 779 * @param d the source array 780 */ 781 public void copyFromUnchecked(short[] d) { 782 copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length); 783 } 784 785 /** 786 * Copy into this Allocation from an array. This method does not guarantee 787 * that the Allocation is compatible with the input buffer; it copies memory 788 * without reinterpretation. 789 * 790 * <p> If the Allocation does not have Vec3 Elements, then the size of the 791 * array in bytes must be at least the size of the Allocation {@link 792 * #getBytesSize getBytesSize()}. 793 * 794 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 795 * is disabled, then the size of the array in bytes must be at least the size 796 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 797 * the cells must be part of the array. 798 * 799 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 800 * is enabled, then the size of the array in bytes must be at least 3/4 the size 801 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 802 * the cells must not be part of the array. 803 * 804 * @param d the source array 805 */ 806 public void copyFromUnchecked(byte[] d) { 807 copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length); 808 } 809 810 /** 811 * Copy into this Allocation from an array. This method does not guarantee 812 * that the Allocation is compatible with the input buffer; it copies memory 813 * without reinterpretation. 814 * 815 * <p> If the Allocation does not have Vec3 Elements, then the size of the 816 * array in bytes must be at least the size of the Allocation {@link 817 * #getBytesSize getBytesSize()}. 818 * 819 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 820 * is disabled, then the size of the array in bytes must be at least the size 821 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 822 * the cells must be part of the array. 823 * 824 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 825 * is enabled, then the size of the array in bytes must be at least 3/4 the size 826 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 827 * the cells must not be part of the array. 828 * 829 * @param d the source array 830 */ 831 public void copyFromUnchecked(float[] d) { 832 copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length); 833 } 834 835 836 /** 837 * Copy into this Allocation from an array. This variant is type checked 838 * and will generate exceptions if the Allocation's {@link 839 * android.renderscript.Element} does not match the array's 840 * primitive type. 841 * 842 * <p> If the Allocation does not have Vec3 Elements, then the size of the 843 * array in bytes must be at least the size of the Allocation {@link 844 * #getBytesSize getBytesSize()}. 845 * 846 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 847 * is disabled, then the size of the array in bytes must be at least the size 848 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 849 * the cells must be part of the array. 850 * 851 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 852 * is enabled, then the size of the array in bytes must be at least 3/4 the size 853 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 854 * the cells must not be part of the array. 855 * 856 * @param array The source array 857 */ 858 public void copyFrom(Object array) { 859 try { 860 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); 861 copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, true), 862 java.lang.reflect.Array.getLength(array)); 863 } finally { 864 Trace.traceEnd(RenderScript.TRACE_TAG); 865 } 866 } 867 868 /** 869 * Copy into this Allocation from an array. This variant is type checked 870 * and will generate exceptions if the Allocation's {@link 871 * android.renderscript.Element} is not a 32 bit integer nor a vector of 32 bit 872 * integers {@link android.renderscript.Element.DataType}. 873 * 874 * <p> If the Allocation does not have Vec3 Elements, then the size of the 875 * array in bytes must be at least the size of the Allocation {@link 876 * #getBytesSize getBytesSize()}. 877 * 878 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 879 * is disabled, then the size of the array in bytes must be at least the size 880 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 881 * the cells must be part of the array. 882 * 883 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 884 * is enabled, then the size of the array in bytes must be at least 3/4 the size 885 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 886 * the cells must not be part of the array. 887 * 888 * @param d the source array 889 */ 890 public void copyFrom(int[] d) { 891 validateIsInt32(); 892 copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length); 893 } 894 895 /** 896 * Copy into this Allocation from an array. This variant is type checked 897 * and will generate exceptions if the Allocation's {@link 898 * android.renderscript.Element} is not a 16 bit integer nor a vector of 16 bit 899 * integers {@link android.renderscript.Element.DataType}. 900 * 901 * <p> If the Allocation does not have Vec3 Elements, then the size of the 902 * array in bytes must be at least the size of the Allocation {@link 903 * #getBytesSize getBytesSize()}. 904 * 905 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 906 * is disabled, then the size of the array in bytes must be at least the size 907 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 908 * the cells must be part of the array. 909 * 910 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 911 * is enabled, then the size of the array in bytes must be at least 3/4 the size 912 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 913 * the cells must not be part of the array. 914 * 915 * @param d the source array 916 */ 917 public void copyFrom(short[] d) { 918 validateIsInt16OrFloat16(); 919 copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length); 920 } 921 922 /** 923 * Copy into this Allocation from an array. This variant is type checked 924 * and will generate exceptions if the Allocation's {@link 925 * android.renderscript.Element} is not an 8 bit integer nor a vector of 8 bit 926 * integers {@link android.renderscript.Element.DataType}. 927 * 928 * <p> If the Allocation does not have Vec3 Elements, then the size of the 929 * array in bytes must be at least the size of the Allocation {@link 930 * #getBytesSize getBytesSize()}. 931 * 932 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 933 * is disabled, then the size of the array in bytes must be at least the size 934 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 935 * the cells must be part of the array. 936 * 937 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 938 * is enabled, then the size of the array in bytes must be at least 3/4 the size 939 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 940 * the cells must not be part of the array. 941 * 942 * @param d the source array 943 */ 944 public void copyFrom(byte[] d) { 945 validateIsInt8(); 946 copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length); 947 } 948 949 /** 950 * Copy into this Allocation from an array. This variant is type checked 951 * and will generate exceptions if the Allocation's {@link 952 * android.renderscript.Element} is neither a 32 bit float nor a vector of 953 * 32 bit floats {@link android.renderscript.Element.DataType}. 954 * 955 * <p> If the Allocation does not have Vec3 Elements, then the size of the 956 * array in bytes must be at least the size of the Allocation {@link 957 * #getBytesSize getBytesSize()}. 958 * 959 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 960 * is disabled, then the size of the array in bytes must be at least the size 961 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 962 * the cells must be part of the array. 963 * 964 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 965 * is enabled, then the size of the array in bytes must be at least 3/4 the size 966 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 967 * the cells must not be part of the array. 968 * 969 * @param d the source array 970 */ 971 public void copyFrom(float[] d) { 972 validateIsFloat32(); 973 copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length); 974 } 975 976 /** 977 * Copy into an Allocation from a {@link android.graphics.Bitmap}. The 978 * height, width, and format of the bitmap must match the existing 979 * allocation. 980 * 981 * <p>If the {@link android.graphics.Bitmap} is the same as the {@link 982 * android.graphics.Bitmap} used to create the Allocation with {@link 983 * #createFromBitmap} and {@link #USAGE_SHARED} is set on the Allocation, 984 * this will synchronize the Allocation with the latest data from the {@link 985 * android.graphics.Bitmap}, potentially avoiding the actual copy.</p> 986 * 987 * @param b the source bitmap 988 */ 989 public void copyFrom(Bitmap b) { 990 try { 991 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); 992 mRS.validate(); 993 if (b.getConfig() == null) { 994 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888); 995 Canvas c = new Canvas(newBitmap); 996 c.drawBitmap(b, 0, 0, null); 997 copyFrom(newBitmap); 998 return; 999 } 1000 validateBitmapSize(b); 1001 validateBitmapFormat(b); 1002 mRS.nAllocationCopyFromBitmap(getID(mRS), b); 1003 } finally { 1004 Trace.traceEnd(RenderScript.TRACE_TAG); 1005 } 1006 } 1007 1008 /** 1009 * Copy an Allocation from an Allocation. The types of both allocations 1010 * must be identical. 1011 * 1012 * @param a the source allocation 1013 */ 1014 public void copyFrom(Allocation a) { 1015 try { 1016 Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom"); 1017 mRS.validate(); 1018 if (!mType.equals(a.getType())) { 1019 throw new RSIllegalArgumentException("Types of allocations must match."); 1020 } 1021 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0); 1022 } finally { 1023 Trace.traceEnd(RenderScript.TRACE_TAG); 1024 } 1025 } 1026 1027 /** 1028 * This is only intended to be used by auto-generated code reflected from 1029 * the RenderScript script files and should not be used by developers. 1030 * 1031 * @param xoff 1032 * @param fp 1033 */ 1034 public void setFromFieldPacker(int xoff, FieldPacker fp) { 1035 mRS.validate(); 1036 int eSize = mType.mElement.getBytesSize(); 1037 final byte[] data = fp.getData(); 1038 int data_length = fp.getPos(); 1039 1040 int count = data_length / eSize; 1041 if ((eSize * count) != data_length) { 1042 throw new RSIllegalArgumentException("Field packer length " + data_length + 1043 " not divisible by element size " + eSize + "."); 1044 } 1045 copy1DRangeFromUnchecked(xoff, count, data); 1046 } 1047 1048 1049 /** 1050 * This is only intended to be used by auto-generated code reflected from 1051 * the RenderScript script files and should not be used by developers. 1052 * 1053 * @param xoff 1054 * @param component_number 1055 * @param fp 1056 */ 1057 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) { 1058 setFromFieldPacker(xoff, 0, 0, component_number, fp); 1059 } 1060 1061 /** 1062 * This is only intended to be used by auto-generated code reflected from 1063 * the RenderScript script files and should not be used by developers. 1064 * 1065 * @param xoff 1066 * @param yoff 1067 * @param zoff 1068 * @param component_number 1069 * @param fp 1070 */ 1071 public void setFromFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) { 1072 mRS.validate(); 1073 if (component_number >= mType.mElement.mElements.length) { 1074 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range."); 1075 } 1076 if(xoff < 0) { 1077 throw new RSIllegalArgumentException("Offset x must be >= 0."); 1078 } 1079 if(yoff < 0) { 1080 throw new RSIllegalArgumentException("Offset y must be >= 0."); 1081 } 1082 if(zoff < 0) { 1083 throw new RSIllegalArgumentException("Offset z must be >= 0."); 1084 } 1085 1086 final byte[] data = fp.getData(); 1087 int data_length = fp.getPos(); 1088 int eSize = mType.mElement.mElements[component_number].getBytesSize(); 1089 eSize *= mType.mElement.mArraySizes[component_number]; 1090 1091 if (data_length != eSize) { 1092 throw new RSIllegalArgumentException("Field packer sizelength " + data_length + 1093 " does not match component size " + eSize + "."); 1094 } 1095 1096 mRS.nAllocationElementData(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, 1097 component_number, data, data_length); 1098 } 1099 1100 private void data1DChecks(int off, int count, int len, int dataSize, boolean usePadding) { 1101 mRS.validate(); 1102 if(off < 0) { 1103 throw new RSIllegalArgumentException("Offset must be >= 0."); 1104 } 1105 if(count < 1) { 1106 throw new RSIllegalArgumentException("Count must be >= 1."); 1107 } 1108 if((off + count) > mCurrentCount) { 1109 throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount + 1110 ", got " + count + " at offset " + off + "."); 1111 } 1112 if(usePadding) { 1113 if(len < dataSize / 4 * 3) { 1114 throw new RSIllegalArgumentException("Array too small for allocation type."); 1115 } 1116 } else { 1117 if(len < dataSize) { 1118 throw new RSIllegalArgumentException("Array too small for allocation type."); 1119 } 1120 } 1121 } 1122 1123 /** 1124 * Generate a mipmap chain. This is only valid if the Type of the Allocation 1125 * includes mipmaps. 1126 * 1127 * <p>This function will generate a complete set of mipmaps from the top 1128 * level LOD and place them into the script memory space.</p> 1129 * 1130 * <p>If the Allocation is also using other memory spaces, a call to {@link 1131 * #syncAll syncAll(Allocation.USAGE_SCRIPT)} is required.</p> 1132 */ 1133 public void generateMipmaps() { 1134 mRS.nAllocationGenerateMipmaps(getID(mRS)); 1135 } 1136 1137 private void copy1DRangeFromUnchecked(int off, int count, Object array, 1138 Element.DataType dt, int arrayLen) { 1139 try { 1140 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked"); 1141 final int dataSize = mType.mElement.getBytesSize() * count; 1142 // AutoPadding for Vec3 Element 1143 boolean usePadding = false; 1144 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) { 1145 usePadding = true; 1146 } 1147 data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding); 1148 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt, 1149 mType.mElement.mType.mSize, usePadding); 1150 } finally { 1151 Trace.traceEnd(RenderScript.TRACE_TAG); 1152 } 1153 } 1154 1155 1156 /** 1157 * Copy an array into a 1D region of this Allocation. This method does not 1158 * guarantee that the Allocation is compatible with the input buffer. 1159 * 1160 * <p> The size of the region is: count * {@link #getElement}.{@link 1161 * Element#getBytesSize}. 1162 * 1163 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1164 * array in bytes must be at least the size of the region. 1165 * 1166 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1167 * is disabled, then the size of the array in bytes must be at least the size 1168 * of the region. The padding bytes for the cells must be part of the array. 1169 * 1170 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1171 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1172 * of the region. The padding bytes for the cells must not be part of the array. 1173 * 1174 * @param off The offset of the first element to be copied. 1175 * @param count The number of elements to be copied. 1176 * @param array The source array 1177 */ 1178 public void copy1DRangeFromUnchecked(int off, int count, Object array) { 1179 copy1DRangeFromUnchecked(off, count, array, 1180 validateObjectIsPrimitiveArray(array, false), 1181 java.lang.reflect.Array.getLength(array)); 1182 } 1183 1184 /** 1185 * Copy an array into a 1D region of this Allocation. This method does not 1186 * guarantee that the Allocation is compatible with the input buffer. 1187 * 1188 * <p> The size of the region is: count * {@link #getElement}.{@link 1189 * Element#getBytesSize}. 1190 * 1191 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1192 * array in bytes must be at least the size of the region. 1193 * 1194 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1195 * is disabled, then the size of the array in bytes must be at least the size 1196 * of the region. The padding bytes for the cells must be part of the array. 1197 * 1198 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1199 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1200 * of the region. The padding bytes for the cells must not be part of the array. 1201 * 1202 * @param off The offset of the first element to be copied. 1203 * @param count The number of elements to be copied. 1204 * @param d the source array 1205 */ 1206 public void copy1DRangeFromUnchecked(int off, int count, int[] d) { 1207 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length); 1208 } 1209 1210 /** 1211 * Copy an array into a 1D region of this Allocation. This method does not 1212 * guarantee that the Allocation is compatible with the input buffer. 1213 * 1214 * <p> The size of the region is: count * {@link #getElement}.{@link 1215 * Element#getBytesSize}. 1216 * 1217 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1218 * array in bytes must be at least the size of the region. 1219 * 1220 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1221 * is disabled, then the size of the array in bytes must be at least the size 1222 * of the region. The padding bytes for the cells must be part of the array. 1223 * 1224 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1225 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1226 * of the region. The padding bytes for the cells must not be part of the array. 1227 * 1228 * @param off The offset of the first element to be copied. 1229 * @param count The number of elements to be copied. 1230 * @param d the source array 1231 */ 1232 public void copy1DRangeFromUnchecked(int off, int count, short[] d) { 1233 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length); 1234 } 1235 1236 /** 1237 * Copy an array into a 1D region of this Allocation. This method does not 1238 * guarantee that the Allocation is compatible with the input buffer. 1239 * 1240 * <p> The size of the region is: count * {@link #getElement}.{@link 1241 * Element#getBytesSize}. 1242 * 1243 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1244 * array in bytes must be at least the size of the region. 1245 * 1246 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1247 * is disabled, then the size of the array in bytes must be at least the size 1248 * of the region. The padding bytes for the cells must be part of the array. 1249 * 1250 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1251 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1252 * of the region. The padding bytes for the cells must not be part of the array. 1253 * 1254 * @param off The offset of the first element to be copied. 1255 * @param count The number of elements to be copied. 1256 * @param d the source array 1257 */ 1258 public void copy1DRangeFromUnchecked(int off, int count, byte[] d) { 1259 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length); 1260 } 1261 1262 /** 1263 * Copy an array into a 1D region of this Allocation. This method does not 1264 * guarantee that the Allocation is compatible with the input buffer. 1265 * 1266 * <p> The size of the region is: count * {@link #getElement}.{@link 1267 * Element#getBytesSize}. 1268 * 1269 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1270 * array in bytes must be at least the size of the region. 1271 * 1272 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1273 * is disabled, then the size of the array in bytes must be at least the size 1274 * of the region. The padding bytes for the cells must be part of the array. 1275 * 1276 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1277 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1278 * of the region. The padding bytes for the cells must not be part of the array. 1279 * 1280 * @param off The offset of the first element to be copied. 1281 * @param count The number of elements to be copied. 1282 * @param d the source array 1283 */ 1284 public void copy1DRangeFromUnchecked(int off, int count, float[] d) { 1285 copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length); 1286 } 1287 1288 /** 1289 * Copy an array into a 1D region of this Allocation. This variant is type checked 1290 * and will generate exceptions if the Allocation's {@link 1291 * android.renderscript.Element} does not match the component type 1292 * of the array passed in. 1293 * 1294 * <p> The size of the region is: count * {@link #getElement}.{@link 1295 * Element#getBytesSize}. 1296 * 1297 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1298 * array in bytes must be at least the size of the region. 1299 * 1300 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1301 * is disabled, then the size of the array in bytes must be at least the size 1302 * of the region. The padding bytes for the cells must be part of the array. 1303 * 1304 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1305 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1306 * of the region. The padding bytes for the cells must not be part of the array. 1307 * 1308 * @param off The offset of the first element to be copied. 1309 * @param count The number of elements to be copied. 1310 * @param array The source array. 1311 */ 1312 public void copy1DRangeFrom(int off, int count, Object array) { 1313 copy1DRangeFromUnchecked(off, count, array, 1314 validateObjectIsPrimitiveArray(array, true), 1315 java.lang.reflect.Array.getLength(array)); 1316 } 1317 1318 /** 1319 * Copy an array into a 1D region of this Allocation. This variant is type checked 1320 * and will generate exceptions if the Allocation's {@link 1321 * android.renderscript.Element} is not an 32 bit integer nor a vector of 32 bit 1322 * integers {@link android.renderscript.Element.DataType}. 1323 * 1324 * <p> The size of the region is: count * {@link #getElement}.{@link 1325 * Element#getBytesSize}. 1326 * 1327 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1328 * array in bytes must be at least the size of the region. 1329 * 1330 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1331 * is disabled, then the size of the array in bytes must be at least the size 1332 * of the region. The padding bytes for the cells must be part of the array. 1333 * 1334 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1335 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1336 * of the region. The padding bytes for the cells must not be part of the array. 1337 * 1338 * @param off The offset of the first element to be copied. 1339 * @param count The number of elements to be copied. 1340 * @param d the source array 1341 */ 1342 public void copy1DRangeFrom(int off, int count, int[] d) { 1343 validateIsInt32(); 1344 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length); 1345 } 1346 1347 /** 1348 * Copy an array into a 1D region of this Allocation. This variant is type checked 1349 * and will generate exceptions if the Allocation's {@link 1350 * android.renderscript.Element} is not an 16 bit integer nor a vector of 16 bit 1351 * integers {@link android.renderscript.Element.DataType}. 1352 * 1353 * <p> The size of the region is: count * {@link #getElement}.{@link 1354 * Element#getBytesSize}. 1355 * 1356 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1357 * array in bytes must be at least the size of the region. 1358 * 1359 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1360 * is disabled, then the size of the array in bytes must be at least the size 1361 * of the region. The padding bytes for the cells must be part of the array. 1362 * 1363 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1364 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1365 * of the region. The padding bytes for the cells must not be part of the array. 1366 * 1367 * @param off The offset of the first element to be copied. 1368 * @param count The number of elements to be copied. 1369 * @param d the source array 1370 */ 1371 public void copy1DRangeFrom(int off, int count, short[] d) { 1372 validateIsInt16OrFloat16(); 1373 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length); 1374 } 1375 1376 /** 1377 * Copy an array into a 1D region of this Allocation. This variant is type checked 1378 * and will generate exceptions if the Allocation's {@link 1379 * android.renderscript.Element} is not an 8 bit integer nor a vector of 8 bit 1380 * integers {@link android.renderscript.Element.DataType}. 1381 * 1382 * <p> The size of the region is: count * {@link #getElement}.{@link 1383 * Element#getBytesSize}. 1384 * 1385 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1386 * array in bytes must be at least the size of the region. 1387 * 1388 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1389 * is disabled, then the size of the array in bytes must be at least the size 1390 * of the region. The padding bytes for the cells must be part of the array. 1391 * 1392 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1393 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1394 * of the region. The padding bytes for the cells must not be part of the array. 1395 * 1396 * @param off The offset of the first element to be copied. 1397 * @param count The number of elements to be copied. 1398 * @param d the source array 1399 */ 1400 public void copy1DRangeFrom(int off, int count, byte[] d) { 1401 validateIsInt8(); 1402 copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length); 1403 } 1404 1405 /** 1406 * Copy an array into a 1D region of this Allocation. This variant is type checked 1407 * and will generate exceptions if the Allocation's {@link 1408 * android.renderscript.Element} is neither a 32 bit float nor a vector of 1409 * 32 bit floats {@link android.renderscript.Element.DataType}. 1410 * 1411 * <p> The size of the region is: count * {@link #getElement}.{@link 1412 * Element#getBytesSize}. 1413 * 1414 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1415 * array in bytes must be at least the size of the region. 1416 * 1417 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1418 * is disabled, then the size of the array in bytes must be at least the size 1419 * of the region. The padding bytes for the cells must be part of the array. 1420 * 1421 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1422 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1423 * of the region. The padding bytes for the cells must not be part of the array. 1424 * 1425 * @param off The offset of the first element to be copied. 1426 * @param count The number of elements to be copied. 1427 * @param d the source array. 1428 */ 1429 public void copy1DRangeFrom(int off, int count, float[] d) { 1430 validateIsFloat32(); 1431 copy1DRangeFromUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length); 1432 } 1433 1434 /** 1435 * Copy part of an Allocation into this Allocation. 1436 * 1437 * @param off The offset of the first element to be copied. 1438 * @param count The number of elements to be copied. 1439 * @param data the source data allocation. 1440 * @param dataOff off The offset of the first element in data to 1441 * be copied. 1442 */ 1443 public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) { 1444 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom"); 1445 mRS.nAllocationData2D(getIDSafe(), off, 0, 1446 mSelectedLOD, mSelectedFace.mID, 1447 count, 1, data.getID(mRS), dataOff, 0, 1448 data.mSelectedLOD, data.mSelectedFace.mID); 1449 Trace.traceEnd(RenderScript.TRACE_TAG); 1450 } 1451 1452 private void validate2DRange(int xoff, int yoff, int w, int h) { 1453 if (mAdaptedAllocation != null) { 1454 1455 } else { 1456 1457 if (xoff < 0 || yoff < 0) { 1458 throw new RSIllegalArgumentException("Offset cannot be negative."); 1459 } 1460 if (h < 0 || w < 0) { 1461 throw new RSIllegalArgumentException("Height or width cannot be negative."); 1462 } 1463 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) { 1464 throw new RSIllegalArgumentException("Updated region larger than allocation."); 1465 } 1466 } 1467 } 1468 1469 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, Object array, 1470 Element.DataType dt, int arrayLen) { 1471 try { 1472 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked"); 1473 mRS.validate(); 1474 validate2DRange(xoff, yoff, w, h); 1475 final int dataSize = mType.mElement.getBytesSize() * w * h; 1476 // AutoPadding for Vec3 Element 1477 boolean usePadding = false; 1478 int sizeBytes = arrayLen * dt.mSize; 1479 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) { 1480 if (dataSize / 4 * 3 > sizeBytes) { 1481 throw new RSIllegalArgumentException("Array too small for allocation type."); 1482 } 1483 usePadding = true; 1484 sizeBytes = dataSize; 1485 } else { 1486 if (dataSize > sizeBytes) { 1487 throw new RSIllegalArgumentException("Array too small for allocation type."); 1488 } 1489 } 1490 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h, 1491 array, sizeBytes, dt, 1492 mType.mElement.mType.mSize, usePadding); 1493 } finally { 1494 Trace.traceEnd(RenderScript.TRACE_TAG); 1495 } 1496 } 1497 1498 /** 1499 * Copy from an array into a rectangular region in this Allocation. The 1500 * array is assumed to be tightly packed. This variant is type checked 1501 * and will generate exceptions if the Allocation's {@link 1502 * android.renderscript.Element} does not match the input data type. 1503 * 1504 * <p> The size of the region is: w * h * {@link #getElement}.{@link 1505 * Element#getBytesSize}. 1506 * 1507 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1508 * array in bytes must be at least the size of the region. 1509 * 1510 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1511 * is disabled, then the size of the array in bytes must be at least the size 1512 * of the region. The padding bytes for the cells must be part of the array. 1513 * 1514 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1515 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1516 * of the region. The padding bytes for the cells must not be part of the array. 1517 * 1518 * @param xoff X offset of the region to update in this Allocation 1519 * @param yoff Y offset of the region to update in this Allocation 1520 * @param w Width of the region to update 1521 * @param h Height of the region to update 1522 * @param array Data to be placed into the Allocation 1523 */ 1524 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, Object array) { 1525 try { 1526 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom"); 1527 copy2DRangeFromUnchecked(xoff, yoff, w, h, array, 1528 validateObjectIsPrimitiveArray(array, true), 1529 java.lang.reflect.Array.getLength(array)); 1530 } finally { 1531 Trace.traceEnd(RenderScript.TRACE_TAG); 1532 } 1533 } 1534 1535 /** 1536 * Copy from an array into a rectangular region in this Allocation. The 1537 * array is assumed to be tightly packed. This variant is type checked 1538 * and will generate exceptions if the Allocation's {@link 1539 * android.renderscript.Element} is not an 8 bit integer nor a vector of 8 bit 1540 * integers {@link android.renderscript.Element.DataType}. 1541 * 1542 * <p> The size of the region is: w * h * {@link #getElement}.{@link 1543 * Element#getBytesSize}. 1544 * 1545 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1546 * array in bytes must be at least the size of the region. 1547 * 1548 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1549 * is disabled, then the size of the array in bytes must be at least the size 1550 * of the region. The padding bytes for the cells must be part of the array. 1551 * 1552 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1553 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1554 * of the region. The padding bytes for the cells must not be part of the array. 1555 * 1556 * @param xoff X offset of the region to update in this Allocation 1557 * @param yoff Y offset of the region to update in this Allocation 1558 * @param w Width of the region to update 1559 * @param h Height of the region to update 1560 * @param data to be placed into the Allocation 1561 */ 1562 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) { 1563 validateIsInt8(); 1564 copy2DRangeFromUnchecked(xoff, yoff, w, h, data, 1565 Element.DataType.SIGNED_8, data.length); 1566 } 1567 1568 /** 1569 * Copy from an array into a rectangular region in this Allocation. The 1570 * array is assumed to be tightly packed. This variant is type checked 1571 * and will generate exceptions if the Allocation's {@link 1572 * android.renderscript.Element} is not a 16 bit integer nor a vector of 16 bit 1573 * integers {@link android.renderscript.Element.DataType}. 1574 * 1575 * <p> The size of the region is: w * h * {@link #getElement}.{@link 1576 * Element#getBytesSize}. 1577 * 1578 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1579 * array in bytes must be at least the size of the region. 1580 * 1581 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1582 * is disabled, then the size of the array in bytes must be at least the size 1583 * of the region. The padding bytes for the cells must be part of the array. 1584 * 1585 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1586 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1587 * of the region. The padding bytes for the cells must not be part of the array. 1588 * 1589 * @param xoff X offset of the region to update in this Allocation 1590 * @param yoff Y offset of the region to update in this Allocation 1591 * @param w Width of the region to update 1592 * @param h Height of the region to update 1593 * @param data to be placed into the Allocation 1594 */ 1595 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) { 1596 validateIsInt16OrFloat16(); 1597 copy2DRangeFromUnchecked(xoff, yoff, w, h, data, 1598 Element.DataType.SIGNED_16, data.length); 1599 } 1600 1601 /** 1602 * Copy from an array into a rectangular region in this Allocation. The 1603 * array is assumed to be tightly packed. This variant is type checked 1604 * and will generate exceptions if the Allocation's {@link 1605 * android.renderscript.Element} is not a 32 bit integer nor a vector of 32 bit 1606 * integers {@link android.renderscript.Element.DataType}. 1607 * 1608 * <p> The size of the region is: w * h * {@link #getElement}.{@link 1609 * Element#getBytesSize}. 1610 * 1611 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1612 * array in bytes must be at least the size of the region. 1613 * 1614 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1615 * is disabled, then the size of the array in bytes must be at least the size 1616 * of the region. The padding bytes for the cells must be part of the array. 1617 * 1618 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1619 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1620 * of the region. The padding bytes for the cells must not be part of the array. 1621 * 1622 * @param xoff X offset of the region to update in this Allocation 1623 * @param yoff Y offset of the region to update in this Allocation 1624 * @param w Width of the region to update 1625 * @param h Height of the region to update 1626 * @param data to be placed into the Allocation 1627 */ 1628 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) { 1629 validateIsInt32(); 1630 copy2DRangeFromUnchecked(xoff, yoff, w, h, data, 1631 Element.DataType.SIGNED_32, data.length); 1632 } 1633 1634 /** 1635 * Copy from an array into a rectangular region in this Allocation. The 1636 * array is assumed to be tightly packed. This variant is type checked 1637 * and will generate exceptions if the Allocation's {@link 1638 * android.renderscript.Element} is neither a 32 bit float nor a vector of 1639 * 32 bit floats {@link android.renderscript.Element.DataType}. 1640 * 1641 * <p> The size of the region is: w * h * {@link #getElement}.{@link 1642 * Element#getBytesSize}. 1643 * 1644 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1645 * array in bytes must be at least the size of the region. 1646 * 1647 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1648 * is disabled, then the size of the array in bytes must be at least the size 1649 * of the region. The padding bytes for the cells must be part of the array. 1650 * 1651 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1652 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1653 * of the region. The padding bytes for the cells must not be part of the array. 1654 * 1655 * @param xoff X offset of the region to update in this Allocation 1656 * @param yoff Y offset of the region to update in this Allocation 1657 * @param w Width of the region to update 1658 * @param h Height of the region to update 1659 * @param data to be placed into the Allocation 1660 */ 1661 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) { 1662 validateIsFloat32(); 1663 copy2DRangeFromUnchecked(xoff, yoff, w, h, data, 1664 Element.DataType.FLOAT_32, data.length); 1665 } 1666 1667 /** 1668 * Copy a rectangular region from an Allocation into a rectangular region in 1669 * this Allocation. 1670 * 1671 * @param xoff X offset of the region in this Allocation 1672 * @param yoff Y offset of the region in this Allocation 1673 * @param w Width of the region to update. 1674 * @param h Height of the region to update. 1675 * @param data source Allocation. 1676 * @param dataXoff X offset in source Allocation 1677 * @param dataYoff Y offset in source Allocation 1678 */ 1679 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, 1680 Allocation data, int dataXoff, int dataYoff) { 1681 try { 1682 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom"); 1683 mRS.validate(); 1684 validate2DRange(xoff, yoff, w, h); 1685 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, 1686 mSelectedLOD, mSelectedFace.mID, 1687 w, h, data.getID(mRS), dataXoff, dataYoff, 1688 data.mSelectedLOD, data.mSelectedFace.mID); 1689 } finally { 1690 Trace.traceEnd(RenderScript.TRACE_TAG); 1691 } 1692 } 1693 1694 /** 1695 * Copy a {@link android.graphics.Bitmap} into an Allocation. The height 1696 * and width of the update will use the height and width of the {@link 1697 * android.graphics.Bitmap}. 1698 * 1699 * @param xoff X offset of the region to update in this Allocation 1700 * @param yoff Y offset of the region to update in this Allocation 1701 * @param data the Bitmap to be copied 1702 */ 1703 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) { 1704 try { 1705 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom"); 1706 mRS.validate(); 1707 if (data.getConfig() == null) { 1708 Bitmap newBitmap = Bitmap.createBitmap(data.getWidth(), data.getHeight(), Bitmap.Config.ARGB_8888); 1709 Canvas c = new Canvas(newBitmap); 1710 c.drawBitmap(data, 0, 0, null); 1711 copy2DRangeFrom(xoff, yoff, newBitmap); 1712 return; 1713 } 1714 validateBitmapFormat(data); 1715 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight()); 1716 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data); 1717 } finally { 1718 Trace.traceEnd(RenderScript.TRACE_TAG); 1719 } 1720 } 1721 1722 private void validate3DRange(int xoff, int yoff, int zoff, int w, int h, int d) { 1723 if (mAdaptedAllocation != null) { 1724 1725 } else { 1726 1727 if (xoff < 0 || yoff < 0 || zoff < 0) { 1728 throw new RSIllegalArgumentException("Offset cannot be negative."); 1729 } 1730 if (h < 0 || w < 0 || d < 0) { 1731 throw new RSIllegalArgumentException("Height or width cannot be negative."); 1732 } 1733 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY) || ((zoff + d) > mCurrentDimZ)) { 1734 throw new RSIllegalArgumentException("Updated region larger than allocation."); 1735 } 1736 } 1737 } 1738 1739 /** 1740 * Copy a rectangular region from the array into the allocation. 1741 * The array is assumed to be tightly packed. 1742 * 1743 * The data type of the array is not required to be the same as 1744 * the element data type. 1745 */ 1746 private void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, 1747 Object array, Element.DataType dt, int arrayLen) { 1748 try { 1749 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeFromUnchecked"); 1750 mRS.validate(); 1751 validate3DRange(xoff, yoff, zoff, w, h, d); 1752 final int dataSize = mType.mElement.getBytesSize() * w * h * d; 1753 // AutoPadding for Vec3 Element 1754 boolean usePadding = false; 1755 int sizeBytes = arrayLen * dt.mSize; 1756 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) { 1757 if (dataSize / 4 * 3 > sizeBytes) { 1758 throw new RSIllegalArgumentException("Array too small for allocation type."); 1759 } 1760 usePadding = true; 1761 sizeBytes = dataSize; 1762 } else { 1763 if (dataSize > sizeBytes) { 1764 throw new RSIllegalArgumentException("Array too small for allocation type."); 1765 } 1766 } 1767 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d, 1768 array, sizeBytes, dt, 1769 mType.mElement.mType.mSize, usePadding); 1770 } finally { 1771 Trace.traceEnd(RenderScript.TRACE_TAG); 1772 } 1773 } 1774 1775 /** 1776 * Copy from an array into a 3D region in this Allocation. The 1777 * array is assumed to be tightly packed. This variant is type checked 1778 * and will generate exceptions if the Allocation's {@link 1779 * android.renderscript.Element} does not match the input data type. 1780 * 1781 * <p> The size of the region is: w * h * d * {@link #getElement}.{@link 1782 * Element#getBytesSize}. 1783 * 1784 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1785 * array in bytes must be at least the size of the region. 1786 * 1787 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1788 * is disabled, then the size of the array in bytes must be at least the size 1789 * of the region. The padding bytes for the cells must be part of the array. 1790 * 1791 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1792 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1793 * of the region. The padding bytes for the cells must not be part of the array. 1794 * 1795 * @param xoff X offset of the region to update in this Allocation 1796 * @param yoff Y offset of the region to update in this Allocation 1797 * @param zoff Z offset of the region to update in this Allocation 1798 * @param w Width of the region to update 1799 * @param h Height of the region to update 1800 * @param d Depth of the region to update 1801 * @param array to be placed into the allocation 1802 */ 1803 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, Object array) { 1804 try { 1805 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeFrom"); 1806 copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, array, 1807 validateObjectIsPrimitiveArray(array, true), 1808 java.lang.reflect.Array.getLength(array)); 1809 } finally { 1810 Trace.traceEnd(RenderScript.TRACE_TAG); 1811 } 1812 } 1813 1814 /** 1815 * Copy a rectangular region into the allocation from another 1816 * allocation. 1817 * 1818 * @param xoff X offset of the region to update in this Allocation 1819 * @param yoff Y offset of the region to update in this Allocation 1820 * @param zoff Z offset of the region to update in this Allocation 1821 * @param w Width of the region to update. 1822 * @param h Height of the region to update. 1823 * @param d Depth of the region to update. 1824 * @param data source allocation. 1825 * @param dataXoff X offset of the region in the source Allocation 1826 * @param dataYoff Y offset of the region in the source Allocation 1827 * @param dataZoff Z offset of the region in the source Allocation 1828 */ 1829 public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, 1830 Allocation data, int dataXoff, int dataYoff, int dataZoff) { 1831 mRS.validate(); 1832 validate3DRange(xoff, yoff, zoff, w, h, d); 1833 mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, 1834 w, h, d, data.getID(mRS), dataXoff, dataYoff, dataZoff, 1835 data.mSelectedLOD); 1836 } 1837 1838 1839 /** 1840 * Copy from the Allocation into a {@link android.graphics.Bitmap}. The 1841 * bitmap must match the dimensions of the Allocation. 1842 * 1843 * @param b The bitmap to be set from the Allocation. 1844 */ 1845 public void copyTo(Bitmap b) { 1846 try { 1847 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo"); 1848 mRS.validate(); 1849 validateBitmapFormat(b); 1850 validateBitmapSize(b); 1851 mRS.nAllocationCopyToBitmap(getID(mRS), b); 1852 } finally { 1853 Trace.traceEnd(RenderScript.TRACE_TAG); 1854 } 1855 } 1856 1857 private void copyTo(Object array, Element.DataType dt, int arrayLen) { 1858 try { 1859 Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo"); 1860 mRS.validate(); 1861 boolean usePadding = false; 1862 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) { 1863 usePadding = true; 1864 } 1865 if (usePadding) { 1866 if (dt.mSize * arrayLen < mSize / 4 * 3) { 1867 throw new RSIllegalArgumentException( 1868 "Size of output array cannot be smaller than size of allocation."); 1869 } 1870 } else { 1871 if (dt.mSize * arrayLen < mSize) { 1872 throw new RSIllegalArgumentException( 1873 "Size of output array cannot be smaller than size of allocation."); 1874 } 1875 } 1876 mRS.nAllocationRead(getID(mRS), array, dt, mType.mElement.mType.mSize, usePadding); 1877 } finally { 1878 Trace.traceEnd(RenderScript.TRACE_TAG); 1879 } 1880 } 1881 1882 /** 1883 * Copy from the Allocation into an array. The method is type checked 1884 * and will generate exceptions if the Allocation's {@link 1885 * android.renderscript.Element} does not match the input data type. 1886 * 1887 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1888 * array in bytes must be at least the size of the Allocation {@link 1889 * #getBytesSize getBytesSize()}. 1890 * 1891 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1892 * is disabled, then the size of the array in bytes must be at least the size 1893 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 1894 * the cells will be part of the array. 1895 * 1896 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1897 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1898 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 1899 * the cells must not be part of the array. 1900 * 1901 * @param array The array to be set from the Allocation. 1902 */ 1903 public void copyTo(Object array) { 1904 copyTo(array, validateObjectIsPrimitiveArray(array, true), 1905 java.lang.reflect.Array.getLength(array)); 1906 } 1907 1908 /** 1909 * Copy from the Allocation into a byte array. This variant is type checked 1910 * and will generate exceptions if the Allocation's {@link 1911 * android.renderscript.Element} is neither an 8 bit integer nor a vector of 8 bit 1912 * integers {@link android.renderscript.Element.DataType}. 1913 * 1914 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1915 * array in bytes must be at least the size of the Allocation {@link 1916 * #getBytesSize getBytesSize()}. 1917 * 1918 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1919 * is disabled, then the size of the array in bytes must be at least the size 1920 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 1921 * the cells will be part of the array. 1922 * 1923 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1924 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1925 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 1926 * the cells must not be part of the array. 1927 * 1928 * @param d The array to be set from the Allocation. 1929 */ 1930 public void copyTo(byte[] d) { 1931 validateIsInt8(); 1932 copyTo(d, Element.DataType.SIGNED_8, d.length); 1933 } 1934 1935 /** 1936 * Copy from the Allocation into a short array. This variant is type checked 1937 * and will generate exceptions if the Allocation's {@link 1938 * android.renderscript.Element} is not a 16 bit integer nor a vector of 16 bit 1939 * integers {@link android.renderscript.Element.DataType}. 1940 * 1941 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1942 * array in bytes must be at least the size of the Allocation {@link 1943 * #getBytesSize getBytesSize()}. 1944 * 1945 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1946 * is disabled, then the size of the array in bytes must be at least the size 1947 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 1948 * the cells will be part of the array. 1949 * 1950 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1951 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1952 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 1953 * the cells must not be part of the array. 1954 * 1955 * @param d The array to be set from the Allocation. 1956 */ 1957 public void copyTo(short[] d) { 1958 validateIsInt16OrFloat16(); 1959 copyTo(d, Element.DataType.SIGNED_16, d.length); 1960 } 1961 1962 /** 1963 * Copy from the Allocation into a int array. This variant is type checked 1964 * and will generate exceptions if the Allocation's {@link 1965 * android.renderscript.Element} is not a 32 bit integer nor a vector of 32 bit 1966 * integers {@link android.renderscript.Element.DataType}. 1967 * 1968 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1969 * array in bytes must be at least the size of the Allocation {@link 1970 * #getBytesSize getBytesSize()}. 1971 * 1972 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1973 * is disabled, then the size of the array in bytes must be at least the size 1974 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 1975 * the cells will be part of the array. 1976 * 1977 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 1978 * is enabled, then the size of the array in bytes must be at least 3/4 the size 1979 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 1980 * the cells must not be part of the array. 1981 * 1982 * @param d The array to be set from the Allocation. 1983 */ 1984 public void copyTo(int[] d) { 1985 validateIsInt32(); 1986 copyTo(d, Element.DataType.SIGNED_32, d.length); 1987 } 1988 1989 /** 1990 * Copy from the Allocation into a float array. This variant is type checked 1991 * and will generate exceptions if the Allocation's {@link 1992 * android.renderscript.Element} is neither a 32 bit float nor a vector of 1993 * 32 bit floats {@link android.renderscript.Element.DataType}. 1994 * 1995 * <p> If the Allocation does not have Vec3 Elements, then the size of the 1996 * array in bytes must be at least the size of the Allocation {@link 1997 * #getBytesSize getBytesSize()}. 1998 * 1999 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2000 * is disabled, then the size of the array in bytes must be at least the size 2001 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 2002 * the cells will be part of the array. 2003 * 2004 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2005 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2006 * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for 2007 * the cells must not be part of the array. 2008 * 2009 * @param d The array to be set from the Allocation. 2010 */ 2011 public void copyTo(float[] d) { 2012 validateIsFloat32(); 2013 copyTo(d, Element.DataType.FLOAT_32, d.length); 2014 } 2015 2016 /** 2017 * @hide 2018 * 2019 * This is only intended to be used by auto-generated code reflected from 2020 * the RenderScript script files and should not be used by developers. 2021 * 2022 * @param xoff 2023 * @param yoff 2024 * @param zoff 2025 * @param component_number 2026 * @param fp 2027 */ 2028 public void copyToFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) { 2029 mRS.validate(); 2030 if (component_number >= mType.mElement.mElements.length) { 2031 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range."); 2032 } 2033 if(xoff < 0) { 2034 throw new RSIllegalArgumentException("Offset x must be >= 0."); 2035 } 2036 if(yoff < 0) { 2037 throw new RSIllegalArgumentException("Offset y must be >= 0."); 2038 } 2039 if(zoff < 0) { 2040 throw new RSIllegalArgumentException("Offset z must be >= 0."); 2041 } 2042 2043 final byte[] data = fp.getData(); 2044 int data_length = data.length; 2045 int eSize = mType.mElement.mElements[component_number].getBytesSize(); 2046 eSize *= mType.mElement.mArraySizes[component_number]; 2047 2048 if (data_length != eSize) { 2049 throw new RSIllegalArgumentException("Field packer sizelength " + data_length + 2050 " does not match component size " + eSize + "."); 2051 } 2052 2053 mRS.nAllocationElementRead(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, 2054 component_number, data, data_length); 2055 } 2056 /** 2057 * Resize a 1D allocation. The contents of the allocation are preserved. 2058 * If new elements are allocated objects are created with null contents and 2059 * the new region is otherwise undefined. 2060 * 2061 * <p>If the new region is smaller the references of any objects outside the 2062 * new region will be released.</p> 2063 * 2064 * <p>A new type will be created with the new dimension.</p> 2065 * 2066 * @param dimX The new size of the allocation. 2067 * 2068 * @deprecated RenderScript objects should be immutable once created. The 2069 * replacement is to create a new allocation and copy the contents. This 2070 * function will throw an exception if API 21 or higher is used. 2071 */ 2072 public synchronized void resize(int dimX) { 2073 if (mRS.getApplicationContext().getApplicationInfo().targetSdkVersion >= 21) { 2074 throw new RSRuntimeException("Resize is not allowed in API 21+."); 2075 } 2076 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) { 2077 throw new RSInvalidStateException("Resize only support for 1D allocations at this time."); 2078 } 2079 mRS.nAllocationResize1D(getID(mRS), dimX); 2080 mRS.finish(); // Necessary because resize is fifoed and update is async. 2081 2082 long typeID = mRS.nAllocationGetType(getID(mRS)); 2083 // Sets zero the mID so that the finalizer of the old mType value won't 2084 // destroy the native object that is being reused. 2085 mType.setID(0); 2086 mType = new Type(typeID, mRS); 2087 mType.updateFromNative(); 2088 updateCacheInfo(mType); 2089 } 2090 2091 private void copy1DRangeToUnchecked(int off, int count, Object array, 2092 Element.DataType dt, int arrayLen) { 2093 try { 2094 Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeToUnchecked"); 2095 final int dataSize = mType.mElement.getBytesSize() * count; 2096 // AutoPadding for Vec3 Element 2097 boolean usePadding = false; 2098 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) { 2099 usePadding = true; 2100 } 2101 data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding); 2102 mRS.nAllocationRead1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt, 2103 mType.mElement.mType.mSize, usePadding); 2104 } finally { 2105 Trace.traceEnd(RenderScript.TRACE_TAG); 2106 } 2107 } 2108 2109 /** 2110 * Copy a 1D region of this Allocation into an array. This method does not 2111 * guarantee that the Allocation is compatible with the input buffer. 2112 * 2113 * <p> The size of the region is: count * {@link #getElement}.{@link 2114 * Element#getBytesSize}. 2115 * 2116 * <p> If the Allocation does not have Vec3 Elements, then the size of the 2117 * array in bytes must be at least the size of the region. 2118 * 2119 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2120 * is disabled, then the size of the array in bytes must be at least the size 2121 * of the region. The padding bytes for the cells must be part of the array. 2122 * 2123 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2124 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2125 * of the region. The padding bytes for the cells must not be part of the array. 2126 * 2127 * @param off The offset of the first element to be copied. 2128 * @param count The number of elements to be copied. 2129 * @param array The dest array 2130 */ 2131 public void copy1DRangeToUnchecked(int off, int count, Object array) { 2132 copy1DRangeToUnchecked(off, count, array, 2133 validateObjectIsPrimitiveArray(array, false), 2134 java.lang.reflect.Array.getLength(array)); 2135 } 2136 2137 /** 2138 * Copy a 1D region of this Allocation into an array. This method does not 2139 * guarantee that the Allocation is compatible with the input buffer. 2140 * 2141 * <p> The size of the region is: count * {@link #getElement}.{@link 2142 * Element#getBytesSize}. 2143 * 2144 * <p> If the Allocation does not have Vec3 Elements, then the size of the 2145 * array in bytes must be at least the size of the region. 2146 * 2147 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2148 * is disabled, then the size of the array in bytes must be at least the size 2149 * of the region. The padding bytes for the cells must be part of the array. 2150 * 2151 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2152 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2153 * of the region. The padding bytes for the cells must not be part of the array. 2154 * 2155 * @param off The offset of the first element to be copied. 2156 * @param count The number of elements to be copied. 2157 * @param d the source array 2158 */ 2159 public void copy1DRangeToUnchecked(int off, int count, int[] d) { 2160 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length); 2161 } 2162 2163 /** 2164 * Copy a 1D region of this Allocation into an array. This method does not 2165 * guarantee that the Allocation is compatible with the input buffer. 2166 * 2167 * <p> The size of the region is: count * {@link #getElement}.{@link 2168 * Element#getBytesSize}. 2169 * 2170 * <p> If the Allocation does not have Vec3 Elements, then the size of the 2171 * array in bytes must be at least the size of the region. 2172 * 2173 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2174 * is disabled, then the size of the array in bytes must be at least the size 2175 * of the region. The padding bytes for the cells must be part of the array. 2176 * 2177 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2178 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2179 * of the region. The padding bytes for the cells must not be part of the array. 2180 * 2181 * @param off The offset of the first element to be copied. 2182 * @param count The number of elements to be copied. 2183 * @param d the source array 2184 */ 2185 public void copy1DRangeToUnchecked(int off, int count, short[] d) { 2186 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length); 2187 } 2188 2189 /** 2190 * Copy a 1D region of this Allocation into an array. This method does not 2191 * guarantee that the Allocation is compatible with the input buffer. 2192 * 2193 * <p> The size of the region is: count * {@link #getElement}.{@link 2194 * Element#getBytesSize}. 2195 * 2196 * <p> If the Allocation does not have Vec3 Elements, then the size of the 2197 * array in bytes must be at least the size of the region. 2198 * 2199 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2200 * is disabled, then the size of the array in bytes must be at least the size 2201 * of the region. The padding bytes for the cells must be part of the array. 2202 * 2203 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2204 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2205 * of the region. The padding bytes for the cells must not be part of the array. 2206 * 2207 * @param off The offset of the first element to be copied. 2208 * @param count The number of elements to be copied. 2209 * @param d the source array 2210 */ 2211 public void copy1DRangeToUnchecked(int off, int count, byte[] d) { 2212 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length); 2213 } 2214 2215 /** 2216 * Copy a 1D region of this Allocation into an array. This method does not 2217 * guarantee that the Allocation is compatible with the input buffer. 2218 * 2219 * <p> The size of the region is: count * {@link #getElement}.{@link 2220 * Element#getBytesSize}. 2221 * 2222 * <p> If the Allocation does not have Vec3 Elements, then the size of the 2223 * array in bytes must be at least the size of the region. 2224 * 2225 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2226 * is disabled, then the size of the array in bytes must be at least the size 2227 * of the region. The padding bytes for the cells must be part of the array. 2228 * 2229 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2230 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2231 * of the region. The padding bytes for the cells must not be part of the array. 2232 * 2233 * @param off The offset of the first element to be copied. 2234 * @param count The number of elements to be copied. 2235 * @param d the source array 2236 */ 2237 public void copy1DRangeToUnchecked(int off, int count, float[] d) { 2238 copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length); 2239 } 2240 2241 /** 2242 * Copy a 1D region of this Allocation into an array. This method is type checked 2243 * and will generate exceptions if the Allocation's {@link 2244 * android.renderscript.Element} does not match the component type 2245 * of the array passed in. 2246 * 2247 * <p> The size of the region is: count * {@link #getElement}.{@link 2248 * Element#getBytesSize}. 2249 * 2250 * <p> If the Allocation does not have Vec3 Elements, then the size of the 2251 * array in bytes must be at least the size of the region. 2252 * 2253 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2254 * is disabled, then the size of the array in bytes must be at least the size 2255 * of the region. The padding bytes for the cells must be part of the array. 2256 * 2257 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2258 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2259 * of the region. The padding bytes for the cells must not be part of the array. 2260 * 2261 * @param off The offset of the first element to be copied. 2262 * @param count The number of elements to be copied. 2263 * @param array The source array. 2264 */ 2265 public void copy1DRangeTo(int off, int count, Object array) { 2266 copy1DRangeToUnchecked(off, count, array, 2267 validateObjectIsPrimitiveArray(array, true), 2268 java.lang.reflect.Array.getLength(array)); 2269 } 2270 2271 /** 2272 * Copy a 1D region of this Allocation into an array. This variant is type checked 2273 * and will generate exceptions if the Allocation's {@link 2274 * android.renderscript.Element} is neither a 32 bit integer nor a vector of 32 bit 2275 * integers {@link android.renderscript.Element.DataType}. 2276 * 2277 * <p> The size of the region is: count * {@link #getElement}.{@link 2278 * Element#getBytesSize}. 2279 * 2280 * <p> If the Allocation does not have Vec3 Elements, then the size of the 2281 * array in bytes must be at least the size of the region. 2282 * 2283 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2284 * is disabled, then the size of the array in bytes must be at least the size 2285 * of the region. The padding bytes for the cells must be part of the array. 2286 * 2287 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2288 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2289 * of the region. The padding bytes for the cells must not be part of the array. 2290 * 2291 * @param off The offset of the first element to be copied. 2292 * @param count The number of elements to be copied. 2293 * @param d the source array 2294 */ 2295 public void copy1DRangeTo(int off, int count, int[] d) { 2296 validateIsInt32(); 2297 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length); 2298 } 2299 2300 /** 2301 * Copy a 1D region of this Allocation into an array. This variant is type checked 2302 * and will generate exceptions if the Allocation's {@link 2303 * android.renderscript.Element} is neither a 16 bit integer nor a vector of 16 bit 2304 * integers {@link android.renderscript.Element.DataType}. 2305 * 2306 * <p> The size of the region is: count * {@link #getElement}.{@link 2307 * Element#getBytesSize}. 2308 * 2309 * <p> If the Allocation does not have Vec3 Elements, then the size of the 2310 * array in bytes must be at least the size of the region. 2311 * 2312 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2313 * is disabled, then the size of the array in bytes must be at least the size 2314 * of the region. The padding bytes for the cells must be part of the array. 2315 * 2316 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2317 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2318 * of the region. The padding bytes for the cells must not be part of the array. 2319 * 2320 * @param off The offset of the first element to be copied. 2321 * @param count The number of elements to be copied. 2322 * @param d the source array 2323 */ 2324 public void copy1DRangeTo(int off, int count, short[] d) { 2325 validateIsInt16OrFloat16(); 2326 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length); 2327 } 2328 2329 /** 2330 * Copy a 1D region of this Allocation into an array. This variant is type checked 2331 * and will generate exceptions if the Allocation's {@link 2332 * android.renderscript.Element} is neither an 8 bit integer nor a vector of 8 bit 2333 * integers {@link android.renderscript.Element.DataType}. 2334 * 2335 * <p> The size of the region is: count * {@link #getElement}.{@link 2336 * Element#getBytesSize}. 2337 * 2338 * <p> If the Allocation does not have Vec3 Elements, then the size of the 2339 * array in bytes must be at least the size of the region. 2340 * 2341 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2342 * is disabled, then the size of the array in bytes must be at least the size 2343 * of the region. The padding bytes for the cells must be part of the array. 2344 * 2345 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2346 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2347 * of the region. The padding bytes for the cells must not be part of the array. 2348 * 2349 * @param off The offset of the first element to be copied. 2350 * @param count The number of elements to be copied. 2351 * @param d the source array 2352 */ 2353 public void copy1DRangeTo(int off, int count, byte[] d) { 2354 validateIsInt8(); 2355 copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length); 2356 } 2357 2358 /** 2359 * Copy a 1D region of this Allocation into an array. This variant is type checked 2360 * and will generate exceptions if the Allocation's {@link 2361 * android.renderscript.Element} is neither a 32 bit float nor a vector of 2362 * 32 bit floats {@link android.renderscript.Element.DataType}. 2363 * 2364 * <p> The size of the region is: count * {@link #getElement}.{@link 2365 * Element#getBytesSize}. 2366 * 2367 * <p> If the Allocation does not have Vec3 Elements, then the size of the 2368 * array in bytes must be at least the size of the region. 2369 * 2370 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2371 * is disabled, then the size of the array in bytes must be at least the size 2372 * of the region. The padding bytes for the cells must be part of the array. 2373 * 2374 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2375 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2376 * of the region. The padding bytes for the cells must not be part of the array. 2377 * 2378 * @param off The offset of the first element to be copied. 2379 * @param count The number of elements to be copied. 2380 * @param d the source array. 2381 */ 2382 public void copy1DRangeTo(int off, int count, float[] d) { 2383 validateIsFloat32(); 2384 copy1DRangeToUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length); 2385 } 2386 2387 2388 void copy2DRangeToUnchecked(int xoff, int yoff, int w, int h, Object array, 2389 Element.DataType dt, int arrayLen) { 2390 try { 2391 Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeToUnchecked"); 2392 mRS.validate(); 2393 validate2DRange(xoff, yoff, w, h); 2394 final int dataSize = mType.mElement.getBytesSize() * w * h; 2395 // AutoPadding for Vec3 Element 2396 boolean usePadding = false; 2397 int sizeBytes = arrayLen * dt.mSize; 2398 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) { 2399 if (dataSize / 4 * 3 > sizeBytes) { 2400 throw new RSIllegalArgumentException("Array too small for allocation type."); 2401 } 2402 usePadding = true; 2403 sizeBytes = dataSize; 2404 } else { 2405 if (dataSize > sizeBytes) { 2406 throw new RSIllegalArgumentException("Array too small for allocation type."); 2407 } 2408 } 2409 mRS.nAllocationRead2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h, 2410 array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding); 2411 } finally { 2412 Trace.traceEnd(RenderScript.TRACE_TAG); 2413 } 2414 } 2415 2416 /** 2417 * Copy from a rectangular region in this Allocation into an array. This 2418 * method is type checked and will generate exceptions if the Allocation's 2419 * {@link android.renderscript.Element} does not match the component type 2420 * of the array passed in. 2421 * 2422 * <p> The size of the region is: w * h * {@link #getElement}.{@link 2423 * Element#getBytesSize}. 2424 * 2425 * <p> If the Allocation does not have Vec3 Elements, then the size of the 2426 * array in bytes must be at least the size of the region. 2427 * 2428 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2429 * is disabled, then the size of the array in bytes must be at least the size 2430 * of the region. The padding bytes for the cells must be part of the array. 2431 * 2432 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2433 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2434 * of the region. The padding bytes for the cells must not be part of the array. 2435 * 2436 * @param xoff X offset of the region to copy in this Allocation 2437 * @param yoff Y offset of the region to copy in this Allocation 2438 * @param w Width of the region to copy 2439 * @param h Height of the region to copy 2440 * @param array Dest Array to be copied into 2441 */ 2442 public void copy2DRangeTo(int xoff, int yoff, int w, int h, Object array) { 2443 copy2DRangeToUnchecked(xoff, yoff, w, h, array, 2444 validateObjectIsPrimitiveArray(array, true), 2445 java.lang.reflect.Array.getLength(array)); 2446 } 2447 2448 /** 2449 * Copy from a rectangular region in this Allocation into an array. This 2450 * variant is type checked and will generate exceptions if the Allocation's 2451 * {@link android.renderscript.Element} is neither an 8 bit integer nor a vector 2452 * of 8 bit integers {@link android.renderscript.Element.DataType}. 2453 * 2454 * <p> The size of the region is: w * h * {@link #getElement}.{@link 2455 * Element#getBytesSize}. 2456 * 2457 * <p> If the Allocation does not have Vec3 Elements, then the size of the 2458 * array in bytes must be at least the size of the region. 2459 * 2460 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2461 * is disabled, then the size of the array in bytes must be at least the size 2462 * of the region. The padding bytes for the cells must be part of the array. 2463 * 2464 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2465 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2466 * of the region. The padding bytes for the cells must not be part of the array. 2467 * 2468 * @param xoff X offset of the region to copy in this Allocation 2469 * @param yoff Y offset of the region to copy in this Allocation 2470 * @param w Width of the region to copy 2471 * @param h Height of the region to copy 2472 * @param data Dest Array to be copied into 2473 */ 2474 public void copy2DRangeTo(int xoff, int yoff, int w, int h, byte[] data) { 2475 validateIsInt8(); 2476 copy2DRangeToUnchecked(xoff, yoff, w, h, data, 2477 Element.DataType.SIGNED_8, data.length); 2478 } 2479 2480 /** 2481 * Copy from a rectangular region in this Allocation into an array. This 2482 * variant is type checked and will generate exceptions if the Allocation's 2483 * {@link android.renderscript.Element} is neither a 16 bit integer nor a vector 2484 * of 16 bit integers {@link android.renderscript.Element.DataType}. 2485 * 2486 * <p> The size of the region is: w * h * {@link #getElement}.{@link 2487 * Element#getBytesSize}. 2488 * 2489 * <p> If the Allocation does not have Vec3 Elements, then the size of the 2490 * array in bytes must be at least the size of the region. 2491 * 2492 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2493 * is disabled, then the size of the array in bytes must be at least the size 2494 * of the region. The padding bytes for the cells must be part of the array. 2495 * 2496 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2497 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2498 * of the region. The padding bytes for the cells must not be part of the array. 2499 * 2500 * @param xoff X offset of the region to copy in this Allocation 2501 * @param yoff Y offset of the region to copy in this Allocation 2502 * @param w Width of the region to copy 2503 * @param h Height of the region to copy 2504 * @param data Dest Array to be copied into 2505 */ 2506 public void copy2DRangeTo(int xoff, int yoff, int w, int h, short[] data) { 2507 validateIsInt16OrFloat16(); 2508 copy2DRangeToUnchecked(xoff, yoff, w, h, data, 2509 Element.DataType.SIGNED_16, data.length); 2510 } 2511 2512 /** 2513 * Copy from a rectangular region in this Allocation into an array. This 2514 * variant is type checked and will generate exceptions if the Allocation's 2515 * {@link android.renderscript.Element} is neither a 32 bit integer nor a vector 2516 * of 32 bit integers {@link android.renderscript.Element.DataType}. 2517 * 2518 * <p> The size of the region is: w * h * {@link #getElement}.{@link 2519 * Element#getBytesSize}. 2520 * 2521 * <p> If the Allocation does not have Vec3 Elements, then the size of the 2522 * array in bytes must be at least the size of the region. 2523 * 2524 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2525 * is disabled, then the size of the array in bytes must be at least the size 2526 * of the region. The padding bytes for the cells must be part of the array. 2527 * 2528 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2529 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2530 * of the region. The padding bytes for the cells must not be part of the array. 2531 * 2532 * @param xoff X offset of the region to copy in this Allocation 2533 * @param yoff Y offset of the region to copy in this Allocation 2534 * @param w Width of the region to copy 2535 * @param h Height of the region to copy 2536 * @param data Dest Array to be copied into 2537 */ 2538 public void copy2DRangeTo(int xoff, int yoff, int w, int h, int[] data) { 2539 validateIsInt32(); 2540 copy2DRangeToUnchecked(xoff, yoff, w, h, data, 2541 Element.DataType.SIGNED_32, data.length); 2542 } 2543 2544 /** 2545 * Copy from a rectangular region in this Allocation into an array. This 2546 * variant is type checked and will generate exceptions if the Allocation's 2547 * {@link android.renderscript.Element} is neither a 32 bit float nor a vector 2548 * of 32 bit floats {@link android.renderscript.Element.DataType}. 2549 * 2550 * <p> The size of the region is: w * h * {@link #getElement}.{@link 2551 * Element#getBytesSize}. 2552 * 2553 * <p> If the Allocation does not have Vec3 Elements, then the size of the 2554 * array in bytes must be at least the size of the region. 2555 * 2556 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2557 * is disabled, then the size of the array in bytes must be at least the size 2558 * of the region. The padding bytes for the cells must be part of the array. 2559 * 2560 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2561 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2562 * of the region. The padding bytes for the cells must not be part of the array. 2563 * 2564 * @param xoff X offset of the region to copy in this Allocation 2565 * @param yoff Y offset of the region to copy in this Allocation 2566 * @param w Width of the region to copy 2567 * @param h Height of the region to copy 2568 * @param data Dest Array to be copied into 2569 */ 2570 public void copy2DRangeTo(int xoff, int yoff, int w, int h, float[] data) { 2571 validateIsFloat32(); 2572 copy2DRangeToUnchecked(xoff, yoff, w, h, data, 2573 Element.DataType.FLOAT_32, data.length); 2574 } 2575 2576 2577 /** 2578 * Copy from a 3D region in this Allocation into an array. This method does 2579 * not guarantee that the Allocation is compatible with the input buffer. 2580 * The array is assumed to be tightly packed. 2581 * 2582 * The data type of the array is not required to be the same as 2583 * the element data type. 2584 */ 2585 private void copy3DRangeToUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, 2586 Object array, Element.DataType dt, int arrayLen) { 2587 try { 2588 Trace.traceBegin(RenderScript.TRACE_TAG, "copy3DRangeToUnchecked"); 2589 mRS.validate(); 2590 validate3DRange(xoff, yoff, zoff, w, h, d); 2591 final int dataSize = mType.mElement.getBytesSize() * w * h * d; 2592 // AutoPadding for Vec3 Element 2593 boolean usePadding = false; 2594 int sizeBytes = arrayLen * dt.mSize; 2595 if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) { 2596 if (dataSize / 4 * 3 > sizeBytes) { 2597 throw new RSIllegalArgumentException("Array too small for allocation type."); 2598 } 2599 usePadding = true; 2600 sizeBytes = dataSize; 2601 } else { 2602 if (dataSize > sizeBytes) { 2603 throw new RSIllegalArgumentException("Array too small for allocation type."); 2604 } 2605 } 2606 mRS.nAllocationRead3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d, 2607 array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding); 2608 } finally { 2609 Trace.traceEnd(RenderScript.TRACE_TAG); 2610 } 2611 } 2612 2613 /* 2614 * Copy from a 3D region in this Allocation into an array. This 2615 * method is type checked and will generate exceptions if the Allocation's 2616 * {@link android.renderscript.Element} does not match the component type 2617 * of the array passed in. 2618 * 2619 * <p> The size of the region is: w * h * d * {@link #getElement}.{@link 2620 * Element#getBytesSize}. 2621 * 2622 * <p> If the Allocation does not have Vec3 Elements, then the size of the 2623 * array in bytes must be at least the size of the region. 2624 * 2625 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2626 * is disabled, then the size of the array in bytes must be at least the size 2627 * of the region. The padding bytes for the cells must be part of the array. 2628 * 2629 * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding} 2630 * is enabled, then the size of the array in bytes must be at least 3/4 the size 2631 * of the region. The padding bytes for the cells must not be part of the array. 2632 * 2633 * @param xoff X offset of the region to copy in this Allocation 2634 * @param yoff Y offset of the region to copy in this Allocation 2635 * @param zoff Z offset of the region to copy in this Allocation 2636 * @param w Width of the region to copy 2637 * @param h Height of the region to copy 2638 * @param d Depth of the region to copy 2639 * @param array Dest Array to be copied into 2640 */ 2641 public void copy3DRangeTo(int xoff, int yoff, int zoff, int w, int h, int d, Object array) { 2642 copy3DRangeToUnchecked(xoff, yoff, zoff, w, h, d, array, 2643 validateObjectIsPrimitiveArray(array, true), 2644 java.lang.reflect.Array.getLength(array)); 2645 } 2646 2647 // creation 2648 2649 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options(); 2650 static { 2651 mBitmapOptions.inScaled = false; 2652 } 2653 2654 /** 2655 * Creates a new Allocation with the given {@link 2656 * android.renderscript.Type}, mipmap flag, and usage flags. 2657 * 2658 * @param type RenderScript type describing data layout 2659 * @param mips specifies desired mipmap behaviour for the 2660 * allocation 2661 * @param usage bit field specifying how the Allocation is 2662 * utilized 2663 */ 2664 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) { 2665 try { 2666 Trace.traceBegin(RenderScript.TRACE_TAG, "createTyped"); 2667 rs.validate(); 2668 if (type.getID(rs) == 0) { 2669 throw new RSInvalidStateException("Bad Type"); 2670 } 2671 // TODO: What if there is an exception after this? The native allocation would leak. 2672 long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0); 2673 if (id == 0) { 2674 throw new RSRuntimeException("Allocation creation failed."); 2675 } 2676 return new Allocation(id, rs, type, false, usage, mips); 2677 } finally { 2678 Trace.traceEnd(RenderScript.TRACE_TAG); 2679 } 2680 } 2681 2682 /** 2683 * Creates an Allocation with the size specified by the type and no mipmaps 2684 * generated by default 2685 * 2686 * @param rs Context to which the allocation will belong. 2687 * @param type renderscript type describing data layout 2688 * @param usage bit field specifying how the allocation is 2689 * utilized 2690 * 2691 * @return allocation 2692 */ 2693 static public Allocation createTyped(RenderScript rs, Type type, int usage) { 2694 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage); 2695 } 2696 2697 /** 2698 * Creates an Allocation for use by scripts with a given {@link 2699 * android.renderscript.Type} and no mipmaps 2700 * 2701 * @param rs Context to which the Allocation will belong. 2702 * @param type RenderScript Type describing data layout 2703 * 2704 * @return allocation 2705 */ 2706 static public Allocation createTyped(RenderScript rs, Type type) { 2707 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT); 2708 } 2709 2710 /** 2711 * Creates an Allocation with a specified number of given elements 2712 * 2713 * @param rs Context to which the Allocation will belong. 2714 * @param e Element to use in the Allocation 2715 * @param count the number of Elements in the Allocation 2716 * @param usage bit field specifying how the Allocation is 2717 * utilized 2718 * 2719 * @return allocation 2720 */ 2721 static public Allocation createSized(RenderScript rs, Element e, 2722 int count, int usage) { 2723 try { 2724 Trace.traceBegin(RenderScript.TRACE_TAG, "createSized"); 2725 rs.validate(); 2726 Type.Builder b = new Type.Builder(rs, e); 2727 b.setX(count); 2728 Type t = b.create(); 2729 2730 long id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0); 2731 if (id == 0) { 2732 throw new RSRuntimeException("Allocation creation failed."); 2733 } 2734 return new Allocation(id, rs, t, true, usage, MipmapControl.MIPMAP_NONE); 2735 } finally { 2736 Trace.traceEnd(RenderScript.TRACE_TAG); 2737 } 2738 } 2739 2740 /** 2741 * Creates an Allocation with a specified number of given elements 2742 * 2743 * @param rs Context to which the Allocation will belong. 2744 * @param e Element to use in the Allocation 2745 * @param count the number of Elements in the Allocation 2746 * 2747 * @return allocation 2748 */ 2749 static public Allocation createSized(RenderScript rs, Element e, int count) { 2750 return createSized(rs, e, count, USAGE_SCRIPT); 2751 } 2752 2753 static Element elementFromBitmap(RenderScript rs, Bitmap b) { 2754 final Bitmap.Config bc = b.getConfig(); 2755 if (bc == Bitmap.Config.ALPHA_8) { 2756 return Element.A_8(rs); 2757 } 2758 if (bc == Bitmap.Config.ARGB_4444) { 2759 return Element.RGBA_4444(rs); 2760 } 2761 if (bc == Bitmap.Config.ARGB_8888) { 2762 return Element.RGBA_8888(rs); 2763 } 2764 if (bc == Bitmap.Config.RGB_565) { 2765 return Element.RGB_565(rs); 2766 } 2767 throw new RSInvalidStateException("Bad bitmap type: " + bc); 2768 } 2769 2770 static Type typeFromBitmap(RenderScript rs, Bitmap b, 2771 MipmapControl mip) { 2772 Element e = elementFromBitmap(rs, b); 2773 Type.Builder tb = new Type.Builder(rs, e); 2774 tb.setX(b.getWidth()); 2775 tb.setY(b.getHeight()); 2776 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL); 2777 return tb.create(); 2778 } 2779 2780 /** 2781 * Creates an Allocation from a {@link android.graphics.Bitmap}. 2782 * 2783 * @param rs Context to which the allocation will belong. 2784 * @param b Bitmap source for the allocation data 2785 * @param mips specifies desired mipmap behaviour for the 2786 * allocation 2787 * @param usage bit field specifying how the allocation is 2788 * utilized 2789 * 2790 * @return Allocation containing bitmap data 2791 * 2792 */ 2793 static public Allocation createFromBitmap(RenderScript rs, Bitmap b, 2794 MipmapControl mips, 2795 int usage) { 2796 try { 2797 Trace.traceBegin(RenderScript.TRACE_TAG, "createFromBitmap"); 2798 rs.validate(); 2799 2800 // WAR undocumented color formats 2801 if (b.getConfig() == null) { 2802 if ((usage & USAGE_SHARED) != 0) { 2803 throw new RSIllegalArgumentException("USAGE_SHARED cannot be used with a Bitmap that has a null config."); 2804 } 2805 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888); 2806 Canvas c = new Canvas(newBitmap); 2807 c.drawBitmap(b, 0, 0, null); 2808 return createFromBitmap(rs, newBitmap, mips, usage); 2809 } 2810 2811 Type t = typeFromBitmap(rs, b, mips); 2812 2813 // enable optimized bitmap path only with no mipmap and script-only usage 2814 if (mips == MipmapControl.MIPMAP_NONE && 2815 t.getElement().isCompatible(Element.RGBA_8888(rs)) && 2816 usage == (USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE)) { 2817 long id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage); 2818 if (id == 0) { 2819 throw new RSRuntimeException("Load failed."); 2820 } 2821 2822 // keep a reference to the Bitmap around to prevent GC 2823 Allocation alloc = new Allocation(id, rs, t, true, usage, mips); 2824 alloc.setBitmap(b); 2825 return alloc; 2826 } 2827 2828 2829 long id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage); 2830 if (id == 0) { 2831 throw new RSRuntimeException("Load failed."); 2832 } 2833 return new Allocation(id, rs, t, true, usage, mips); 2834 } finally { 2835 Trace.traceEnd(RenderScript.TRACE_TAG); 2836 } 2837 } 2838 2839 /** 2840 * Gets or creates a ByteBuffer that contains the raw data of the current Allocation. 2841 * <p> If the Allocation is created with USAGE_IO_INPUT, the returned ByteBuffer 2842 * would contain the up-to-date data as READ ONLY. 2843 * For a 2D or 3D Allocation, the raw data maybe padded so that each row of 2844 * the Allocation has certain alignment. The size of each row including padding, 2845 * called stride, can be queried using the {@link #getStride()} method. 2846 * 2847 * Note: Operating on the ByteBuffer of a destroyed Allocation will triger errors. 2848 * 2849 * @return ByteBuffer The ByteBuffer associated with raw data pointer of the Allocation. 2850 */ 2851 public ByteBuffer getByteBuffer() { 2852 // Create a new ByteBuffer if it is not initialized or using IO_INPUT. 2853 if (mType.hasFaces()) { 2854 throw new RSInvalidStateException("Cubemap is not supported for getByteBuffer()."); 2855 } 2856 if (mType.getYuv() == android.graphics.ImageFormat.NV21 || 2857 mType.getYuv() == android.graphics.ImageFormat.YV12 || 2858 mType.getYuv() == android.graphics.ImageFormat.YUV_420_888 ) { 2859 throw new RSInvalidStateException("YUV format is not supported for getByteBuffer()."); 2860 } 2861 if (mByteBuffer == null || (mUsage & USAGE_IO_INPUT) != 0) { 2862 int xBytesSize = mType.getX() * mType.getElement().getBytesSize(); 2863 long[] stride = new long[1]; 2864 mByteBuffer = mRS.nAllocationGetByteBuffer(getID(mRS), stride, xBytesSize, mType.getY(), mType.getZ()); 2865 mByteBufferStride = stride[0]; 2866 } 2867 if ((mUsage & USAGE_IO_INPUT) != 0) { 2868 return mByteBuffer.asReadOnlyBuffer(); 2869 } 2870 return mByteBuffer; 2871 } 2872 2873 /** 2874 * Creates a new Allocation Array with the given {@link 2875 * android.renderscript.Type}, and usage flags. 2876 * Note: If the input allocation is of usage: USAGE_IO_INPUT, 2877 * the created Allocation will be sharing the same BufferQueue. 2878 * 2879 * @param rs RenderScript context 2880 * @param t RenderScript type describing data layout 2881 * @param usage bit field specifying how the Allocation is 2882 * utilized 2883 * @param numAlloc Number of Allocations in the array. 2884 * @return Allocation[] 2885 */ 2886 public static Allocation[] createAllocations(RenderScript rs, Type t, int usage, int numAlloc) { 2887 try { 2888 Trace.traceBegin(RenderScript.TRACE_TAG, "createAllocations"); 2889 rs.validate(); 2890 if (t.getID(rs) == 0) { 2891 throw new RSInvalidStateException("Bad Type"); 2892 } 2893 2894 Allocation[] mAllocationArray = new Allocation[numAlloc]; 2895 mAllocationArray[0] = createTyped(rs, t, usage); 2896 if ((usage & USAGE_IO_INPUT) != 0) { 2897 if (numAlloc > MAX_NUMBER_IO_INPUT_ALLOC) { 2898 mAllocationArray[0].destroy(); 2899 throw new RSIllegalArgumentException("Exceeds the max number of Allocations allowed: " + 2900 MAX_NUMBER_IO_INPUT_ALLOC); 2901 } 2902 mAllocationArray[0].setupBufferQueue(numAlloc);; 2903 } 2904 2905 for (int i=1; i<numAlloc; i++) { 2906 mAllocationArray[i] = createFromAllocation(rs, mAllocationArray[0]); 2907 } 2908 return mAllocationArray; 2909 } finally { 2910 Trace.traceEnd(RenderScript.TRACE_TAG); 2911 } 2912 } 2913 2914 /** 2915 * Creates a new Allocation with the given {@link 2916 * android.renderscript.Allocation}. The same data layout of 2917 * the input Allocation will be applied. 2918 * <p> If the input allocation is of usage: USAGE_IO_INPUT, the created 2919 * Allocation will be sharing the same BufferQueue. 2920 * 2921 * @param rs Context to which the allocation will belong. 2922 * @param alloc RenderScript Allocation describing data layout. 2923 * @return Allocation sharing the same data structure. 2924 */ 2925 static Allocation createFromAllocation(RenderScript rs, Allocation alloc) { 2926 try { 2927 Trace.traceBegin(RenderScript.TRACE_TAG, "createFromAllcation"); 2928 rs.validate(); 2929 if (alloc.getID(rs) == 0) { 2930 throw new RSInvalidStateException("Bad input Allocation"); 2931 } 2932 2933 Type type = alloc.getType(); 2934 int usage = alloc.getUsage(); 2935 MipmapControl mips = alloc.getMipmap(); 2936 long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0); 2937 if (id == 0) { 2938 throw new RSRuntimeException("Allocation creation failed."); 2939 } 2940 Allocation outAlloc = new Allocation(id, rs, type, false, usage, mips); 2941 if ((usage & USAGE_IO_INPUT) != 0) { 2942 outAlloc.shareBufferQueue(alloc); 2943 } 2944 return outAlloc; 2945 } finally { 2946 Trace.traceEnd(RenderScript.TRACE_TAG); 2947 } 2948 } 2949 2950 /** 2951 * Initialize BufferQueue with specified max number of buffers. 2952 */ 2953 void setupBufferQueue(int numAlloc) { 2954 mRS.validate(); 2955 if ((mUsage & USAGE_IO_INPUT) == 0) { 2956 throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT."); 2957 } 2958 mRS.nAllocationSetupBufferQueue(getID(mRS), numAlloc); 2959 } 2960 2961 /** 2962 * Share the BufferQueue with another {@link #USAGE_IO_INPUT} Allocation. 2963 * 2964 * @param alloc Allocation to associate with allocation 2965 */ 2966 void shareBufferQueue(Allocation alloc) { 2967 mRS.validate(); 2968 if ((mUsage & USAGE_IO_INPUT) == 0) { 2969 throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT."); 2970 } 2971 mGetSurfaceSurface = alloc.getSurface(); 2972 mRS.nAllocationShareBufferQueue(getID(mRS), alloc.getID(mRS)); 2973 } 2974 2975 /** 2976 * Gets the stride of the Allocation. 2977 * For a 2D or 3D Allocation, the raw data maybe padded so that each row of 2978 * the Allocation has certain alignment. The size of each row including such 2979 * padding is called stride. 2980 * 2981 * @return the stride. For 1D Allocation, the stride will be the number of 2982 * bytes of this Allocation. For 2D and 3D Allocations, the stride 2983 * will be the stride in X dimension measuring in bytes. 2984 */ 2985 public long getStride() { 2986 if (mByteBufferStride == -1) { 2987 getByteBuffer(); 2988 } 2989 return mByteBufferStride; 2990 } 2991 2992 /** 2993 * Get the timestamp for the most recent buffer held by this Allocation. 2994 * The timestamp is guaranteed to be unique and monotonically increasing. 2995 * Default value: -1. The timestamp will be updated after each {@link 2996 * #ioReceive ioReceive()} call. 2997 * 2998 * It can be used to identify the images by comparing the unique timestamps 2999 * when used with {@link android.hardware.camera2} APIs. 3000 * Example steps: 3001 * 1. Save {@link android.hardware.camera2.TotalCaptureResult} when the 3002 * capture is completed. 3003 * 2. Get the timestamp after {@link #ioReceive ioReceive()} call. 3004 * 3. Comparing totalCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP) with 3005 * alloc.getTimeStamp(). 3006 * @return long Timestamp associated with the buffer held by the Allocation. 3007 */ 3008 public long getTimeStamp() { 3009 return mTimeStamp; 3010 } 3011 3012 /** 3013 * Returns the handle to a raw buffer that is being managed by the screen 3014 * compositor. This operation is only valid for Allocations with {@link 3015 * #USAGE_IO_INPUT}. 3016 * 3017 * @return Surface object associated with allocation 3018 * 3019 */ 3020 public Surface getSurface() { 3021 if ((mUsage & USAGE_IO_INPUT) == 0) { 3022 throw new RSInvalidStateException("Allocation is not a surface texture."); 3023 } 3024 3025 if (mGetSurfaceSurface == null) { 3026 mGetSurfaceSurface = mRS.nAllocationGetSurface(getID(mRS)); 3027 } 3028 3029 return mGetSurfaceSurface; 3030 } 3031 3032 /** 3033 * Associate a {@link android.view.Surface} with this Allocation. This 3034 * operation is only valid for Allocations with {@link #USAGE_IO_OUTPUT}. 3035 * 3036 * @param sur Surface to associate with allocation 3037 */ 3038 public void setSurface(Surface sur) { 3039 mRS.validate(); 3040 if ((mUsage & USAGE_IO_OUTPUT) == 0) { 3041 throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT."); 3042 } 3043 3044 mRS.nAllocationSetSurface(getID(mRS), sur); 3045 } 3046 3047 /** 3048 * Creates an Allocation from a {@link android.graphics.Bitmap}. 3049 * 3050 * <p>With target API version 18 or greater, this Allocation will be created 3051 * with {@link #USAGE_SHARED}, {@link #USAGE_SCRIPT}, and {@link 3052 * #USAGE_GRAPHICS_TEXTURE}. With target API version 17 or lower, this 3053 * Allocation will be created with {@link #USAGE_GRAPHICS_TEXTURE}.</p> 3054 * 3055 * @param rs Context to which the allocation will belong. 3056 * @param b bitmap source for the allocation data 3057 * 3058 * @return Allocation containing bitmap data 3059 * 3060 */ 3061 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) { 3062 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) { 3063 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, 3064 USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE); 3065 } 3066 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, 3067 USAGE_GRAPHICS_TEXTURE); 3068 } 3069 3070 /** 3071 * Creates a cubemap Allocation from a {@link android.graphics.Bitmap} 3072 * containing the horizontal list of cube faces. Each face must be a square, 3073 * have the same size as all other faces, and have a width that is a power 3074 * of 2. 3075 * 3076 * @param rs Context to which the allocation will belong. 3077 * @param b Bitmap with cubemap faces layed out in the following 3078 * format: right, left, top, bottom, front, back 3079 * @param mips specifies desired mipmap behaviour for the cubemap 3080 * @param usage bit field specifying how the cubemap is utilized 3081 * 3082 * @return allocation containing cubemap data 3083 * 3084 */ 3085 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b, 3086 MipmapControl mips, 3087 int usage) { 3088 rs.validate(); 3089 3090 int height = b.getHeight(); 3091 int width = b.getWidth(); 3092 3093 if (width % 6 != 0) { 3094 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6"); 3095 } 3096 if (width / 6 != height) { 3097 throw new RSIllegalArgumentException("Only square cube map faces supported"); 3098 } 3099 boolean isPow2 = (height & (height - 1)) == 0; 3100 if (!isPow2) { 3101 throw new RSIllegalArgumentException("Only power of 2 cube faces supported"); 3102 } 3103 3104 Element e = elementFromBitmap(rs, b); 3105 Type.Builder tb = new Type.Builder(rs, e); 3106 tb.setX(height); 3107 tb.setY(height); 3108 tb.setFaces(true); 3109 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL); 3110 Type t = tb.create(); 3111 3112 long id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage); 3113 if(id == 0) { 3114 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e); 3115 } 3116 return new Allocation(id, rs, t, true, usage, mips); 3117 } 3118 3119 /** 3120 * Creates a non-mipmapped cubemap Allocation for use as a graphics texture 3121 * from a {@link android.graphics.Bitmap} containing the horizontal list of 3122 * cube faces. Each face must be a square, have the same size as all other 3123 * faces, and have a width that is a power of 2. 3124 * 3125 * @param rs Context to which the allocation will belong. 3126 * @param b bitmap with cubemap faces layed out in the following 3127 * format: right, left, top, bottom, front, back 3128 * 3129 * @return allocation containing cubemap data 3130 * 3131 */ 3132 static public Allocation createCubemapFromBitmap(RenderScript rs, 3133 Bitmap b) { 3134 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, 3135 USAGE_GRAPHICS_TEXTURE); 3136 } 3137 3138 /** 3139 * Creates a cubemap Allocation from 6 {@link android.graphics.Bitmap} 3140 * objects containing the cube faces. Each face must be a square, have the 3141 * same size as all other faces, and have a width that is a power of 2. 3142 * 3143 * @param rs Context to which the allocation will belong. 3144 * @param xpos cubemap face in the positive x direction 3145 * @param xneg cubemap face in the negative x direction 3146 * @param ypos cubemap face in the positive y direction 3147 * @param yneg cubemap face in the negative y direction 3148 * @param zpos cubemap face in the positive z direction 3149 * @param zneg cubemap face in the negative z direction 3150 * @param mips specifies desired mipmap behaviour for the cubemap 3151 * @param usage bit field specifying how the cubemap is utilized 3152 * 3153 * @return allocation containing cubemap data 3154 * 3155 */ 3156 static public Allocation createCubemapFromCubeFaces(RenderScript rs, 3157 Bitmap xpos, 3158 Bitmap xneg, 3159 Bitmap ypos, 3160 Bitmap yneg, 3161 Bitmap zpos, 3162 Bitmap zneg, 3163 MipmapControl mips, 3164 int usage) { 3165 int height = xpos.getHeight(); 3166 if (xpos.getWidth() != height || 3167 xneg.getWidth() != height || xneg.getHeight() != height || 3168 ypos.getWidth() != height || ypos.getHeight() != height || 3169 yneg.getWidth() != height || yneg.getHeight() != height || 3170 zpos.getWidth() != height || zpos.getHeight() != height || 3171 zneg.getWidth() != height || zneg.getHeight() != height) { 3172 throw new RSIllegalArgumentException("Only square cube map faces supported"); 3173 } 3174 boolean isPow2 = (height & (height - 1)) == 0; 3175 if (!isPow2) { 3176 throw new RSIllegalArgumentException("Only power of 2 cube faces supported"); 3177 } 3178 3179 Element e = elementFromBitmap(rs, xpos); 3180 Type.Builder tb = new Type.Builder(rs, e); 3181 tb.setX(height); 3182 tb.setY(height); 3183 tb.setFaces(true); 3184 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL); 3185 Type t = tb.create(); 3186 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage); 3187 3188 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap); 3189 adapter.setFace(Type.CubemapFace.POSITIVE_X); 3190 adapter.copyFrom(xpos); 3191 adapter.setFace(Type.CubemapFace.NEGATIVE_X); 3192 adapter.copyFrom(xneg); 3193 adapter.setFace(Type.CubemapFace.POSITIVE_Y); 3194 adapter.copyFrom(ypos); 3195 adapter.setFace(Type.CubemapFace.NEGATIVE_Y); 3196 adapter.copyFrom(yneg); 3197 adapter.setFace(Type.CubemapFace.POSITIVE_Z); 3198 adapter.copyFrom(zpos); 3199 adapter.setFace(Type.CubemapFace.NEGATIVE_Z); 3200 adapter.copyFrom(zneg); 3201 3202 return cubemap; 3203 } 3204 3205 /** 3206 * Creates a non-mipmapped cubemap Allocation for use as a sampler input 3207 * from 6 {@link android.graphics.Bitmap} objects containing the cube 3208 * faces. Each face must be a square, have the same size as all other faces, 3209 * and have a width that is a power of 2. 3210 * 3211 * @param rs Context to which the allocation will belong. 3212 * @param xpos cubemap face in the positive x direction 3213 * @param xneg cubemap face in the negative x direction 3214 * @param ypos cubemap face in the positive y direction 3215 * @param yneg cubemap face in the negative y direction 3216 * @param zpos cubemap face in the positive z direction 3217 * @param zneg cubemap face in the negative z direction 3218 * 3219 * @return allocation containing cubemap data 3220 * 3221 */ 3222 static public Allocation createCubemapFromCubeFaces(RenderScript rs, 3223 Bitmap xpos, 3224 Bitmap xneg, 3225 Bitmap ypos, 3226 Bitmap yneg, 3227 Bitmap zpos, 3228 Bitmap zneg) { 3229 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg, 3230 zpos, zneg, MipmapControl.MIPMAP_NONE, 3231 USAGE_GRAPHICS_TEXTURE); 3232 } 3233 3234 /** 3235 * Creates an Allocation from the Bitmap referenced 3236 * by resource ID. 3237 * 3238 * @param rs Context to which the allocation will belong. 3239 * @param res application resources 3240 * @param id resource id to load the data from 3241 * @param mips specifies desired mipmap behaviour for the 3242 * allocation 3243 * @param usage bit field specifying how the allocation is 3244 * utilized 3245 * 3246 * @return Allocation containing resource data 3247 * 3248 */ 3249 static public Allocation createFromBitmapResource(RenderScript rs, 3250 Resources res, 3251 int id, 3252 MipmapControl mips, 3253 int usage) { 3254 3255 rs.validate(); 3256 if ((usage & (USAGE_SHARED | USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) { 3257 throw new RSIllegalArgumentException("Unsupported usage specified."); 3258 } 3259 Bitmap b = BitmapFactory.decodeResource(res, id); 3260 Allocation alloc = createFromBitmap(rs, b, mips, usage); 3261 b.recycle(); 3262 return alloc; 3263 } 3264 3265 /** 3266 * Creates a non-mipmapped Allocation to use as a graphics texture from the 3267 * {@link android.graphics.Bitmap} referenced by resource ID. 3268 * 3269 * <p>With target API version 18 or greater, this allocation will be created 3270 * with {@link #USAGE_SCRIPT} and {@link #USAGE_GRAPHICS_TEXTURE}. With 3271 * target API version 17 or lower, this allocation will be created with 3272 * {@link #USAGE_GRAPHICS_TEXTURE}.</p> 3273 * 3274 * @param rs Context to which the allocation will belong. 3275 * @param res application resources 3276 * @param id resource id to load the data from 3277 * 3278 * @return Allocation containing resource data 3279 * 3280 */ 3281 static public Allocation createFromBitmapResource(RenderScript rs, 3282 Resources res, 3283 int id) { 3284 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) { 3285 return createFromBitmapResource(rs, res, id, 3286 MipmapControl.MIPMAP_NONE, 3287 USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE); 3288 } 3289 return createFromBitmapResource(rs, res, id, 3290 MipmapControl.MIPMAP_NONE, 3291 USAGE_GRAPHICS_TEXTURE); 3292 } 3293 3294 /** 3295 * Creates an Allocation containing string data encoded in UTF-8 format. 3296 * 3297 * @param rs Context to which the allocation will belong. 3298 * @param str string to create the allocation from 3299 * @param usage bit field specifying how the allocaiton is 3300 * utilized 3301 * 3302 */ 3303 static public Allocation createFromString(RenderScript rs, 3304 String str, 3305 int usage) { 3306 rs.validate(); 3307 byte[] allocArray = null; 3308 try { 3309 allocArray = str.getBytes("UTF-8"); 3310 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage); 3311 alloc.copyFrom(allocArray); 3312 return alloc; 3313 } 3314 catch (Exception e) { 3315 throw new RSRuntimeException("Could not convert string to utf-8."); 3316 } 3317 } 3318 3319 /** 3320 * Interface to handle notification when new buffers are available via 3321 * {@link #USAGE_IO_INPUT}. An application will receive one notification 3322 * when a buffer is available. Additional buffers will not trigger new 3323 * notifications until a buffer is processed. 3324 */ 3325 public interface OnBufferAvailableListener { 3326 public void onBufferAvailable(Allocation a); 3327 } 3328 3329 /** 3330 * Set a notification handler for {@link #USAGE_IO_INPUT}. 3331 * 3332 * @param callback instance of the OnBufferAvailableListener 3333 * class to be called when buffer arrive. 3334 */ 3335 public void setOnBufferAvailableListener(OnBufferAvailableListener callback) { 3336 synchronized(mAllocationMap) { 3337 mAllocationMap.put(new Long(getID(mRS)), this); 3338 mBufferNotifier = callback; 3339 } 3340 } 3341 3342 static void sendBufferNotification(long id) { 3343 synchronized(mAllocationMap) { 3344 Allocation a = mAllocationMap.get(new Long(id)); 3345 3346 if ((a != null) && (a.mBufferNotifier != null)) { 3347 a.mBufferNotifier.onBufferAvailable(a); 3348 } 3349 } 3350 } 3351 3352 /** 3353 * For USAGE_IO_OUTPUT, destroy() implies setSurface(null). 3354 * 3355 */ 3356 @Override 3357 public void destroy() { 3358 if((mUsage & USAGE_IO_OUTPUT) != 0) { 3359 setSurface(null); 3360 } 3361 3362 if (mType != null && mOwningType) { 3363 mType.destroy(); 3364 } 3365 3366 super.destroy(); 3367 } 3368 3369 } 3370