/*
 * Copyright (C) 2013 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.
 */

#ifndef ANDROID_RSCPPSTRUCTS_H
#define ANDROID_RSCPPSTRUCTS_H

#include "rsDefines.h"
#include "util/RefBase.h"
#include "rsDispatch.h"

#include <vector>
#include <string>

/**
 * Every row in an RS allocation is guaranteed to be aligned by this amount, and
 * every row in a user-backed allocation must be aligned by this amount.
 */
#define RS_CPU_ALLOCATION_ALIGNMENT 16

namespace android {
namespace RSC {

typedef void (*ErrorHandlerFunc_t)(uint32_t errorNum, const char *errorText);
typedef void (*MessageHandlerFunc_t)(uint32_t msgNum, const void *msgData, size_t msgLen);

class RS;
class BaseObj;
class Element;
class Type;
class Allocation;
class Script;
class ScriptC;
class Sampler;

/**
 * Possible error codes used by RenderScript. Once a status other than RS_SUCCESS
 * is returned, the RenderScript context is considered dead and cannot perform any
 * additional work.
 */
 enum RSError {
     RS_SUCCESS = 0,                 ///< No error
     RS_ERROR_INVALID_PARAMETER = 1, ///< An invalid parameter was passed to a function
     RS_ERROR_RUNTIME_ERROR = 2,     ///< The RenderScript driver returned an error; this is
                                     ///< often indicative of a kernel that crashed
     RS_ERROR_INVALID_ELEMENT = 3,   ///< An invalid Element was passed to a function
     RS_ERROR_MAX = 9999

 };

 /**
  * YUV formats supported by the RenderScript API.
  */
 enum RSYuvFormat {
     RS_YUV_NONE = 0, ///< No YUV data
     RS_YUV_YV12 = 1, ///< YUV data in YV12 format
     RS_YUV_NV21 = 2, ///< YUV data in NV21 format
     RS_YUV_MAX = 3
 };

 /**
  * Flags that can control RenderScript behavior on a per-context level.
  */
 enum RSInitFlags {
     RS_INIT_SYNCHRONOUS = 1, ///< All RenderScript calls will be synchronous. May reduce latency.
     RS_INIT_LOW_LATENCY = 2, ///< Prefer low latency devices over potentially higher throughput devices.
     RS_INIT_MAX = 4
 };

 /**
  * The RenderScript context. This class controls initialization, resource management, and teardown.
  */
 class RS : public android::RSC::LightRefBase<RS> {

 public:
    RS();
    virtual ~RS();

    /**
     * Initializes a RenderScript context. A context must be initialized before it can be used.
     * @param[in] flags Optional flags for this context.
     * @return true on success
     */
    bool init(uint32_t flags = 0);

    /**
     * Sets the error handler function for this context. This error handler is
     * called whenever an error is set.
     *
     * @param[in] func Error handler function
     */
    void setErrorHandler(ErrorHandlerFunc_t func);

    /**
     * Returns the current error handler function for this context.
     *
     * @return pointer to current error handler function or NULL if not set
     */
    ErrorHandlerFunc_t getErrorHandler() { return mErrorFunc; }

    /**
     * Sets the message handler function for this context. This message handler
     * is called whenever a message is sent from a RenderScript kernel.
     *
     *  @param[in] func Message handler function
     */
    void setMessageHandler(MessageHandlerFunc_t func);

    /**
     * Returns the current message handler function for this context.
     *
     * @return pointer to current message handler function or NULL if not set
     */
    MessageHandlerFunc_t getMessageHandler() { return mMessageFunc; }

    /**
     * Returns current status for the context.
     *
     * @return current error
     */
    RSError getError();

    /**
     * Waits for any currently running asynchronous operations to finish. This
     * should only be used for performance testing and timing.
     */
    void finish();

    RsContext getContext() { return mContext; }
    void throwError(RSError error, const char *errMsg);

    static dispatchTable* dispatch;

 private:
    static bool usingNative;
    static bool initDispatch(int targetApi);

    bool init(int targetApi, uint32_t flags);
    static void * threadProc(void *);

    static bool gInitialized;
    static pthread_mutex_t gInitMutex;

    pthread_t mMessageThreadId;
    pid_t mNativeMessageThreadId;
    bool mMessageRun;

    RsDevice mDev;
    RsContext mContext;
    RSError mCurrentError;

    ErrorHandlerFunc_t mErrorFunc;
    MessageHandlerFunc_t mMessageFunc;
    bool mInit;

    struct {
        sp<const Element> U8;
        sp<const Element> U8_2;
        sp<const Element> U8_3;
        sp<const Element> U8_4;
        sp<const Element> I8;
        sp<const Element> I8_2;
        sp<const Element> I8_3;
        sp<const Element> I8_4;
        sp<const Element> U16;
        sp<const Element> U16_2;
        sp<const Element> U16_3;
        sp<const Element> U16_4;
        sp<const Element> I16;
        sp<const Element> I16_2;
        sp<const Element> I16_3;
        sp<const Element> I16_4;
        sp<const Element> U32;
        sp<const Element> U32_2;
        sp<const Element> U32_3;
        sp<const Element> U32_4;
        sp<const Element> I32;
        sp<const Element> I32_2;
        sp<const Element> I32_3;
        sp<const Element> I32_4;
        sp<const Element> U64;
        sp<const Element> U64_2;
        sp<const Element> U64_3;
        sp<const Element> U64_4;
        sp<const Element> I64;
        sp<const Element> I64_2;
        sp<const Element> I64_3;
        sp<const Element> I64_4;
        sp<const Element> F32;
        sp<const Element> F32_2;
        sp<const Element> F32_3;
        sp<const Element> F32_4;
        sp<const Element> F64;
        sp<const Element> F64_2;
        sp<const Element> F64_3;
        sp<const Element> F64_4;
        sp<const Element> BOOLEAN;

        sp<const Element> ELEMENT;
        sp<const Element> TYPE;
        sp<const Element> ALLOCATION;
        sp<const Element> SAMPLER;
        sp<const Element> SCRIPT;
        sp<const Element> MESH;
        sp<const Element> PROGRAM_FRAGMENT;
        sp<const Element> PROGRAM_VERTEX;
        sp<const Element> PROGRAM_RASTER;
        sp<const Element> PROGRAM_STORE;

        sp<const Element> A_8;
        sp<const Element> RGB_565;
        sp<const Element> RGB_888;
        sp<const Element> RGBA_5551;
        sp<const Element> RGBA_4444;
        sp<const Element> RGBA_8888;

        sp<const Element> YUV;

        sp<const Element> MATRIX_4X4;
        sp<const Element> MATRIX_3X3;
        sp<const Element> MATRIX_2X2;
    } mElements;

    struct {
        sp<const Sampler> CLAMP_NEAREST;
        sp<const Sampler> CLAMP_LINEAR;
        sp<const Sampler> CLAMP_LINEAR_MIP_LINEAR;
        sp<const Sampler> WRAP_NEAREST;
        sp<const Sampler> WRAP_LINEAR;
        sp<const Sampler> WRAP_LINEAR_MIP_LINEAR;
        sp<const Sampler> MIRRORED_REPEAT_NEAREST;
        sp<const Sampler> MIRRORED_REPEAT_LINEAR;
        sp<const Sampler> MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
    } mSamplers;
    friend class Sampler;
    friend class Element;
};

 /**
  * Base class for all RenderScript objects. Not for direct use by developers.
  */
class BaseObj : public android::RSC::LightRefBase<BaseObj> {
public:
    void * getID() const;
    virtual ~BaseObj();
    virtual void updateFromNative();
    virtual bool equals(sp<const BaseObj> obj);

protected:
    void *mID;
    sp<RS> mRS;
    std::string mName;

