/*
 * Copyright (C) 2009 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_RS_BUILD_FOR_HOST
#include "rsContext.h"

#include <GLES/gl.h>
#include <GLES2/gl2.h>
#include <GLES/glext.h>
#else
#include "rsContextHostStub.h"

#include <OpenGL/gl.h>
#include <OpenGl/glext.h>
#endif

#include "utils/StopWatch.h"

using namespace android;
using namespace android::renderscript;

Allocation::Allocation(Context *rsc, const Type *type) : ObjectBase(rsc)
{
    init(rsc, type);

    mPtr = malloc(mType->getSizeBytes());
    if (mType->getElement()->getHasReferences()) {
        memset(mPtr, 0, mType->getSizeBytes());
    }
    if (!mPtr) {
        LOGE("Allocation::Allocation, alloc failure");
    }
}

Allocation::Allocation(Context *rsc, const Type *type, void *bmp,
                       void *callbackData, RsBitmapCallback_t callback)
: ObjectBase(rsc)
{
    init(rsc, type);

    mPtr = bmp;
    mUserBitmapCallback = callback;
    mUserBitmapCallbackData = callbackData;
}

void Allocation::init(Context *rsc, const Type *type)
{
    mPtr = NULL;

    mCpuWrite = false;
    mCpuRead = false;
    mGpuWrite = false;
    mGpuRead = false;

    mReadWriteRatio = 0;
    mUpdateSize = 0;

    mIsTexture = false;
    mTextureID = 0;
    mIsVertexBuffer = false;
    mBufferID = 0;
    mUploadDefered = false;

    mUserBitmapCallback = NULL;
    mUserBitmapCallbackData = NULL;

    mType.set(type);
    rsAssert(type);

    mPtr = NULL;
}

Allocation::~Allocation()
{
    if (mUserBitmapCallback != NULL) {
        mUserBitmapCallback(mUserBitmapCallbackData);
    } else {
        free(mPtr);
    }
    mPtr = NULL;

    if (mBufferID) {
        // Causes a SW crash....
        //LOGV(" mBufferID %i", mBufferID);
        //glDeleteBuffers(1, &mBufferID);
        //mBufferID = 0;
    }
    if (mTextureID) {
        glDeleteTextures(1, &mTextureID);
        mTextureID = 0;
    }
}

void Allocation::setCpuWritable(bool)
{
}

void Allocation::setGpuWritable(bool)
{
}

void Allocation::setCpuReadable(bool)
{
}

void Allocation::setGpuReadable(bool)
{
}

bool Allocation::fixAllocation()
{
    return false;
}

void Allocation::deferedUploadToTexture(const Context *rsc, bool genMipmap, uint32_t lodOffset)
{
    rsAssert(lodOffset < mType->getLODCount());
    mIsTexture = true;
    mTextureLOD = lodOffset;
    mUploadDefered = true;
    mTextureGenMipmap = !mType->getDimLOD() && genMipmap;
}

void Allocation::uploadToTexture(const Context *rsc)
{
    //rsAssert(!mTextureId);

    mIsTexture = true;
    if (!rsc->checkDriver()) {
        mUploadDefered = true;
        return;
    }

    GLenum type = mType->getElement()->getComponent().getGLType();
    GLenum format = mType->getElement()->getComponent().getGLFormat();

    if (!type || !format) {
        return;
    }

    bool isFirstUpload = false;

    if (!mTextureID) {
        glGenTextures(1, &mTextureID);

        if (!mTextureID) {
            // This should not happen, however, its likely the cause of the
            // white sqare bug.
            // Force a crash to 1: restart the app, 2: make sure we get a bugreport.
            LOGE("Upload to texture failed to gen mTextureID");
            rsc->dumpDebug();
            mUploadDefered = true;
            return;
        }
        isFirstUpload = true;
    }
    glBindTexture(GL_TEXTURE_2D, mTextureID);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    Adapter2D adapt(getContext(), this);
    for(uint32_t lod = 0; (lod + mTextureLOD) < mType->getLODCount(); lod++) {
        adapt.setLOD(lod+mTextureLOD);

        uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
        if(isFirstUpload) {
            glTexImage2D(GL_TEXTURE_2D, lod, format,
                         adapt.getDimX(), adapt.getDimY(),
                         0, format, type, ptr);
        } else {
            glTexSubImage2D(GL_TEXTURE_2D, lod, 0, 0,
                         adapt.getDimX(), adapt.getDimY(),
                         format, type, ptr);
        }
    }
    if (mTextureGenMipmap) {
#ifndef ANDROID_RS_BUILD_FOR_HOST
        glGenerateMipmap(GL_TEXTURE_2D);
#endif //ANDROID_RS_BUILD_FOR_HOST
    }

    rsc->checkError("Allocation::uploadToTexture");
}

void Allocation::deferedUploadToBufferObject(const Context *rsc)
{
    mIsVertexBuffer = true;
    mUploadDefered = true;
}

void Allocation::uploadToBufferObject(const Context *rsc)
{
    rsAssert(!mType->getDimY());
    rsAssert(!mType->getDimZ());

    mIsVertexBuffer = true;
    if (!rsc->checkDriver()) {
        mUploadDefered = true;
        return;
    }

    if (!mBufferID) {
        glGenBuffers(1, &mBufferID);
    }
    if (!mBufferID) {
        LOGE("Upload to buffer object failed");
        mUploadDefered = true;
        return;
    }

    glBindBuffer(GL_ARRAY_BUFFER, mBufferID);
    glBufferData(GL_ARRAY_BUFFER, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    rsc->checkError("Allocation::uploadToBufferObject");
}

void Allocation::uploadCheck(const Context *rsc)
{
    if (mUploadDefered) {
        mUploadDefered = false;
        if (mIsVertexBuffer) {
            uploadToBufferObject(rsc);
        }
        if (mIsTexture) {
            uploadToTexture(rsc);
        }
    }
}


void Allocation::data(Context *rsc, const void *data, uint32_t sizeBytes)
{
    uint32_t size = mType->getSizeBytes();
    if (size != sizeBytes) {
        LOGE("Allocation::data called with mismatched size expected %i, got %i", size, sizeBytes);
        return;
    }

    if (mType->getElement()->getHasReferences()) {
        incRefs(data, sizeBytes / mType->getElement()->getSizeBytes());
        decRefs(mPtr, sizeBytes / mType->getElement()->getSizeBytes());
    }

    memcpy(mPtr, data, size);
    sendDirty();
    mUploadDefered = true;
}

void Allocation::read(void *data)
{
    memcpy(data, mPtr, mType->getSizeBytes());
}

void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes)
{
    uint32_t eSize = mType->getElementSizeBytes();
    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
    ptr += eSize * xoff;
    uint32_t size = count * eSize;

    if (size != sizeBytes) {
        LOGE("Allocation::subData called with mismatched size expected %i, got %i", size, sizeBytes);
        mType->dumpLOGV("type info");
        return;
    }

    if (mType->getElement()->getHasReferences()) {
        incRefs(data, count);
        decRefs(ptr, count);
    }

    memcpy(ptr, data, size);
    sendDirty();
    mUploadDefered = true;
}

void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff,
             uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes)
{
    uint32_t eSize = mType->getElementSizeBytes();
    uint32_t lineSize = eSize * w;
    uint32_t destW = mType->getDimX();

    const uint8_t *src = static_cast<const uint8_t *>(data);
    uint8_t *dst = static_cast<uint8_t *>(mPtr);
    dst += eSize * (xoff + yoff * destW);

    if ((lineSize * eSize * h) != sizeBytes) {
        rsAssert(!"Allocation::subData called with mismatched size");
        return;
    }

    for (uint32_t line=yoff; line < (yoff+h); line++) {
        if (mType->getElement()->getHasReferences()) {
            incRefs(src, w);
            decRefs(dst, w);
        }
        memcpy(dst, src, lineSize);
        src += lineSize;
        dst += destW * eSize;
    }
    sendDirty();
    mUploadDefered = true;
}

void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
             uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes)
{
}

void Allocation::subElementData(Context *rsc, uint32_t x, const void *data,
                                uint32_t cIdx, uint32_t sizeBytes)
{
    uint32_t eSize = mType->getElementSizeBytes();
    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
    ptr += eSize * x;

    if (cIdx >= mType->getElement()->getFieldCount()) {
        LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
        return;
    }

    if (x >= mType->getDimX()) {
        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
        return;
    }

    const Element * e = mType->getElement()->getField(cIdx);
    ptr += mType->getElement()->getFieldOffsetBytes(cIdx);

    if (sizeBytes != e->getSizeBytes()) {
        LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
        return;
    }

    if (e->getHasReferences()) {
        e->incRefs(data);
        e->decRefs(ptr);
    }

    memcpy(ptr, data, sizeBytes);
    sendDirty();
    mUploadDefered = true;
}

void Allocation::subElementData(Context *rsc, uint32_t x, uint32_t y,
                                const void *data, uint32_t cIdx, uint32_t sizeBytes)
{
    uint32_t eSize = mType->getElementSizeBytes();
    uint8_t * ptr = static_cast<uint8_t *>(mPtr);
    ptr += eSize * (x + y * mType->getDimX());

    if (x >= mType->getDimX()) {
        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
        return;
    }

    if (y >= mType->getDimY()) {
        LOGE("Error Allocation::subElementData X offset %i out of range.", x);
        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
        return;
    }

    if (cIdx >= mType->getElement()->getFieldCount()) {
        LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
        return;
    }

    const Element * e = mType->getElement()->getField(cIdx);
    ptr += mType->getElement()->getFieldOffsetBytes(cIdx);

    if (sizeBytes != e->getSizeBytes()) {
        LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
        rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
        return;
    }

    if (e->getHasReferences()) {
        e->incRefs(data);
        e->decRefs(ptr);
    }

    memcpy(ptr, data, sizeBytes);
    sendDirty();
    mUploadDefered = true;
}

void Allocation::addProgramToDirty(const Program *p)
{
    mToDirtyList.push(p);
}

void Allocation::removeProgramToDirty(const Program *p)
{
    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
        if (mToDirtyList[ct] == p) {
            mToDirtyList.removeAt(ct);
            return;
        }
    }
    rsAssert(0);
}

void Allocation::dumpLOGV(const char *prefix) const
{
    ObjectBase::dumpLOGV(prefix);

    String8 s(prefix);
    s.append(" type ");
    if (mType.get()) {
        mType->dumpLOGV(s.string());
    }

    LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i",
          prefix, mPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead);

    LOGV("%s allocation mIsTexture=%i mTextureID=%i, mIsVertexBuffer=%i, mBufferID=%i",
          prefix, mIsTexture, mTextureID, mIsVertexBuffer, mBufferID);

}

void Allocation::serialize(OStream *stream) const
{
    // Need to identify ourselves
    stream->addU32((uint32_t)getClassId());

    String8 name(getName());
    stream->addString(&name);

    // First thing we need to serialize is the type object since it will be needed
    // to initialize the class
    mType->serialize(stream);

    uint32_t dataSize = mType->getSizeBytes();
    // Write how much data we are storing
    stream->addU32(dataSize);
    // Now write the data
    stream->addByteArray(mPtr, dataSize);
}

Allocation *Allocation::createFromStream(Context *rsc, IStream *stream)
{
    // First make sure we are reading the correct object
    RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
    if(classID != RS_A3D_CLASS_ID_ALLOCATION) {
        LOGE("allocation loading skipped due to invalid class id\n");
        return NULL;
    }

    String8 name;
    stream->loadString(&name);

    Type *type = Type::createFromStream(rsc, stream);
    if(!type) {
        return NULL;
    }
    type->compute();

    // Number of bytes we wrote out for this allocation
    uint32_t dataSize = stream->loadU32();
    if(dataSize != type->getSizeBytes()) {
        LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
        ObjectBase::checkDelete(type);
        return NULL;
    }

    Allocation *alloc = new Allocation(rsc, type);
    alloc->setName(name.string(), name.size());

    // Read in all of our allocation data
    alloc->data(rsc, stream->getPtr() + stream->getPos(), dataSize);
    stream->reset(stream->getPos() + dataSize);

    return alloc;
}

void Allocation::sendDirty() const
{
    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
        mToDirtyList[ct]->forceDirty();
    }
}

void Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const
{
    const uint8_t *p = static_cast<const uint8_t *>(ptr);
    const Element *e = mType->getElement();
    uint32_t stride = e->getSizeBytes();

    p += stride * startOff;
    while (ct > 0) {
        e->incRefs(p);
        ct --;
        p += stride;
    }
}

void Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const
{
    const uint8_t *p = static_cast<const uint8_t *>(ptr);
    const Element *e = mType->getElement();
    uint32_t stride = e->getSizeBytes();

    p += stride * startOff;
    while (ct > 0) {
        e->decRefs(p);
        ct --;
        p += stride;
    }
}

void Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len)
{
}

void Allocation::resize1D(Context *rsc, uint32_t dimX)
{
    Type *t = mType->cloneAndResize1D(rsc, dimX);

    uint32_t oldDimX = mType->getDimX();
    if (dimX == oldDimX) {
        return;
    }

    if (dimX < oldDimX) {
        decRefs(mPtr, oldDimX - dimX, dimX);
    }
    mPtr = realloc(mPtr, t->getSizeBytes());

    if (dimX > oldDimX) {
        const Element *e = mType->getElement();
        uint32_t stride = e->getSizeBytes();
        memset(((uint8_t *)mPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
    }
    mType.set(t);
}

void Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY)
{
    LOGE("not implemented");
}

/////////////////
//


namespace android {
namespace renderscript {

void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel)
{
    Allocation *alloc = static_cast<Allocation *>(va);
    alloc->deferedUploadToTexture(rsc, genmip, baseMipLevel);
}

void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va)
{
    Allocation *alloc = static_cast<Allocation *>(va);
    alloc->deferedUploadToBufferObject(rsc);
}

static void mip565(const Adapter2D &out, const Adapter2D &in)
{
    uint32_t w = out.getDimX();
    uint32_t h = out.getDimY();

    for (uint32_t y=0; y < h; y++) {
        uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y));
        const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2));
        const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1));

        for (uint32_t x=0; x < w; x++) {
            *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
            oPtr ++;
            i1 += 2;
            i2 += 2;
        }
    }
}

static void mip8888(const Adapter2D &out, const Adapter2D &in)
{
    uint32_t w = out.getDimX();
    uint32_t h = out.getDimY();

    for (uint32_t y=0; y < h; y++) {
        uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y));
        const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2));
        const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1));

        for (uint32_t x=0; x < w; x++) {
            *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
            oPtr ++;
            i1 += 2;
            i2 += 2;
        }
    }
}

static void mip8(const Adapter2D &out, const Adapter2D &in)
{
    uint32_t w = out.getDimX();
    uint32_t h = out.getDimY();

    for (uint32_t y=0; y < h; y++) {
        uint8_t *oPtr = static_cast<uint8_t *>(out.getElement(0, y));
        const uint8_t *i1 = static_cast<uint8_t *>(in.getElement(0, y*2));
        const uint8_t *i2 = static_cast<uint8_t *>(in.getElement(0, y*2+1));

        for (uint32_t x=0; x < w; x++) {
            *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
            oPtr ++;
            i1 += 2;
            i2 += 2;
        }
    }
}

static void mip(const Adapter2D &out, const Adapter2D &in)
{
    switch(out.getBaseType()->getElement()->getSizeBits()) {
    case 32:
        mip8888(out, in);
        break;
    case 16:
        mip565(out, in);
        break;
    case 8:
        mip8(out, in);
        break;

    }

}

typedef void (*ElementConverter_t)(void *dst, const void *src, uint32_t count);

static void elementConverter_cpy_16(void *dst, const void *src, uint32_t count)
{
    memcpy(dst, src, count * 2);
}
static void elementConverter_cpy_8(void *dst, const void *src, uint32_t count)
{
    memcpy(dst, src, count);
}
static void elementConverter_cpy_32(void *dst, const void *src, uint32_t count)
{
    memcpy(dst, src, count * 4);
}


static void elementConverter_888_to_565(void *dst, const void *src, uint32_t count)
{
    uint16_t *d = static_cast<uint16_t *>(dst);
    const uint8_t *s = static_cast<const uint8_t *>(src);

    while(count--) {
        *d = rs888to565(s[0], s[1], s[2]);
        d++;
        s+= 3;
    }
}

static void elementConverter_8888_to_565(void *dst, const void *src, uint32_t count)
{
    uint16_t *d = static_cast<uint16_t *>(dst);
    const uint8_t *s = static_cast<const uint8_t *>(src);

    while(count--) {
        *d = rs888to565(s[0], s[1], s[2]);
        d++;
        s+= 4;
    }
}

static ElementConverter_t pickConverter(const Element *dst, const Element *src)
{
    GLenum srcGLType = src->getComponent().getGLType();
    GLenum srcGLFmt = src->getComponent().getGLFormat();
    GLenum dstGLType = dst->getComponent().getGLType();
    GLenum dstGLFmt = dst->getComponent().getGLFormat();

    if (srcGLFmt == dstGLFmt && srcGLType == dstGLType) {
        switch(dst->getSizeBytes()) {
        case 4:
            return elementConverter_cpy_32;
        case 2:
            return elementConverter_cpy_16;
        case 1:
            return elementConverter_cpy_8;
        }
    }

    if (srcGLType == GL_UNSIGNED_BYTE &&
        srcGLFmt == GL_RGB &&
        dstGLType == GL_UNSIGNED_SHORT_5_6_5 &&
        dstGLFmt == GL_RGB) {

        return elementConverter_888_to_565;
    }

    if (srcGLType == GL_UNSIGNED_BYTE &&
        srcGLFmt == GL_RGBA &&
        dstGLType == GL_UNSIGNED_SHORT_5_6_5 &&
        dstGLFmt == GL_RGB) {

        return elementConverter_8888_to_565;
    }

    LOGE("pickConverter, unsuported combo, src %p,  dst %p", src, dst);
    LOGE("pickConverter, srcGLType = %x,  srcGLFmt = %x", srcGLType, srcGLFmt);
    LOGE("pickConverter, dstGLType = %x,  dstGLFmt = %x", dstGLType, dstGLFmt);
    src->dumpLOGV("SRC ");
    dst->dumpLOGV("DST ");
    return 0;
}

#ifndef ANDROID_RS_BUILD_FOR_HOST

RsAllocation rsi_AllocationCreateBitmapRef(Context *rsc, RsType vtype,
                                           void *bmp, void *callbackData, RsBitmapCallback_t callback)
{
    const Type * type = static_cast<const Type *>(vtype);
    Allocation * alloc = new Allocation(rsc, type, bmp, callbackData, callback);
    alloc->incUserRef();
    return alloc;
}

void rsi_AllocationUpdateFromBitmap(Context *rsc, RsAllocation va, RsElement _src, const void *data)
{
    Allocation *texAlloc = static_cast<Allocation *>(va);
    const Element *src = static_cast<const Element *>(_src);
    const Element *dst = texAlloc->getType()->getElement();
    uint32_t w = texAlloc->getType()->getDimX();
    uint32_t h = texAlloc->getType()->getDimY();
    bool genMips = texAlloc->getType()->getDimLOD();

    ElementConverter_t cvt = pickConverter(dst, src);
    if (cvt) {
        cvt(texAlloc->getPtr(), data, w * h);
        if (genMips) {
            Adapter2D adapt(rsc, texAlloc);
            Adapter2D adapt2(rsc, texAlloc);
            for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
                adapt.setLOD(lod);
                adapt2.setLOD(lod + 1);
                mip(adapt2, adapt);
            }
        }
    } else {
        rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format");
    }
}

void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes)
{
    Allocation *a = static_cast<Allocation *>(va);
    a->data(rsc, data, sizeBytes);
}

void rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes)
{
    Allocation *a = static_cast<Allocation *>(va);
    a->subData(rsc, xoff, count, data, sizeBytes);
}

void rsi_Allocation2DSubElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, const void *data, uint32_t eoff, uint32_t sizeBytes)
{
    Allocation *a = static_cast<Allocation *>(va);
    a->subElementData(rsc, x, y, data, eoff, sizeBytes);
}

void rsi_Allocation1DSubElementData(Context *rsc, RsAllocation va, uint32_t x, const void *data, uint32_t eoff, uint32_t sizeBytes)
{
    Allocation *a = static_cast<Allocation *>(va);
    a->subElementData(rsc, x, data, eoff, sizeBytes);
}

void rsi_Allocation2DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes)
{
    Allocation *a = static_cast<Allocation *>(va);
    a->subData(rsc, xoff, yoff, w, h, data, sizeBytes);
}

void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data)
{
    Allocation *a = static_cast<Allocation *>(va);
    a->read(data);
}

void rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX)
{
    Allocation *a = static_cast<Allocation *>(va);
    a->resize1D(rsc, dimX);
}

void rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY)
{
    Allocation *a = static_cast<Allocation *>(va);
    a->resize2D(rsc, dimX, dimY);
}

#endif //ANDROID_RS_BUILD_FOR_HOST

}
}

const void * rsaAllocationGetType(RsContext con, RsAllocation va)
{
    Allocation *a = static_cast<Allocation *>(va);
    a->getType()->incUserRef();

    return a->getType();
}

RsAllocation rsaAllocationCreateTyped(RsContext con, RsType vtype)
{
    Context *rsc = static_cast<Context *>(con);
    Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype));
    alloc->incUserRef();
    return alloc;
}

RsAllocation rsaAllocationCreateFromBitmap(RsContext con, uint32_t w, uint32_t h, RsElement _dst, RsElement _src,  bool genMips, const void *data)
{
    Context *rsc = static_cast<Context *>(con);
    const Element *src = static_cast<const Element *>(_src);
    const Element *dst = static_cast<const Element *>(_dst);

    //LOGE("%p rsi_AllocationCreateFromBitmap %i %i %i", rsc, w, h, genMips);
    RsDimension dims[] = {RS_DIMENSION_X, RS_DIMENSION_Y, RS_DIMENSION_LOD};
    uint32_t dimValues[] = {w, h, genMips};
    RsType type = rsaTypeCreate(rsc, _dst, 3, dims, dimValues);

    RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, type);
    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
    if (texAlloc == NULL) {
        LOGE("Memory allocation failure");
        return NULL;
    }

    ElementConverter_t cvt = pickConverter(dst, src);
    if (cvt) {
        cvt(texAlloc->getPtr(), data, w * h);
        if (genMips) {
            Adapter2D adapt(rsc, texAlloc);
            Adapter2D adapt2(rsc, texAlloc);
            for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
                adapt.setLOD(lod);
                adapt2.setLOD(lod + 1);
                mip(adapt2, adapt);
            }
        }
    } else {
        rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format");
    }

    return texAlloc;
}
