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

using namespace android;
using namespace android::renderscript;


Adapter1D::Adapter1D()
{
    reset();
}

Adapter1D::Adapter1D(Allocation *a)
{
    reset();
    setAllocation(a);
}

void Adapter1D::reset()
{
    mY = 0;
    mZ = 0;
    mLOD = 0;
    mFace = 0;
}

void * Adapter1D::getElement(uint32_t x)
{
    rsAssert(mAllocation.get());
    rsAssert(mAllocation->getPtr());
    rsAssert(mAllocation->getType());
    uint8_t * ptr = static_cast<uint8_t *>(mAllocation->getPtr());
    ptr += mAllocation->getType()->getLODOffset(mLOD, x, mY);
    return ptr;
}

void Adapter1D::subData(uint32_t xoff, uint32_t count, const void *data)
{
    if (mAllocation.get() && mAllocation.get()->getType()) {
        void *ptr = getElement(xoff);
        count *= mAllocation.get()->getType()->getElementSizeBytes();
        memcpy(ptr, data, count);
    }
}

void Adapter1D::data(const void *data)
{
    memcpy(getElement(0), 
           data, 
           mAllocation.get()->getType()->getSizeBytes());
}

namespace android {
namespace renderscript {

RsAdapter1D rsi_Adapter1DCreate(Context *rsc)
{
    return new Adapter1D();
}

void rsi_Adapter1DDestroy(Context *rsc, RsAdapter1D va)
{
    Adapter1D * a = static_cast<Adapter1D *>(va);
    a->decRef();
}

void rsi_Adapter1DBindAllocation(Context *rsc, RsAdapter1D va, RsAllocation valloc)
{
    Adapter1D * a = static_cast<Adapter1D *>(va);
    Allocation * alloc = static_cast<Allocation *>(valloc);
    a->setAllocation(alloc);
}

void rsi_Adapter1DSetConstraint(Context *rsc, RsAdapter1D va, RsDimension dim, uint32_t value)
{
    Adapter1D * a = static_cast<Adapter1D *>(va);
    switch(dim) {
    case RS_DIMENSION_X:
        rsAssert(!"Cannot contrain X in an 1D adapter");
        return;
    case RS_DIMENSION_Y:
        a->setY(value);
        break;
    case RS_DIMENSION_Z:
        a->setZ(value);
        break;
    case RS_DIMENSION_LOD:
        a->setLOD(value);
        break;
    case RS_DIMENSION_FACE:
        a->setFace(value);
        break;
    default:
        rsAssert(!"Unimplemented constraint");
        return;
    }
}

void rsi_Adapter1DSubData(Context *rsc, RsAdapter1D va, uint32_t xoff, uint32_t count, const void *data)
{
    Adapter1D * a = static_cast<Adapter1D *>(va);
    a->subData(xoff, count, data);
}

void rsi_Adapter1DData(Context *rsc, RsAdapter1D va, const void *data)
{
    Adapter1D * a = static_cast<Adapter1D *>(va);
    a->data(data);
}

}
}

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

Adapter2D::Adapter2D()
{
    reset();
}

Adapter2D::Adapter2D(Allocation *a)
{
    reset();
    setAllocation(a);
}

void Adapter2D::reset()
{
    mZ = 0;
    mLOD = 0;
    mFace = 0;
}

void * Adapter2D::getElement(uint32_t x, uint32_t y) const
{
    rsAssert(mAllocation.get());
    rsAssert(mAllocation->getPtr());
    rsAssert(mAllocation->getType());
    uint8_t * ptr = static_cast<uint8_t *>(mAllocation->getPtr());
    ptr += mAllocation->getType()->getLODOffset(mLOD, x, y);
    return ptr;
}

void Adapter2D::subData(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data)
{
    rsAssert(mAllocation.get());
    rsAssert(mAllocation->getPtr());
    rsAssert(mAllocation->getType());

    uint32_t eSize = mAllocation.get()->getType()->getElementSizeBytes();
    uint32_t lineSize = eSize * w;
    uint32_t destW = getDimX();

    const uint8_t *src = static_cast<const uint8_t *>(data);
    for (uint32_t line=yoff; line < (yoff+h); line++) {
        memcpy(getElement(xoff, line), src, lineSize);
        src += lineSize;
    }
}

void Adapter2D::data(const void *data)
{
    memcpy(getElement(0,0), 
           data, 
           mAllocation.get()->getType()->getSizeBytes());
}



namespace android {
namespace renderscript {

RsAdapter2D rsi_Adapter2DCreate(Context *rsc)
{
    return new Adapter2D();
}

void rsi_Adapter2DDestroy(Context *rsc, RsAdapter2D va)
{
    Adapter2D * a = static_cast<Adapter2D *>(va);
    a->decRef();
}

void rsi_Adapter2DBindAllocation(Context *rsc, RsAdapter2D va, RsAllocation valloc)
{
    Adapter2D * a = static_cast<Adapter2D *>(va);
    Allocation * alloc = static_cast<Allocation *>(valloc);
    a->setAllocation(alloc);
}

void rsi_Adapter2DSetConstraint(Context *rsc, RsAdapter2D va, RsDimension dim, uint32_t value)
{
    Adapter2D * a = static_cast<Adapter2D *>(va);
    switch(dim) {
    case RS_DIMENSION_X:
        rsAssert(!"Cannot contrain X in an 2D adapter");
        return;
    case RS_DIMENSION_Y:
        rsAssert(!"Cannot contrain Y in an 2D adapter");
        break;
    case RS_DIMENSION_Z:
        a->setZ(value);
        break;
    case RS_DIMENSION_LOD:
        a->setLOD(value);
        break;
    case RS_DIMENSION_FACE:
        a->setFace(value);
        break;
    default:
        rsAssert(!"Unimplemented constraint");
        return;
    }
}

void rsi_Adapter2DData(Context *rsc, RsAdapter2D va, const void *data)
{
    Adapter2D * a = static_cast<Adapter2D *>(va);
    a->data(data);
}

void rsi_Adapter2DSubData(Context *rsc, RsAdapter2D va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data)
{
    Adapter2D * a = static_cast<Adapter2D *>(va);
    a->subData(xoff, yoff, w, h, data);
}

}
}
