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 mAllocationArray[0].destroy(); 2899 throw new RSIllegalArgumentException("Exceeds the max number of Allocations allowed: " + 2900 MAX_NUMBER_IO_INPUT_ALLOC); 2901 } 2902 mAllocationArray[0].setupBufferQueue(numAlloc);; 2903 } 2904 2905 for (int i=1; i<numAlloc; i++) { 2906 mAllocationArray[i] = createFromAllocation(rs, mAllocationArray[0]); 2907 } 2908 return mAllocationArray; 2909 } finally { 2910 Trace.traceEnd(RenderScript.TRACE_TAG); 2911 } 2912 } 2913 2914 /** 2915 * Creates a new Allocation with the given {@link 2916 * android.renderscript.Allocation}. The same data layout of 2917 * the input Allocation will be applied. 2918 * <p> If the input allocation is of usage: USAGE_IO_INPUT, the created 2919 * Allocation will be sharing the same BufferQueue. 2920 * 2921 * @param rs Context to which the allocation will belong. 2922 * @param alloc RenderScript Allocation describing data layout. 2923 * @return Allocation sharing the same data structure. 2924 */ createFromAllocation(RenderScript rs, Allocation alloc)2925 static Allocation createFromAllocation(RenderScript rs, Allocation alloc) { 2926 try { 2927 Trace.traceBegin(RenderScript.TRACE_TAG, "createFromAllcation"); 2928 rs.validate(); 2929 if (alloc.getID(rs) == 0) { 2930 throw new RSInvalidStateException("Bad input Allocation"); 2931 } 2932 2933 Type type = alloc.getType(); 2934 int usage = alloc.getUsage(); 2935 MipmapControl mips = alloc.getMipmap(); 2936 long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0); 2937 if (id == 0) { 2938 throw new RSRuntimeException("Allocation creation failed."); 2939 } 2940 Allocation outAlloc = new Allocation(id, rs, type, false, usage, mips); 2941 if ((usage & USAGE_IO_INPUT) != 0) { 2942 outAlloc.shareBufferQueue(alloc); 2943 } 2944 return outAlloc; 2945 } finally { 2946 Trace.traceEnd(RenderScript.TRACE_TAG); 2947 } 2948 } 2949 2950 /** 2951 * Initialize BufferQueue with specified max number of buffers. 2952 */ setupBufferQueue(int numAlloc)2953 void setupBufferQueue(int numAlloc) { 2954 mRS.validate(); 2955 if ((mUsage & USAGE_IO_INPUT) == 0) { 2956 throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT."); 2957 } 2958 mRS.nAllocationSetupBufferQueue(getID(mRS), numAlloc); 2959 } 2960 2961 /** 2962 * Share the BufferQueue with another {@link #USAGE_IO_INPUT} Allocation. 2963 * 2964 * @param alloc Allocation to associate with allocation 2965 */ shareBufferQueue(Allocation alloc)2966 void shareBufferQueue(Allocation alloc) { 2967 mRS.validate(); 2968 if ((mUsage & USAGE_IO_INPUT) == 0) { 2969 throw new RSInvalidStateException("Allocation is not USAGE_IO_INPUT."); 2970 } 2971 mGetSurfaceSurface = alloc.getSurface(); 2972 mRS.nAllocationShareBufferQueue(getID(mRS), alloc.getID(mRS)); 2973 } 2974 2975 /** 2976 * Gets the stride of the Allocation. 2977 * For a 2D or 3D Allocation, the raw data maybe padded so that each row of 2978 * the Allocation has certain alignment. The size of each row including such 2979 * padding is called stride. 2980 * 2981 * @return the stride. For 1D Allocation, the stride will be the number of 2982 * bytes of this Allocation. For 2D and 3D Allocations, the stride 2983 * will be the stride in X dimension measuring in bytes. 2984 */ getStride()2985 public long getStride() { 2986 if (mByteBufferStride == -1) { 2987 getByteBuffer(); 2988 } 2989 return mByteBufferStride; 2990 } 2991 2992 /** 2993 * Get the timestamp for the most recent buffer held by this Allocation. 2994 * The timestamp is guaranteed to be unique and monotonically increasing. 2995 * Default value: -1. The timestamp will be updated after each {@link 2996 * #ioReceive ioReceive()} call. 2997 * 2998 * It can be used to identify the images by comparing the unique timestamps 2999 * when used with {@link android.hardware.camera2} APIs. 3000 * Example steps: 3001 * 1. Save {@link android.hardware.camera2.TotalCaptureResult} when the 3002 * capture is completed. 3003 * 2. Get the timestamp after {@link #ioReceive ioReceive()} call. 3004 * 3. Comparing totalCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP) with 3005 * alloc.getTimeStamp(). 3006 * @return long Timestamp associated with the buffer held by the Allocation. 3007 */ getTimeStamp()3008 public long getTimeStamp() { 3009 return mTimeStamp; 3010 } 3011 3012 /** 3013 * Returns the handle to a raw buffer that is being managed by the screen 3014 * compositor. This operation is only valid for Allocations with {@link 3015 * #USAGE_IO_INPUT}. 3016 * 3017 * @return Surface object associated with allocation 3018 * 3019 */ getSurface()3020 public Surface getSurface() { 3021 if ((mUsage & USAGE_IO_INPUT) == 0) { 3022 throw new RSInvalidStateException("Allocation is not a surface texture."); 3023 } 3024 3025 if (mGetSurfaceSurface == null) { 3026 mGetSurfaceSurface = mRS.nAllocationGetSurface(getID(mRS)); 3027 } 3028 3029 return mGetSurfaceSurface; 3030 } 3031 3032 /** 3033 * Associate a {@link android.view.Surface} with this Allocation. This 3034 * operation is only valid for Allocations with {@link #USAGE_IO_OUTPUT}. 3035 * 3036 * @param sur Surface to associate with allocation 3037 */ setSurface(Surface sur)3038 public void setSurface(Surface sur) { 3039 mRS.validate(); 3040 if ((mUsage & USAGE_IO_OUTPUT) == 0) { 3041 throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT."); 3042 } 3043 3044 mRS.nAllocationSetSurface(getID(mRS), sur); 3045 } 3046 3047 /** 3048 * Creates an Allocation from a {@link android.graphics.Bitmap}. 3049 * 3050 * <p>With target API version 18 or greater, this Allocation will be created 3051 * with {@link #USAGE_SHARED}, {@link #USAGE_SCRIPT}, and {@link 3052 * #USAGE_GRAPHICS_TEXTURE}. With target API version 17 or lower, this 3053 * Allocation will be created with {@link #USAGE_GRAPHICS_TEXTURE}.</p> 3054 * 3055 * @param rs Context to which the allocation will belong. 3056 * @param b bitmap source for the allocation data 3057 * 3058 * @return Allocation containing bitmap data 3059 * 3060 */ createFromBitmap(RenderScript rs, Bitmap b)3061 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) { 3062 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) { 3063 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, 3064 USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE); 3065 } 3066 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, 3067 USAGE_GRAPHICS_TEXTURE); 3068 } 3069 3070 /** 3071 * Creates a cubemap Allocation from a {@link android.graphics.Bitmap} 3072 * containing the horizontal list of cube faces. Each face must be a square, 3073 * have the same size as all other faces, and have a width that is a power 3074 * of 2. 3075 * 3076 * @param rs Context to which the allocation will belong. 3077 * @param b Bitmap with cubemap faces layed out in the following 3078 * format: right, left, top, bottom, front, back 3079 * @param mips specifies desired mipmap behaviour for the cubemap 3080 * @param usage bit field specifying how the cubemap is utilized 3081 * 3082 * @return allocation containing cubemap data 3083 * 3084 */ createCubemapFromBitmap(RenderScript rs, Bitmap b, MipmapControl mips, int usage)3085 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b, 3086 MipmapControl mips, 3087 int usage) { 3088 rs.validate(); 3089 3090 int height = b.getHeight(); 3091 int width = b.getWidth(); 3092 3093 if (width % 6 != 0) { 3094 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6"); 3095 } 3096 if (width / 6 != height) { 3097 throw new RSIllegalArgumentException("Only square cube map faces supported"); 3098 } 3099 boolean isPow2 = (height & (height - 1)) == 0; 3100 if (!isPow2) { 3101 throw new RSIllegalArgumentException("Only power of 2 cube faces supported"); 3102 } 3103 3104 Element e = elementFromBitmap(rs, b); 3105 Type.Builder tb = new Type.Builder(rs, e); 3106 tb.setX(height); 3107 tb.setY(height); 3108 tb.setFaces(true); 3109 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL); 3110 Type t = tb.create(); 3111 3112 long id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage); 3113 if(id == 0) { 3114 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e); 3115 } 3116 return new Allocation(id, rs, t, true, usage, mips); 3117 } 3118 3119 /** 3120 * Creates a non-mipmapped cubemap Allocation for use as a graphics texture 3121 * from a {@link android.graphics.Bitmap} containing the horizontal list of 3122 * cube faces. Each face must be a square, have the same size as all other 3123 * faces, and have a width that is a power of 2. 3124 * 3125 * @param rs Context to which the allocation will belong. 3126 * @param b bitmap with cubemap faces layed out in the following 3127 * format: right, left, top, bottom, front, back 3128 * 3129 * @return allocation containing cubemap data 3130 * 3131 */ createCubemapFromBitmap(RenderScript rs, Bitmap b)3132 static public Allocation createCubemapFromBitmap(RenderScript rs, 3133 Bitmap b) { 3134 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, 3135 USAGE_GRAPHICS_TEXTURE); 3136 } 3137 3138 /** 3139 * Creates a cubemap Allocation from 6 {@link android.graphics.Bitmap} 3140 * objects containing the cube faces. Each face must be a square, have the 3141 * same size as all other faces, and have a width that is a power of 2. 3142 * 3143 * @param rs Context to which the allocation will belong. 3144 * @param xpos cubemap face in the positive x direction 3145 * @param xneg cubemap face in the negative x direction 3146 * @param ypos cubemap face in the positive y direction 3147 * @param yneg cubemap face in the negative y direction 3148 * @param zpos cubemap face in the positive z direction 3149 * @param zneg cubemap face in the negative z direction 3150 * @param mips specifies desired mipmap behaviour for the cubemap 3151 * @param usage bit field specifying how the cubemap is utilized 3152 * 3153 * @return allocation containing cubemap data 3154 * 3155 */ createCubemapFromCubeFaces(RenderScript rs, Bitmap xpos, Bitmap xneg, Bitmap ypos, Bitmap yneg, Bitmap zpos, Bitmap zneg, MipmapControl mips, int usage)3156 static public Allocation createCubemapFromCubeFaces(RenderScript rs, 3157 Bitmap xpos, 3158 Bitmap xneg, 3159 Bitmap ypos, 3160 Bitmap yneg, 3161 Bitmap zpos, 3162 Bitmap zneg, 3163 MipmapControl mips, 3164 int usage) { 3165 int height = xpos.getHeight(); 3166 if (xpos.getWidth() != height || 3167 xneg.getWidth() != height || xneg.getHeight() != height || 3168 ypos.getWidth() != height || ypos.getHeight() != height || 3169 yneg.getWidth() != height || yneg.getHeight() != height || 3170 zpos.getWidth() != height || zpos.getHeight() != height || 3171 zneg.getWidth() != height || zneg.getHeight() != height) { 3172 throw new RSIllegalArgumentException("Only square cube map faces supported"); 3173 } 3174 boolean isPow2 = (height & (height - 1)) == 0; 3175 if (!isPow2) { 3176 throw new RSIllegalArgumentException("Only power of 2 cube faces supported"); 3177 } 3178 3179 Element e = elementFromBitmap(rs, xpos); 3180 Type.Builder tb = new Type.Builder(rs, e); 3181 tb.setX(height); 3182 tb.setY(height); 3183 tb.setFaces(true); 3184 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL); 3185 Type t = tb.create(); 3186 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage); 3187 3188 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap); 3189 adapter.setFace(Type.CubemapFace.POSITIVE_X); 3190 adapter.copyFrom(xpos); 3191 adapter.setFace(Type.CubemapFace.NEGATIVE_X); 3192 adapter.copyFrom(xneg); 3193 adapter.setFace(Type.CubemapFace.POSITIVE_Y); 3194 adapter.copyFrom(ypos); 3195 adapter.setFace(Type.CubemapFace.NEGATIVE_Y); 3196 adapter.copyFrom(yneg); 3197 adapter.setFace(Type.CubemapFace.POSITIVE_Z); 3198 adapter.copyFrom(zpos); 3199 adapter.setFace(Type.CubemapFace.NEGATIVE_Z); 3200 adapter.copyFrom(zneg); 3201 3202 return cubemap; 3203 } 3204 3205 /** 3206 * Creates a non-mipmapped cubemap Allocation for use as a sampler input 3207 * from 6 {@link android.graphics.Bitmap} objects containing the cube 3208 * faces. Each face must be a square, have the same size as all other faces, 3209 * and have a width that is a power of 2. 3210 * 3211 * @param rs Context to which the allocation will belong. 3212 * @param xpos cubemap face in the positive x direction 3213 * @param xneg cubemap face in the negative x direction 3214 * @param ypos cubemap face in the positive y direction 3215 * @param yneg cubemap face in the negative y direction 3216 * @param zpos cubemap face in the positive z direction 3217 * @param zneg cubemap face in the negative z direction 3218 * 3219 * @return allocation containing cubemap data 3220 * 3221 */ createCubemapFromCubeFaces(RenderScript rs, Bitmap xpos, Bitmap xneg, Bitmap ypos, Bitmap yneg, Bitmap zpos, Bitmap zneg)3222 static public Allocation createCubemapFromCubeFaces(RenderScript rs, 3223 Bitmap xpos, 3224 Bitmap xneg, 3225 Bitmap ypos, 3226 Bitmap yneg, 3227 Bitmap zpos, 3228 Bitmap zneg) { 3229 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg, 3230 zpos, zneg, MipmapControl.MIPMAP_NONE, 3231 USAGE_GRAPHICS_TEXTURE); 3232 } 3233 3234 /** 3235 * Creates an Allocation from the Bitmap referenced 3236 * by resource ID. 3237 * 3238 * @param rs Context to which the allocation will belong. 3239 * @param res application resources 3240 * @param id resource id to load the data from 3241 * @param mips specifies desired mipmap behaviour for the 3242 * allocation 3243 * @param usage bit field specifying how the allocation is 3244 * utilized 3245 * 3246 * @return Allocation containing resource data 3247 * 3248 */ createFromBitmapResource(RenderScript rs, Resources res, int id, MipmapControl mips, int usage)3249 static public Allocation createFromBitmapResource(RenderScript rs, 3250 Resources res, 3251 int id, 3252 MipmapControl mips, 3253 int usage) { 3254 3255 rs.validate(); 3256 if ((usage & (USAGE_SHARED | USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) { 3257 throw new RSIllegalArgumentException("Unsupported usage specified."); 3258 } 3259 Bitmap b = BitmapFactory.decodeResource(res, id); 3260 Allocation alloc = createFromBitmap(rs, b, mips, usage); 3261 b.recycle(); 3262 return alloc; 3263 } 3264 3265 /** 3266 * Creates a non-mipmapped Allocation to use as a graphics texture from the 3267 * {@link android.graphics.Bitmap} referenced by resource ID. 3268 * 3269 * <p>With target API version 18 or greater, this allocation will be created 3270 * with {@link #USAGE_SCRIPT} and {@link #USAGE_GRAPHICS_TEXTURE}. With 3271 * target API version 17 or lower, this allocation will be created with 3272 * {@link #USAGE_GRAPHICS_TEXTURE}.</p> 3273 * 3274 * @param rs Context to which the allocation will belong. 3275 * @param res application resources 3276 * @param id resource id to load the data from 3277 * 3278 * @return Allocation containing resource data 3279 * 3280 */ createFromBitmapResource(RenderScript rs, Resources res, int id)3281 static public Allocation createFromBitmapResource(RenderScript rs, 3282 Resources res, 3283 int id) { 3284 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) { 3285 return createFromBitmapResource(rs, res, id, 3286 MipmapControl.MIPMAP_NONE, 3287 USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE); 3288 } 3289 return createFromBitmapResource(rs, res, id, 3290 MipmapControl.MIPMAP_NONE, 3291 USAGE_GRAPHICS_TEXTURE); 3292 } 3293 3294 /** 3295 * Creates an Allocation containing string data encoded in UTF-8 format. 3296 * 3297 * @param rs Context to which the allocation will belong. 3298 * @param str string to create the allocation from 3299 * @param usage bit field specifying how the allocaiton is 3300 * utilized 3301 * 3302 */ createFromString(RenderScript rs, String str, int usage)3303 static public Allocation createFromString(RenderScript rs, 3304 String str, 3305 int usage) { 3306 rs.validate(); 3307 byte[] allocArray = null; 3308 try { 3309 allocArray = str.getBytes("UTF-8"); 3310 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage); 3311 alloc.copyFrom(allocArray); 3312 return alloc; 3313 } 3314 catch (Exception e) { 3315 throw new RSRuntimeException("Could not convert string to utf-8."); 3316 } 3317 } 3318 3319 /** 3320 * Interface to handle notification when new buffers are available via 3321 * {@link #USAGE_IO_INPUT}. An application will receive one notification 3322 * when a buffer is available. Additional buffers will not trigger new 3323 * notifications until a buffer is processed. 3324 */ 3325 public interface OnBufferAvailableListener { onBufferAvailable(Allocation a)3326 public void onBufferAvailable(Allocation a); 3327 } 3328 3329 /** 3330 * Set a notification handler for {@link #USAGE_IO_INPUT}. 3331 * 3332 * @param callback instance of the OnBufferAvailableListener 3333 * class to be called when buffer arrive. 3334 */ setOnBufferAvailableListener(OnBufferAvailableListener callback)3335 public void setOnBufferAvailableListener(OnBufferAvailableListener callback) { 3336 synchronized(mAllocationMap) { 3337 mAllocationMap.put(new Long(getID(mRS)), this); 3338 mBufferNotifier = callback; 3339 } 3340 } 3341 sendBufferNotification(long id)3342 static void sendBufferNotification(long id) { 3343 synchronized(mAllocationMap) { 3344 Allocation a = mAllocationMap.get(new Long(id)); 3345 3346 if ((a != null) && (a.mBufferNotifier != null)) { 3347 a.mBufferNotifier.onBufferAvailable(a); 3348 } 3349 } 3350 } 3351 3352 /** 3353 * For USAGE_IO_OUTPUT, destroy() implies setSurface(null). 3354 * 3355 */ 3356 @Override destroy()3357 public void destroy() { 3358 if((mUsage & USAGE_IO_OUTPUT) != 0) { 3359 setSurface(null); 3360 } 3361 3362 if (mType != null && mOwningType) { 3363 mType.destroy(); 3364 } 3365 3366 super.destroy(); 3367 } 3368 3369 } 3370