    BaseObj(void *id, sp<RS> rs);
    void checkValid();

    static void * getObjID(sp<const BaseObj> o);

};

 /**
  * This class provides the primary method through which data is passed to and
  * from RenderScript kernels. An Allocation provides the backing store for a
  * given Type.
  *
  * An Allocation also contains a set of usage flags that denote how the
  * Allocation could be used. For example, an Allocation may have usage flags
  * specifying that it can be used from a script as well as input to a
  * Sampler. A developer must synchronize across these different usages using
  * syncAll(int) in order to ensure that different users of the Allocation have
  * a consistent view of memory. For example, in the case where an Allocation is
  * used as the output of one kernel and as Sampler input in a later kernel, a
  * developer must call syncAll(RS_ALLOCATION_USAGE_SCRIPT) prior to launching the
  * second kernel to ensure correctness.
  */
class Allocation : public BaseObj {
protected:
    sp<const Type> mType;
    uint32_t mUsage;
    sp<Allocation> mAdaptedAllocation;

    bool mConstrainedLOD;
    bool mConstrainedFace;
    bool mConstrainedY;
    bool mConstrainedZ;
    bool mReadAllowed;
    bool mWriteAllowed;
    uint32_t mSelectedY;
    uint32_t mSelectedZ;
    uint32_t mSelectedLOD;
    RsAllocationCubemapFace mSelectedFace;

    uint32_t mCurrentDimX;
    uint32_t mCurrentDimY;
    uint32_t mCurrentDimZ;
    uint32_t mCurrentCount;

    void * getIDSafe() const;
    void updateCacheInfo(sp<const Type> t);

    Allocation(void *id, sp<RS> rs, sp<const Type> t, uint32_t usage);

    void validateIsInt32();
    void validateIsInt16();
    void validateIsInt8();
    void validateIsFloat32();
    void validateIsObject();

    virtual void updateFromNative();

    void validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h);
    void validate3DRange(uint32_t xoff, uint32_t yoff, uint32_t zoff,
                         uint32_t w, uint32_t h, uint32_t d);

public:

    /**
     * Return Type for the allocation.
     * @return pointer to underlying Type
     */
    sp<const Type> getType() const {
        return mType;
    }

    /**
     * Propagate changes from one usage of the Allocation to other usages of the Allocation.
     * @param[in] srcLocation source location with changes to propagate elsewhere
     */
    void syncAll(RsAllocationUsageType srcLocation);
    void ioSendOutput();
    void ioGetInput();

    /**
     * Generate a mipmap chain. This is only valid if the Type of the Allocation
     * includes mipmaps. This function will generate a complete set of mipmaps
     * from the top level LOD and place them into the script memory space. If
     * the Allocation is also using other memory spaces, a call to
     * syncAll(Allocation.USAGE_SCRIPT) is required.
     */
    void generateMipmaps();

    /**
     * Copy an array into part of this Allocation.
     * @param[in] off offset of first Element to be overwritten
     * @param[in] count number of Elements to copy
     * @param[in] data array from which to copy
     */
    void copy1DRangeFrom(uint32_t off, size_t count, const void *data);

    /**
     * Copy part of an Allocation into part of this Allocation.
     * @param[in] off offset of first Element to be overwritten
     * @param[in] count number of Elements to copy
     * @param[in] data Allocation from which to copy
     * @param[in] dataOff offset of first Element in data to copy
     */
    void copy1DRangeFrom(uint32_t off, size_t count, sp<const Allocation> data, uint32_t dataOff);

    /**
     * Copy an array into part of this Allocation.
     * @param[in] off offset of first Element to be overwritten
     * @param[in] count number of Elements to copy
     * @param[in] data array from which to copy
     */
    void copy1DRangeTo(uint32_t off, size_t count, void *data);

    /**
     * Copy entire array to an Allocation.
     * @param[in] data array from which to copy
     */
    void copy1DFrom(const void* data);

    /**
     * Copy entire Allocation to an array.
     * @param[in] data destination array
     */
    void copy1DTo(void* data);

    /**
     * Copy from an array into a rectangular region in this Allocation. The
     * array is assumed to be tightly packed.
     * @param[in] xoff X offset of region to update in this Allocation
     * @param[in] yoff Y offset of region to update in this Allocation
     * @param[in] w Width of region to update
     * @param[in] h Height of region to update
     * @param[in] data Array from which to copy
     */
    void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
                         const void *data);

