/*
 * 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.
 */

#include "rsContext.h"

#include <GLES/gl.h>
#include <GLES2/gl2.h>
#include <GLES/glext.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 (!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)
{
    mAllocFile = __FILE__;
    mAllocLine = __LINE__;
    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;
    }

    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;
        }
    }
    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));
        glTexImage2D(GL_TEXTURE_2D, lod, format,
                     adapt.getDimX(), adapt.getDimY(),
                     0, format, type, ptr);
    }
    if (mTextureGenMipmap) {
        glGenerateMipmap(GL_TEXTURE_2D);
    }

}

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

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


void Allocation::data(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;
    }
    memcpy(mPtr, data, size);
    sendDirty();
    mUploadDefered = true;
}

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

void Allocation::subData(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;
    }
    memcpy(ptr, data, size);
    sendDirty();
    mUploadDefered = true;
}

void Allocation::subData(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++) {
        uint8_t * ptr = static_cast<uint8_t *>(mPtr);
        memcpy(dst, src, lineSize);
        src += lineSize;
        dst += destW * eSize;
    }
    sendDirty();
    mUploadDefered = true;
}

void Allocation::subData(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::addProgramToDirty(const Program *p)
{
    mToDirtyList.add(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::sendDirty() const
{
    for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
        mToDirtyList[ct]->forceDirty();
    }
}

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


namespace android {
namespace renderscript {

RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype)
{
    const Type * type = static_cast<const Type *>(vtype);

    Allocation * alloc = new Allocation(rsc, type);
    alloc->incUserRef();
    return alloc;
}

RsAllocation rsi_AllocationCreateSized(Context *rsc, RsElement e, size_t count)
{
    Type * type = new Type(rsc);
    type->setDimX(count);
    type->setElement(static_cast<Element *>(e));
    type->compute();
    return rsi_AllocationCreateTyped(rsc, type);
}

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 &&
        dstGLType == GL_RGB) {

        return elementConverter_888_to_565;
    }

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

        return elementConverter_8888_to_565;
    }

    LOGE("pickConverter, unsuported combo, src %p,  dst %p", src, dst);
    return 0;
}

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

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

    // Check for pow2 on pre es 2.0 versions.
    rsAssert(rsc->checkVersion2_0() || (!(w & (w-1)) && !(h & (h-1))));

    //LOGE("rsi_AllocationCreateFromBitmap %i %i %i %i %i", w, h, dstFmt, srcFmt, genMips);
    rsi_TypeBegin(rsc, _dst);
    rsi_TypeAdd(rsc, RS_DIMENSION_X, w);
    rsi_TypeAdd(rsc, RS_DIMENSION_Y, h);
    if (genMips) {
        rsi_TypeAdd(rsc, RS_DIMENSION_LOD, 1);
    }
    RsType type = rsi_TypeCreate(rsc);

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

    ElementConverter_t cvt = pickConverter(dst, src);
    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);
        }
    }

    return texAlloc;
}

RsAllocation rsi_AllocationCreateFromBitmapBoxed(Context *rsc, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data)
{
    const Element *srcE = static_cast<const Element *>(_src);
    const Element *dstE = static_cast<const Element *>(_dst);
    uint32_t w2 = rsHigherPow2(w);
    uint32_t h2 = rsHigherPow2(h);

    if ((w2 == w) && (h2 == h)) {
        return rsi_AllocationCreateFromBitmap(rsc, w, h, _dst, _src, genMips, data);
    }

    uint32_t bpp = srcE->getSizeBytes();
    size_t size = w2 * h2 * bpp;
    uint8_t *tmp = static_cast<uint8_t *>(malloc(size));
    memset(tmp, 0, size);

    const uint8_t * src = static_cast<const uint8_t *>(data);
    for (uint32_t y = 0; y < h; y++) {
        uint8_t * ydst = &tmp[(y + ((h2 - h) >> 1)) * w2 * bpp];
        memcpy(&ydst[((w2 - w) >> 1) * bpp], src, w * bpp);
        src += w * bpp;
    }

    RsAllocation ret = rsi_AllocationCreateFromBitmap(rsc, w2, h2, _dst, _src, genMips, tmp);
    free(tmp);
    return ret;
}

void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes)
{
    Allocation *a = static_cast<Allocation *>(va);
    a->data(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(xoff, count, data, 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(xoff, yoff, w, h, data, sizeBytes);
}

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


}
}
