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