    /**
     * Copy from this Allocation into a rectangular region in an array. The
     * array is assumed to be tightly packed.
     * @param[in] xoff X offset of region to copy from this Allocation
     * @param[in] yoff Y offset of region to copy from this Allocation
     * @param[in] w Width of region to update
     * @param[in] h Height of region to update
     * @param[in] data destination array
     */
    void copy2DRangeTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
                       void *data);

    /**
     * Copy from an Allocation into a rectangular region in this Allocation.
     * @param[in] xoff X offset of region to update in this Allocation
     * @param[in] yoff Y offset of region to update in this Allocation
     * @param[in] w Width of region to update
     * @param[in] h Height of region to update
     * @param[in] data Allocation from which to copy
     * @param[in] dataXoff X offset of region to copy from in data
     * @param[in] dataYoff Y offset of region to copy from in data
     */
    void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
                         sp<const Allocation> data, uint32_t dataXoff, uint32_t dataYoff);

    /**
     * Copy from a strided array into a rectangular region in this Allocation.
     * @param[in] xoff X offset of region to update in this Allocation
     * @param[in] yoff Y offset of region to update in this Allocation
     * @param[in] w Width of region to update
     * @param[in] h Height of region to update
     * @param[in] data array from which to copy
     * @param[in] stride stride of data in bytes
     */
    void copy2DStridedFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
                           const void *data, size_t stride);

    /**
     * Copy from a strided array into this Allocation.
     * @param[in] data array from which to copy
     * @param[in] stride stride of data in bytes
     */
    void copy2DStridedFrom(const void *data, size_t stride);

    /**
     * Copy from a rectangular region in this Allocation into a strided array.
     * @param[in] xoff X offset of region to update in this Allocation
     * @param[in] yoff Y offset of region to update in this Allocation
     * @param[in] w Width of region to update
     * @param[in] h Height of region to update
     * @param[in] data destination array
     * @param[in] stride stride of data in bytes
     */
    void copy2DStridedTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
                         void *data, size_t stride);

    /**
     * Copy this Allocation into a strided array.
     * @param[in] data destination array
     * @param[in] stride stride of data in bytes
     */
    void copy2DStridedTo(void *data, size_t stride);


    /**
     * Copy from an array into a 3D region in this Allocation. The
     * array is assumed to be tightly packed.
     * @param[in] xoff X offset of region to update in this Allocation
     * @param[in] yoff Y offset of region to update in this Allocation
     * @param[in] zoff Z offset of region to update in this Allocation
     * @param[in] w Width of region to update
     * @param[in] h Height of region to update
     * @param[in] d Depth of region to update
     * @param[in] data Array from which to copy
     */
    void copy3DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t w,
                         uint32_t h, uint32_t d, const void* data);

    /**
     * Copy from an Allocation into a 3D region in this Allocation.
     * @param[in] xoff X offset of region to update in this Allocation
     * @param[in] yoff Y offset of region to update in this Allocation
     * @param[in] zoff Z offset of region to update in this Allocation
     * @param[in] w Width of region to update
     * @param[in] h Height of region to update
     * @param[in] d Depth of region to update
     * @param[in] data Allocation from which to copy
     * @param[in] dataXoff X offset of region in data to copy from
     * @param[in] dataYoff Y offset of region in data to copy from
     * @param[in] dataZoff Z offset of region in data to copy from
     */
    void copy3DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t zoff,
                         uint32_t w, uint32_t h, uint32_t d,
                         sp<const Allocation> data,
                         uint32_t dataXoff, uint32_t dataYoff, uint32_t dataZoff);

    /**
     * Creates an Allocation for use by scripts with a given Type.
     * @param[in] rs Context to which the Allocation will belong
     * @param[in] type Type of the Allocation
     * @param[in] mipsmapctrl desired mipmap behavior for the Allocation
     * @param[in] usage usage for the Allocation
     * @return new Allocation
     */
    static sp<Allocation> createTyped(sp<RS> rs, sp<const Type> type,
                                   RsAllocationMipmapControl mipsmapctrl, uint32_t usage);

    /**
     * Creates an Allocation for use by scripts with a given Type and a backing pointer. For use
     * with RS_ALLOCATION_USAGE_SHARED.
     * @param[in] rs Context to which the Allocation will belong
     * @param[in] type Type of the Allocation
     * @param[in] mipsmapctrl desired mipmap behavior for the Allocation
     * @param[in] usage usage for the Allocation
     * @param[in] pointer existing backing store to use for this Allocation if possible
     * @return new Allocation
     */
    static sp<Allocation> createTyped(sp<RS> rs, sp<const Type> type,
                                   RsAllocationMipmapControl mipsmapctrl, uint32_t usage, void * pointer);

    /**
     * Creates an Allocation for use by scripts with a given Type with no mipmaps.
     * @param[in] rs Context to which the Allocation will belong
     * @param[in] type Type of the Allocation
     * @param[in] usage usage for the Allocation
     * @return new Allocation
     */
    static sp<Allocation> createTyped(sp<RS> rs, sp<const Type> type,
                                   uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT);
    /**
     * Creates an Allocation with a specified number of given elements.
     * @param[in] rs Context to which the Allocation will belong
     * @param[in] e Element used in the Allocation
     * @param[in] count Number of elements of the Allocation
     * @param[in] usage usage for the Allocation
     * @return new Allocation
     */
    static sp<Allocation> createSized(sp<RS> rs, sp<const Element> e, size_t count,
                                   uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT);

    /**
     * Creates a 2D Allocation with a specified number of given elements.
     * @param[in] rs Context to which the Allocation will belong
     * @param[in] e Element used in the Allocation
     * @param[in] x Width in Elements of the Allocation
     * @param[in] y Height of the Allocation
     * @param[in] usage usage for the Allocation
     * @return new Allocation
     */
    static sp<Allocation> createSized2D(sp<RS> rs, sp<const Element> e,
                                        size_t x, size_t y,
                                        uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT);


};

 /**
  * An Element represents one item within an Allocation. An Element is roughly
  * equivalent to a C type in a RenderScript kernel. Elements may be basic
  * or complex. Some basic elements are:

  * - A single float value (equivalent to a float in a kernel)
  * - A four-element float vector (equivalent to a float4 in a kernel)
  * - An unsigned 32-bit integer (equivalent to an unsigned int in a kernel)
  * - A single signed 8-bit integer (equivalent to a char in a kernel)

  * Basic Elements are comprised of a Element.DataType and a
  * Element.DataKind. The DataType encodes C type information of an Element,
  * while the DataKind encodes how that Element should be interpreted by a
  * Sampler. Note that Allocation objects with DataKind USER cannot be used as
  * input for a Sampler. In general, Allocation objects that are intended for
  * use with a Sampler should use bitmap-derived Elements such as
  * Element::RGBA_8888.
 */


class Element : public BaseObj {
public:
    bool isComplex();

    /**
     * Elements could be simple, such as an int or a float, or a structure with
     * multiple sub-elements, such as a collection of floats, float2,
     * float4. This function returns zero for simple elements or the number of
     * sub-elements otherwise.
     * @return number of sub-elements
     */
    size_t getSubElementCount() {
        return mVisibleElementMap.size();
    }

    /**
     * For complex Elements, this returns the sub-element at a given index.
     * @param[in] index index of sub-element
     * @return sub-element
     */
    sp<const Element> getSubElement(uint32_t index);

    /**
     * For complex Elements, this returns the name of the sub-element at a given
     * index.
     * @param[in] index index of sub-element
     * @return name of sub-element
     */
    const char * getSubElementName(uint32_t index);

    /**
     * For complex Elements, this returns the size of the sub-element at a given
     * index.
     * @param[in] index index of sub-element
     * @return size of sub-element
     */
    size_t getSubElementArraySize(uint32_t index);

    /**
     * Returns the location of a sub-element within a complex Element.
     * @param[in] index index of sub-element
     * @return offset in bytes
     */
    uint32_t getSubElementOffsetBytes(uint32_t index);

    /**
     * Returns the data type used for the Element.
     * @return data type
     */
    RsDataType getDataType() const {
        return mType;
    }

    /**
     * Returns the data kind used for the Element.
     * @return data kind
     */
    RsDataKind getDataKind() const {
        return mKind;
    }

    /**
     * Returns the size in bytes of the Element.
     * @return size in bytes
     */
    size_t getSizeBytes() const {
        return mSizeBytes;
    }

    /**
     * Returns the number of vector components for this Element.
     * @return number of vector components
     */
    uint32_t getVectorSize() const {
        return mVectorSize;
    }

    /**
     * Utility function for returning an Element containing a single bool.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> BOOLEAN(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a single unsigned char.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> U8(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a single signed char.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> I8(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a single unsigned short.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> U16(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a single signed short.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> I16(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a single unsigned int.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> U32(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a single signed int.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> I32(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a single unsigned long long.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> U64(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a single signed long long.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> I64(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a single float.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> F32(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a single double.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> F64(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a single Element.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> ELEMENT(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a single Type.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> TYPE(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a single Allocation.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> ALLOCATION(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a single Sampler.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> SAMPLER(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a single Script.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> SCRIPT(sp<RS> rs);
    /**
     * Utility function for returning an Element containing an ALPHA_8 pixel.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> A_8(sp<RS> rs);
    /**
     * Utility function for returning an Element containing an RGB_565 pixel.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> RGB_565(sp<RS> rs);
    /**
     * Utility function for returning an Element containing an RGB_888 pixel.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> RGB_888(sp<RS> rs);
    /**
     * Utility function for returning an Element containing an RGBA_5551 pixel.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> RGBA_5551(sp<RS> rs);
    /**
     * Utility function for returning an Element containing an RGBA_4444 pixel.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> RGBA_4444(sp<RS> rs);
    /**
     * Utility function for returning an Element containing an RGBA_8888 pixel.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> RGBA_8888(sp<RS> rs);

    /**
     * Utility function for returning an Element containing a float2.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> F32_2(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a float3.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> F32_3(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a float4.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> F32_4(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a double2.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> F64_2(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a double3.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> F64_3(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a double4.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> F64_4(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a uchar2.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> U8_2(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a uchar3.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> U8_3(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a uchar4.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> U8_4(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a char2.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> I8_2(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a char3.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> I8_3(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a char4.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> I8_4(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a ushort2.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> U16_2(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a ushort3.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> U16_3(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a ushort4.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> U16_4(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a short2.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> I16_2(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a short3.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> I16_3(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a short4.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> I16_4(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a uint2.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> U32_2(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a uint3.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> U32_3(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a uint4.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> U32_4(sp<RS> rs);
    /**
     * Utility function for returning an Element containing an int2.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> I32_2(sp<RS> rs);
    /**
     * Utility function for returning an Element containing an int3.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> I32_3(sp<RS> rs);
    /**
     * Utility function for returning an Element containing an int4.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> I32_4(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a ulong2.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> U64_2(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a ulong3.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> U64_3(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a ulong4.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> U64_4(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a long2.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> I64_2(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a long3.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> I64_3(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a long4.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> I64_4(sp<RS> rs);
    /**
     * Utility function for returning an Element containing a YUV pixel.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> YUV(sp<RS> rs);
    /**
     * Utility function for returning an Element containing an rs_matrix_4x4.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> MATRIX_4X4(sp<RS> rs);
    /**
     * Utility function for returning an Element containing an rs_matrix_3x3.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> MATRIX_3X3(sp<RS> rs);
    /**
     * Utility function for returning an Element containing an rs_matrix_2x2.
     * @param[in] rs RenderScript context
     * @return Element
     */
    static sp<const Element> MATRIX_2X2(sp<RS> rs);

