Allocation.java revision fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210
1/* 2 * Copyright (C) 2008 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.util.Log; 26import android.util.TypedValue; 27 28/** 29 * Memory allocation class for renderscript. An allocation combines a Type with 30 * memory to provide storage for user data and objects. 31 * 32 * Allocations may exist in one or more memory spaces. Currently those are 33 * Script: accessable by RS scripts. 34 * Graphics Texture: accessable as a graphics texture. 35 * Graphics Vertex: accessable as graphical vertex data. 36 * Graphics Constants: Accessable as constants in user shaders 37 * 38 * By default java side updates are always applied to the script accessable 39 * memory. If this is not present they are then applied to the various HW 40 * memory types. A syncAll call is necessary after the script data is update to 41 * keep the other memory spaces in sync. 42 * 43 **/ 44public class Allocation extends BaseObj { 45 Type mType; 46 Bitmap mBitmap; 47 int mUsage; 48 49 /** 50 * The usage of the allocation. These signal to renderscript 51 * where to place the allocation in memory. 52 * 53 * SCRIPT The allocation will be bound to and accessed by 54 * scripts. 55 */ 56 public static final int USAGE_SCRIPT = 0x0001; 57 58 /** 59 * GRAPHICS_TEXTURE The allcation will be used as a texture 60 * source by one or more graphcics programs. 61 * 62 */ 63 public static final int USAGE_GRAPHICS_TEXTURE = 0x0002; 64 65 /** 66 * GRAPHICS_VERTEX The allocation will be used as a graphics 67 * mesh. 68 * 69 */ 70 public static final int USAGE_GRAPHICS_VERTEX = 0x0004; 71 72 73 /** 74 * GRAPHICS_CONSTANTS The allocation will be used as the source 75 * of shader constants by one or more programs. 76 * 77 */ 78 public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008; 79 80 81 /** 82 * Controls mipmap behavior when using the bitmap creation and 83 * update functions. 84 */ 85 public enum MipmapControl { 86 /** 87 * No mipmaps will be generated and the type generated from the 88 * incoming bitmap will not contain additional LODs. 89 */ 90 MIPMAP_NONE(0), 91 92 /** 93 * A Full mipmap chain will be created in script memory. The 94 * type of the allocation will contain a full mipmap chain. On 95 * upload to graphics the full chain will be transfered. 96 */ 97 MIPMAP_FULL(1), 98 99 /** 100 * The type of the allocation will be the same as MIPMAP_NONE. 101 * It will not contain mipmaps. On upload to graphics the 102 * graphics copy of the allocation data will contain a full 103 * mipmap chain generated from the top level in script memory. 104 */ 105 MIPMAP_ON_SYNC_TO_TEXTURE(2); 106 107 int mID; 108 MipmapControl(int id) { 109 mID = id; 110 } 111 } 112 113 Allocation(int id, RenderScript rs, Type t, int usage) { 114 super(id, rs); 115 if ((usage & ~(USAGE_SCRIPT | 116 USAGE_GRAPHICS_TEXTURE | 117 USAGE_GRAPHICS_VERTEX | 118 USAGE_GRAPHICS_CONSTANTS)) != 0) { 119 throw new RSIllegalArgumentException("Unknown usage specified."); 120 } 121 mType = t; 122 } 123 124 @Override 125 void updateFromNative() { 126 super.updateFromNative(); 127 int typeID = mRS.nAllocationGetType(getID()); 128 if(typeID != 0) { 129 mType = new Type(typeID, mRS); 130 mType.updateFromNative(); 131 } 132 } 133 134 public Type getType() { 135 return mType; 136 } 137 138 public void syncAll(int srcLocation) { 139 switch (srcLocation) { 140 case USAGE_SCRIPT: 141 case USAGE_GRAPHICS_CONSTANTS: 142 case USAGE_GRAPHICS_TEXTURE: 143 case USAGE_GRAPHICS_VERTEX: 144 break; 145 default: 146 throw new RSIllegalArgumentException("Source must be exactly one usage type."); 147 } 148 mRS.validate(); 149 mRS.nAllocationSyncAll(getID(), srcLocation); 150 } 151 152 public void copyFrom(BaseObj[] d) { 153 mRS.validate(); 154 if (d.length != mType.getCount()) { 155 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " + 156 mType.getCount() + ", array length = " + d.length); 157 } 158 int i[] = new int[d.length]; 159 for (int ct=0; ct < d.length; ct++) { 160 i[ct] = d[ct].getID(); 161 } 162 copy1DRangeFrom(0, mType.getCount(), i); 163 } 164 165 private void validateBitmapFormat(Bitmap b) { 166 Bitmap.Config bc = b.getConfig(); 167 switch (bc) { 168 case ALPHA_8: 169 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) { 170 throw new RSIllegalArgumentException("Allocation kind is " + 171 mType.getElement().mKind + ", type " + 172 mType.getElement().mType + 173 " of " + mType.getElement().getSizeBytes() + 174 " bytes, passed bitmap was " + bc); 175 } 176 break; 177 case ARGB_8888: 178 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) || 179 (mType.getElement().getSizeBytes() != 4)) { 180 throw new RSIllegalArgumentException("Allocation kind is " + 181 mType.getElement().mKind + ", type " + 182 mType.getElement().mType + 183 " of " + mType.getElement().getSizeBytes() + 184 " bytes, passed bitmap was " + bc); 185 } 186 break; 187 case RGB_565: 188 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) || 189 (mType.getElement().getSizeBytes() != 2)) { 190 throw new RSIllegalArgumentException("Allocation kind is " + 191 mType.getElement().mKind + ", type " + 192 mType.getElement().mType + 193 " of " + mType.getElement().getSizeBytes() + 194 " bytes, passed bitmap was " + bc); 195 } 196 break; 197 case ARGB_4444: 198 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) || 199 (mType.getElement().getSizeBytes() != 2)) { 200 throw new RSIllegalArgumentException("Allocation kind is " + 201 mType.getElement().mKind + ", type " + 202 mType.getElement().mType + 203 " of " + mType.getElement().getSizeBytes() + 204 " bytes, passed bitmap was " + bc); 205 } 206 break; 207 208 } 209 } 210 211 private void validateBitmapSize(Bitmap b) { 212 if(mType.getX() != b.getWidth() || 213 mType.getY() != b.getHeight()) { 214 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch"); 215 } 216 } 217 218 public void copyFrom(int[] d) { 219 mRS.validate(); 220 copy1DRangeFrom(0, mType.getCount(), d); 221 } 222 public void copyFrom(short[] d) { 223 mRS.validate(); 224 copy1DRangeFrom(0, mType.getCount(), d); 225 } 226 public void copyFrom(byte[] d) { 227 mRS.validate(); 228 copy1DRangeFrom(0, mType.getCount(), d); 229 } 230 public void copyFrom(float[] d) { 231 mRS.validate(); 232 copy1DRangeFrom(0, mType.getCount(), d); 233 } 234 public void copyFrom(Bitmap b) { 235 mRS.validate(); 236 validateBitmapSize(b); 237 validateBitmapFormat(b); 238 mRS.nAllocationCopyFromBitmap(getID(), b); 239 } 240 241 /** 242 * @hide 243 * 244 * This is only intended to be used by auto-generate code reflected from the 245 * renderscript script files. 246 * 247 * @param xoff 248 * @param fp 249 */ 250 public void setOneElement(int xoff, FieldPacker fp) { 251 int eSize = mType.mElement.getSizeBytes(); 252 final byte[] data = fp.getData(); 253 254 int count = data.length / eSize; 255 if ((eSize * count) != data.length) { 256 throw new RSIllegalArgumentException("Field packer length " + data.length + 257 " not divisible by element size " + eSize + "."); 258 } 259 data1DChecks(xoff, count, data.length, data.length); 260 mRS.nAllocationData1D(getID(), xoff, 0, count, data, data.length); 261 } 262 263 264 /** 265 * @hide 266 * 267 * This is only intended to be used by auto-generate code reflected from the 268 * renderscript script files. 269 * 270 * @param xoff 271 * @param component_number 272 * @param fp 273 */ 274 public void setOneComponent(int xoff, int component_number, FieldPacker fp) { 275 if (component_number >= mType.mElement.mElements.length) { 276 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range."); 277 } 278 if(xoff < 0) { 279 throw new RSIllegalArgumentException("Offset must be >= 0."); 280 } 281 282 final byte[] data = fp.getData(); 283 int eSize = mType.mElement.mElements[component_number].getSizeBytes(); 284 285 if (data.length != eSize) { 286 throw new RSIllegalArgumentException("Field packer sizelength " + data.length + 287 " does not match component size " + eSize + "."); 288 } 289 290 mRS.nAllocationElementData1D(getID(), xoff, 0, component_number, data, data.length); 291 } 292 293 private void data1DChecks(int off, int count, int len, int dataSize) { 294 mRS.validate(); 295 if(off < 0) { 296 throw new RSIllegalArgumentException("Offset must be >= 0."); 297 } 298 if(count < 1) { 299 throw new RSIllegalArgumentException("Count must be >= 1."); 300 } 301 if((off + count) > mType.getCount()) { 302 throw new RSIllegalArgumentException("Overflow, Available count " + mType.getCount() + 303 ", got " + count + " at offset " + off + "."); 304 } 305 if((len) < dataSize) { 306 throw new RSIllegalArgumentException("Array too small for allocation type."); 307 } 308 } 309 310 /** 311 * Generate a mipmap chain. Requires the type of the allocation 312 * include mipmaps. 313 * 314 * This function will generate a complete set of mipmaps from 315 * the top level lod and place them into the script memoryspace. 316 * 317 * If the allocation is also using other memory spaces a 318 * followup sync will be required. 319 */ 320 public void generateMipmaps() { 321 mRS.nAllocationGenerateMipmaps(getID()); 322 } 323 324 public void copy1DRangeFrom(int off, int count, int[] d) { 325 int dataSize = mType.mElement.getSizeBytes() * count; 326 data1DChecks(off, count, d.length * 4, dataSize); 327 mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize); 328 } 329 public void copy1DRangeFrom(int off, int count, short[] d) { 330 int dataSize = mType.mElement.getSizeBytes() * count; 331 data1DChecks(off, count, d.length * 2, dataSize); 332 mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize); 333 } 334 public void copy1DRangeFrom(int off, int count, byte[] d) { 335 int dataSize = mType.mElement.getSizeBytes() * count; 336 data1DChecks(off, count, d.length, dataSize); 337 mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize); 338 } 339 public void copy1DRangeFrom(int off, int count, float[] d) { 340 int dataSize = mType.mElement.getSizeBytes() * count; 341 data1DChecks(off, count, d.length * 4, dataSize); 342 mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize); 343 } 344 345 private void validate2DRange(int xoff, int yoff, int w, int h) { 346 if (xoff < 0 || yoff < 0) { 347 throw new RSIllegalArgumentException("Offset cannot be negative."); 348 } 349 if (h < 0 || w < 0) { 350 throw new RSIllegalArgumentException("Height or width cannot be negative."); 351 } 352 if ((xoff + w) > mType.mDimX || 353 (yoff + h) > mType.mDimY) { 354 throw new RSIllegalArgumentException("Updated region larger than allocation."); 355 } 356 } 357 358 /** 359 * Copy a rectanglular region from the array into the 360 * allocation. The incoming array is assumed to be tightly 361 * packed. 362 * 363 * @param xoff X offset of the region to update 364 * @param yoff Y offset of the region to update 365 * @param w Width of the incoming region to update 366 * @param h Height of the incoming region to update 367 * @param data to be placed into the allocation 368 */ 369 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) { 370 mRS.validate(); 371 validate2DRange(xoff, yoff, w, h); 372 mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length); 373 } 374 375 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) { 376 mRS.validate(); 377 validate2DRange(xoff, yoff, w, h); 378 mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 2); 379 } 380 381 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) { 382 mRS.validate(); 383 validate2DRange(xoff, yoff, w, h); 384 mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 4); 385 } 386 387 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) { 388 mRS.validate(); 389 validate2DRange(xoff, yoff, w, h); 390 mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 4); 391 } 392 393 /** 394 * Copy a bitmap into an allocation. The height and width of 395 * the update will use the height and width of the incoming 396 * bitmap. 397 * 398 * @param xoff X offset of the region to update 399 * @param yoff Y offset of the region to update 400 * @param data the bitmap to be copied 401 */ 402 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) { 403 mRS.validate(); 404 validateBitmapFormat(data); 405 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight()); 406 mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, data); 407 } 408 409 410 public void copyTo(Bitmap b) { 411 mRS.validate(); 412 validateBitmapFormat(b); 413 validateBitmapSize(b); 414 mRS.nAllocationCopyToBitmap(getID(), b); 415 } 416 417 public void copyTo(byte[] d) { 418 mRS.validate(); 419 mRS.nAllocationRead(getID(), d); 420 } 421 422 public void copyTo(short[] d) { 423 mRS.validate(); 424 mRS.nAllocationRead(getID(), d); 425 } 426 427 public void copyTo(int[] d) { 428 mRS.validate(); 429 mRS.nAllocationRead(getID(), d); 430 } 431 432 public void copyTo(float[] d) { 433 mRS.validate(); 434 mRS.nAllocationRead(getID(), d); 435 } 436 437 /** 438 * Resize a 1D allocation. The contents of the allocation are 439 * preserved. If new elements are allocated objects are created 440 * with null contents and the new region is otherwise undefined. 441 * 442 * If the new region is smaller the references of any objects 443 * outside the new region will be released. 444 * 445 * A new type will be created with the new dimension. 446 * 447 * @param dimX The new size of the allocation. 448 */ 449 public synchronized void resize(int dimX) { 450 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) { 451 throw new RSInvalidStateException("Resize only support for 1D allocations at this time."); 452 } 453 mRS.nAllocationResize1D(getID(), dimX); 454 mRS.finish(); // Necessary because resize is fifoed and update is async. 455 456 int typeID = mRS.nAllocationGetType(getID()); 457 mType = new Type(typeID, mRS); 458 mType.updateFromNative(); 459 } 460 461 /* 462 public void resize(int dimX, int dimY) { 463 if ((mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) { 464 throw new RSIllegalStateException("Resize only support for 2D allocations at this time."); 465 } 466 if (mType.getY() == 0) { 467 throw new RSIllegalStateException("Resize only support for 2D allocations at this time."); 468 } 469 mRS.nAllocationResize2D(getID(), dimX, dimY); 470 } 471 */ 472 473 474 475 // creation 476 477 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options(); 478 static { 479 mBitmapOptions.inScaled = false; 480 } 481 482 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mc, int usage) { 483 rs.validate(); 484 if (type.getID() == 0) { 485 throw new RSInvalidStateException("Bad Type"); 486 } 487 int id = rs.nAllocationCreateTyped(type.getID(), mc.mID, usage); 488 if (id == 0) { 489 throw new RSRuntimeException("Allocation creation failed."); 490 } 491 return new Allocation(id, rs, type, usage); 492 } 493 494 static public Allocation createTyped(RenderScript rs, Type type, int usage) { 495 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage); 496 } 497 498 static public Allocation createTyped(RenderScript rs, Type type) { 499 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT); 500 } 501 502 static public Allocation createSized(RenderScript rs, Element e, 503 int count, int usage) { 504 rs.validate(); 505 Type.Builder b = new Type.Builder(rs, e); 506 b.setX(count); 507 Type t = b.create(); 508 509 int id = rs.nAllocationCreateTyped(t.getID(), MipmapControl.MIPMAP_NONE.mID, usage); 510 if (id == 0) { 511 throw new RSRuntimeException("Allocation creation failed."); 512 } 513 return new Allocation(id, rs, t, usage); 514 } 515 516 static public Allocation createSized(RenderScript rs, Element e, int count) { 517 return createSized(rs, e, count, USAGE_SCRIPT); 518 } 519 520 static Element elementFromBitmap(RenderScript rs, Bitmap b) { 521 final Bitmap.Config bc = b.getConfig(); 522 if (bc == Bitmap.Config.ALPHA_8) { 523 return Element.A_8(rs); 524 } 525 if (bc == Bitmap.Config.ARGB_4444) { 526 return Element.RGBA_4444(rs); 527 } 528 if (bc == Bitmap.Config.ARGB_8888) { 529 return Element.RGBA_8888(rs); 530 } 531 if (bc == Bitmap.Config.RGB_565) { 532 return Element.RGB_565(rs); 533 } 534 throw new RSInvalidStateException("Bad bitmap type: " + bc); 535 } 536 537 static Type typeFromBitmap(RenderScript rs, Bitmap b, 538 MipmapControl mip) { 539 Element e = elementFromBitmap(rs, b); 540 Type.Builder tb = new Type.Builder(rs, e); 541 tb.setX(b.getWidth()); 542 tb.setY(b.getHeight()); 543 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL); 544 return tb.create(); 545 } 546 547 static public Allocation createFromBitmap(RenderScript rs, Bitmap b, 548 MipmapControl mips, 549 int usage) { 550 rs.validate(); 551 Type t = typeFromBitmap(rs, b, mips); 552 553 int id = rs.nAllocationCreateFromBitmap(t.getID(), mips.mID, b, usage); 554 if (id == 0) { 555 throw new RSRuntimeException("Load failed."); 556 } 557 return new Allocation(id, rs, t, usage); 558 } 559 560 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) { 561 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, 562 USAGE_GRAPHICS_TEXTURE); 563 } 564 565 /** 566 * Creates a cubemap allocation from a bitmap containing the 567 * horizontal list of cube faces. Each individual face must be 568 * the same size and power of 2 569 * 570 * @param rs 571 * @param b bitmap with cubemap faces layed out in the following 572 * format: right, left, top, bottom, front, back 573 * @param mips specifies desired mipmap behaviour for the cubemap 574 * @param usage bitfield specifying how the cubemap is utilized 575 * 576 **/ 577 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b, 578 MipmapControl mips, 579 int usage) { 580 rs.validate(); 581 582 int height = b.getHeight(); 583 int width = b.getWidth(); 584 585 if (width % 6 != 0) { 586 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6"); 587 } 588 if (width / 6 != height) { 589 throw new RSIllegalArgumentException("Only square cube map faces supported"); 590 } 591 boolean isPow2 = (height & (height - 1)) == 0; 592 if (!isPow2) { 593 throw new RSIllegalArgumentException("Only power of 2 cube faces supported"); 594 } 595 596 Element e = elementFromBitmap(rs, b); 597 Type.Builder tb = new Type.Builder(rs, e); 598 tb.setX(height); 599 tb.setY(height); 600 tb.setFaces(true); 601 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL); 602 Type t = tb.create(); 603 604 int id = rs.nAllocationCubeCreateFromBitmap(t.getID(), mips.mID, b, usage); 605 if(id == 0) { 606 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e); 607 } 608 return new Allocation(id, rs, t, usage); 609 } 610 611 static public Allocation createCubemapFromBitmap(RenderScript rs, 612 Bitmap b) { 613 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE, 614 USAGE_GRAPHICS_TEXTURE); 615 } 616 617 static public Allocation createCubemapFromCubeFaces(RenderScript rs, 618 Bitmap xpos, 619 Bitmap xneg, 620 Bitmap ypos, 621 Bitmap yneg, 622 Bitmap zpos, 623 Bitmap zneg, 624 MipmapControl mips, 625 int usage) { 626 int height = xpos.getHeight(); 627 if (xpos.getWidth() != height || 628 xneg.getWidth() != height || xneg.getHeight() != height || 629 ypos.getWidth() != height || ypos.getHeight() != height || 630 yneg.getWidth() != height || yneg.getHeight() != height || 631 zpos.getWidth() != height || zpos.getHeight() != height || 632 zneg.getWidth() != height || zneg.getHeight() != height) { 633 throw new RSIllegalArgumentException("Only square cube map faces supported"); 634 } 635 boolean isPow2 = (height & (height - 1)) == 0; 636 if (!isPow2) { 637 throw new RSIllegalArgumentException("Only power of 2 cube faces supported"); 638 } 639 640 Element e = elementFromBitmap(rs, xpos); 641 Type.Builder tb = new Type.Builder(rs, e); 642 tb.setX(height); 643 tb.setY(height); 644 tb.setFaces(true); 645 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL); 646 Type t = tb.create(); 647 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage); 648 649 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap); 650 adapter.setFace(Type.CubemapFace.POSITVE_X); 651 adapter.copyFrom(xpos); 652 adapter.setFace(Type.CubemapFace.NEGATIVE_X); 653 adapter.copyFrom(xneg); 654 adapter.setFace(Type.CubemapFace.POSITVE_Y); 655 adapter.copyFrom(ypos); 656 adapter.setFace(Type.CubemapFace.NEGATIVE_Y); 657 adapter.copyFrom(yneg); 658 adapter.setFace(Type.CubemapFace.POSITVE_Z); 659 adapter.copyFrom(zpos); 660 adapter.setFace(Type.CubemapFace.NEGATIVE_Z); 661 adapter.copyFrom(zneg); 662 663 return cubemap; 664 } 665 666 static public Allocation createCubemapFromCubeFaces(RenderScript rs, 667 Bitmap xpos, 668 Bitmap xneg, 669 Bitmap ypos, 670 Bitmap yneg, 671 Bitmap zpos, 672 Bitmap zneg) { 673 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg, 674 zpos, zneg, MipmapControl.MIPMAP_NONE, 675 USAGE_GRAPHICS_TEXTURE); 676 } 677 678 static public Allocation createFromBitmapResource(RenderScript rs, 679 Resources res, 680 int id, 681 MipmapControl mips, 682 int usage) { 683 684 rs.validate(); 685 Bitmap b = BitmapFactory.decodeResource(res, id); 686 Allocation alloc = createFromBitmap(rs, b, mips, usage); 687 b.recycle(); 688 return alloc; 689 } 690 691 static public Allocation createFromBitmapResource(RenderScript rs, 692 Resources res, 693 int id) { 694 return createFromBitmapResource(rs, res, id, 695 MipmapControl.MIPMAP_NONE, 696 USAGE_GRAPHICS_TEXTURE); 697 } 698 699 static public Allocation createFromString(RenderScript rs, 700 String str, 701 int usage) { 702 rs.validate(); 703 byte[] allocArray = null; 704 try { 705 allocArray = str.getBytes("UTF-8"); 706 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage); 707 alloc.copyFrom(allocArray); 708 return alloc; 709 } 710 catch (Exception e) { 711 throw new RSRuntimeException("Could not convert string to utf-8."); 712 } 713 } 714} 715 716 717