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