Allocation.java revision c5f519c5ec57400f04f1d0bdc69f7bfddf47f8cb
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 ioSend() { 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 * Delete once code is updated. 379 * @hide 380 */ 381 public void ioSendOutput() { 382 ioSend(); 383 } 384 385 /** 386 * Receive the latest input into the Allocation. 387 * 388 * @hide 389 * 390 */ 391 public void ioReceive() { 392 if ((mUsage & USAGE_IO_INPUT) == 0) { 393 throw new RSIllegalArgumentException( 394 "Can only receive if IO_INPUT usage specified."); 395 } 396 mRS.validate(); 397 mRS.nAllocationIoReceive(getID()); 398 } 399 400 /** 401 * Copy an array of RS objects to the allocation. 402 * 403 * @param d Source array. 404 */ 405 public void copyFrom(BaseObj[] d) { 406 mRS.validate(); 407 validateIsObject(); 408 if (d.length != mCurrentCount) { 409 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " + 410 mCurrentCount + ", array length = " + d.length); 411 } 412 int i[] = new int[d.length]; 413 for (int ct=0; ct < d.length; ct++) { 414 i[ct] = d[ct].getID(); 415 } 416 copy1DRangeFromUnchecked(0, mCurrentCount, i); 417 } 418 419 private void validateBitmapFormat(Bitmap b) { 420 Bitmap.Config bc = b.getConfig(); 421 switch (bc) { 422 case ALPHA_8: 423 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) { 424 throw new RSIllegalArgumentException("Allocation kind is " + 425 mType.getElement().mKind + ", type " + 426 mType.getElement().mType + 427 " of " + mType.getElement().getSizeBytes() + 428 " bytes, passed bitmap was " + bc); 429 } 430 break; 431 case ARGB_8888: 432 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) || 433 (mType.getElement().getSizeBytes() != 4)) { 434 throw new RSIllegalArgumentException("Allocation kind is " + 435 mType.getElement().mKind + ", type " + 436 mType.getElement().mType + 437 " of " + mType.getElement().getSizeBytes() + 438 " bytes, passed bitmap was " + bc); 439 } 440 break; 441 case RGB_565: 442 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) || 443 (mType.getElement().getSizeBytes() != 2)) { 444 throw new RSIllegalArgumentException("Allocation kind is " + 445 mType.getElement().mKind + ", type " + 446 mType.getElement().mType + 447 " of " + mType.getElement().getSizeBytes() + 448 " bytes, passed bitmap was " + bc); 449 } 450 break; 451 case ARGB_4444: 452 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) || 453 (mType.getElement().getSizeBytes() != 2)) { 454 throw new RSIllegalArgumentException("Allocation kind is " + 455 mType.getElement().mKind + ", type " + 456 mType.getElement().mType + 457 " of " + mType.getElement().getSizeBytes() + 458 " bytes, passed bitmap was " + bc); 459 } 460 break; 461 462 } 463 } 464 465 private void validateBitmapSize(Bitmap b) { 466 if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) { 467 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch"); 468 } 469 } 470 471 /** 472 * Copy an allocation from an array. This variant is not type 473 * checked which allows an application to fill in structured 474 * data from an array. 475 * 476 * @param d the source data array 477 */ 478 public void copyFromUnchecked(int[] d) { 479 mRS.validate(); 480 copy1DRangeFromUnchecked(0, mCurrentCount, d); 481 } 482 /** 483 * Copy an allocation from an array. This variant is not type 484 * checked which allows an application to fill in structured 485 * data from an array. 486 * 487 * @param d the source data array 488 */ 489 public void copyFromUnchecked(short[] d) { 490 mRS.validate(); 491 copy1DRangeFromUnchecked(0, mCurrentCount, d); 492 } 493 /** 494 * Copy an allocation from an array. This variant is not type 495 * checked which allows an application to fill in structured 496 * data from an array. 497 * 498 * @param d the source data array 499 */ 500 public void copyFromUnchecked(byte[] d) { 501 mRS.validate(); 502 copy1DRangeFromUnchecked(0, mCurrentCount, d); 503 } 504 /** 505 * Copy an allocation from an array. This variant is not type 506 * checked which allows an application to fill in structured 507 * data from an array. 508 * 509 * @param d the source data array 510 */ 511 public void copyFromUnchecked(float[] d) { 512 mRS.validate(); 513 copy1DRangeFromUnchecked(0, mCurrentCount, d); 514 } 515 516 /** 517 * Copy an allocation from an array. This variant is type 518 * checked and will generate exceptions if the Allocation type 519 * is not a 32 bit integer type. 520 * 521 * @param d the source data array 522 */ 523 public void copyFrom(int[] d) { 524 mRS.validate(); 525 copy1DRangeFrom(0, mCurrentCount, d); 526 } 527 528 /** 529 * Copy an allocation from an array. This variant is type 530 * checked and will generate exceptions if the Allocation type 531 * is not a 16 bit integer type. 532 * 533 * @param d the source data array 534 */ 535 public void copyFrom(short[] d) { 536 mRS.validate(); 537 copy1DRangeFrom(0, mCurrentCount, d); 538 } 539 540 /** 541 * Copy an allocation from an array. This variant is type 542 * checked and will generate exceptions if the Allocation type 543 * is not a 8 bit integer type. 544 * 545 * @param d the source data array 546 */ 547 public void copyFrom(byte[] d) { 548 mRS.validate(); 549 copy1DRangeFrom(0, mCurrentCount, d); 550 } 551 552 /** 553 * Copy an allocation from an array. This variant is type 554 * checked and will generate exceptions if the Allocation type 555 * is not a 32 bit float type. 556 * 557 * @param d the source data array 558 */ 559 public void copyFrom(float[] d) { 560 mRS.validate(); 561 copy1DRangeFrom(0, mCurrentCount, d); 562 } 563 564 /** 565 * Copy an allocation from a bitmap. The height, width, and 566 * format of the bitmap must match the existing allocation. 567 * 568 * @param b the source bitmap 569 */ 570 public void copyFrom(Bitmap b) { 571 mRS.validate(); 572 validateBitmapSize(b); 573 validateBitmapFormat(b); 574 mRS.nAllocationCopyFromBitmap(getID(), b); 575 } 576 577 /** 578 * This is only intended to be used by auto-generate code reflected from the 579 * renderscript script files. 580 * 581 * @param xoff 582 * @param fp 583 */ 584 public void setFromFieldPacker(int xoff, FieldPacker fp) { 585 mRS.validate(); 586 int eSize = mType.mElement.getSizeBytes(); 587 final byte[] data = fp.getData(); 588 589 int count = data.length / eSize; 590 if ((eSize * count) != data.length) { 591 throw new RSIllegalArgumentException("Field packer length " + data.length + 592 " not divisible by element size " + eSize + "."); 593 } 594 copy1DRangeFromUnchecked(xoff, count, data); 595 } 596 597 /** 598 * This is only intended to be used by auto-generate code reflected from the 599 * renderscript script files. 600 * 601 * @param xoff 602 * @param component_number 603 * @param fp 604 */ 605 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) { 606 mRS.validate(); 607 if (component_number >= mType.mElement.mElements.length) { 608 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range."); 609 } 610 if(xoff < 0) { 611 throw new RSIllegalArgumentException("Offset must be >= 0."); 612 } 613 614 final byte[] data = fp.getData(); 615 int eSize = mType.mElement.mElements[component_number].getSizeBytes(); 616 eSize *= mType.mElement.mArraySizes[component_number]; 617 618 if (data.length != eSize) { 619 throw new RSIllegalArgumentException("Field packer sizelength " + data.length + 620 " does not match component size " + eSize + "."); 621 } 622 623 mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD, 624 component_number, data, data.length); 625 } 626 627 private void data1DChecks(int off, int count, int len, int dataSize) { 628 mRS.validate(); 629 if(off < 0) { 630 throw new RSIllegalArgumentException("Offset must be >= 0."); 631 } 632 if(count < 1) { 633 throw new RSIllegalArgumentException("Count must be >= 1."); 634 } 635 if((off + count) > mCurrentCount) { 636 throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount + 637 ", got " + count + " at offset " + off + "."); 638 } 639 if(len < dataSize) { 640 throw new RSIllegalArgumentException("Array too small for allocation type."); 641 } 642 } 643 644 /** 645 * Generate a mipmap chain. Requires the type of the allocation 646 * include mipmaps. 647 * 648 * This function will generate a complete set of mipmaps from 649 * the top level lod and place them into the script memoryspace. 650 * 651 * If the allocation is also using other memory spaces a 652 * followup sync will be required. 653 */ 654 public void generateMipmaps() { 655 mRS.nAllocationGenerateMipmaps(getID()); 656 } 657 658 /** 659 * Copy part of an allocation from an array. This variant is 660 * not type checked which allows an application to fill in 661 * structured data from an array. 662 * 663 * @param off The offset of the first element to be copied. 664 * @param count The number of elements to be copied. 665 * @param d the source data array 666 */ 667 public void copy1DRangeFromUnchecked(int off, int count, int[] d) { 668 int dataSize = mType.mElement.getSizeBytes() * count; 669 data1DChecks(off, count, d.length * 4, dataSize); 670 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize); 671 } 672 /** 673 * Copy part of an allocation from an array. This variant is 674 * not type checked which allows an application to fill in 675 * structured data from an array. 676 * 677 * @param off The offset of the first element to be copied. 678 * @param count The number of elements to be copied. 679 * @param d the source data array 680 */ 681 public void copy1DRangeFromUnchecked(int off, int count, short[] d) { 682 int dataSize = mType.mElement.getSizeBytes() * count; 683 data1DChecks(off, count, d.length * 2, dataSize); 684 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize); 685 } 686 /** 687 * Copy part of an allocation from an array. This variant is 688 * not type checked which allows an application to fill in 689 * structured data from an array. 690 * 691 * @param off The offset of the first element to be copied. 692 * @param count The number of elements to be copied. 693 * @param d the source data array 694 */ 695 public void copy1DRangeFromUnchecked(int off, int count, byte[] d) { 696 int dataSize = mType.mElement.getSizeBytes() * count; 697 data1DChecks(off, count, d.length, dataSize); 698 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize); 699 } 700 /** 701 * Copy part of an allocation from an array. This variant is 702 * not type checked which allows an application to fill in 703 * structured data from an array. 704 * 705 * @param off The offset of the first element to be copied. 706 * @param count The number of elements to be copied. 707 * @param d the source data array 708 */ 709 public void copy1DRangeFromUnchecked(int off, int count, float[] d) { 710 int dataSize = mType.mElement.getSizeBytes() * count; 711 data1DChecks(off, count, d.length * 4, dataSize); 712 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize); 713 } 714 715 /** 716 * Copy part of an allocation from an array. This variant is 717 * type checked and will generate exceptions if the Allocation 718 * type is not a 32 bit integer type. 719 * 720 * @param off The offset of the first element to be copied. 721 * @param count The number of elements to be copied. 722 * @param d the source data array 723 */ 724 public void copy1DRangeFrom(int off, int count, int[] d) { 725 validateIsInt32(); 726 copy1DRangeFromUnchecked(off, count, d); 727 } 728 729 /** 730 * Copy part of an allocation from an array. This variant is 731 * type checked and will generate exceptions if the Allocation 732 * type is not a 16 bit integer type. 733 * 734 * @param off The offset of the first element to be copied. 735 * @param count The number of elements to be copied. 736 * @param d the source data array 737 */ 738 public void copy1DRangeFrom(int off, int count, short[] d) { 739 validateIsInt16(); 740 copy1DRangeFromUnchecked(off, count, d); 741 } 742 743 /** 744 * Copy part of an allocation from an array. This variant is 745 * type checked and will generate exceptions if the Allocation 746 * type is not a 8 bit integer type. 747 * 748 * @param off The offset of the first element to be copied. 749 * @param count The number of elements to be copied. 750 * @param d the source data array 751 */ 752 public void copy1DRangeFrom(int off, int count, byte[] d) { 753 validateIsInt8(); 754 copy1DRangeFromUnchecked(off, count, d); 755 } 756 757 /** 758 * Copy part of an allocation from an array. This variant is 759 * type checked and will generate exceptions if the Allocation 760 * type is not a 32 bit float type. 761 * 762 * @param off The offset of the first element to be copied. 763 * @param count The number of elements to be copied. 764 * @param d the source data array. 765 */ 766 public void copy1DRangeFrom(int off, int count, float[] d) { 767 validateIsFloat32(); 768 copy1DRangeFromUnchecked(off, count, d); 769 } 770 771 /** 772 * Copy part of an allocation from another allocation. 773 * 774 * @param off The offset of the first element to be copied. 775 * @param count The number of elements to be copied. 776 * @param data the source data allocation. 777 * @param dataOff off The offset of the first element in data to 778 * be copied. 779 */ 780 public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) { 781 mRS.nAllocationData2D(getIDSafe(), off, 0, 782 mSelectedLOD, mSelectedFace.mID, 783 count, 1, data.getID(), dataOff, 0, 784 data.mSelectedLOD, data.mSelectedFace.mID); 785 } 786 787 private void validate2DRange(int xoff, int yoff, int w, int h) { 788 if (mAdaptedAllocation != null) { 789 790 } else { 791 792 if (xoff < 0 || yoff < 0) { 793 throw new RSIllegalArgumentException("Offset cannot be negative."); 794 } 795 if (h < 0 || w < 0) { 796 throw new RSIllegalArgumentException("Height or width cannot be negative."); 797 } 798 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) { 799 throw new RSIllegalArgumentException("Updated region larger than allocation."); 800 } 801 } 802 } 803 804 /** 805 * Copy a rectangular region from the array into the allocation. 806 * The incoming array is assumed to be tightly packed. 807 * 808 * @param xoff X offset of the region to update 809 * @param yoff Y offset of the region to update 810 * @param w Width of the incoming region to update 811 * @param h Height of the incoming region to update 812 * @param data to be placed into the allocation 813 */ 814 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) { 815 mRS.validate(); 816 validate2DRange(xoff, yoff, w, h); 817 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, 818 w, h, data, data.length); 819 } 820 821 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) { 822 mRS.validate(); 823 validate2DRange(xoff, yoff, w, h); 824 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, 825 w, h, data, data.length * 2); 826 } 827 828 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) { 829 mRS.validate(); 830 validate2DRange(xoff, yoff, w, h); 831 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, 832 w, h, data, data.length * 4); 833 } 834 835 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) { 836 mRS.validate(); 837 validate2DRange(xoff, yoff, w, h); 838 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, 839 w, h, data, data.length * 4); 840 } 841 842 /** 843 * Copy a rectangular region into the allocation from another 844 * allocation. 845 * 846 * @param xoff X offset of the region to update. 847 * @param yoff Y offset of the region to update. 848 * @param w Width of the incoming region to update. 849 * @param h Height of the incoming region to update. 850 * @param data source allocation. 851 * @param dataXoff X offset in data of the region to update. 852 * @param dataYoff Y offset in data of the region to update. 853 */ 854 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, 855 Allocation data, int dataXoff, int dataYoff) { 856 mRS.validate(); 857 validate2DRange(xoff, yoff, w, h); 858 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, 859 mSelectedLOD, mSelectedFace.mID, 860 w, h, data.getID(), dataXoff, dataYoff, 861 data.mSelectedLOD, data.mSelectedFace.mID); 862 } 863 864 /** 865 * Copy a bitmap into an allocation. The height and width of 866 * the update will use the height and width of the incoming 867 * bitmap. 868 * 869 * @param xoff X offset of the region to update 870 * @param yoff Y offset of the region to update 871 * @param data the bitmap to be copied 872 */ 873 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) { 874 mRS.validate(); 875 validateBitmapFormat(data); 876 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight()); 877 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data); 878 } 879 880 881 /** 882 * Copy from the Allocation into a Bitmap. The bitmap must 883 * match the dimensions of the Allocation. 884 * 885 * @param b The bitmap to be set from the Allocation. 886 */ 887 public void copyTo(Bitmap b) { 888 mRS.validate(); 889 validateBitmapFormat(b); 890 validateBitmapSize(b); 891 mRS.nAllocationCopyToBitmap(getID(), b); 892 } 893 894 /** 895 * Copy from the Allocation into a byte array. The array must 896 * be at least as large as the Allocation. The allocation must 897 * be of an 8 bit elemental type. 898 * 899 * @param d The array to be set from the Allocation. 900 */ 901 public void copyTo(byte[] d) { 902 validateIsInt8(); 903 mRS.validate(); 904 mRS.nAllocationRead(getID(), d); 905 } 906 907 /** 908 * Copy from the Allocation into a short array. The array must 909 * be at least as large as the Allocation. The allocation must 910 * be of an 16 bit elemental type. 911 * 912 * @param d The array to be set from the Allocation. 913 */ 914 public void copyTo(short[] d) { 915 validateIsInt16(); 916 mRS.validate(); 917 mRS.nAllocationRead(getID(), d); 918 } 919 920 /** 921 * Copy from the Allocation into a int array. The array must be 922 * at least as large as the Allocation. The allocation must be 923 * of an 32 bit elemental type. 924 * 925 * @param d The array to be set from the Allocation. 926 */ 927 public void copyTo(int[] d) { 928 validateIsInt32(); 929 mRS.validate(); 930 mRS.nAllocationRead(getID(), d); 931 } 932 933 /** 934 * Copy from the Allocation into a float array. The array must 935 * be at least as large as the Allocation. The allocation must 936 * be of an 32 bit float elemental type. 937 * 938 * @param d The array to be set from the Allocation. 939 */ 940 public void copyTo(float[] d) { 941 validateIsFloat32(); 942 mRS.validate(); 943 mRS.nAllocationRead(getID(), d); 944 } 945 946 /** 947 * Resize a 1D allocation. The contents of the allocation are 948 * preserved. If new elements are allocated objects are created 949 * with null contents and the new region is otherwise undefined. 950 * 951 * If the new region is smaller the references of any objects 952 * outside the new region will be released. 953 * 954 * A new type will be created with the new dimension. 955 * 956 * @param dimX The new size of the allocation. 957 */ 958 public synchronized void resize(int dimX) { 959 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) { 960 throw new RSInvalidStateException("Resize only support for 1D allocations at this time."); 961 } 962 mRS.nAllocationResize1D(getID(), dimX); 963 mRS.finish(); // Necessary because resize is fifoed and update is async. 964 965 int typeID = mRS.nAllocationGetType(getID()); 966 mType = new Type(typeID, mRS); 967 mType.updateFromNative(); 968 updateCacheInfo(mType); 969 } 970 971 /** 972 * Resize a 2D allocation. The contents of the allocation are 973 * preserved. If new elements are allocated objects are created 974 * with null contents and the new region is otherwise undefined. 975 * 976 * If the new region is smaller the references of any objects 977 * outside the new region will be released. 978 * 979 * A new type will be created with the new dimension. 980 * 981 * @hide 982 * @param dimX The new size of the allocation. 983 * @param dimY The new size of the allocation. 984 */ 985 public void resize(int dimX, int dimY) { 986 if ((mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) { 987 throw new RSInvalidStateException( 988 "Resize only support for 2D allocations at this time."); 989 } 990 if (mType.getY() == 0) { 991 throw new RSInvalidStateException( 992 "Resize only support for 2D allocations at this time."); 993 } 994 mRS.nAllocationResize2D(getID(), dimX, dimY); 995 mRS.finish(); // Necessary because resize is fifoed and update is async. 996 997 int typeID = mRS.nAllocationGetType(getID()); 998 mType = new Type(typeID, mRS); 999 mType.updateFromNative(); 1000 updateCacheInfo(mType); 1001 } 1002 1003 1004 1005 // creation 1006 1007 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options(); 1008 static { 1009 mBitmapOptions.inScaled = false; 1010 } 1011 1012 /** 1013 * 1014 * @param type renderscript type describing data layout 1015 * @param mips specifies desired mipmap behaviour for the 1016 * allocation 1017 * @param usage bit field specifying how the allocation is 1018 * utilized 1019 */ 1020 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) { 1021 rs.validate(); 1022 if (type.getID() == 0) { 1023 throw new RSInvalidStateException("Bad Type"); 1024 } 1025 int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage, 0); 1026 if (id == 0) { 1027 throw new RSRuntimeException("Allocation creation failed."); 1028 } 1029 return new Allocation(id, rs, type, usage); 1030 } 1031 1032 /** 1033 * @hide 1034 * This API is hidden and only intended to be used for 1035 * transitional purposes. 1036 * 1037 * @param type renderscript type describing data layout 1038 * @param mips specifies desired mipmap behaviour for the 1039 * allocation 1040 * @param usage bit field specifying how the allocation is 1041 * utilized 1042 */ 1043 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, 1044 int usage, int pointer) { 1045 rs.validate(); 1046 if (type.getID() == 0) { 1047 throw new RSInvalidStateException("Bad Type"); 1048 } 1049 int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage, pointer); 1050 if (id == 0) { 1051 throw new RSRuntimeException("Allocation creation failed."); 1052 } 1053 return new Allocation(id, rs, type, usage); 1054 } 1055 1056 /** 1057 * Creates a renderscript allocation with the size specified by 1058 * the type and no mipmaps generated by default 1059 * 1060 * @param rs Context to which the allocation will belong. 1061 * @param type renderscript type describing data layout 1062 * @param usage bit field specifying how the allocation is 1063 * utilized 1064 * 1065 * @return allocation 1066 */ 1067 static public Allocation createTyped(RenderScript rs, Type type, int usage) { 1068 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage); 1069 } 1070 1071 /** 1072 * Creates a renderscript allocation for use by the script with 1073 * the size specified by the type and no mipmaps generated by 1074 * default 1075 * 1076 * @param rs Context to which the allocation will belong. 1077 * @param type renderscript type describing data layout 1078 * 1079 * @return allocation 1080 */ 1081 static public Allocation createTyped(RenderScript rs, Type type) { 1082 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT); 1083 } 1084 1085 /** 1086 * Creates a renderscript allocation with a specified number of 1087 * given elements 1088 * 1089 * @param rs Context to which the allocation will belong. 1090 * @param e describes what each element of an allocation is 1091 * @param count specifies the number of element in the allocation 1092 * @param usage bit field specifying how the allocation is 1093 * utilized 1094 * 1095 * @return allocation 1096 */ 1097 static public Allocation createSized(RenderScript rs, Element e, 1098 int count, int usage) { 1099 rs.validate(); 1100 Type.Builder b = new Type.Builder(rs, e); 1101 b.setX(count); 1102 Type t = b.create(); 1103 1104 int id = rs.nAllocationCreateTyped(t.getID(), MipmapControl.MIPMAP_NONE.mID, usage, 0); 1105 if (id == 0) { 1106 throw new RSRuntimeException("Allocation creation failed."); 1107 } 1108 return new Allocation(id, rs, t, usage); 1109 } 1110 1111 /** 1112 * Creates a renderscript allocation with a specified number of 1113 * given elements 1114 * 1115 * @param rs Context to which the allocation will belong. 1116 * @param e describes what each element of an allocation is 1117 * @param count specifies the number of element in the allocation 1118 * 1119 * @return allocation 1120 */ 1121 static public Allocation createSized(RenderScript rs, Element e, int count) { 1122 return createSized(rs, e, count, USAGE_SCRIPT); 1123 } 1124 1125 static Element elementFromBitmap(RenderScript rs, Bitmap b) { 1126 final Bitmap.Config bc = b.getConfig(); 1127 if (bc == Bitmap.Config.ALPHA_8) { 1128 return Element.A_8(rs); 1129 } 1130 if (bc == Bitmap.Config.ARGB_4444) { 1131 return Element.RGBA_4444(rs); 1132 } 1133 if (bc == Bitmap.Config.ARGB_8888) { 1134 return Element.RGBA_8888(rs); 1135 } 1136 if (bc == Bitmap.Config.RGB_565) { 1137 return Element.RGB_565(rs); 1138 } 1139 throw new RSInvalidStateException("Bad bitmap type: " + bc); 1140 } 1141 1142 static Type typeFromBitmap(RenderScript rs, Bitmap b, 1143 MipmapControl mip) { 1144 Element e = elementFromBitmap(rs, b); 1145 Type.Builder tb = new Type.Builder(rs, e); 1146 tb.setX(b.getWidth()); 1147 tb.setY(b.getHeight()); 1148 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL); 1149 return tb.create(); 1150 } 1151 1152 /** 1153 * Creates a renderscript allocation from a bitmap 1154 * 1155 * @param rs Context to which the allocation will belong. 1156 * @param b bitmap source for the allocation data 1157 * @param mips specifies desired mipmap behaviour for the 1158 * allocation 1159 * @param usage bit field specifying how the allocation is 1160 * utilized 1161 * 1162 * @return renderscript allocation containing bitmap data 1163 * 1164 */ 1165 static public Allocation createFromBitmap(RenderScript rs, Bitmap b, 1166 MipmapControl mips, 1167 int usage) { 1168 rs.validate(); 1169 Type t = typeFromBitmap(rs, b, mips); 1170 1171 int id = rs.nAllocationCreateFromBitmap(t.getID(), mips.mID, b, usage); 1172 if (id == 0) { 1173 throw new RSRuntimeException("Load failed."); 1174 } 1175 return new Allocation(id, rs, t, usage); 1176 } 1177 1178 /** 1179 * 1180 * 1181 * @hide 1182 * 1183 */ 1184 public SurfaceTexture getSurfaceTexture() { 1185 if ((mUsage & USAGE_IO_INPUT) == 0) { 1186 throw new RSInvalidStateException("Allocation is not a surface texture."); 1187 } 1188 1189 int id = mRS.nAllocationGetSurfaceTextureID(getID()); 1190 SurfaceTexture st = new SurfaceTexture(id); 1191 mRS.nAllocationGetSurfaceTextureID2(getID(), st); 1192 1193 return st; 1194 } 1195 1196 /** 1197 * 1198 * @hide 1199 * 1200 */ 1201 public Surface getSurface() { 1202 return new Surface(getSurfaceTexture()); 1203 } 1204 1205 /** 1206 * @hide 1207 */ 1208 public void setSurface(Surface sur) { 1209 mRS.validate(); 1210 if ((mUsage & USAGE_IO_OUTPUT) == 0) { 1211 throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT."); 1212 } 1213 1214 mRS.nAllocationSetSurface(getID(), sur); 1215 } 1216 1217 /** 1218 * @hide 1219 */ 1220 public void setSurfaceTexture(SurfaceTexture st) { 1221 mRS.validate(); 1222 if ((mUsage & USAGE_IO_OUTPUT) == 0) { 1223 throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT."); 1224 } 1225 1226 Surface s = new Surface(st); 1227 mRS.nAllocationSetSurface(getID(), s); 1228 } 1229 1230 /** 1231 * Creates a non-mipmapped renderscript allocation to use as a 1232 * graphics texture 1233 * 1234 * @param rs Context to which the allocation will belong. 1235 * @param b bitmap source for the allocation data 1236 * 1237 * @return renderscript allocation containing bitmap data 1238 * 1239 */ 1240 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) { 1241 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, 1242 USAGE_GRAPHICS_TEXTURE); 1243 } 1244 1245 /** 1246 * Creates a cubemap allocation from a bitmap containing the 1247 * horizontal list of cube faces. Each individual face must be 1248 * the same size and power of 2 1249 * 1250 * @param rs Context to which the allocation will belong. 1251 * @param b bitmap with cubemap faces layed out in the following 1252 * format: right, left, top, bottom, front, back 1253 * @param mips specifies desired mipmap behaviour for the cubemap 1254 * @param usage bit field specifying how the cubemap is utilized 1255 * 1256 * @return allocation containing cubemap data 1257 * 1258 */ 1259 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b, 1260 MipmapControl mips, 1261 int usage) { 1262 rs.validate(); 1263 1264 int height = b.getHeight(); 1265 int width = b.getWidth(); 1266 1267 if (width % 6 != 0) { 1268 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6"); 1269 } 1270 if (width / 6 != height) { 1271 throw new RSIllegalArgumentException("Only square cube map faces supported"); 1272 } 1273 boolean isPow2 = (height & (height - 1)) == 0; 1274 if (!isPow2) { 1275 throw new RSIllegalArgumentException("Only power of 2 cube faces supported"); 1276 } 1277 1278 Element e = elementFromBitmap(rs, b); 1279 Type.Builder tb = new Type.Builder(rs, e); 1280 tb.setX(height); 1281 tb.setY(height); 1282 tb.setFaces(true); 1283 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL); 1284 Type t = tb.create(); 1285 1286 int id = rs.nAllocationCubeCreateFromBitmap(t.getID(), mips.mID, b, usage); 1287 if(id == 0) { 1288 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e); 1289 } 1290 return new Allocation(id, rs, t, usage); 1291 } 1292 1293 /** 1294 * Creates a non-mipmapped cubemap allocation for use as a 1295 * graphics texture from a bitmap containing the horizontal list 1296 * of cube faces. Each individual face must be the same size and 1297 * power of 2 1298 * 1299 * @param rs Context to which the allocation will belong. 1300 * @param b bitmap with cubemap faces layed out in the following 1301 * format: right, left, top, bottom, front, back 1302 * 1303 * @return allocation containing cubemap data 1304 * 1305 */ 1306 static public Allocation createCubemapFromBitmap(RenderScript rs, 1307 Bitmap b) { 1308 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, 1309 USAGE_GRAPHICS_TEXTURE); 1310 } 1311 1312 /** 1313 * Creates a cubemap allocation from 6 bitmaps containing 1314 * the cube faces. All the faces must be the same size and 1315 * power of 2 1316 * 1317 * @param rs Context to which the allocation will belong. 1318 * @param xpos cubemap face in the positive x direction 1319 * @param xneg cubemap face in the negative x direction 1320 * @param ypos cubemap face in the positive y direction 1321 * @param yneg cubemap face in the negative y direction 1322 * @param zpos cubemap face in the positive z direction 1323 * @param zneg cubemap face in the negative z direction 1324 * @param mips specifies desired mipmap behaviour for the cubemap 1325 * @param usage bit field specifying how the cubemap is utilized 1326 * 1327 * @return allocation containing cubemap data 1328 * 1329 */ 1330 static public Allocation createCubemapFromCubeFaces(RenderScript rs, 1331 Bitmap xpos, 1332 Bitmap xneg, 1333 Bitmap ypos, 1334 Bitmap yneg, 1335 Bitmap zpos, 1336 Bitmap zneg, 1337 MipmapControl mips, 1338 int usage) { 1339 int height = xpos.getHeight(); 1340 if (xpos.getWidth() != height || 1341 xneg.getWidth() != height || xneg.getHeight() != height || 1342 ypos.getWidth() != height || ypos.getHeight() != height || 1343 yneg.getWidth() != height || yneg.getHeight() != height || 1344 zpos.getWidth() != height || zpos.getHeight() != height || 1345 zneg.getWidth() != height || zneg.getHeight() != height) { 1346 throw new RSIllegalArgumentException("Only square cube map faces supported"); 1347 } 1348 boolean isPow2 = (height & (height - 1)) == 0; 1349 if (!isPow2) { 1350 throw new RSIllegalArgumentException("Only power of 2 cube faces supported"); 1351 } 1352 1353 Element e = elementFromBitmap(rs, xpos); 1354 Type.Builder tb = new Type.Builder(rs, e); 1355 tb.setX(height); 1356 tb.setY(height); 1357 tb.setFaces(true); 1358 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL); 1359 Type t = tb.create(); 1360 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage); 1361 1362 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap); 1363 adapter.setFace(Type.CubemapFace.POSITIVE_X); 1364 adapter.copyFrom(xpos); 1365 adapter.setFace(Type.CubemapFace.NEGATIVE_X); 1366 adapter.copyFrom(xneg); 1367 adapter.setFace(Type.CubemapFace.POSITIVE_Y); 1368 adapter.copyFrom(ypos); 1369 adapter.setFace(Type.CubemapFace.NEGATIVE_Y); 1370 adapter.copyFrom(yneg); 1371 adapter.setFace(Type.CubemapFace.POSITIVE_Z); 1372 adapter.copyFrom(zpos); 1373 adapter.setFace(Type.CubemapFace.NEGATIVE_Z); 1374 adapter.copyFrom(zneg); 1375 1376 return cubemap; 1377 } 1378 1379 /** 1380 * Creates a non-mipmapped cubemap allocation for use as a 1381 * graphics texture from 6 bitmaps containing 1382 * the cube faces. All the faces must be the same size and 1383 * power of 2 1384 * 1385 * @param rs Context to which the allocation will belong. 1386 * @param xpos cubemap face in the positive x direction 1387 * @param xneg cubemap face in the negative x direction 1388 * @param ypos cubemap face in the positive y direction 1389 * @param yneg cubemap face in the negative y direction 1390 * @param zpos cubemap face in the positive z direction 1391 * @param zneg cubemap face in the negative z direction 1392 * 1393 * @return allocation containing cubemap data 1394 * 1395 */ 1396 static public Allocation createCubemapFromCubeFaces(RenderScript rs, 1397 Bitmap xpos, 1398 Bitmap xneg, 1399 Bitmap ypos, 1400 Bitmap yneg, 1401 Bitmap zpos, 1402 Bitmap zneg) { 1403 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg, 1404 zpos, zneg, MipmapControl.MIPMAP_NONE, 1405 USAGE_GRAPHICS_TEXTURE); 1406 } 1407 1408 /** 1409 * Creates a renderscript allocation from the bitmap referenced 1410 * by resource id 1411 * 1412 * @param rs Context to which the allocation will belong. 1413 * @param res application resources 1414 * @param id resource id to load the data from 1415 * @param mips specifies desired mipmap behaviour for the 1416 * allocation 1417 * @param usage bit field specifying how the allocation is 1418 * utilized 1419 * 1420 * @return renderscript allocation containing resource data 1421 * 1422 */ 1423 static public Allocation createFromBitmapResource(RenderScript rs, 1424 Resources res, 1425 int id, 1426 MipmapControl mips, 1427 int usage) { 1428 1429 rs.validate(); 1430 Bitmap b = BitmapFactory.decodeResource(res, id); 1431 Allocation alloc = createFromBitmap(rs, b, mips, usage); 1432 b.recycle(); 1433 return alloc; 1434 } 1435 1436 /** 1437 * Creates a non-mipmapped renderscript allocation to use as a 1438 * graphics texture from the bitmap referenced by resource id 1439 * 1440 * @param rs Context to which the allocation will belong. 1441 * @param res application resources 1442 * @param id resource id to load the data from 1443 * 1444 * @return renderscript allocation containing resource data 1445 * 1446 */ 1447 static public Allocation createFromBitmapResource(RenderScript rs, 1448 Resources res, 1449 int id) { 1450 return createFromBitmapResource(rs, res, id, 1451 MipmapControl.MIPMAP_NONE, 1452 USAGE_GRAPHICS_TEXTURE); 1453 } 1454 1455 /** 1456 * Creates a renderscript allocation containing string data 1457 * encoded in UTF-8 format 1458 * 1459 * @param rs Context to which the allocation will belong. 1460 * @param str string to create the allocation from 1461 * @param usage bit field specifying how the allocaiton is 1462 * utilized 1463 * 1464 */ 1465 static public Allocation createFromString(RenderScript rs, 1466 String str, 1467 int usage) { 1468 rs.validate(); 1469 byte[] allocArray = null; 1470 try { 1471 allocArray = str.getBytes("UTF-8"); 1472 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage); 1473 alloc.copyFrom(allocArray); 1474 return alloc; 1475 } 1476 catch (Exception e) { 1477 throw new RSRuntimeException("Could not convert string to utf-8."); 1478 } 1479 } 1480} 1481 1482 1483