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