    void updateFromNative();

    /**
     * Create an Element with a given DataType.
     * @param[in] rs RenderScript context
     * @param[in] dt data type
     * @return Element
     */
    static sp<const Element> createUser(sp<RS> rs, RsDataType dt);
    /**
     * Create a vector Element with the given DataType
     * @param[in] rs RenderScript
     * @param[in] dt DataType
     * @param[in] size vector size
     * @return Element
     */
    static sp<const Element> createVector(sp<RS> rs, RsDataType dt, uint32_t size);
    /**
     * Create an Element with a given DataType and DataKind.
     * @param[in] rs RenderScript context
     * @param[in] dt DataType
     * @param[in] dk DataKind
     * @return Element
     */
    static sp<const Element> createPixel(sp<RS> rs, RsDataType dt, RsDataKind dk);

    /**
     * Returns true if the Element can interoperate with this Element.
     * @param[in] e Element to compare
     * @return true if Elements can interoperate
     */
    bool isCompatible(sp<const Element>e) const;

    /**
     * Builder class for producing complex elements with matching field and name
     * pairs. The builder starts empty. The order in which elements are added is
     * retained for the layout in memory.
     */
    class Builder {
    private:
        sp<RS> mRS;
        std::vector<sp<Element> > mElements;
        std::vector<std::string> mElementNames;
        std::vector<uint32_t> mArraySizes;
        bool mSkipPadding;

    public:
        Builder(sp<RS> rs);
        ~Builder();
        void add(sp<Element> e, std::string &name, uint32_t arraySize = 1);
        sp<const Element> create();
    };

protected:
    Element(void *id, sp<RS> rs,
            std::vector<sp<Element> > &elements,
            std::vector<std::string> &elementNames,
            std::vector<uint32_t> &arraySizes);
    Element(void *id, sp<RS> rs, RsDataType dt, RsDataKind dk, bool norm, uint32_t size);
    Element(sp<RS> rs);
    virtual ~Element();

private:
    void updateVisibleSubElements();

    std::vector<sp<Element> > mElements;
    std::vector<std::string> mElementNames;
    std::vector<uint32_t> mArraySizes;
    std::vector<uint32_t> mVisibleElementMap;
    std::vector<uint32_t> mOffsetInBytes;

    RsDataType mType;
    RsDataKind mKind;
    bool mNormalized;
    size_t mSizeBytes;
    size_t mVectorSize;
};

class FieldPacker {
protected:
    unsigned char* mData;
    size_t mPos;
    size_t mLen;

public:
    FieldPacker(size_t len)
        : mPos(0), mLen(len) {
            mData = new unsigned char[len];
        }

    virtual ~FieldPacker() {
        delete [] mData;
    }

    void align(size_t v) {
        if ((v & (v - 1)) != 0) {
            //            ALOGE("Non-power-of-two alignment: %zu", v);
            return;
        }

        while ((mPos & (v - 1)) != 0) {
            mData[mPos++] = 0;
        }
    }

    void reset() {
        mPos = 0;
    }

    void reset(size_t i) {
        if (i >= mLen) {
            //            ALOGE("Out of bounds: i (%zu) >= len (%zu)", i, mLen);
            return;
        }
        mPos = i;
    }

    void skip(size_t i) {
        size_t res = mPos + i;
        if (res > mLen) {
            //            ALOGE("Exceeded buffer length: i (%zu) > len (%zu)", i, mLen);
            return;
        }
        mPos = res;
    }

    void* getData() const {
        return mData;
    }

    size_t getLength() const {
        return mLen;
    }

    template <typename T>
        void add(T t) {
        align(sizeof(t));
        if (mPos + sizeof(t) <= mLen) {
            memcpy(&mData[mPos], &t, sizeof(t));
            mPos += sizeof(t);
        }
    }

    /*
      void add(rs_matrix4x4 m) {
      for (size_t i = 0; i < 16; i++) {
      add(m.m[i]);
      }
      }

      void add(rs_matrix3x3 m) {
      for (size_t i = 0; i < 9; i++) {
      add(m.m[i]);
      }
      }

      void add(rs_matrix2x2 m) {
      for (size_t i = 0; i < 4; i++) {
      add(m.m[i]);
      }
      }
    */

    void add(sp<BaseObj> obj) {
        if (obj != NULL) {
            add((uint32_t) (uintptr_t) obj->getID());
        } else {
            add((uint32_t) 0);
        }
    }
};

/**
 * A Type describes the Element and dimensions used for an Allocation or a
 * parallel operation.
 *
 * A Type always includes an Element and an X dimension. A Type may be
 * multidimensional, up to three dimensions. A nonzero value in the Y or Z
 * dimensions indicates that the dimension is present. Note that a Type with
 * only a given X dimension and a Type with the same X dimension but Y = 1 are
 * not equivalent.
 *
 * A Type also supports inclusion of level of detail (LOD) or cube map
 * faces. LOD and cube map faces are booleans to indicate present or not
 * present.
 *
 * A Type also supports YUV format information to support an Allocation in a YUV
 * format. The YUV formats supported are YV12 and NV21.
 */
class Type : public BaseObj {
protected:
    friend class Allocation;

    uint32_t mDimX;
    uint32_t mDimY;
    uint32_t mDimZ;
    RSYuvFormat mYuvFormat;
    bool mDimMipmaps;
    bool mDimFaces;
    size_t mElementCount;
    sp<const Element> mElement;

    Type(void *id, sp<RS> rs);

    void calcElementCount();
    virtual void updateFromNative();

public:

    /**
     * Returns the YUV format.
     * @return YUV format of the Allocation
     */
    RSYuvFormat getYuvFormat() const {
        return mYuvFormat;
    }

    /**
     * Returns the Element of the Allocation.
     * @return YUV format of the Allocation
     */
    sp<const Element> getElement() const {
        return mElement;
    }

    /**
     * Returns the X dimension of the Allocation.
     * @return X dimension of the allocation
     */
    uint32_t getX() const {
        return mDimX;
    }

    /**
     * Returns the Y dimension of the Allocation.
     * @return Y dimension of the allocation
     */
    uint32_t getY() const {
        return mDimY;
    }

    /**
     * Returns the Z dimension of the Allocation.
     * @return Z dimension of the allocation
     */
    uint32_t getZ() const {
        return mDimZ;
    }

    /**
     * Returns true if the Allocation has mipmaps.
     * @return true if the Allocation has mipmaps
     */
    bool hasMipmaps() const {
        return mDimMipmaps;
    }

    /**
     * Returns true if the Allocation is a cube map
     * @return true if the Allocation is a cube map
     */
    bool hasFaces() const {
        return mDimFaces;
    }

