summaryrefslogtreecommitdiff
path: root/graphics/java/android/renderscript/Allocation.java
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/java/android/renderscript/Allocation.java')
-rw-r--r--graphics/java/android/renderscript/Allocation.java924
1 files changed, 709 insertions, 215 deletions
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index b27c7f502e96..b15121a23c11 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -18,7 +18,6 @@ package android.renderscript;
import java.io.IOException;
import java.io.InputStream;
-
import android.content.res.Resources;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
@@ -27,243 +26,549 @@ import android.util.Log;
import android.util.TypedValue;
/**
- * @hide
+ * Memory allocation class for renderscript. An allocation combines a Type with
+ * memory to provide storage for user data and objects.
+ *
+ * Allocations may exist in one or more memory spaces. Currently those are
+ * Script: accessable by RS scripts.
+ * Graphics Texture: accessable as a graphics texture.
+ * Graphics Vertex: accessable as graphical vertex data.
+ * Graphics Constants: Accessable as constants in user shaders
+ *
+ * By default java side updates are always applied to the script accessable
+ * memory. If this is not present they are then applied to the various HW
+ * memory types. A syncAll call is necessary after the script data is update to
+ * keep the other memory spaces in sync.
*
**/
public class Allocation extends BaseObj {
Type mType;
Bitmap mBitmap;
+ int mUsage;
+
+ /**
+ * The usage of the allocation. These signal to renderscript
+ * where to place the allocation in memory.
+ *
+ * SCRIPT The allocation will be bound to and accessed by
+ * scripts.
+ */
+ public static final int USAGE_SCRIPT = 0x0001;
+
+ /**
+ * GRAPHICS_TEXTURE The allcation will be used as a texture
+ * source by one or more graphcics programs.
+ *
+ */
+ public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
+
+ /**
+ * GRAPHICS_VERTEX The allocation will be used as a graphics
+ * mesh.
+ *
+ */
+ public static final int USAGE_GRAPHICS_VERTEX = 0x0004;
+
+
+ /**
+ * GRAPHICS_CONSTANTS The allocation will be used as the source
+ * of shader constants by one or more programs.
+ *
+ */
+ public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008;
+
+
+ /**
+ * Controls mipmap behavior when using the bitmap creation and
+ * update functions.
+ */
+ public enum MipmapControl {
+ /**
+ * No mipmaps will be generated and the type generated from the
+ * incoming bitmap will not contain additional LODs.
+ */
+ MIPMAP_NONE(0),
+
+ /**
+ * A Full mipmap chain will be created in script memory. The
+ * type of the allocation will contain a full mipmap chain. On
+ * upload to graphics the full chain will be transfered.
+ */
+ MIPMAP_FULL(1),
+
+ /**
+ * The type of the allocation will be the same as MIPMAP_NONE.
+ * It will not contain mipmaps. On upload to graphics the
+ * graphics copy of the allocation data will contain a full
+ * mipmap chain generated from the top level in script memory.
+ */
+ MIPMAP_ON_SYNC_TO_TEXTURE(2);
+
+ int mID;
+ MipmapControl(int id) {
+ mID = id;
+ }
+ }
- Allocation(int id, RenderScript rs, Type t) {
- super(rs);
- mID = id;
+ Allocation(int id, RenderScript rs, Type t, int usage) {
+ super(id, rs);
+ if ((usage & ~(USAGE_SCRIPT |
+ USAGE_GRAPHICS_TEXTURE |
+ USAGE_GRAPHICS_VERTEX |
+ USAGE_GRAPHICS_CONSTANTS)) != 0) {
+ throw new RSIllegalArgumentException("Unknown usage specified.");
+ }
mType = t;
}
+ @Override
+ void updateFromNative() {
+ super.updateFromNative();
+ int typeID = mRS.nAllocationGetType(getID());
+ if(typeID != 0) {
+ mType = new Type(typeID, mRS);
+ mType.updateFromNative();
+ }
+ }
+
public Type getType() {
return mType;
}
- public void uploadToTexture(int baseMipLevel) {
+ public void syncAll(int srcLocation) {
+ switch (srcLocation) {
+ case USAGE_SCRIPT:
+ case USAGE_GRAPHICS_CONSTANTS:
+ case USAGE_GRAPHICS_TEXTURE:
+ case USAGE_GRAPHICS_VERTEX:
+ break;
+ default:
+ throw new RSIllegalArgumentException("Source must be exactly one usage type.");
+ }
mRS.validate();
- mRS.nAllocationUploadToTexture(mID, false, baseMipLevel);
+ mRS.nAllocationSyncAll(getID(), srcLocation);
}
- public void uploadToTexture(boolean genMips, int baseMipLevel) {
+ public void copyFrom(BaseObj[] d) {
mRS.validate();
- mRS.nAllocationUploadToTexture(mID, genMips, baseMipLevel);
+ if (d.length != mType.getCount()) {
+ throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
+ mType.getCount() + ", array length = " + d.length);
+ }
+ int i[] = new int[d.length];
+ for (int ct=0; ct < d.length; ct++) {
+ i[ct] = d[ct].getID();
+ }
+ copy1DRangeFrom(0, mType.getCount(), i);
+ }
+
+ private void validateBitmapFormat(Bitmap b) {
+ Bitmap.Config bc = b.getConfig();
+ switch (bc) {
+ case ALPHA_8:
+ if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
+ throw new RSIllegalArgumentException("Allocation kind is " +
+ mType.getElement().mKind + ", type " +
+ mType.getElement().mType +
+ " of " + mType.getElement().getSizeBytes() +
+ " bytes, passed bitmap was " + bc);
+ }
+ break;
+ case ARGB_8888:
+ if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
+ (mType.getElement().getSizeBytes() != 4)) {
+ throw new RSIllegalArgumentException("Allocation kind is " +
+ mType.getElement().mKind + ", type " +
+ mType.getElement().mType +
+ " of " + mType.getElement().getSizeBytes() +
+ " bytes, passed bitmap was " + bc);
+ }
+ break;
+ case RGB_565:
+ if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
+ (mType.getElement().getSizeBytes() != 2)) {
+ throw new RSIllegalArgumentException("Allocation kind is " +
+ mType.getElement().mKind + ", type " +
+ mType.getElement().mType +
+ " of " + mType.getElement().getSizeBytes() +
+ " bytes, passed bitmap was " + bc);
+ }
+ break;
+ case ARGB_4444:
+ if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
+ (mType.getElement().getSizeBytes() != 2)) {
+ throw new RSIllegalArgumentException("Allocation kind is " +
+ mType.getElement().mKind + ", type " +
+ mType.getElement().mType +
+ " of " + mType.getElement().getSizeBytes() +
+ " bytes, passed bitmap was " + bc);
+ }
+ break;
+
+ }
}
- public void uploadToBufferObject() {
- mRS.validate();
- mRS.nAllocationUploadToBufferObject(mID);
+ private void validateBitmapSize(Bitmap b) {
+ if(mType.getX() != b.getWidth() ||
+ mType.getY() != b.getHeight()) {
+ throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
+ }
}
- public void data(int[] d) {
+ public void copyFrom(int[] d) {
mRS.validate();
- subData1D(0, mType.getElementCount(), d);
+ copy1DRangeFrom(0, mType.getCount(), d);
}
- public void data(short[] d) {
+ public void copyFrom(short[] d) {
mRS.validate();
- subData1D(0, mType.getElementCount(), d);
+ copy1DRangeFrom(0, mType.getCount(), d);
}
- public void data(byte[] d) {
+ public void copyFrom(byte[] d) {
mRS.validate();
- subData1D(0, mType.getElementCount(), d);
+ copy1DRangeFrom(0, mType.getCount(), d);
}
- public void data(float[] d) {
+ public void copyFrom(float[] d) {
mRS.validate();
- subData1D(0, mType.getElementCount(), d);
+ copy1DRangeFrom(0, mType.getCount(), d);
+ }
+ public void copyFrom(Bitmap b) {
+ mRS.validate();
+ validateBitmapSize(b);
+ validateBitmapFormat(b);
+ mRS.nAllocationCopyFromBitmap(getID(), b);
+ }
+
+ /**
+ * @hide
+ *
+ * This is only intended to be used by auto-generate code reflected from the
+ * renderscript script files.
+ *
+ * @param xoff
+ * @param fp
+ */
+ public void setOneElement(int xoff, FieldPacker fp) {
+ int eSize = mType.mElement.getSizeBytes();
+ final byte[] data = fp.getData();
+
+ int count = data.length / eSize;
+ if ((eSize * count) != data.length) {
+ throw new RSIllegalArgumentException("Field packer length " + data.length +
+ " not divisible by element size " + eSize + ".");
+ }
+ data1DChecks(xoff, count, data.length, data.length);
+ mRS.nAllocationData1D(getID(), xoff, 0, count, data, data.length);
+ }
+
+
+ /**
+ * @hide
+ *
+ * This is only intended to be used by auto-generate code reflected from the
+ * renderscript script files.
+ *
+ * @param xoff
+ * @param component_number
+ * @param fp
+ */
+ public void setOneComponent(int xoff, int component_number, FieldPacker fp) {
+ if (component_number >= mType.mElement.mElements.length) {
+ throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
+ }
+ if(xoff < 0) {
+ throw new RSIllegalArgumentException("Offset must be >= 0.");
+ }
+
+ final byte[] data = fp.getData();
+ int eSize = mType.mElement.mElements[component_number].getSizeBytes();
+
+ if (data.length != eSize) {
+ throw new RSIllegalArgumentException("Field packer sizelength " + data.length +
+ " does not match component size " + eSize + ".");
+ }
+
+ mRS.nAllocationElementData1D(getID(), xoff, 0, component_number, data, data.length);
}
private void data1DChecks(int off, int count, int len, int dataSize) {
mRS.validate();
- if((off < 0) || (count < 1) || ((off + count) > mType.getElementCount())) {
- throw new IllegalArgumentException("Offset or Count out of bounds.");
+ if(off < 0) {
+ throw new RSIllegalArgumentException("Offset must be >= 0.");
+ }
+ if(count < 1) {
+ throw new RSIllegalArgumentException("Count must be >= 1.");
+ }
+ if((off + count) > mType.getCount()) {
+ throw new RSIllegalArgumentException("Overflow, Available count " + mType.getCount() +
+ ", got " + count + " at offset " + off + ".");
}
if((len) < dataSize) {
- throw new IllegalArgumentException("Array too small for allocation type.");
+ throw new RSIllegalArgumentException("Array too small for allocation type.");
}
}
- public void subData1D(int off, int count, int[] d) {
+ /**
+ * Generate a mipmap chain. Requires the type of the allocation
+ * include mipmaps.
+ *
+ * This function will generate a complete set of mipmaps from
+ * the top level lod and place them into the script memoryspace.
+ *
+ * If the allocation is also using other memory spaces a
+ * followup sync will be required.
+ */
+ public void generateMipmaps() {
+ mRS.nAllocationGenerateMipmaps(getID());
+ }
+
+ public void copy1DRangeFrom(int off, int count, int[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length * 4, dataSize);
- mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
+ mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
}
- public void subData1D(int off, int count, short[] d) {
+ public void copy1DRangeFrom(int off, int count, short[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length * 2, dataSize);
- mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
+ mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
}
- public void subData1D(int off, int count, byte[] d) {
+ public void copy1DRangeFrom(int off, int count, byte[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length, dataSize);
- mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
+ mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
}
- public void subData1D(int off, int count, float[] d) {
+ public void copy1DRangeFrom(int off, int count, float[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length * 4, dataSize);
- mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
+ mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
}
-
-
- public void subData2D(int xoff, int yoff, int w, int h, int[] d) {
- mRS.validate();
- mRS.nAllocationSubData2D(mID, xoff, yoff, w, h, d, d.length * 4);
+ private void validate2DRange(int xoff, int yoff, int w, int h) {
+ if (xoff < 0 || yoff < 0) {
+ throw new RSIllegalArgumentException("Offset cannot be negative.");
+ }
+ if (h < 0 || w < 0) {
+ throw new RSIllegalArgumentException("Height or width cannot be negative.");
+ }
+ if ((xoff + w) > mType.mDimX ||
+ (yoff + h) > mType.mDimY) {
+ throw new RSIllegalArgumentException("Updated region larger than allocation.");
+ }
}
- public void subData2D(int xoff, int yoff, int w, int h, float[] d) {
+ /**
+ * Copy a rectanglular region from the array into the
+ * allocation. The incoming array is assumed to be tightly
+ * packed.
+ *
+ * @param xoff X offset of the region to update
+ * @param yoff Y offset of the region to update
+ * @param w Width of the incoming region to update
+ * @param h Height of the incoming region to update
+ * @param data to be placed into the allocation
+ */
+ public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
mRS.validate();
- mRS.nAllocationSubData2D(mID, xoff, yoff, w, h, d, d.length * 4);
+ validate2DRange(xoff, yoff, w, h);
+ mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length);
}
- public void readData(int[] d) {
+ public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
mRS.validate();
- mRS.nAllocationRead(mID, d);
+ validate2DRange(xoff, yoff, w, h);
+ mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 2);
}
- public void readData(float[] d) {
+ public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
mRS.validate();
- mRS.nAllocationRead(mID, d);
+ validate2DRange(xoff, yoff, w, h);
+ mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 4);
}
- public void data(Object o) {
+ public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
+ mRS.validate();
+ validate2DRange(xoff, yoff, w, h);
+ mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 4);
+ }
+
+ /**
+ * Copy a bitmap into an allocation. The height and width of
+ * the update will use the height and width of the incoming
+ * bitmap.
+ *
+ * @param xoff X offset of the region to update
+ * @param yoff Y offset of the region to update
+ * @param data the bitmap to be copied
+ */
+ public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
mRS.validate();
- mRS.nAllocationSubDataFromObject(mID, mType, 0, o);
+ validateBitmapFormat(data);
+ validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
+ mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, data);
}
- public void read(Object o) {
+
+ public void copyTo(Bitmap b) {
mRS.validate();
- mRS.nAllocationSubReadFromObject(mID, mType, 0, o);
+ validateBitmapFormat(b);
+ validateBitmapSize(b);
+ mRS.nAllocationCopyToBitmap(getID(), b);
}
- public void subData(int offset, Object o) {
+ public void copyTo(byte[] d) {
mRS.validate();
- mRS.nAllocationSubDataFromObject(mID, mType, offset, o);
+ mRS.nAllocationRead(getID(), d);
}
- public class Adapter1D extends BaseObj {
- Adapter1D(int id, RenderScript rs) {
- super(rs);
- mID = id;
- }
-
- public void setConstraint(Dimension dim, int value) {
- mRS.validate();
- mRS.nAdapter1DSetConstraint(mID, dim.mID, value);
- }
-
- public void data(int[] d) {
- mRS.validate();
- mRS.nAdapter1DData(mID, d);
- }
-
- public void data(float[] d) {
- mRS.validate();
- mRS.nAdapter1DData(mID, d);
- }
-
- public void subData(int off, int count, int[] d) {
- mRS.validate();
- mRS.nAdapter1DSubData(mID, off, count, d);
- }
-
- public void subData(int off, int count, float[] d) {
- mRS.validate();
- mRS.nAdapter1DSubData(mID, off, count, d);
- }
+ public void copyTo(short[] d) {
+ mRS.validate();
+ mRS.nAllocationRead(getID(), d);
}
- public Adapter1D createAdapter1D() {
+ public void copyTo(int[] d) {
mRS.validate();
- int id = mRS.nAdapter1DCreate();
- if(id == 0) {
- throw new IllegalStateException("allocation failed.");
- }
- mRS.nAdapter1DBindAllocation(id, mID);
- return new Adapter1D(id, mRS);
+ mRS.nAllocationRead(getID(), d);
}
-
- public class Adapter2D extends BaseObj {
- Adapter2D(int id, RenderScript rs) {
- super(rs);
- mID = id;
- }
-
- public void setConstraint(Dimension dim, int value) {
- mRS.validate();
- mRS.nAdapter2DSetConstraint(mID, dim.mID, value);
- }
-
- public void data(int[] d) {
- mRS.validate();
- mRS.nAdapter2DData(mID, d);
+ public void copyTo(float[] d) {
+ mRS.validate();
+ mRS.nAllocationRead(getID(), d);
+ }
+
+ /**
+ * Resize a 1D allocation. The contents of the allocation are
+ * preserved. If new elements are allocated objects are created
+ * with null contents and the new region is otherwise undefined.
+ *
+ * If the new region is smaller the references of any objects
+ * outside the new region will be released.
+ *
+ * A new type will be created with the new dimension.
+ *
+ * @param dimX The new size of the allocation.
+ */
+ public synchronized void resize(int dimX) {
+ if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
+ throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
}
+ mRS.nAllocationResize1D(getID(), dimX);
+ mRS.finish(); // Necessary because resize is fifoed and update is async.
- public void data(float[] d) {
- mRS.validate();
- mRS.nAdapter2DData(mID, d);
- }
+ int typeID = mRS.nAllocationGetType(getID());
+ mType = new Type(typeID, mRS);
+ mType.updateFromNative();
+ }
- public void subData(int xoff, int yoff, int w, int h, int[] d) {
- mRS.validate();
- mRS.nAdapter2DSubData(mID, xoff, yoff, w, h, d);
+ /*
+ public void resize(int dimX, int dimY) {
+ if ((mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) {
+ throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
}
-
- public void subData(int xoff, int yoff, int w, int h, float[] d) {
- mRS.validate();
- mRS.nAdapter2DSubData(mID, xoff, yoff, w, h, d);
+ if (mType.getY() == 0) {
+ throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
}
+ mRS.nAllocationResize2D(getID(), dimX, dimY);
}
+ */
- public Adapter2D createAdapter2D() {
- mRS.validate();
- int id = mRS.nAdapter2DCreate();
- if(id == 0) {
- throw new IllegalStateException("allocation failed.");
- }
- mRS.nAdapter2DBindAllocation(id, mID);
- return new Adapter2D(id, mRS);
- }
// creation
- private static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
+ static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
static {
mBitmapOptions.inScaled = false;
}
- static public Allocation createTyped(RenderScript rs, Type type)
- throws IllegalArgumentException {
-
+ /**
+ *
+ * @param type renderscript type describing data layout
+ * @param mips specifies desired mipmap behaviour for the
+ * allocation
+ * @param usage bit field specifying how the allocation is
+ * utilized
+ */
+ static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
rs.validate();
- if(type.mID == 0) {
- throw new IllegalStateException("Bad Type");
+ if (type.getID() == 0) {
+ throw new RSInvalidStateException("Bad Type");
}
- int id = rs.nAllocationCreateTyped(type.mID);
- return new Allocation(id, rs, type);
- }
-
- static public Allocation createSized(RenderScript rs, Element e, int count)
- throws IllegalArgumentException {
-
+ int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage);
+ if (id == 0) {
+ throw new RSRuntimeException("Allocation creation failed.");
+ }
+ return new Allocation(id, rs, type, usage);
+ }
+
+ /**
+ * Creates a renderscript allocation with the size specified by
+ * the type and no mipmaps generated by default
+ *
+ * @param rs
+ * @param type renderscript type describing data layout
+ * @param usage bit field specifying how the allocation is
+ * utilized
+ *
+ * @return allocation
+ */
+ static public Allocation createTyped(RenderScript rs, Type type, int usage) {
+ return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
+ }
+
+ /**
+ * Creates a renderscript allocation for use by the script with
+ * the size specified by the type and no mipmaps generated by
+ * default
+ *
+ * @param rs
+ * @param type renderscript type describing data layout
+ *
+ * @return allocation
+ */
+ static public Allocation createTyped(RenderScript rs, Type type) {
+ return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
+ }
+
+ /**
+ * Creates a renderscript allocation with a specified number of
+ * given elements
+ *
+ * @param rs
+ * @param e describes what each element of an allocation is
+ * @param count specifies the number of element in the allocation
+ * @param usage bit field specifying how the allocation is
+ * utilized
+ *
+ * @return allocation
+ */
+ static public Allocation createSized(RenderScript rs, Element e,
+ int count, int usage) {
rs.validate();
Type.Builder b = new Type.Builder(rs, e);
- b.add(Dimension.X, count);
+ b.setX(count);
Type t = b.create();
- int id = rs.nAllocationCreateTyped(t.mID);
- if(id == 0) {
- throw new IllegalStateException("Bad element.");
+ int id = rs.nAllocationCreateTyped(t.getID(), MipmapControl.MIPMAP_NONE.mID, usage);
+ if (id == 0) {
+ throw new RSRuntimeException("Allocation creation failed.");
}
- return new Allocation(id, rs, t);
+ return new Allocation(id, rs, t, usage);
+ }
+
+ /**
+ * Creates a renderscript allocation with a specified number of
+ * given elements
+ *
+ * @param rs
+ * @param e describes what each element of an allocation is
+ * @param count specifies the number of element in the allocation
+ *
+ * @return allocation
+ */
+ static public Allocation createSized(RenderScript rs, Element e, int count) {
+ return createSized(rs, e, count, USAGE_SCRIPT);
}
- static private Element elementFromBitmap(RenderScript rs, Bitmap b) {
+ static Element elementFromBitmap(RenderScript rs, Bitmap b) {
final Bitmap.Config bc = b.getConfig();
if (bc == Bitmap.Config.ALPHA_8) {
return Element.A_8(rs);
@@ -277,105 +582,294 @@ public class Allocation extends BaseObj {
if (bc == Bitmap.Config.RGB_565) {
return Element.RGB_565(rs);
}
- throw new IllegalStateException("Bad bitmap type.");
+ throw new RSInvalidStateException("Bad bitmap type: " + bc);
}
- static private Type typeFromBitmap(RenderScript rs, Bitmap b) {
+ static Type typeFromBitmap(RenderScript rs, Bitmap b,
+ MipmapControl mip) {
Element e = elementFromBitmap(rs, b);
Type.Builder tb = new Type.Builder(rs, e);
- tb.add(Dimension.X, b.getWidth());
- tb.add(Dimension.Y, b.getHeight());
+ tb.setX(b.getWidth());
+ tb.setY(b.getHeight());
+ tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
return tb.create();
}
- static public Allocation createFromBitmap(RenderScript rs, Bitmap b, Element dstFmt, boolean genMips)
- throws IllegalArgumentException {
-
+ /**
+ * Creates a renderscript allocation from a bitmap
+ *
+ * @param rs
+ * @param b bitmap source for the allocation data
+ * @param mips specifies desired mipmap behaviour for the
+ * allocation
+ * @param usage bit field specifying how the allocation is
+ * utilized
+ *
+ * @return renderscript allocation containing bitmap data
+ *
+ */
+ static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
+ MipmapControl mips,
+ int usage) {
rs.validate();
- Type t = typeFromBitmap(rs, b);
+ Type t = typeFromBitmap(rs, b, mips);
- int id = rs.nAllocationCreateFromBitmap(dstFmt.mID, genMips, b);
- if(id == 0) {
- throw new IllegalStateException("Load failed.");
+ int id = rs.nAllocationCreateFromBitmap(t.getID(), mips.mID, b, usage);
+ if (id == 0) {
+ throw new RSRuntimeException("Load failed.");
}
- return new Allocation(id, rs, t);
- }
-
- static public Allocation createBitmapRef(RenderScript rs, Bitmap b)
- throws IllegalArgumentException {
-
+ return new Allocation(id, rs, t, usage);
+ }
+
+ /**
+ * Creates a non-mipmapped renderscript allocation to use as a
+ * graphics texture
+ *
+ * @param rs
+ * @param b bitmap source for the allocation data
+ *
+ * @return renderscript allocation containing bitmap data
+ *
+ */
+ static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
+ return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
+ USAGE_GRAPHICS_TEXTURE);
+ }
+
+ /**
+ * Creates a cubemap allocation from a bitmap containing the
+ * horizontal list of cube faces. Each individual face must be
+ * the same size and power of 2
+ *
+ * @param rs
+ * @param b bitmap with cubemap faces layed out in the following
+ * format: right, left, top, bottom, front, back
+ * @param mips specifies desired mipmap behaviour for the cubemap
+ * @param usage bit field specifying how the cubemap is utilized
+ *
+ * @return allocation containing cubemap data
+ *
+ */
+ static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
+ MipmapControl mips,
+ int usage) {
rs.validate();
- Type t = typeFromBitmap(rs, b);
- int id = rs.nAllocationCreateBitmapRef(t.getID(), b);
- if(id == 0) {
- throw new IllegalStateException("Load failed.");
- }
+ int height = b.getHeight();
+ int width = b.getWidth();
- Allocation a = new Allocation(id, rs, t);
- a.mBitmap = b;
- return a;
- }
+ if (width % 6 != 0) {
+ throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
+ }
+ if (width / 6 != height) {
+ throw new RSIllegalArgumentException("Only square cube map faces supported");
+ }
+ boolean isPow2 = (height & (height - 1)) == 0;
+ if (!isPow2) {
+ throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
+ }
- static Allocation createFromBitmapBoxed(RenderScript rs, Bitmap b, Element dstFmt, boolean genMips)
- throws IllegalArgumentException {
+ Element e = elementFromBitmap(rs, b);
+ Type.Builder tb = new Type.Builder(rs, e);
+ tb.setX(height);
+ tb.setY(height);
+ tb.setFaces(true);
+ tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
+ Type t = tb.create();
- rs.validate();
- int id = rs.nAllocationCreateFromBitmapBoxed(dstFmt.mID, genMips, b);
+ int id = rs.nAllocationCubeCreateFromBitmap(t.getID(), mips.mID, b, usage);
if(id == 0) {
- throw new IllegalStateException("Load failed.");
+ throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
+ }
+ return new Allocation(id, rs, t, usage);
+ }
+
+ /**
+ * Creates a non-mipmapped cubemap allocation for use as a
+ * graphics texture from a bitmap containing the horizontal list
+ * of cube faces. Each individual face must be the same size and
+ * power of 2
+ *
+ * @param rs
+ * @param b bitmap with cubemap faces layed out in the following
+ * format: right, left, top, bottom, front, back
+ *
+ * @return allocation containing cubemap data
+ *
+ */
+ static public Allocation createCubemapFromBitmap(RenderScript rs,
+ Bitmap b) {
+ return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
+ USAGE_GRAPHICS_TEXTURE);
+ }
+
+ /**
+ * Creates a cubemap allocation from 6 bitmaps containing
+ * the cube faces. All the faces must be the same size and
+ * power of 2
+ *
+ * @param rs
+ * @param xpos cubemap face in the positive x direction
+ * @param xneg cubemap face in the negative x direction
+ * @param ypos cubemap face in the positive y direction
+ * @param yneg cubemap face in the negative y direction
+ * @param zpos cubemap face in the positive z direction
+ * @param zneg cubemap face in the negative z direction
+ * @param mips specifies desired mipmap behaviour for the cubemap
+ * @param usage bit field specifying how the cubemap is utilized
+ *
+ * @return allocation containing cubemap data
+ *
+ */
+ static public Allocation createCubemapFromCubeFaces(RenderScript rs,
+ Bitmap xpos,
+ Bitmap xneg,
+ Bitmap ypos,
+ Bitmap yneg,
+ Bitmap zpos,
+ Bitmap zneg,
+ MipmapControl mips,
+ int usage) {
+ int height = xpos.getHeight();
+ if (xpos.getWidth() != height ||
+ xneg.getWidth() != height || xneg.getHeight() != height ||
+ ypos.getWidth() != height || ypos.getHeight() != height ||
+ yneg.getWidth() != height || yneg.getHeight() != height ||
+ zpos.getWidth() != height || zpos.getHeight() != height ||
+ zneg.getWidth() != height || zneg.getHeight() != height) {
+ throw new RSIllegalArgumentException("Only square cube map faces supported");
+ }
+ boolean isPow2 = (height & (height - 1)) == 0;
+ if (!isPow2) {
+ throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
}
- return new Allocation(id, rs, null);
- }
- static public Allocation createFromBitmapResource(RenderScript rs, Resources res, int id, Element dstFmt, boolean genMips)
- throws IllegalArgumentException {
+ Element e = elementFromBitmap(rs, xpos);
+ Type.Builder tb = new Type.Builder(rs, e);
+ tb.setX(height);
+ tb.setY(height);
+ tb.setFaces(true);
+ tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
+ Type t = tb.create();
+ Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
+
+ AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
+ adapter.setFace(Type.CubemapFace.POSITVE_X);
+ adapter.copyFrom(xpos);
+ adapter.setFace(Type.CubemapFace.NEGATIVE_X);
+ adapter.copyFrom(xneg);
+ adapter.setFace(Type.CubemapFace.POSITVE_Y);
+ adapter.copyFrom(ypos);
+ adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
+ adapter.copyFrom(yneg);
+ adapter.setFace(Type.CubemapFace.POSITVE_Z);
+ adapter.copyFrom(zpos);
+ adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
+ adapter.copyFrom(zneg);
+
+ return cubemap;
+ }
+
+ /**
+ * Creates a non-mipmapped cubemap allocation for use as a
+ * graphics texture from 6 bitmaps containing
+ * the cube faces. All the faces must be the same size and
+ * power of 2
+ *
+ * @param rs
+ * @param xpos cubemap face in the positive x direction
+ * @param xneg cubemap face in the negative x direction
+ * @param ypos cubemap face in the positive y direction
+ * @param yneg cubemap face in the negative y direction
+ * @param zpos cubemap face in the positive z direction
+ * @param zneg cubemap face in the negative z direction
+ *
+ * @return allocation containing cubemap data
+ *
+ */
+ static public Allocation createCubemapFromCubeFaces(RenderScript rs,
+ Bitmap xpos,
+ Bitmap xneg,
+ Bitmap ypos,
+ Bitmap yneg,
+ Bitmap zpos,
+ Bitmap zneg) {
+ return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
+ zpos, zneg, MipmapControl.MIPMAP_NONE,
+ USAGE_GRAPHICS_TEXTURE);
+ }
+
+ /**
+ * Creates a renderscript allocation from the bitmap referenced
+ * by resource id
+ *
+ * @param rs
+ * @param res application resources
+ * @param id resource id to load the data from
+ * @param mips specifies desired mipmap behaviour for the
+ * allocation
+ * @param usage bit field specifying how the allocation is
+ * utilized
+ *
+ * @return renderscript allocation containing resource data
+ *
+ */
+ static public Allocation createFromBitmapResource(RenderScript rs,
+ Resources res,
+ int id,
+ MipmapControl mips,
+ int usage) {
rs.validate();
- InputStream is = null;
+ Bitmap b = BitmapFactory.decodeResource(res, id);
+ Allocation alloc = createFromBitmap(rs, b, mips, usage);
+ b.recycle();
+ return alloc;
+ }
+
+ /**
+ * Creates a non-mipmapped renderscript allocation to use as a
+ * graphics texture from the bitmap referenced by resource id
+ *
+ * @param rs
+ * @param res application resources
+ * @param id resource id to load the data from
+ *
+ * @return renderscript allocation containing resource data
+ *
+ */
+ static public Allocation createFromBitmapResource(RenderScript rs,
+ Resources res,
+ int id) {
+ return createFromBitmapResource(rs, res, id,
+ MipmapControl.MIPMAP_NONE,
+ USAGE_GRAPHICS_TEXTURE);
+ }
+
+ /**
+ * Creates a renderscript allocation containing string data
+ * encoded in UTF-8 format
+ *
+ * @param rs
+ * @param str string to create the allocation from
+ * @param usage bit field specifying how the allocaiton is
+ * utilized
+ *
+ */
+ static public Allocation createFromString(RenderScript rs,
+ String str,
+ int usage) {
+ rs.validate();
+ byte[] allocArray = null;
try {
- final TypedValue value = new TypedValue();
- is = res.openRawResource(id, value);
-
- int asset = ((AssetManager.AssetInputStream) is).getAssetInt();
- int allocationId = rs.nAllocationCreateFromAssetStream(dstFmt.mID, genMips,
- asset);
-
- if(allocationId == 0) {
- throw new IllegalStateException("Load failed.");
- }
- return new Allocation(allocationId, rs, null);
- } catch (Exception e) {
- // Ignore
- } finally {
- if (is != null) {
- try {
- is.close();
- } catch (IOException e) {
- // Ignore
- }
- }
+ allocArray = str.getBytes("UTF-8");
+ Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
+ alloc.copyFrom(allocArray);
+ return alloc;
}
-
- return null;
- }
-
- static public Allocation createFromBitmapResourceBoxed(RenderScript rs, Resources res, int id, Element dstFmt, boolean genMips)
- throws IllegalArgumentException {
-
- mBitmapOptions.inPreferredConfig = null;
- if (dstFmt == rs.mElement_RGBA_8888) {
- mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
- } else if (dstFmt == rs.mElement_RGB_888) {
- mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
- } else if (dstFmt == rs.mElement_RGBA_4444) {
- mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_4444;
- } else if (dstFmt == rs.mElement_RGB_565) {
- mBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
+ catch (Exception e) {
+ throw new RSRuntimeException("Could not convert string to utf-8.");
}
-
- Bitmap b = BitmapFactory.decodeResource(res, id, mBitmapOptions);
- return createFromBitmapBoxed(rs, b, dstFmt, genMips);
}
}