Allocation.java revision fb9aa9f3ef11878caaf6fcfb5ea49ffb9f7abf33
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 17package android.renderscript; 18 19import java.io.IOException; 20import java.io.InputStream; 21import android.content.res.Resources; 22import android.content.res.AssetManager; 23import android.graphics.Bitmap; 24import android.graphics.BitmapFactory; 25import android.view.Surface; 26import android.graphics.SurfaceTexture; 27import android.util.Log; 28import android.util.TypedValue; 29 30/** 31 * <p> 32 * Memory allocation class for renderscript. An allocation combines a 33 * {@link android.renderscript.Type} with the memory to provide storage for user data and objects. 34 * This implies that all memory in Renderscript is typed. 35 * </p> 36 * 37 * <p>Allocations are the primary way data moves into and out of scripts. Memory is user 38 * synchronized and it's possible for allocations to exist in multiple memory spaces 39 * concurrently. Currently those spaces are:</p> 40 * <ul> 41 * <li>Script: accessable by RS scripts.</li> 42 * <li>Graphics Texture: accessable as a graphics texture.</li> 43 * <li>Graphics Vertex: accessable as graphical vertex data.</li> 44 * <li>Graphics Constants: Accessable as constants in user shaders</li> 45 * </ul> 46 * </p> 47 * <p> 48 * For example, when creating a allocation for a texture, the user can 49 * specify its memory spaces as both script and textures. This means that it can both 50 * be used as script binding and as a GPU texture for rendering. To maintain 51 * synchronization if a script modifies an allocation used by other targets it must 52 * call a synchronizing function to push the updates to the memory, otherwise the results 53 * are undefined. 54 * </p> 55 * <p>By default, Android system side updates are always applied to the script accessable 56 * memory. If this is not present, they are then applied to the various HW 57 * memory types. A {@link android.renderscript.Allocation#syncAll syncAll()} 58 * call is necessary after the script data is updated to 59 * keep the other memory spaces in sync.</p> 60 * 61 * <p>Allocation data is uploaded in one of two primary ways. For simple 62 * arrays there are copyFrom() functions that take an array from the control code and 63 * copy it to the slave memory store. Both type checked and unchecked copies are provided. 64 * The unchecked variants exist to allow apps to copy over arrays of structures from a 65 * control language that does not support structures.</p> 66 * 67 * <div class="special reference"> 68 * <h3>Developer Guides</h3> 69 * <p>For more information about creating an application that uses Renderscript, read the 70 * <a href="{@docRoot}guide/topics/graphics/renderscript.html">Renderscript</a> developer guide.</p> 71 * </div> 72 **/ 73public class Allocation extends BaseObj { 74 Type mType; 75 Bitmap mBitmap; 76 int mUsage; 77 Allocation mAdaptedAllocation; 78 79 boolean mConstrainedLOD; 80 boolean mConstrainedFace; 81 boolean mConstrainedY; 82 boolean mConstrainedZ; 83 boolean mReadAllowed = true; 84 boolean mWriteAllowed = true; 85 int mSelectedY; 86 int mSelectedZ; 87 int mSelectedLOD; 88 Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X; 89 90 int mCurrentDimX; 91 int mCurrentDimY; 92 int mCurrentDimZ; 93 int mCurrentCount; 94 95 96 /** 97 * The usage of the allocation. These signal to renderscript 98 * where to place the allocation in memory. 99 * 100 * SCRIPT The allocation will be bound to and accessed by 101 * scripts. 102 */ 103 public static final int USAGE_SCRIPT = 0x0001; 104 105 /** 106 * GRAPHICS_TEXTURE The allocation will be used as a texture 107 * source by one or more graphics programs. 108 * 109 */ 110 public static final int USAGE_GRAPHICS_TEXTURE = 0x0002; 111 112 /** 113 * GRAPHICS_VERTEX The allocation will be used as a graphics 114 * mesh. 115 * 116 */ 117 public static final int USAGE_GRAPHICS_VERTEX = 0x0004; 118 119 120 /** 121 * GRAPHICS_CONSTANTS The allocation will be used as the source 122 * of shader constants by one or more programs. 123 * 124 */ 125 public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008; 126 127 /** 128 * USAGE_GRAPHICS_RENDER_TARGET The allocation will be used as a 129 * target for offscreen rendering 130 * 131 */ 132 public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010; 133 134 /** 135 * USAGE_IO_INPUT The allocation will be used as SurfaceTexture 136 * consumer. This usage will cause the allocation to be created 137 * read only. 138 * 139 * @hide 140 */ 141 public static final int USAGE_IO_INPUT = 0x0020; 142 143 /** 144 * USAGE_IO_OUTPUT The allocation will be used as a 145 * SurfaceTexture producer. The dimensions and format of the 146 * SurfaceTexture will be forced to those of the allocation. 147 * 148 * @hide 149 */ 150 public static final int USAGE_IO_OUTPUT = 0x0040; 151 152 /** 153 * Controls mipmap behavior when using the bitmap creation and 154 * update functions. 155 */ 156 public enum MipmapControl { 157 /** 158 * No mipmaps will be generated and the type generated from the 159 * incoming bitmap will not contain additional LODs. 160 */ 161 MIPMAP_NONE(0), 162 163 /** 164 * A Full mipmap chain will be created in script memory. The 165 * type of the allocation will contain a full mipmap chain. On 166 * upload to graphics the full chain will be transfered. 167 */ 168 MIPMAP_FULL(1), 169 170 /** 171 * The type of the allocation will be the same as MIPMAP_NONE. 172 * It will not contain mipmaps. On upload to graphics the 173 * graphics copy of the allocation data will contain a full 174 * mipmap chain generated from the top level in script memory. 175 */ 176 MIPMAP_ON_SYNC_TO_TEXTURE(2); 177 178 int mID; 179 MipmapControl(int id) { 180 mID = id; 181 } 182 } 183 184 185 private int getIDSafe() { 186 if (mAdaptedAllocation != null) { 187 return mAdaptedAllocation.getID(); 188 } 189 return getID(); 190 } 191 192 193 /** 194 * Get the element of the type of the Allocation. 195 * 196 * @hide 197 * @return Element 198 * 199 */ 200 public Element getElement() { 201 return mType.getElement(); 202 } 203 204 /** 205 * Get the usage flags of the Allocation. 206 * 207 * @hide 208 * @return usage 209 * 210 */ 211 public int getUsage() { 212 return mUsage; 213 } 214 215 /** 216 * Get the size of the Allocation in bytes. 217 * 218 * @hide 219 * @return sizeInBytes 220 * 221 */ 222 public int getSizeBytes() { 223 return mType.getCount() * mType.getElement().getSizeBytes(); 224 } 225 226 private void updateCacheInfo(Type t) { 227 mCurrentDimX = t.getX(); 228 mCurrentDimY = t.getY(); 229 mCurrentDimZ = t.getZ(); 230 mCurrentCount = mCurrentDimX; 231 if (mCurrentDimY > 1) { 232 mCurrentCount *= mCurrentDimY; 233 } 234 if (mCurrentDimZ > 1) { 235 mCurrentCount *= mCurrentDimZ; 236 } 237 } 238 239 Allocation(int id, RenderScript rs, Type t, int usage) { 240 super(id, rs); 241 if ((usage & ~(USAGE_SCRIPT | 242 USAGE_GRAPHICS_TEXTURE | 243 USAGE_GRAPHICS_VERTEX | 244 USAGE_GRAPHICS_CONSTANTS | 245 USAGE_GRAPHICS_RENDER_TARGET | 246 USAGE_IO_INPUT | 247 USAGE_IO_OUTPUT)) != 0) { 248 throw new RSIllegalArgumentException("Unknown usage specified."); 249 } 250 251 if ((usage & USAGE_IO_INPUT) != 0) { 252 mWriteAllowed = false; 253 254 if ((usage & ~(USAGE_IO_INPUT | 255 USAGE_GRAPHICS_TEXTURE | 256 USAGE_SCRIPT)) != 0) { 257 throw new RSIllegalArgumentException("Invalid usage combination."); 258 } 259 } 260 261 mType = t; 262 mUsage = usage; 263 264 if (t != null) { 265 updateCacheInfo(t); 266 } 267 } 268 269 private void validateIsInt32() { 270 if ((mType.mElement.mType == Element.DataType.SIGNED_32) || 271 (mType.mElement.mType == Element.DataType.UNSIGNED_32)) { 272 return; 273 } 274 throw new RSIllegalArgumentException( 275 "32 bit integer source does not match allocation type " + mType.mElement.mType); 276 } 277 278 private void validateIsInt16() { 279 if ((mType.mElement.mType == Element.DataType.SIGNED_16) || 280 (mType.mElement.mType == Element.DataType.UNSIGNED_16)) { 281 return; 282 } 283 throw new RSIllegalArgumentException( 284 "16 bit integer source does not match allocation type " + mType.mElement.mType); 285 } 286 287 private void validateIsInt8() { 288 if ((mType.mElement.mType == Element.DataType.SIGNED_8) || 289 (mType.mElement.mType == Element.DataType.UNSIGNED_8)) { 290 return; 291 } 292 throw new RSIllegalArgumentException( 293 "8 bit integer source does not match allocation type " + mType.mElement.mType); 294 } 295 296 private void validateIsFloat32() { 297 if (mType.mElement.mType == Element.DataType.FLOAT_32) { 298 return; 299 } 300 throw new RSIllegalArgumentException( 301 "32 bit float source does not match allocation type " + mType.mElement.mType); 302 } 303 304 private void validateIsObject() { 305 if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) || 306 (mType.mElement.mType == Element.DataType.RS_TYPE) || 307 (mType.mElement.mType == Element.DataType.RS_ALLOCATION) || 308 (mType.mElement.mType == Element.DataType.RS_SAMPLER) || 309 (mType.mElement.mType == Element.DataType.RS_SCRIPT) || 310 (mType.mElement.mType == Element.DataType.RS_MESH) || 311 (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) || 312 (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) || 313 (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) || 314 (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) { 315 return; 316 } 317 throw new RSIllegalArgumentException( 318 "Object source does not match allocation type " + mType.mElement.mType); 319 } 320 321 @Override 322 void updateFromNative() { 323 super.updateFromNative(); 324 int typeID = mRS.nAllocationGetType(getID()); 325 if(typeID != 0) { 326 mType = new Type(typeID, mRS); 327 mType.updateFromNative(); 328 updateCacheInfo(mType); 329 } 330 } 331 332 /** 333 * Get the type of the Allocation. 334 * 335 * @return Type 336 * 337 */ 338 public Type getType() { 339 return mType; 340 } 341 342 /** 343 * Propagate changes from one usage of the allocation to the 344 * remaining usages of the allocation. 345 * 346 */ 347 public void syncAll(int srcLocation) { 348 switch (srcLocation) { 349 case USAGE_SCRIPT: 350 case USAGE_GRAPHICS_CONSTANTS: 351 case USAGE_GRAPHICS_TEXTURE: 352 case USAGE_GRAPHICS_VERTEX: 353 break; 354 default: 355 throw new RSIllegalArgumentException("Source must be exactly one usage type."); 356 } 357 mRS.validate(); 358 mRS.nAllocationSyncAll(getIDSafe(), srcLocation); 359 } 360 361 /** 362 * Send a buffer to the output stream. The contents of the 363 * Allocation will be undefined after this operation. 364 * 365 * @hide 366 * 367 */ 368 public void ioSendOutput() { 369 if ((mUsage & USAGE_IO_OUTPUT) == 0) { 370 throw new RSIllegalArgumentException( 371 "Can only send buffer if IO_OUTPUT usage specified."); 372 } 373 mRS.validate(); 374 mRS.nAllocationIoSend(getID()); 375 } 376 377 /** 378 * Receive the latest input into the Allocation. 379 * 380 * @hide 381 * 382 */ 383 public void ioGetInput() { 384 if ((mUsage & USAGE_IO_INPUT) == 0) { 385 throw new RSIllegalArgumentException( 386 "Can only receive if IO_INPUT usage specified."); 387 } 388 mRS.validate(); 389 mRS.nAllocationIoReceive(getID()); 390 } 391 392 /** 393 * Copy an array of RS objects to the allocation. 394 * 395 * @param d Source array. 396 */ 397 public void copyFrom(BaseObj[] d) { 398 mRS.validate(); 399 validateIsObject(); 400 if (d.length != mCurrentCount) { 401 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " + 402 mCurrentCount + ", array length = " + d.length); 403 } 404 int i[] = new int[d.length]; 405 for (int ct=0; ct < d.length; ct++) { 406 i[ct] = d[ct].getID(); 407 } 408 copy1DRangeFromUnchecked(0, mCurrentCount, i); 409 } 410 411 private void validateBitmapFormat(Bitmap b) { 412 Bitmap.Config bc = b.getConfig(); 413 switch (bc) { 414 case ALPHA_8: 415 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) { 416 throw new RSIllegalArgumentException("Allocation kind is " + 417 mType.getElement().mKind + ", type " + 418 mType.getElement().mType + 419 " of " + mType.getElement().getSizeBytes() + 420 " bytes, passed bitmap was " + bc); 421 } 422 break; 423 case ARGB_8888: 424 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) || 425 (mType.getElement().getSizeBytes() != 4)) { 426 throw new RSIllegalArgumentException("Allocation kind is " + 427 mType.getElement().mKind + ", type " + 428 mType.getElement().mType + 429 " of " + mType.getElement().getSizeBytes() + 430 " bytes, passed bitmap was " + bc); 431 } 432 break; 433 case RGB_565: 434 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) || 435 (mType.getElement().getSizeBytes() != 2)) { 436 throw new RSIllegalArgumentException("Allocation kind is " + 437 mType.getElement().mKind + ", type " + 438 mType.getElement().mType + 439 " of " + mType.getElement().getSizeBytes() + 440 " bytes, passed bitmap was " + bc); 441 } 442 break; 443 case ARGB_4444: 444 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) || 445 (mType.getElement().getSizeBytes() != 2)) { 446 throw new RSIllegalArgumentException("Allocation kind is " + 447 mType.getElement().mKind + ", type " + 448 mType.getElement().mType + 449 " of " + mType.getElement().getSizeBytes() + 450 " bytes, passed bitmap was " + bc); 451 } 452 break; 453 454 } 455 } 456 457 private void validateBitmapSize(Bitmap b) { 458 if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) { 459 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch"); 460 } 461 } 462 463 /** 464 * Copy an allocation from an array. This variant is not type 465 * checked which allows an application to fill in structured 466 * data from an array. 467 * 468 * @param d the source data array 469 */ 470 public void copyFromUnchecked(int[] d) { 471 mRS.validate(); 472 copy1DRangeFromUnchecked(0, mCurrentCount, d); 473 } 474 /** 475 * Copy an allocation from an array. This variant is not type 476 * checked which allows an application to fill in structured 477 * data from an array. 478 * 479 * @param d the source data array 480 */ 481 public void copyFromUnchecked(short[] d) { 482 mRS.validate(); 483 copy1DRangeFromUnchecked(0, mCurrentCount, d); 484 } 485 /** 486 * Copy an allocation from an array. This variant is not type 487 * checked which allows an application to fill in structured 488 * data from an array. 489 * 490 * @param d the source data array 491 */ 492 public void copyFromUnchecked(byte[] d) { 493 mRS.validate(); 494 copy1DRangeFromUnchecked(0, mCurrentCount, d); 495 } 496 /** 497 * Copy an allocation from an array. This variant is not type 498 * checked which allows an application to fill in structured 499 * data from an array. 500 * 501 * @param d the source data array 502 */ 503 public void copyFromUnchecked(float[] d) { 504 mRS.validate(); 505 copy1DRangeFromUnchecked(0, mCurrentCount, d); 506 } 507 508 /** 509 * Copy an allocation from an array. This variant is type 510 * checked and will generate exceptions if the Allocation type 511 * is not a 32 bit integer type. 512 * 513 * @param d the source data array 514 */ 515 public void copyFrom(int[] d) { 516 mRS.validate(); 517 copy1DRangeFrom(0, mCurrentCount, d); 518 } 519 520 /** 521 * Copy an allocation from an array. This variant is type 522 * checked and will generate exceptions if the Allocation type 523 * is not a 16 bit integer type. 524 * 525 * @param d the source data array 526 */ 527 public void copyFrom(short[] d) { 528 mRS.validate(); 529 copy1DRangeFrom(0, mCurrentCount, d); 530 } 531 532 /** 533 * Copy an allocation from an array. This variant is type 534 * checked and will generate exceptions if the Allocation type 535 * is not a 8 bit integer type. 536 * 537 * @param d the source data array 538 */ 539 public void copyFrom(byte[] d) { 540 mRS.validate(); 541 copy1DRangeFrom(0, mCurrentCount, d); 542 } 543 544 /** 545 * Copy an allocation from an array. This variant is type 546 * checked and will generate exceptions if the Allocation type 547 * is not a 32 bit float type. 548 * 549 * @param d the source data array 550 */ 551 public void copyFrom(float[] d) { 552 mRS.validate(); 553 copy1DRangeFrom(0, mCurrentCount, d); 554 } 555 556 /** 557 * Copy an allocation from a bitmap. The height, width, and 558 * format of the bitmap must match the existing allocation. 559 * 560 * @param b the source bitmap 561 */ 562 public void copyFrom(Bitmap b) { 563 mRS.validate(); 564 validateBitmapSize(b); 565 validateBitmapFormat(b); 566 mRS.nAllocationCopyFromBitmap(getID(), b); 567 } 568 569 /** 570 * This is only intended to be used by auto-generate code reflected from the 571 * renderscript script files. 572 * 573 * @param xoff 574 * @param fp 575 */ 576 public void setFromFieldPacker(int xoff, FieldPacker fp) { 577 mRS.validate(); 578 int eSize = mType.mElement.getSizeBytes(); 579 final byte[] data = fp.getData(); 580 581 int count = data.length / eSize; 582 if ((eSize * count) != data.length) { 583 throw new RSIllegalArgumentException("Field packer length " + data.length + 584 " not divisible by element size " + eSize + "."); 585 } 586 copy1DRangeFromUnchecked(xoff, count, data); 587 } 588 589 /** 590 * This is only intended to be used by auto-generate code reflected from the 591 * renderscript script files. 592 * 593 * @param xoff 594 * @param component_number 595 * @param fp 596 */ 597 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) { 598 mRS.validate(); 599 if (component_number >= mType.mElement.mElements.length) { 600 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range."); 601 } 602 if(xoff < 0) { 603 throw new RSIllegalArgumentException("Offset must be >= 0."); 604 } 605 606 final byte[] data = fp.getData(); 607 int eSize = mType.mElement.mElements[component_number].getSizeBytes(); 608 eSize *= mType.mElement.mArraySizes[component_number]; 609 610 if (data.length != eSize) { 611 throw new RSIllegalArgumentException("Field packer sizelength " + data.length + 612 " does not match component size " + eSize + "."); 613 } 614 615 mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD, 616 component_number, data, data.length); 617 } 618 619 private void data1DChecks(int off, int count, int len, int dataSize) { 620 mRS.validate(); 621 if(off < 0) { 622 throw new RSIllegalArgumentException("Offset must be >= 0."); 623 } 624 if(count < 1) { 625 throw new RSIllegalArgumentException("Count must be >= 1."); 626 } 627 if((off + count) > mCurrentCount) { 628 throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount + 629 ", got " + count + " at offset " + off + "."); 630 } 631 if(len < dataSize) { 632 throw new RSIllegalArgumentException("Array too small for allocation type."); 633 } 634 } 635 636 /** 637 * Generate a mipmap chain. Requires the type of the allocation 638 * include mipmaps. 639 * 640 * This function will generate a complete set of mipmaps from 641 * the top level lod and place them into the script memoryspace. 642 * 643 * If the allocation is also using other memory spaces a 644 * followup sync will be required. 645 */ 646 public void generateMipmaps() { 647 mRS.nAllocationGenerateMipmaps(getID()); 648 } 649 650 /** 651 * Copy part of an allocation from an array. This variant is 652 * not type checked which allows an application to fill in 653 * structured data from an array. 654 * 655 * @param off The offset of the first element to be copied. 656 * @param count The number of elements to be copied. 657 * @param d the source data array 658 */ 659 public void copy1DRangeFromUnchecked(int off, int count, int[] d) { 660 int dataSize = mType.mElement.getSizeBytes() * count; 661 data1DChecks(off, count, d.length * 4, dataSize); 662 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize); 663 } 664 /** 665 * Copy part of an allocation from an array. This variant is 666 * not type checked which allows an application to fill in 667 * structured data from an array. 668 * 669 * @param off The offset of the first element to be copied. 670 * @param count The number of elements to be copied. 671 * @param d the source data array 672 */ 673 public void copy1DRangeFromUnchecked(int off, int count, short[] d) { 674 int dataSize = mType.mElement.getSizeBytes() * count; 675 data1DChecks(off, count, d.length * 2, dataSize); 676 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize); 677 } 678 /** 679 * Copy part of an allocation from an array. This variant is 680 * not type checked which allows an application to fill in 681 * structured data from an array. 682 * 683 * @param off The offset of the first element to be copied. 684 * @param count The number of elements to be copied. 685 * @param d the source data array 686 */ 687 public void copy1DRangeFromUnchecked(int off, int count, byte[] d) { 688 int dataSize = mType.mElement.getSizeBytes() * count; 689 data1DChecks(off, count, d.length, dataSize); 690 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize); 691 } 692 /** 693 * Copy part of an allocation from an array. This variant is 694 * not type checked which allows an application to fill in 695 * structured data from an array. 696 * 697 * @param off The offset of the first element to be copied. 698 * @param count The number of elements to be copied. 699 * @param d the source data array 700 */ 701 public void copy1DRangeFromUnchecked(int off, int count, float[] d) { 702 int dataSize = mType.mElement.getSizeBytes() * count; 703 data1DChecks(off, count, d.length * 4, dataSize); 704 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize); 705 } 706 707 /** 708 * Copy part of an allocation from an array. This variant is 709 * type checked and will generate exceptions if the Allocation 710 * type is not a 32 bit integer type. 711 * 712 * @param off The offset of the first element to be copied. 713 * @param count The number of elements to be copied. 714 * @param d the source data array 715 */ 716 public void copy1DRangeFrom(int off, int count, int[] d) { 717 validateIsInt32(); 718 copy1DRangeFromUnchecked(off, count, d); 719 } 720 721 /** 722 * Copy part of an allocation from an array. This variant is 723 * type checked and will generate exceptions if the Allocation 724 * type is not a 16 bit integer type. 725 * 726 * @param off The offset of the first element to be copied. 727 * @param count The number of elements to be copied. 728 * @param d the source data array 729 */ 730 public void copy1DRangeFrom(int off, int count, short[] d) { 731 validateIsInt16(); 732 copy1DRangeFromUnchecked(off, count, d); 733 } 734 735 /** 736 * Copy part of an allocation from an array. This variant is 737 * type checked and will generate exceptions if the Allocation 738 * type is not a 8 bit integer type. 739 * 740 * @param off The offset of the first element to be copied. 741 * @param count The number of elements to be copied. 742 * @param d the source data array 743 */ 744 public void copy1DRangeFrom(int off, int count, byte[] d) { 745 validateIsInt8(); 746 copy1DRangeFromUnchecked(off, count, d); 747 } 748 749 /** 750 * Copy part of an allocation from an array. This variant is 751 * type checked and will generate exceptions if the Allocation 752 * type is not a 32 bit float type. 753 * 754 * @param off The offset of the first element to be copied. 755 * @param count The number of elements to be copied. 756 * @param d the source data array. 757 */ 758 public void copy1DRangeFrom(int off, int count, float[] d) { 759 validateIsFloat32(); 760 copy1DRangeFromUnchecked(off, count, d); 761 } 762 763 /** 764 * Copy part of an allocation from another allocation. 765 * 766 * @param off The offset of the first element to be copied. 767 * @param count The number of elements to be copied. 768 * @param data the source data allocation. 769 * @param dataOff off The offset of the first element in data to 770 * be copied. 771 */ 772 public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) { 773 mRS.nAllocationData2D(getIDSafe(), off, 0, 774 mSelectedLOD, mSelectedFace.mID, 775 count, 1, data.getID(), dataOff, 0, 776 data.mSelectedLOD, data.mSelectedFace.mID); 777 } 778 779 private void validate2DRange(int xoff, int yoff, int w, int h) { 780 if (mAdaptedAllocation != null) { 781 782 } else { 783 784 if (xoff < 0 || yoff < 0) { 785 throw new RSIllegalArgumentException("Offset cannot be negative."); 786 } 787 if (h < 0 || w < 0) { 788 throw new RSIllegalArgumentException("Height or width cannot be negative."); 789 } 790 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) { 791 throw new RSIllegalArgumentException("Updated region larger than allocation."); 792 } 793 } 794 } 795 796 /** 797 * Copy a rectangular region from the array into the allocation. 798 * The incoming array is assumed to be tightly packed. 799 * 800 * @param xoff X offset of the region to update 801 * @param yoff Y offset of the region to update 802 * @param w Width of the incoming region to update 803 * @param h Height of the incoming region to update 804 * @param data to be placed into the allocation 805 */ 806 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) { 807 mRS.validate(); 808 validate2DRange(xoff, yoff, w, h); 809 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, 810 w, h, data, data.length); 811 } 812 813 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) { 814 mRS.validate(); 815 validate2DRange(xoff, yoff, w, h); 816 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, 817 w, h, data, data.length * 2); 818 } 819 820 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) { 821 mRS.validate(); 822 validate2DRange(xoff, yoff, w, h); 823 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, 824 w, h, data, data.length * 4); 825 } 826 827 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) { 828 mRS.validate(); 829 validate2DRange(xoff, yoff, w, h); 830 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, 831 w, h, data, data.length * 4); 832 } 833 834 /** 835 * Copy a rectangular region into the allocation from another 836 * allocation. 837 * 838 * @param xoff X offset of the region to update. 839 * @param yoff Y offset of the region to update. 840 * @param w Width of the incoming region to update. 841 * @param h Height of the incoming region to update. 842 * @param data source allocation. 843 * @param dataXoff X offset in data of the region to update. 844 * @param dataYoff Y offset in data of the region to update. 845 */ 846 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, 847 Allocation data, int dataXoff, int dataYoff) { 848 mRS.validate(); 849 validate2DRange(xoff, yoff, w, h); 850 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, 851 mSelectedLOD, mSelectedFace.mID, 852 w, h, data.getID(), dataXoff, dataYoff, 853 data.mSelectedLOD, data.mSelectedFace.mID); 854 } 855 856 /** 857 * Copy a bitmap into an allocation. The height and width of 858 * the update will use the height and width of the incoming 859 * bitmap. 860 * 861 * @param xoff X offset of the region to update 862 * @param yoff Y offset of the region to update 863 * @param data the bitmap to be copied 864 */ 865 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) { 866 mRS.validate(); 867 validateBitmapFormat(data); 868 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight()); 869 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data); 870 } 871 872 873 /** 874 * Copy from the Allocation into a Bitmap. The bitmap must 875 * match the dimensions of the Allocation. 876 * 877 * @param b The bitmap to be set from the Allocation. 878 */ 879 public void copyTo(Bitmap b) { 880 mRS.validate(); 881 validateBitmapFormat(b); 882 validateBitmapSize(b); 883 mRS.nAllocationCopyToBitmap(getID(), b); 884 } 885 886 /** 887 * Copy from the Allocation into a byte array. The array must 888 * be at least as large as the Allocation. The allocation must 889 * be of an 8 bit elemental type. 890 * 891 * @param d The array to be set from the Allocation. 892 */ 893 public void copyTo(byte[] d) { 894 validateIsInt8(); 895 mRS.validate(); 896 mRS.nAllocationRead(getID(), d); 897 } 898 899 /** 900 * Copy from the Allocation into a short array. The array must 901 * be at least as large as the Allocation. The allocation must 902 * be of an 16 bit elemental type. 903 * 904 * @param d The array to be set from the Allocation. 905 */ 906 public void copyTo(short[] d) { 907 validateIsInt16(); 908 mRS.validate(); 909 mRS.nAllocationRead(getID(), d); 910 } 911 912 /** 913 * Copy from the Allocation into a int array. The array must be 914 * at least as large as the Allocation. The allocation must be 915 * of an 32 bit elemental type. 916 * 917 * @param d The array to be set from the Allocation. 918 */ 919 public void copyTo(int[] d) { 920 validateIsInt32(); 921 mRS.validate(); 922 mRS.nAllocationRead(getID(), d); 923 } 924 925 /** 926 * Copy from the Allocation into a float array. The array must 927 * be at least as large as the Allocation. The allocation must 928 * be of an 32 bit float elemental type. 929 * 930 * @param d The array to be set from the Allocation. 931 */ 932 public void copyTo(float[] d) { 933 validateIsFloat32(); 934 mRS.validate(); 935 mRS.nAllocationRead(getID(), d); 936 } 937 938 /** 939 * Resize a 1D allocation. The contents of the allocation are 940 * preserved. If new elements are allocated objects are created 941 * with null contents and the new region is otherwise undefined. 942 * 943 * If the new region is smaller the references of any objects 944 * outside the new region will be released. 945 * 946 * A new type will be created with the new dimension. 947 * 948 * @param dimX The new size of the allocation. 949 */ 950 public synchronized void resize(int dimX) { 951 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) { 952 throw new RSInvalidStateException("Resize only support for 1D allocations at this time."); 953 } 954 mRS.nAllocationResize1D(getID(), dimX); 955 mRS.finish(); // Necessary because resize is fifoed and update is async. 956 957 int typeID = mRS.nAllocationGetType(getID()); 958 mType = new Type(typeID, mRS); 959 mType.updateFromNative(); 960 updateCacheInfo(mType); 961 } 962 963 /** 964 * Resize a 2D allocation. The contents of the allocation are 965 * preserved. If new elements are allocated objects are created 966 * with null contents and the new region is otherwise undefined. 967 * 968 * If the new region is smaller the references of any objects 969 * outside the new region will be released. 970 * 971 * A new type will be created with the new dimension. 972 * 973 * @hide 974 * @param dimX The new size of the allocation. 975 * @param dimY The new size of the allocation. 976 */ 977 public void resize(int dimX, int dimY) { 978 if ((mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) { 979 throw new RSInvalidStateException( 980 "Resize only support for 2D allocations at this time."); 981 } 982 if (mType.getY() == 0) { 983 throw new RSInvalidStateException( 984 "Resize only support for 2D allocations at this time."); 985 } 986 mRS.nAllocationResize2D(getID(), dimX, dimY); 987 mRS.finish(); // Necessary because resize is fifoed and update is async. 988 989 int typeID = mRS.nAllocationGetType(getID()); 990 mType = new Type(typeID, mRS); 991 mType.updateFromNative(); 992 updateCacheInfo(mType); 993 } 994 995 996 997 // creation 998 999 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options(); 1000 static { 1001 mBitmapOptions.inScaled = false; 1002 } 1003 1004 /** 1005 * 1006 * @param type renderscript type describing data layout 1007 * @param mips specifies desired mipmap behaviour for the 1008 * allocation 1009 * @param usage bit field specifying how the allocation is 1010 * utilized 1011 */ 1012 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) { 1013 rs.validate(); 1014 if (type.getID() == 0) { 1015 throw new RSInvalidStateException("Bad Type"); 1016 } 1017 int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage, 0); 1018 if (id == 0) { 1019 throw new RSRuntimeException("Allocation creation failed."); 1020 } 1021 return new Allocation(id, rs, type, usage); 1022 } 1023 1024 /** 1025 * @hide 1026 * This API is hidden and only intended to be used for 1027 * transitional purposes. 1028 * 1029 * @param type renderscript type describing data layout 1030 * @param mips specifies desired mipmap behaviour for the 1031 * allocation 1032 * @param usage bit field specifying how the allocation is 1033 * utilized 1034 */ 1035 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, 1036 int usage, int pointer) { 1037 rs.validate(); 1038 if (type.getID() == 0) { 1039 throw new RSInvalidStateException("Bad Type"); 1040 } 1041 int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage, pointer); 1042 if (id == 0) { 1043 throw new RSRuntimeException("Allocation creation failed."); 1044 } 1045 return new Allocation(id, rs, type, usage); 1046 } 1047 1048 /** 1049 * Creates a renderscript allocation with the size specified by 1050 * the type and no mipmaps generated by default 1051 * 1052 * @param rs Context to which the allocation will belong. 1053 * @param type renderscript type describing data layout 1054 * @param usage bit field specifying how the allocation is 1055 * utilized 1056 * 1057 * @return allocation 1058 */ 1059 static public Allocation createTyped(RenderScript rs, Type type, int usage) { 1060 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage); 1061 } 1062 1063 /** 1064 * Creates a renderscript allocation for use by the script with 1065 * the size specified by the type and no mipmaps generated by 1066 * default 1067 * 1068 * @param rs Context to which the allocation will belong. 1069 * @param type renderscript type describing data layout 1070 * 1071 * @return allocation 1072 */ 1073 static public Allocation createTyped(RenderScript rs, Type type) { 1074 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT); 1075 } 1076 1077 /** 1078 * Creates a renderscript allocation with a specified number of 1079 * given elements 1080 * 1081 * @param rs Context to which the allocation will belong. 1082 * @param e describes what each element of an allocation is 1083 * @param count specifies the number of element in the allocation 1084 * @param usage bit field specifying how the allocation is 1085 * utilized 1086 * 1087 * @return allocation 1088 */ 1089 static public Allocation createSized(RenderScript rs, Element e, 1090 int count, int usage) { 1091 rs.validate(); 1092 Type.Builder b = new Type.Builder(rs, e); 1093 b.setX(count); 1094 Type t = b.create(); 1095 1096 int id = rs.nAllocationCreateTyped(t.getID(), MipmapControl.MIPMAP_NONE.mID, usage, 0); 1097 if (id == 0) { 1098 throw new RSRuntimeException("Allocation creation failed."); 1099 } 1100 return new Allocation(id, rs, t, usage); 1101 } 1102 1103 /** 1104 * Creates a renderscript allocation with a specified number of 1105 * given elements 1106 * 1107 * @param rs Context to which the allocation will belong. 1108 * @param e describes what each element of an allocation is 1109 * @param count specifies the number of element in the allocation 1110 * 1111 * @return allocation 1112 */ 1113 static public Allocation createSized(RenderScript rs, Element e, int count) { 1114 return createSized(rs, e, count, USAGE_SCRIPT); 1115 } 1116 1117 static Element elementFromBitmap(RenderScript rs, Bitmap b) { 1118 final Bitmap.Config bc = b.getConfig(); 1119 if (bc == Bitmap.Config.ALPHA_8) { 1120 return Element.A_8(rs); 1121 } 1122 if (bc == Bitmap.Config.ARGB_4444) { 1123 return Element.RGBA_4444(rs); 1124 } 1125 if (bc == Bitmap.Config.ARGB_8888) { 1126 return Element.RGBA_8888(rs); 1127 } 1128 if (bc == Bitmap.Config.RGB_565) { 1129 return Element.RGB_565(rs); 1130 } 1131 throw new RSInvalidStateException("Bad bitmap type: " + bc); 1132 } 1133 1134 static Type typeFromBitmap(RenderScript rs, Bitmap b, 1135 MipmapControl mip) { 1136 Element e = elementFromBitmap(rs, b); 1137 Type.Builder tb = new Type.Builder(rs, e); 1138 tb.setX(b.getWidth()); 1139 tb.setY(b.getHeight()); 1140 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL); 1141 return tb.create(); 1142 } 1143 1144 /** 1145 * Creates a renderscript allocation from a bitmap 1146 * 1147 * @param rs Context to which the allocation will belong. 1148 * @param b bitmap source for the allocation data 1149 * @param mips specifies desired mipmap behaviour for the 1150 * allocation 1151 * @param usage bit field specifying how the allocation is 1152 * utilized 1153 * 1154 * @return renderscript allocation containing bitmap data 1155 * 1156 */ 1157 static public Allocation createFromBitmap(RenderScript rs, Bitmap b, 1158 MipmapControl mips, 1159 int usage) { 1160 rs.validate(); 1161 Type t = typeFromBitmap(rs, b, mips); 1162 1163 int id = rs.nAllocationCreateFromBitmap(t.getID(), mips.mID, b, usage); 1164 if (id == 0) { 1165 throw new RSRuntimeException("Load failed."); 1166 } 1167 return new Allocation(id, rs, t, usage); 1168 } 1169 1170 /** 1171 * 1172 * 1173 * @hide 1174 * 1175 */ 1176 public SurfaceTexture getSurfaceTexture() { 1177 if ((mUsage & USAGE_IO_INPUT) == 0) { 1178 throw new RSInvalidStateException("Allocation is not a surface texture."); 1179 } 1180 1181 int id = mRS.nAllocationGetSurfaceTextureID(getID()); 1182 SurfaceTexture st = new SurfaceTexture(id); 1183 mRS.nAllocationGetSurfaceTextureID2(getID(), st); 1184 1185 return st; 1186 } 1187 1188 /** 1189 * 1190 * @hide 1191 * 1192 */ 1193 public Surface getSurface() { 1194 return new Surface(getSurfaceTexture()); 1195 } 1196 1197 /** 1198 * @hide 1199 */ 1200 public void setSurface(Surface sur) { 1201 mRS.validate(); 1202 if ((mUsage & USAGE_IO_OUTPUT) == 0) { 1203 throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT."); 1204 } 1205 1206 mRS.nAllocationSetSurface(getID(), sur); 1207 } 1208 1209 /** 1210 * @hide 1211 */ 1212 public void setSurfaceTexture(SurfaceTexture st) { 1213 mRS.validate(); 1214 if ((mUsage & USAGE_IO_OUTPUT) == 0) { 1215 throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT."); 1216 } 1217 1218 Surface s = new Surface(st); 1219 mRS.nAllocationSetSurface(getID(), s); 1220 } 1221 1222 /** 1223 * Creates a non-mipmapped renderscript allocation to use as a 1224 * graphics texture 1225 * 1226 * @param rs Context to which the allocation will belong. 1227 * @param b bitmap source for the allocation data 1228 * 1229 * @return renderscript allocation containing bitmap data 1230 * 1231 */ 1232 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) { 1233 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, 1234 USAGE_GRAPHICS_TEXTURE); 1235 } 1236 1237 /** 1238 * Creates a cubemap allocation from a bitmap containing the 1239 * horizontal list of cube faces. Each individual face must be 1240 * the same size and power of 2 1241 * 1242 * @param rs Context to which the allocation will belong. 1243 * @param b bitmap with cubemap faces layed out in the following 1244 * format: right, left, top, bottom, front, back 1245 * @param mips specifies desired mipmap behaviour for the cubemap 1246 * @param usage bit field specifying how the cubemap is utilized 1247 * 1248 * @return allocation containing cubemap data 1249 * 1250 */ 1251 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b, 1252 MipmapControl mips, 1253 int usage) { 1254 rs.validate(); 1255 1256 int height = b.getHeight(); 1257 int width = b.getWidth(); 1258 1259 if (width % 6 != 0) { 1260 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6"); 1261 } 1262 if (width / 6 != height) { 1263 throw new RSIllegalArgumentException("Only square cube map faces supported"); 1264 } 1265 boolean isPow2 = (height & (height - 1)) == 0; 1266 if (!isPow2) { 1267 throw new RSIllegalArgumentException("Only power of 2 cube faces supported"); 1268 } 1269 1270 Element e = elementFromBitmap(rs, b); 1271 Type.Builder tb = new Type.Builder(rs, e); 1272 tb.setX(height); 1273 tb.setY(height); 1274 tb.setFaces(true); 1275 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL); 1276 Type t = tb.create(); 1277 1278 int id = rs.nAllocationCubeCreateFromBitmap(t.getID(), mips.mID, b, usage); 1279 if(id == 0) { 1280 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e); 1281 } 1282 return new Allocation(id, rs, t, usage); 1283 } 1284 1285 /** 1286 * Creates a non-mipmapped cubemap allocation for use as a 1287 * graphics texture from a bitmap containing the horizontal list 1288 * of cube faces. Each individual face must be the same size and 1289 * power of 2 1290 * 1291 * @param rs Context to which the allocation will belong. 1292 * @param b bitmap with cubemap faces layed out in the following 1293 * format: right, left, top, bottom, front, back 1294 * 1295 * @return allocation containing cubemap data 1296 * 1297 */ 1298 static public Allocation createCubemapFromBitmap(RenderScript rs, 1299 Bitmap b) { 1300 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, 1301 USAGE_GRAPHICS_TEXTURE); 1302 } 1303 1304 /** 1305 * Creates a cubemap allocation from 6 bitmaps containing 1306 * the cube faces. All the faces must be the same size and 1307 * power of 2 1308 * 1309 * @param rs Context to which the allocation will belong. 1310 * @param xpos cubemap face in the positive x direction 1311 * @param xneg cubemap face in the negative x direction 1312 * @param ypos cubemap face in the positive y direction 1313 * @param yneg cubemap face in the negative y direction 1314 * @param zpos cubemap face in the positive z direction 1315 * @param zneg cubemap face in the negative z direction 1316 * @param mips specifies desired mipmap behaviour for the cubemap 1317 * @param usage bit field specifying how the cubemap is utilized 1318 * 1319 * @return allocation containing cubemap data 1320 * 1321 */ 1322 static public Allocation createCubemapFromCubeFaces(RenderScript rs, 1323 Bitmap xpos, 1324 Bitmap xneg, 1325 Bitmap ypos, 1326 Bitmap yneg, 1327 Bitmap zpos, 1328 Bitmap zneg, 1329 MipmapControl mips, 1330 int usage) { 1331 int height = xpos.getHeight(); 1332 if (xpos.getWidth() != height || 1333 xneg.getWidth() != height || xneg.getHeight() != height || 1334 ypos.getWidth() != height || ypos.getHeight() != height || 1335 yneg.getWidth() != height || yneg.getHeight() != height || 1336 zpos.getWidth() != height || zpos.getHeight() != height || 1337 zneg.getWidth() != height || zneg.getHeight() != height) { 1338 throw new RSIllegalArgumentException("Only square cube map faces supported"); 1339 } 1340 boolean isPow2 = (height & (height - 1)) == 0; 1341 if (!isPow2) { 1342 throw new RSIllegalArgumentException("Only power of 2 cube faces supported"); 1343 } 1344 1345 Element e = elementFromBitmap(rs, xpos); 1346 Type.Builder tb = new Type.Builder(rs, e); 1347 tb.setX(height); 1348 tb.setY(height); 1349 tb.setFaces(true); 1350 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL); 1351 Type t = tb.create(); 1352 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage); 1353 1354 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap); 1355 adapter.setFace(Type.CubemapFace.POSITIVE_X); 1356 adapter.copyFrom(xpos); 1357 adapter.setFace(Type.CubemapFace.NEGATIVE_X); 1358 adapter.copyFrom(xneg); 1359 adapter.setFace(Type.CubemapFace.POSITIVE_Y); 1360 adapter.copyFrom(ypos); 1361 adapter.setFace(Type.CubemapFace.NEGATIVE_Y); 1362 adapter.copyFrom(yneg); 1363 adapter.setFace(Type.CubemapFace.POSITIVE_Z); 1364 adapter.copyFrom(zpos); 1365 adapter.setFace(Type.CubemapFace.NEGATIVE_Z); 1366 adapter.copyFrom(zneg); 1367 1368 return cubemap; 1369 } 1370 1371 /** 1372 * Creates a non-mipmapped cubemap allocation for use as a 1373 * graphics texture from 6 bitmaps containing 1374 * the cube faces. All the faces must be the same size and 1375 * power of 2 1376 * 1377 * @param rs Context to which the allocation will belong. 1378 * @param xpos cubemap face in the positive x direction 1379 * @param xneg cubemap face in the negative x direction 1380 * @param ypos cubemap face in the positive y direction 1381 * @param yneg cubemap face in the negative y direction 1382 * @param zpos cubemap face in the positive z direction 1383 * @param zneg cubemap face in the negative z direction 1384 * 1385 * @return allocation containing cubemap data 1386 * 1387 */ 1388 static public Allocation createCubemapFromCubeFaces(RenderScript rs, 1389 Bitmap xpos, 1390 Bitmap xneg, 1391 Bitmap ypos, 1392 Bitmap yneg, 1393 Bitmap zpos, 1394 Bitmap zneg) { 1395 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg, 1396 zpos, zneg, MipmapControl.MIPMAP_NONE, 1397 USAGE_GRAPHICS_TEXTURE); 1398 } 1399 1400 /** 1401 * Creates a renderscript allocation from the bitmap referenced 1402 * by resource id 1403 * 1404 * @param rs Context to which the allocation will belong. 1405 * @param res application resources 1406 * @param id resource id to load the data from 1407 * @param mips specifies desired mipmap behaviour for the 1408 * allocation 1409 * @param usage bit field specifying how the allocation is 1410 * utilized 1411 * 1412 * @return renderscript allocation containing resource data 1413 * 1414 */ 1415 static public Allocation createFromBitmapResource(RenderScript rs, 1416 Resources res, 1417 int id, 1418 MipmapControl mips, 1419 int usage) { 1420 1421 rs.validate(); 1422 Bitmap b = BitmapFactory.decodeResource(res, id); 1423 Allocation alloc = createFromBitmap(rs, b, mips, usage); 1424 b.recycle(); 1425 return alloc; 1426 } 1427 1428 /** 1429 * Creates a non-mipmapped renderscript allocation to use as a 1430 * graphics texture from the bitmap referenced by resource id 1431 * 1432 * @param rs Context to which the allocation will belong. 1433 * @param res application resources 1434 * @param id resource id to load the data from 1435 * 1436 * @return renderscript allocation containing resource data 1437 * 1438 */ 1439 static public Allocation createFromBitmapResource(RenderScript rs, 1440 Resources res, 1441 int id) { 1442 return createFromBitmapResource(rs, res, id, 1443 MipmapControl.MIPMAP_NONE, 1444 USAGE_GRAPHICS_TEXTURE); 1445 } 1446 1447 /** 1448 * Creates a renderscript allocation containing string data 1449 * encoded in UTF-8 format 1450 * 1451 * @param rs Context to which the allocation will belong. 1452 * @param str string to create the allocation from 1453 * @param usage bit field specifying how the allocaiton is 1454 * utilized 1455 * 1456 */ 1457 static public Allocation createFromString(RenderScript rs, 1458 String str, 1459 int usage) { 1460 rs.validate(); 1461 byte[] allocArray = null; 1462 try { 1463 allocArray = str.getBytes("UTF-8"); 1464 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage); 1465 alloc.copyFrom(allocArray); 1466 return alloc; 1467 } 1468 catch (Exception e) { 1469 throw new RSRuntimeException("Could not convert string to utf-8."); 1470 } 1471 } 1472} 1473 1474 1475