/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.util.TypedValue;

/**
 * <p>
 * Memory allocation class for renderscript.  An allocation combines a
 * {@link android.renderscript.Type} with the memory to provide storage for user data and objects.
 * This implies that all memory in Renderscript is typed.
 * </p>
 *
 * <p>Allocations are the primary way data moves into and out of scripts. Memory is user
 * synchronized and it's possible for allocations to exist in multiple memory spaces
 * concurrently. Currently those spaces are:</p>
 * <ul>
 * <li>Script: accessable by RS scripts.</li>
 * <li>Graphics Texture: accessable as a graphics texture.</li>
 * <li>Graphics Vertex: accessable as graphical vertex data.</li>
 * <li>Graphics Constants: Accessable as constants in user shaders</li>
 * </ul>
 * </p>
 * <p>
 * For example, when creating a allocation for a texture, the user can
 * specify its memory spaces as both script and textures. This means that it can both
 * be used as script binding and as a GPU texture for rendering. To maintain
 * synchronization if a script modifies an allocation used by other targets it must
 * call a synchronizing function to push the updates to the memory, otherwise the results
 * are undefined.
 * </p>
 * <p>By default, Android system 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 {@link android.renderscript.Allocation#syncAll syncAll()}
 * call is necessary after the script data is updated to
 * keep the other memory spaces in sync.</p>
 *
 * <p>Allocation data is uploaded in one of two primary ways. For simple
 * arrays there are copyFrom() functions that take an array from the control code and
 * copy it to the slave memory store. Both type checked and unchecked copies are provided.
 * The unchecked variants exist to allow apps to copy over arrays of structures from a
 * control language that does not support structures.</p>
 *
 **/
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;

    /**
     * @hide
     * USAGE_GRAPHICS_RENDER_TARGET The allcation will be used as a
     * target for offscreen rendering
     *
     */
    public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;


    /**
     * 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, int usage) {
        super(id, rs);
        if ((usage & ~(USAGE_SCRIPT |
                       USAGE_GRAPHICS_TEXTURE |
                       USAGE_GRAPHICS_VERTEX |
                       USAGE_GRAPHICS_CONSTANTS |
                       USAGE_GRAPHICS_RENDER_TARGET)) != 0) {
            throw new RSIllegalArgumentException("Unknown usage specified.");
        }
        mType = t;
    }

    private void validateIsInt32() {
        if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
            (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
            return;
        }
        throw new RSIllegalArgumentException(
            "32 bit integer source does not match allocation type " + mType.mElement.mType);
    }

    private void validateIsInt16() {
        if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
            (mType.mElement.mType == Element.DataType.UNSIGNED_16)) {
            return;
        }
        throw new RSIllegalArgumentException(
            "16 bit integer source does not match allocation type " + mType.mElement.mType);
    }

    private void validateIsInt8() {
        if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
            (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
            return;
        }
        throw new RSIllegalArgumentException(
            "8 bit integer source does not match allocation type " + mType.mElement.mType);
    }

    private void validateIsFloat32() {
        if (mType.mElement.mType == Element.DataType.FLOAT_32) {
            return;
        }
        throw new RSIllegalArgumentException(
            "32 bit float source does not match allocation type " + mType.mElement.mType);
    }

    private void validateIsObject() {
        if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
            (mType.mElement.mType == Element.DataType.RS_TYPE) ||
            (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
            (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
            (mType.mElement.mType == Element.DataType.RS_SCRIPT) ||
            (mType.mElement.mType == Element.DataType.RS_MESH) ||
            (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) ||
            (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) ||
            (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) ||
            (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) {
            return;
        }
        throw new RSIllegalArgumentException(
            "Object source does not match allocation type " + mType.mElement.mType);
    }

    @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 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.nAllocationSyncAll(getID(), srcLocation);
    }

    public void copyFrom(BaseObj[] d) {
        mRS.validate();
        validateIsObject();
        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();
        }
        copy1DRangeFromUnchecked(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;

        }
    }

    private void validateBitmapSize(Bitmap b) {
        if(mType.getX() != b.getWidth() ||
           mType.getY() != b.getHeight()) {
            throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
        }
    }

    /**
     * Copy an allocation from an array.  This variant is not type
     * checked which allows an application to fill in structured
     * data from an array.
     *
     * @param d the source data array
     */
    public void copyFromUnchecked(int[] d) {
        mRS.validate();
        copy1DRangeFromUnchecked(0, mType.getCount(), d);
    }
    /**
     * Copy an allocation from an array.  This variant is not type
     * checked which allows an application to fill in structured
     * data from an array.
     *
     * @param d the source data array
     */
    public void copyFromUnchecked(short[] d) {
        mRS.validate();
        copy1DRangeFromUnchecked(0, mType.getCount(), d);
    }
    /**
     * Copy an allocation from an array.  This variant is not type
     * checked which allows an application to fill in structured
     * data from an array.
     *
     * @param d the source data array
     */
    public void copyFromUnchecked(byte[] d) {
        mRS.validate();
        copy1DRangeFromUnchecked(0, mType.getCount(), d);
    }
    /**
     * Copy an allocation from an array.  This variant is not type
     * checked which allows an application to fill in structured
     * data from an array.
     *
     * @param d the source data array
     */
    public void copyFromUnchecked(float[] d) {
        mRS.validate();
        copy1DRangeFromUnchecked(0, mType.getCount(), d);
    }

    /**
     * Copy an allocation from an array.  This variant is type
     * checked and will generate exceptions if the Allocation type
     * is not a 32 bit integer type.
     *
     * @param d the source data array
     */
    public void copyFrom(int[] d) {
        mRS.validate();
        copy1DRangeFrom(0, mType.getCount(), d);
    }

    /**
     * Copy an allocation from an array.  This variant is type
     * checked and will generate exceptions if the Allocation type
     * is not a 16 bit integer type.
     *
     * @param d the source data array
     */
    public void copyFrom(short[] d) {
        mRS.validate();
        copy1DRangeFrom(0, mType.getCount(), d);
    }

    /**
     * Copy an allocation from an array.  This variant is type
     * checked and will generate exceptions if the Allocation type
     * is not a 8 bit integer type.
     *
     * @param d the source data array
     */
    public void copyFrom(byte[] d) {
        mRS.validate();
        copy1DRangeFrom(0, mType.getCount(), d);
    }

    /**
     * Copy an allocation from an array.  This variant is type
     * checked and will generate exceptions if the Allocation type
     * is not a 32 bit float type.
     *
     * @param d the source data array
     */
    public void copyFrom(float[] d) {
        mRS.validate();
        copy1DRangeFrom(0, mType.getCount(), d);
    }

    /**
     * Copy an allocation from a bitmap.  The height, width, and
     * format of the bitmap must match the existing allocation.
     *
     * @param b the source bitmap
     */
    public void copyFrom(Bitmap b) {
        mRS.validate();
        validateBitmapSize(b);
        validateBitmapFormat(b);
        mRS.nAllocationCopyFromBitmap(getID(), b);
    }

    /**
     * This is only intended to be used by auto-generate code reflected from the
     * renderscript script files.
     *
     * @param xoff
     * @param fp
     */
    public void setFromFieldPacker(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);
    }

    /**
     * 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 setFromFieldPacker(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) {
            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 RSIllegalArgumentException("Array too small for allocation type.");
        }
    }

    /**
     * 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());
    }

    /**
     * Copy part of an allocation from an array.  This variant is
     * not type checked which allows an application to fill in
     * structured data from an array.
     *
     * @param off The offset of the first element to be copied.
     * @param count The number of elements to be copied.
     * @param d the source data array
     */
    public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
        int dataSize = mType.mElement.getSizeBytes() * count;
        data1DChecks(off, count, d.length * 4, dataSize);
        mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
    }
    /**
     * Copy part of an allocation from an array.  This variant is
     * not type checked which allows an application to fill in
     * structured data from an array.
     *
     * @param off The offset of the first element to be copied.
     * @param count The number of elements to be copied.
     * @param d the source data array
     */
    public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
        int dataSize = mType.mElement.getSizeBytes() * count;
        data1DChecks(off, count, d.length * 2, dataSize);
        mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
    }
    /**
     * Copy part of an allocation from an array.  This variant is
     * not type checked which allows an application to fill in
     * structured data from an array.
     *
     * @param off The offset of the first element to be copied.
     * @param count The number of elements to be copied.
     * @param d the source data array
     */
    public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
        int dataSize = mType.mElement.getSizeBytes() * count;
        data1DChecks(off, count, d.length, dataSize);
        mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
    }
    /**
     * Copy part of an allocation from an array.  This variant is
     * not type checked which allows an application to fill in
     * structured data from an array.
     *
     * @param off The offset of the first element to be copied.
     * @param count The number of elements to be copied.
     * @param d the source data array
     */
    public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
        int dataSize = mType.mElement.getSizeBytes() * count;
        data1DChecks(off, count, d.length * 4, dataSize);
        mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
    }

    /**
     * Copy part of an allocation from an array.  This variant is
     * type checked and will generate exceptions if the Allocation
     * type is not a 32 bit integer type.
     *
     * @param off The offset of the first element to be copied.
     * @param count The number of elements to be copied.
     * @param d the source data array
     */
    public void copy1DRangeFrom(int off, int count, int[] d) {
        validateIsInt32();
        copy1DRangeFromUnchecked(off, count, d);
    }

    /**
     * Copy part of an allocation from an array.  This variant is
     * type checked and will generate exceptions if the Allocation
     * type is not a 16 bit integer type.
     *
     * @param off The offset of the first element to be copied.
     * @param count The number of elements to be copied.
     * @param d the source data array
     */
    public void copy1DRangeFrom(int off, int count, short[] d) {
        validateIsInt16();
        copy1DRangeFromUnchecked(off, count, d);
    }

    /**
     * Copy part of an allocation from an array.  This variant is
     * type checked and will generate exceptions if the Allocation
     * type is not a 8 bit integer type.
     *
     * @param off The offset of the first element to be copied.
     * @param count The number of elements to be copied.
     * @param d the source data array
     */
    public void copy1DRangeFrom(int off, int count, byte[] d) {
        validateIsInt8();
        copy1DRangeFromUnchecked(off, count, d);
    }

    /**
     * Copy part of an allocation from an array.  This variant is
     * type checked and will generate exceptions if the Allocation
     * type is not a 32 bit float type.
     *
     * @param off The offset of the first element to be copied.
     * @param count The number of elements to be copied.
     * @param d the source data array
     */
    public void copy1DRangeFrom(int off, int count, float[] d) {
        validateIsFloat32();
        copy1DRangeFromUnchecked(off, count, d);
    }

    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.");
        }
    }

    /**
     * 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();
        validate2DRange(xoff, yoff, w, h);
        mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length);
    }

    public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
        mRS.validate();
        validate2DRange(xoff, yoff, w, h);
        mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 2);
    }

    public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
        mRS.validate();
        validate2DRange(xoff, yoff, w, h);
        mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 4);
    }

    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();
        validateBitmapFormat(data);
        validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
        mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, data);
    }


    public void copyTo(Bitmap b) {
        mRS.validate();
        validateBitmapFormat(b);
        validateBitmapSize(b);
        mRS.nAllocationCopyToBitmap(getID(), b);
    }

    public void copyTo(byte[] d) {
        validateIsInt8();
        mRS.validate();
        mRS.nAllocationRead(getID(), d);
    }

    public void copyTo(short[] d) {
        validateIsInt16();
        mRS.validate();
        mRS.nAllocationRead(getID(), d);
    }

    public void copyTo(int[] d) {
        validateIsInt32();
        mRS.validate();
        mRS.nAllocationRead(getID(), d);
    }

    public void copyTo(float[] d) {
        validateIsFloat32();
        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.

        int typeID = mRS.nAllocationGetType(getID());
        mType = new Type(typeID, mRS);
        mType.updateFromNative();
    }

    /*
    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.");
        }
        if (mType.getY() == 0) {
            throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
        }
        mRS.nAllocationResize2D(getID(), dimX, dimY);
    }
    */



    // creation

    static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
    static {
        mBitmapOptions.inScaled = false;
    }

    /**
     *
     * @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.getID() == 0) {
            throw new RSInvalidStateException("Bad Type");
        }
        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 Context to which the allocation will belong.
     * @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 Context to which the allocation will belong.
     * @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 Context to which the allocation will belong.
     * @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.setX(count);
        Type t = b.create();

        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, usage);
    }

    /**
     * Creates a renderscript allocation with a specified number of
     * given elements
     *
     * @param rs Context to which the allocation will belong.
     * @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 Element elementFromBitmap(RenderScript rs, Bitmap b) {
        final Bitmap.Config bc = b.getConfig();
        if (bc == Bitmap.Config.ALPHA_8) {
            return Element.A_8(rs);
        }
        if (bc == Bitmap.Config.ARGB_4444) {
            return Element.RGBA_4444(rs);
        }
        if (bc == Bitmap.Config.ARGB_8888) {
            return Element.RGBA_8888(rs);
        }
        if (bc == Bitmap.Config.RGB_565) {
            return Element.RGB_565(rs);
        }
        throw new RSInvalidStateException("Bad bitmap type: " + bc);
    }

    static Type typeFromBitmap(RenderScript rs, Bitmap b,
                                       MipmapControl mip) {
        Element e = elementFromBitmap(rs, b);
        Type.Builder tb = new Type.Builder(rs, e);
        tb.setX(b.getWidth());
        tb.setY(b.getHeight());
        tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
        return tb.create();
    }

    /**
     * Creates a renderscript allocation from a bitmap
     *
     * @param rs Context to which the allocation will belong.
     * @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, mips);

        int id = rs.nAllocationCreateFromBitmap(t.getID(), mips.mID, b, usage);
        if (id == 0) {
            throw new RSRuntimeException("Load failed.");
        }
        return new Allocation(id, rs, t, usage);
    }

    /**
     * Creates a non-mipmapped renderscript allocation to use as a
     * graphics texture
     *
     * @param rs Context to which the allocation will belong.
     * @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 Context to which the allocation will belong.
     * @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();

        int height = b.getHeight();
        int width = b.getWidth();

        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");
        }

        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();

        int id = rs.nAllocationCubeCreateFromBitmap(t.getID(), mips.mID, b, usage);
        if(id == 0) {
            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 Context to which the allocation will belong.
     * @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 Context to which the allocation will belong.
     * @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");
        }

        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 Context to which the allocation will belong.
     * @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 Context to which the allocation will belong.
     * @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();
        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 Context to which the allocation will belong.
     * @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 Context to which the allocation will belong.
     * @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 {
            allocArray = str.getBytes("UTF-8");
            Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
            alloc.copyFrom(allocArray);
            return alloc;
        }
        catch (Exception e) {
            throw new RSRuntimeException("Could not convert string to utf-8.");
        }
    }
}


