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