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