    /**
     * Returns number of accessible Elements in the Allocation
     * @return number of accessible Elements in the Allocation
     */
    size_t getCount() const {
        return mElementCount;
    }

    /**
     * Returns size in bytes of all Elements in the Allocation
     * @return size in bytes of all Elements in the Allocation
     */
    size_t getSizeBytes() const {
        return mElementCount * mElement->getSizeBytes();
    }

    /**
     * Creates a new Type with the given Element and dimensions.
     * @param[in] rs RenderScript context
     * @param[in] e Element
     * @param[in] dimX X dimension
     * @param[in] dimY Y dimension
     * @param[in] dimZ Z dimension
     * @return new Type
     */
    static sp<const Type> create(sp<RS> rs, sp<const Element> e, uint32_t dimX, uint32_t dimY, uint32_t dimZ);

    class Builder {
    protected:
        sp<RS> mRS;
        uint32_t mDimX;
        uint32_t mDimY;
        uint32_t mDimZ;
        RSYuvFormat mYuvFormat;
        bool mDimMipmaps;
        bool mDimFaces;
        sp<const Element> mElement;

    public:
        Builder(sp<RS> rs, sp<const Element> e);

        void setX(uint32_t value);
        void setY(uint32_t value);
        void setZ(uint32_t value);
        void setYuvFormat(RSYuvFormat format);
        void setMipmaps(bool value);
        void setFaces(bool value);
        sp<const Type> create();
    };

};

/**
 * The parent class for all executable Scripts. This should not be used by applications.
 */
class Script : public BaseObj {
private:

protected:
    Script(void *id, sp<RS> rs);
    void forEach(uint32_t slot, sp<const Allocation> in, sp<const Allocation> out,
            const void *v, size_t) const;
    void bindAllocation(sp<Allocation> va, uint32_t slot) const;
    void setVar(uint32_t index, const void *, size_t len) const;
    void setVar(uint32_t index, sp<const BaseObj> o) const;
    void invoke(uint32_t slot, const void *v, size_t len) const;


    void invoke(uint32_t slot) const {
        invoke(slot, NULL, 0);
    }
    void setVar(uint32_t index, float v) const {
        setVar(index, &v, sizeof(v));
    }
    void setVar(uint32_t index, double v) const {
        setVar(index, &v, sizeof(v));
    }
    void setVar(uint32_t index, int32_t v) const {
        setVar(index, &v, sizeof(v));
    }
    void setVar(uint32_t index, int64_t v) const {
        setVar(index, &v, sizeof(v));
    }
    void setVar(uint32_t index, bool v) const {
        setVar(index, &v, sizeof(v));
    }

public:
    class FieldBase {
    protected:
        sp<const Element> mElement;
        sp<Allocation> mAllocation;

        void init(sp<RS> rs, uint32_t dimx, uint32_t usages = 0);

    public:
        sp<const Element> getElement() {
            return mElement;
        }

        sp<const Type> getType() {
            return mAllocation->getType();
        }

        sp<const Allocation> getAllocation() {
            return mAllocation;
        }

        //void updateAllocation();
    };
};

/**
 * The parent class for all user-defined scripts. This is intended to be used by auto-generated code only.
 */
class ScriptC : public Script {
protected:
    ScriptC(sp<RS> rs,
            const void *codeTxt, size_t codeLength,
            const char *cachedName, size_t cachedNameLength,
            const char *cacheDir, size_t cacheDirLength);

};

/**
 * The parent class for all script intrinsics. Intrinsics provide highly optimized implementations of
 * basic functions. This is not intended to be used directly.
 */
class ScriptIntrinsic : public Script {
 protected:
    sp<const Element> mElement;
    ScriptIntrinsic(sp<RS> rs, int id, sp<const Element> e);
    virtual ~ScriptIntrinsic();
};

/**
 * Intrinsic for converting RGB to RGBA by using a 3D lookup table. The incoming
 * r,g,b values are use as normalized x,y,z coordinates into a 3D
 * allocation. The 8 nearest values are sampled and linearly interpolated. The
 * result is placed in the output.
 */
class ScriptIntrinsic3DLUT : public ScriptIntrinsic {
 private:
    ScriptIntrinsic3DLUT(sp<RS> rs, sp<const Element> e);
 public:
    /**
     * Supported Element types are U8_4. Default lookup table is identity.
     * @param[in] rs RenderScript context
     * @param[in] e Element
     * @return new ScriptIntrinsic
     */
    static sp<ScriptIntrinsic3DLUT> create(sp<RS> rs, sp<const Element> e);

    /**
     * Launch the intrinsic.
     * @param[in] ain input Allocation
     * @param[in] aout output Allocation
     */
    void forEach(sp<Allocation> ain, sp<Allocation> aout);

    /**
     * Sets the lookup table. The lookup table must use the same Element as the
     * intrinsic.
     * @param[in] lut new lookup table
     */
    void setLUT(sp<Allocation> lut);
};

/**
 * Intrinsic kernel for blending two Allocations.
 */
class ScriptIntrinsicBlend : public ScriptIntrinsic {
 private:
    ScriptIntrinsicBlend(sp<RS> rs, sp<const Element> e);
 public:
    /**
     * Supported Element types are U8_4.
     * @param[in] rs RenderScript context
     * @param[in] e Element
     * @return new ScriptIntrinsicBlend
     */
    static sp<ScriptIntrinsicBlend> create(sp<RS> rs, sp<const Element> e);
    /**
     * sets dst = {0, 0, 0, 0}
     * @param[in] in input Allocation
     * @param[in] out output Allocation
     */
    void forEachClear(sp<Allocation> in, sp<Allocation> out);
    /**
     * Sets dst = src
     * @param[in] in input Allocation
     * @param[in] out output Allocation
     */
    void forEachSrc(sp<Allocation> in, sp<Allocation> out);
    /**
     * Sets dst = dst (NOP)
     * @param[in] in input Allocation
     * @param[in] out output Allocation
     */
    void forEachDst(sp<Allocation> in, sp<Allocation> out);
    /**
     * Sets dst = src + dst * (1.0 - src.a)
     * @param[in] in input Allocation
     * @param[in] out output Allocation
     */
    void forEachSrcOver(sp<Allocation> in, sp<Allocation> out);
    /**
     * Sets dst = dst + src * (1.0 - dst.a)
     * @param[in] in input Allocation
     * @param[in] out output Allocation
     */
    void forEachDstOver(sp<Allocation> in, sp<Allocation> out);
    /**
     * Sets dst = src * dst.a
     * @param[in] in input Allocation
     * @param[in] out output Allocation
     */
    void forEachSrcIn(sp<Allocation> in, sp<Allocation> out);
    /**
     * Sets dst = dst * src.a
     * @param[in] in input Allocation
     * @param[in] out output Allocation
     */
    void forEachDstIn(sp<Allocation> in, sp<Allocation> out);
    /**
     * Sets dst = src * (1.0 - dst.a)
     * @param[in] in input Allocation
     * @param[in] out output Allocation
     */
    void forEachSrcOut(sp<Allocation> in, sp<Allocation> out);
    /**
     * Sets dst = dst * (1.0 - src.a)
     * @param[in] in input Allocation
     * @param[in] out output Allocation
     */
    void forEachDstOut(sp<Allocation> in, sp<Allocation> out);
    /**
     * Sets dst.rgb = src.rgb * dst.a + (1.0 - src.a) * dst.rgb
     * @param[in] in input Allocation
     * @param[in] out output Allocation
     */
    void forEachSrcAtop(sp<Allocation> in, sp<Allocation> out);
    /**
     * Sets dst.rgb = dst.rgb * src.a + (1.0 - dst.a) * src.rgb
     * @param[in] in input Allocation
     * @param[in] out output Allocation
     */
    void forEachDstAtop(sp<Allocation> in, sp<Allocation> out);
    /**
     * Sets dst = {src.r ^ dst.r, src.g ^ dst.g, src.b ^ dst.b, src.a ^ dst.a}
     * @param[in] in input Allocation
     * @param[in] out output Allocation
     */
    void forEachXor(sp<Allocation> in, sp<Allocation> out);
    /**
     * Sets dst = src * dst
     * @param[in] in input Allocation
     * @param[in] out output Allocation
     */
    void forEachMultiply(sp<Allocation> in, sp<Allocation> out);
    /**
     * Sets dst = min(src + dst, 1.0)
     * @param[in] in input Allocation
     * @param[in] out output Allocation
     */
    void forEachAdd(sp<Allocation> in, sp<Allocation> out);
    /**
     * Sets dst = max(dst - src, 0.0)
     * @param[in] in input Allocation
     * @param[in] out output Allocation
     */
    void forEachSubtract(sp<Allocation> in, sp<Allocation> out);
};

