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