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