/**
 * Intrinsic Gausian blur filter. Applies a Gaussian blur of the specified
 * radius to all elements of an Allocation.
 */
class ScriptIntrinsicBlur : public ScriptIntrinsic {
 private:
    ScriptIntrinsicBlur(sp<RS> rs, sp<const Element> e);
 public:
    /**
     * Supported Element types are U8 and U8_4.
     * @param[in] rs RenderScript context
     * @param[in] e Element
     * @return new ScriptIntrinsicBlur
     */
    static sp<ScriptIntrinsicBlur> create(sp<RS> rs, sp<const Element> e);
    /**
     * Sets the input of the blur.
     * @param[in] in input Allocation
     */
    void setInput(sp<Allocation> in);
    /**
     * Runs the intrinsic.
     * @param[in] output Allocation
     */
    void forEach(sp<Allocation> out);
    /**
     * Sets the radius of the blur. The supported range is 0 < radius <= 25.
     * @param[in] radius radius of the blur
     */
    void setRadius(float radius);
};

/**
 * Intrinsic for applying a color matrix to allocations. This has the
 * same effect as loading each element and converting it to a
 * F32_N, multiplying the result by the 4x4 color matrix
 * as performed by rsMatrixMultiply() and writing it to the output
 * after conversion back to U8_N or F32_N.
 */
class ScriptIntrinsicColorMatrix : public ScriptIntrinsic {
 private:
    ScriptIntrinsicColorMatrix(sp<RS> rs, sp<const Element> e);
 public:
    /**
     * Creates a new intrinsic.
     * @param[in] rs RenderScript context
     * @return new ScriptIntrinsicColorMatrix
     */
    static sp<ScriptIntrinsicColorMatrix> create(sp<RS> rs);
    /**
     * Applies the color matrix. Supported types are U8 and F32 with
     * vector lengths between 1 and 4.
     * @param[in] in input Allocation
     * @param[out] out output Allocation
     */
    void forEach(sp<Allocation> in, sp<Allocation> out);
    /**
     * Set the value to be added after the color matrix has been
     * applied. The default value is {0, 0, 0, 0}.
     * @param[in] add float[4] of values
     */
    void setAdd(float* add);

    /**
     * Set the color matrix which will be applied to each cell of the
     * image. The alpha channel will be copied.
     *
     * @param[in] m float[9] of values
     */
    void setColorMatrix3(float* m);
    /**
     * Set the color matrix which will be applied to each cell of the
     * image.
     *
     * @param[in] m float[16] of values
     */
    void setColorMatrix4(float* m);
    /**
     * Set a color matrix to convert from RGB to luminance. The alpha
     * channel will be a copy.
     */
    void setGreyscale();
    /**
     * Set the matrix to convert from RGB to YUV with a direct copy of
     * the 4th channel.
     */
    void setRGBtoYUV();
    /**
     * Set the matrix to convert from YUV to RGB with a direct copy of
     * the 4th channel.
     */
    void setYUVtoRGB();
};

/**
 * Intrinsic for applying a 3x3 convolve to an allocation.
 */
class ScriptIntrinsicConvolve3x3 : public ScriptIntrinsic {
 private:
    ScriptIntrinsicConvolve3x3(sp<RS> rs, sp<const Element> e);
 public:
    /**
     * Supported types U8 and F32 with vector lengths between 1 and
     * 4. The default convolution kernel is the identity.
     * @param[in] rs RenderScript context
     * @param[in] e Element
     * @return new ScriptIntrinsicConvolve3x3
     */
    static sp<ScriptIntrinsicConvolve3x3> create(sp<RS> rs, sp<const Element> e);
    /**
     * Sets input for intrinsic.
     * @param[in] in input Allocation
     */
    void setInput(sp<Allocation> in);
    /**
     * Launches the intrinsic.
     * @param[in] out output Allocation
     */
    void forEach(sp<Allocation> out);
    /**
     * Sets convolution kernel.
     * @param[in] v float[9] of values
     */
    void setCoefficients(float* v);
};

/**
 * Intrinsic for applying a 5x5 convolve to an allocation.
 */
class ScriptIntrinsicConvolve5x5 : public ScriptIntrinsic {
 private:
    ScriptIntrinsicConvolve5x5(sp<RS> rs, sp<const Element> e);
 public:
    /**
     * Supported types U8 and F32 with vector lengths between 1 and
     * 4. The default convolution kernel is the identity.
     * @param[in] rs RenderScript context
     * @param[in] e Element
     * @return new ScriptIntrinsicConvolve5x5
     */
    static sp<ScriptIntrinsicConvolve5x5> create(sp<RS> rs, sp<const Element> e);
    /**
     * Sets input for intrinsic.
     * @param[in] in input Allocation
     */
    void setInput(sp<Allocation> in);
    /**
     * Launches the intrinsic.
     * @param[in] out output Allocation
     */
    void forEach(sp<Allocation> out);
    /**
     * Sets convolution kernel.
     * @param[in] v float[25] of values
     */
    void setCoefficients(float* v);
};

/**
 * Intrinsic for computing a histogram.
 */
class ScriptIntrinsicHistogram : public ScriptIntrinsic {
 private:
    ScriptIntrinsicHistogram(sp<RS> rs, sp<const Element> e);
    sp<Allocation> mOut;
 public:
    /**
     * Create an intrinsic for calculating the histogram of an uchar
     * or uchar4 image.
     *
     * Supported elements types are U8_4, U8_3, U8_2, and U8.
     *
     * @param[in] rs The RenderScript context
     * @param[in] e Element type for inputs
     *
     * @return ScriptIntrinsicHistogram
     */
    static sp<ScriptIntrinsicHistogram> create(sp<RS> rs);
    /**
     * Set the output of the histogram.  32 bit integer types are
     * supported.
     *
     * @param[in] aout The output allocation
     */
    void setOutput(sp<Allocation> aout);
    /**
     * Set the coefficients used for the dot product calculation. The
     * default is {0.299f, 0.587f, 0.114f, 0.f}.
     *
     * Coefficients must be >= 0 and sum to 1.0 or less.
     *
     * @param[in] r Red coefficient
     * @param[in] g Green coefficient
     * @param[in] b Blue coefficient
     * @param[in] a Alpha coefficient
     */
    void setDotCoefficients(float r, float g, float b, float a);
    /**
     * Process an input buffer and place the histogram into the output
     * allocation. The output allocation may be a narrower vector size
     * than the input. In this case the vector size of the output is
     * used to determine how many of the input channels are used in
     * the computation. This is useful if you have an RGBA input
     * buffer but only want the histogram for RGB.
     *
     * 1D and 2D input allocations are supported.
     *
     * @param[in] ain The input image
     */
    void forEach(sp<Allocation> ain);
    /**
     * Process an input buffer and place the histogram into the output
     * allocation. The dot product of the input channel and the
     * coefficients from 'setDotCoefficients' are used to calculate
     * the output values.
     *
     * 1D and 2D input allocations are supported.
     *
     * @param ain The input image
     */
    void forEach_dot(sp<Allocation> ain);
};

