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