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