/**
 * Intrinsic for applying a per-channel lookup table. Each channel of
 * the input has an independant lookup table. The tables are 256
 * entries in size and can cover the full value range of U8_4.
 **/
class ScriptIntrinsicLUT : public ScriptIntrinsic {
 private:
    sp<Allocation> LUT;
    bool mDirty;
    unsigned char mCache[1024];
    void setTable(unsigned int offset, unsigned char base, unsigned int length, unsigned char* lutValues);
    ScriptIntrinsicLUT(sp<RS> rs, sp<const Element> e);

 public:
    /**
     * Supported elements types are U8_4.
     *
     * The defaults tables are identity.
     *
     * @param[in] rs The RenderScript context
     * @param[in] e Element type for intputs and outputs
     *
     * @return ScriptIntrinsicLUT
     */
    static sp<ScriptIntrinsicLUT> create(sp<RS> rs, sp<const Element> e);
    /**
     * Invoke the kernel and apply the lookup to each cell of ain and
     * copy to aout.
     *
     * @param[in] ain Input allocation
     * @param[in] aout Output allocation
     */
    void forEach(sp<Allocation> ain, sp<Allocation> aout);
    /**
     * Sets entries in LUT for the red channel.
     * @param[in] base base of region to update
     * @param[in] length length of region to update
     * @param[in] lutValues LUT values to use
     */
    void setRed(unsigned char base, unsigned int length, unsigned char* lutValues);
    /**
     * Sets entries in LUT for the green channel.
     * @param[in] base base of region to update
     * @param[in] length length of region to update
     * @param[in] lutValues LUT values to use
     */
    void setGreen(unsigned char base, unsigned int length, unsigned char* lutValues);
    /**
     * Sets entries in LUT for the blue channel.
     * @param[in] base base of region to update
     * @param[in] length length of region to update
     * @param[in] lutValues LUT values to use
     */
    void setBlue(unsigned char base, unsigned int length, unsigned char* lutValues);
    /**
     * Sets entries in LUT for the alpha channel.
     * @param[in] base base of region to update
     * @param[in] length length of region to update
     * @param[in] lutValues LUT values to use
     */
    void setAlpha(unsigned char base, unsigned int length, unsigned char* lutValues);
    virtual ~ScriptIntrinsicLUT();
};

/**
 * Intrinsic for converting an Android YUV buffer to RGB.
 *
 * The input allocation should be supplied in a supported YUV format
 * as a YUV element Allocation. The output is RGBA; the alpha channel
 * will be set to 255.
 */
class ScriptIntrinsicYuvToRGB : public ScriptIntrinsic {
 private:
    ScriptIntrinsicYuvToRGB(sp<RS> rs, sp<const Element> e);
 public:
    /**
     * Create an intrinsic for converting YUV to RGB.
     *
     * Supported elements types are U8_4.
     *
     * @param[in] rs The RenderScript context
     * @param[in] e Element type for output
     *
     * @return ScriptIntrinsicYuvToRGB
     */
    static sp<ScriptIntrinsicYuvToRGB> create(sp<RS> rs, sp<const Element> e);
    /**
     * Set the input YUV allocation.
     *
     * @param[in] ain The input allocation.
     */
    void setInput(sp<Allocation> in);

    /**
     * Convert the image to RGB.
     *
     * @param[in] aout Output allocation. Must match creation element
     *                 type.
     */
    void forEach(sp<Allocation> out);

};

/**
 * Sampler object that defines how Allocations can be read as textures
 * within a kernel. Samplers are used in conjunction with the rsSample
 * runtime function to return values from normalized coordinates.
 *
 * Any Allocation used with a Sampler must have been created with
 * RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE; using a Sampler on an
 * Allocation that was not created with
 * RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE is undefined.
 **/
 class Sampler : public BaseObj {
 private:
    Sampler(sp<RS> rs, void* id);
    RsSamplerValue mMin;
    RsSamplerValue mMag;
    RsSamplerValue mWrapS;
    RsSamplerValue mWrapT;
    RsSamplerValue mWrapR;
    float mAniso;

 public:
    /**
     * Creates a non-standard Sampler.
     * @param[in] rs RenderScript context
     * @param[in] min minification
     * @param[in] mag magnification
     * @param[in] wrapS S wrapping mode
     * @param[in] wrapT T wrapping mode
     * @param[in] anisotropy anisotropy setting
     */
    static sp<Sampler> create(sp<RS> rs, RsSamplerValue min, RsSamplerValue mag, RsSamplerValue wrapS, RsSamplerValue wrapT, float anisotropy);

    /**
     * @return minification setting for the sampler
     */
    RsSamplerValue getMinification();
    /**
     * @return magnification setting for the sampler
     */
    RsSamplerValue getMagnification();
    /**
     * @return S wrapping mode for the sampler
     */
    RsSamplerValue getWrapS();
    /**
     * @return T wrapping mode for the sampler
     */
    RsSamplerValue getWrapT();
    /**
     * @return anisotropy setting for the sampler
     */
    float getAnisotropy();

    /**
     * Retrieve a sampler with min and mag set to nearest and wrap modes set to
     * clamp.
     *
     * @param rs Context to which the sampler will belong.
     *
     * @return Sampler
     */
    sp<const Sampler> CLAMP_NEAREST(sp<RS> rs);
    /**
     * Retrieve a sampler with min and mag set to linear and wrap modes set to
     * clamp.
     *
     * @param rs Context to which the sampler will belong.
     *
     * @return Sampler
     */
    sp<const Sampler> CLAMP_LINEAR(sp<RS> rs);
    /**
     * Retrieve a sampler with mag set to linear, min linear mipmap linear, and
     * wrap modes set to clamp.
     *
     * @param rs Context to which the sampler will belong.
     *
     * @return Sampler
     */
    sp<const Sampler> CLAMP_LINEAR_MIP_LINEAR(sp<RS> rs);
    /**
     * Retrieve a sampler with min and mag set to nearest and wrap modes set to
     * wrap.
     *
     * @param rs Context to which the sampler will belong.
     *
     * @return Sampler
     */
    sp<const Sampler> WRAP_NEAREST(sp<RS> rs);
    /**
     * Retrieve a sampler with min and mag set to linear and wrap modes set to
     * wrap.
     *
     * @param rs Context to which the sampler will belong.
     *
     * @return Sampler
     */
    sp<const Sampler> WRAP_LINEAR(sp<RS> rs);
    /**
     * Retrieve a sampler with mag set to linear, min linear mipmap linear, and
     * wrap modes set to wrap.
     *
     * @param rs Context to which the sampler will belong.
     *
     * @return Sampler
     */
    sp<const Sampler> WRAP_LINEAR_MIP_LINEAR(sp<RS> rs);
    /**
     * Retrieve a sampler with min and mag set to nearest and wrap modes set to
     * mirrored repeat.
     *
     * @param rs Context to which the sampler will belong.
     *
     * @return Sampler
     */
    sp<const Sampler> MIRRORED_REPEAT_NEAREST(sp<RS> rs);
    /**
     * Retrieve a sampler with min and mag set to linear and wrap modes set to
     * mirrored repeat.
     *
     * @param rs Context to which the sampler will belong.
     *
     * @return Sampler
     */
    sp<const Sampler> MIRRORED_REPEAT_LINEAR(sp<RS> rs);
    /**
     * Retrieve a sampler with min and mag set to linear and wrap modes set to
     * mirrored repeat.
     *
     * @param rs Context to which the sampler will belong.
     *
     * @return Sampler
     */
    sp<const Sampler> MIRRORED_REPEAT_LINEAR_MIP_LINEAR(sp<RS> rs);

};

class Byte2 {
 public:
  int8_t x, y;

  Byte2(int8_t initX, int8_t initY)
    : x(initX), y(initY) {}
  Byte2() : x(0), y(0) {}
};

class Byte3 {
 public:
  int8_t x, y, z;

  Byte3(int8_t initX, int8_t initY, int8_t initZ)
    : x(initX), y(initY), z(initZ) {}
  Byte3() : x(0), y(0), z(0) {}
};

class Byte4 {
 public:
  int8_t x, y, z, w;

  Byte4(int8_t initX, int8_t initY, int8_t initZ, int8_t initW)
    : x(initX), y(initY), z(initZ), w(initW) {}
  Byte4() : x(0), y(0), z(0), w(0) {}
};

class UByte2 {
 public:
  uint8_t x, y;

  UByte2(uint8_t initX, uint8_t initY)
    : x(initX), y(initY) {}
  UByte2() : x(0), y(0) {}
};

class UByte3 {
 public:
  uint8_t x, y, z;

  UByte3(uint8_t initX, uint8_t initY, uint8_t initZ)
    : x(initX), y(initY), z(initZ) {}
  UByte3() : x(0), y(0), z(0) {}
};

class UByte4 {
 public:
  uint8_t x, y, z, w;

  UByte4(uint8_t initX, uint8_t initY, uint8_t initZ, uint8_t initW)
    : x(initX), y(initY), z(initZ), w(initW) {}
  UByte4() : x(0), y(0), z(0), w(0) {}
};

class Short2 {
 public:
  short x, y;

  Short2(short initX, short initY)
    : x(initX), y(initY) {}
  Short2() : x(0), y(0) {}
};

class Short3 {
 public:
  short x, y, z;

  Short3(short initX, short initY, short initZ)
    : x(initX), y(initY), z(initZ) {}
  Short3() : x(0), y(0), z(0) {}
};

class Short4 {
 public:
  short x, y, z, w;

  Short4(short initX, short initY, short initZ, short initW)
    : x(initX), y(initY), z(initZ), w(initW) {}
  Short4() : x(0), y(0), z(0), w(0) {}
};

class UShort2 {
 public:
  uint16_t x, y;

  UShort2(uint16_t initX, uint16_t initY)
    : x(initX), y(initY) {}
  UShort2() : x(0), y(0) {}
};

class UShort3 {
 public:
  uint16_t x, y, z;

  UShort3(uint16_t initX, uint16_t initY, uint16_t initZ)
    : x(initX), y(initY), z(initZ) {}
  UShort3() : x(0), y(0), z(0) {}
};

class UShort4 {
 public:
  uint16_t x, y, z, w;

  UShort4(uint16_t initX, uint16_t initY, uint16_t initZ, uint16_t initW)
    : x(initX), y(initY), z(initZ), w(initW) {}
  UShort4() : x(0), y(0), z(0), w(0) {}
};

class Int2 {
 public:
  int x, y;

  Int2(int initX, int initY)
    : x(initX), y(initY) {}
  Int2() : x(0), y(0) {}
};

class Int3 {
 public:
  int x, y, z;

  Int3(int initX, int initY, int initZ)
    : x(initX), y(initY), z(initZ) {}
  Int3() : x(0), y(0), z(0) {}
};

class Int4 {
 public:
  int x, y, z, w;

  Int4(int initX, int initY, int initZ, int initW)
    : x(initX), y(initY), z(initZ), w(initW) {}
  Int4() : x(0), y(0), z(0), w(0) {}
};

class UInt2 {
 public:
  uint32_t x, y;

  UInt2(uint32_t initX, uint32_t initY)
    : x(initX), y(initY) {}
  UInt2() : x(0), y(0) {}
};

class UInt3 {
 public:
  uint32_t x, y, z;

  UInt3(uint32_t initX, uint32_t initY, uint32_t initZ)
    : x(initX), y(initY), z(initZ) {}
  UInt3() : x(0), y(0), z(0) {}
};

class UInt4 {
 public:
  uint32_t x, y, z, w;

  UInt4(uint32_t initX, uint32_t initY, uint32_t initZ, uint32_t initW)
    : x(initX), y(initY), z(initZ), w(initW) {}
  UInt4() : x(0), y(0), z(0), w(0) {}
};

class Long2 {
 public:
  int64_t x, y;

  Long2(int64_t initX, int64_t initY)
    : x(initX), y(initY) {}
  Long2() : x(0), y(0) {}
};

class Long3 {
 public:
  int64_t x, y, z;

  Long3(int64_t initX, int64_t initY, int64_t initZ)
    : x(initX), y(initY), z(initZ) {}
  Long3() : x(0), y(0), z(0) {}
};

class Long4 {
 public:
  int64_t x, y, z, w;

  Long4(int64_t initX, int64_t initY, int64_t initZ, int64_t initW)
    : x(initX), y(initY), z(initZ), w(initW) {}
  Long4() : x(0), y(0), z(0), w(0) {}
};

class ULong2 {
 public:
  uint64_t x, y;

  ULong2(uint64_t initX, uint64_t initY)
    : x(initX), y(initY) {}
  ULong2() : x(0), y(0) {}
};

class ULong3 {
 public:
  uint64_t x, y, z;

  ULong3(uint64_t initX, uint64_t initY, uint64_t initZ)
    : x(initX), y(initY), z(initZ) {}
  ULong3() : x(0), y(0), z(0) {}
};

class ULong4 {
 public:
  uint64_t x, y, z, w;

  ULong4(uint64_t initX, uint64_t initY, uint64_t initZ, uint64_t initW)
    : x(initX), y(initY), z(initZ), w(initW) {}
  ULong4() : x(0), y(0), z(0), w(0) {}
};

class Float2 {
 public:
  float x, y;

  Float2(float initX, float initY)
    : x(initX), y(initY) {}
  Float2() : x(0), y(0) {}
};

class Float3 {
 public:
  float x, y, z;

  Float3(float initX, float initY, float initZ)
    : x(initX), y(initY), z(initZ) {}
  Float3() : x(0.f), y(0.f), z(0.f) {}
};

class Float4 {
 public:
  float x, y, z, w;

  Float4(float initX, float initY, float initZ, float initW)
    : x(initX), y(initY), z(initZ), w(initW) {}
  Float4() : x(0.f), y(0.f), z(0.f), w(0.f) {}
};

class Double2 {
 public:
  double x, y;

  Double2(double initX, double initY)
    : x(initX), y(initY) {}
  Double2() : x(0), y(0) {}
};

class Double3 {
 public:
  double x, y, z;

  Double3(double initX, double initY, double initZ)
    : x(initX), y(initY), z(initZ) {}
  Double3() : x(0), y(0), z(0) {}
};

class Double4 {
 public:
  double x, y, z, w;

  Double4(double initX, double initY, double initZ, double initW)
    : x(initX), y(initY), z(initZ), w(initW) {}
  Double4() : x(0), y(0), z(0), w(0) {}
};

}

}

#endif
