/*
 * Copyright (C) 2011 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 "rsCpuCore.h"
#include "rsCpuScript.h"
#include "rsScriptGroup.h"
#include "rsCpuScriptGroup.h"

using namespace android;
using namespace android::renderscript;

CpuScriptGroupImpl::CpuScriptGroupImpl(RsdCpuReferenceImpl *ctx, const ScriptGroupBase *sg) {
    mCtx = ctx;
    mSG = (ScriptGroup*)sg;
}

CpuScriptGroupImpl::~CpuScriptGroupImpl() {

}

bool CpuScriptGroupImpl::init() {
    return true;
}

void CpuScriptGroupImpl::setInput(const ScriptKernelID *kid, Allocation *a) {
}

void CpuScriptGroupImpl::setOutput(const ScriptKernelID *kid, Allocation *a) {
}


typedef void (*ScriptGroupRootFunc_t)(const RsExpandKernelDriverInfo *kinfo,
                                      uint32_t xstart, uint32_t xend,
                                      uint32_t outstep);

void CpuScriptGroupImpl::scriptGroupRoot(const RsExpandKernelDriverInfo *kinfo,
                                         uint32_t xstart, uint32_t xend,
                                         uint32_t outstep) {


    const ScriptList *sl             = (const ScriptList *)kinfo->usr;
    RsExpandKernelDriverInfo *mkinfo = const_cast<RsExpandKernelDriverInfo *>(kinfo);

    const uint32_t oldInStride = mkinfo->inStride[0];

    for (size_t ct = 0; ct < sl->count; ct++) {
        ScriptGroupRootFunc_t func;
        func          = (ScriptGroupRootFunc_t)sl->fnPtrs[ct];
        mkinfo->usr   = sl->usrPtrs[ct];

        if (sl->ins[ct]) {
            rsAssert(kinfo->inLen == 1);

            mkinfo->inPtr[0] = (const uint8_t *)sl->ins[ct]->mHal.drvState.lod[0].mallocPtr;

            mkinfo->inStride[0] = sl->ins[ct]->mHal.state.elementSizeBytes;

            if (sl->inExts[ct]) {
                mkinfo->inPtr[0] =
                  (mkinfo->inPtr[0] +
                   sl->ins[ct]->mHal.drvState.lod[0].stride * kinfo->current.y);

            } else if (sl->ins[ct]->mHal.drvState.lod[0].dimY > kinfo->lid) {
                mkinfo->inPtr[0] =
                  (mkinfo->inPtr[0] +
                   sl->ins[ct]->mHal.drvState.lod[0].stride * kinfo->lid);
            }

        } else {
            rsAssert(kinfo->inLen == 0);

            mkinfo->inPtr[0]     = nullptr;
            mkinfo->inStride[0]  = 0;
        }

        uint32_t ostep;
        if (sl->outs[ct]) {
            rsAssert(kinfo->outLen == 1);

            mkinfo->outPtr[0] =
              (uint8_t *)sl->outs[ct]->mHal.drvState.lod[0].mallocPtr;

            ostep = sl->outs[ct]->mHal.state.elementSizeBytes;

            if (sl->outExts[ct]) {
                mkinfo->outPtr[0] =
                  mkinfo->outPtr[0] +
                  sl->outs[ct]->mHal.drvState.lod[0].stride * kinfo->current.y;

            } else if (sl->outs[ct]->mHal.drvState.lod[0].dimY > kinfo->lid) {
                mkinfo->outPtr[0] =
                  mkinfo->outPtr[0] +
                  sl->outs[ct]->mHal.drvState.lod[0].stride * kinfo->lid;
            }
        } else {
            rsAssert(kinfo->outLen == 0);

            mkinfo->outPtr[0] = nullptr;
            ostep             = 0;
        }

        //ALOGE("kernel %i %p,%p  %p,%p", ct, mp->ptrIn, mp->in, mp->ptrOut, mp->out);
        func(kinfo, xstart, xend, ostep);
    }
    //ALOGE("script group root");

    mkinfo->inStride[0] = oldInStride;
    mkinfo->usr         = sl;
}



void CpuScriptGroupImpl::execute() {
    Vector<Allocation *> ins;
    Vector<bool> inExts;
    Vector<Allocation *> outs;
    Vector<bool> outExts;
    Vector<const ScriptKernelID *> kernels;
    bool fieldDep = false;

    for (size_t ct=0; ct < mSG->mNodes.size(); ct++) {
        ScriptGroup::Node *n = mSG->mNodes[ct];
        Script *s = n->mKernels[0]->mScript;
        if (s->hasObjectSlots()) {
            // Disable the ScriptGroup optimization if we have global RS
            // objects that might interfere between kernels.
            fieldDep = true;
        }

        //ALOGE("node %i, order %i, in %i out %i", (int)ct, n->mOrder, (int)n->mInputs.size(), (int)n->mOutputs.size());

        for (size_t ct2=0; ct2 < n->mInputs.size(); ct2++) {
            if (n->mInputs[ct2]->mDstField.get() && n->mInputs[ct2]->mDstField->mScript) {
                //ALOGE("field %p %zu", n->mInputs[ct2]->mDstField->mScript, n->mInputs[ct2]->mDstField->mSlot);
                s->setVarObj(n->mInputs[ct2]->mDstField->mSlot, n->mInputs[ct2]->mAlloc.get());
            }
        }

        for (size_t ct2=0; ct2 < n->mKernels.size(); ct2++) {
            const ScriptKernelID *k = n->mKernels[ct2];
            Allocation *ain = nullptr;
            Allocation *aout = nullptr;
            bool inExt = false;
            bool outExt = false;

            for (size_t ct3=0; ct3 < n->mInputs.size(); ct3++) {
                if (n->mInputs[ct3]->mDstKernel.get() == k) {
                    ain = n->mInputs[ct3]->mAlloc.get();
                    break;
                }
            }
            if (ain == nullptr) {
                for (size_t ct3=0; ct3 < mSG->mInputs.size(); ct3++) {
                    if (mSG->mInputs[ct3]->mKernel == k) {
                        ain = mSG->mInputs[ct3]->mAlloc.get();
                        inExt = true;
                        break;
                    }
                }
            }

            for (size_t ct3=0; ct3 < n->mOutputs.size(); ct3++) {
                if (n->mOutputs[ct3]->mSource.get() == k) {
                    aout = n->mOutputs[ct3]->mAlloc.get();
                    if(n->mOutputs[ct3]->mDstField.get() != nullptr) {
                        fieldDep = true;
                    }
                    break;
                }
            }
            if (aout == nullptr) {
                for (size_t ct3=0; ct3 < mSG->mOutputs.size(); ct3++) {
                    if (mSG->mOutputs[ct3]->mKernel == k) {
                        aout = mSG->mOutputs[ct3]->mAlloc.get();
                        outExt = true;
                        break;
                    }
                }
            }

            rsAssert((k->mHasKernelOutput == (aout != nullptr)) &&
                     (k->mHasKernelInput == (ain != nullptr)));

            ins.add(ain);
            inExts.add(inExt);
            outs.add(aout);
            outExts.add(outExt);
            kernels.add(k);
        }

    }

    MTLaunchStruct mtls;

    if (fieldDep) {
        for (size_t ct=0; ct < ins.size(); ct++) {
            Script *s = kernels[ct]->mScript;
            RsdCpuScriptImpl *si = (RsdCpuScriptImpl *)mCtx->lookupScript(s);
            uint32_t slot = kernels[ct]->mSlot;

            uint32_t inLen;
            const Allocation **ains;

            if (ins[ct] == nullptr) {
                inLen = 0;
                ains  = nullptr;

            } else {
                inLen = 1;
                ains  = const_cast<const Allocation**>(&ins[ct]);
            }

            bool launchOK = si->forEachMtlsSetup(ains, inLen, outs[ct], nullptr, 0, nullptr, &mtls);

            si->forEachKernelSetup(slot, &mtls);
            si->preLaunch(slot, ains, inLen, outs[ct], mtls.fep.usr,
                          mtls.fep.usrLen, nullptr);

            if (launchOK) {
                mCtx->launchThreads(ains, inLen, outs[ct], nullptr, &mtls);
            }

            si->postLaunch(slot, ains, inLen, outs[ct], nullptr, 0, nullptr);
        }
    } else {
        ScriptList sl;
        sl.ins = ins.array();
        sl.outs = outs.array();
        sl.kernels = kernels.array();
        sl.count = kernels.size();

        uint32_t inLen;
        const Allocation **ains;

        if (ins[0] == nullptr) {
            inLen = 0;
            ains  = nullptr;

        } else {
            inLen = 1;
            ains  = const_cast<const Allocation**>(&ins[0]);
        }

        Vector<const void *> usrPtrs;
        Vector<const void *> fnPtrs;
        Vector<uint32_t> sigs;
        for (size_t ct=0; ct < kernels.size(); ct++) {
            Script *s = kernels[ct]->mScript;
            RsdCpuScriptImpl *si = (RsdCpuScriptImpl *)mCtx->lookupScript(s);

            si->forEachKernelSetup(kernels[ct]->mSlot, &mtls);
            fnPtrs.add((void *)mtls.kernel);
            usrPtrs.add(mtls.fep.usr);
            sigs.add(mtls.fep.usrLen);
            si->preLaunch(kernels[ct]->mSlot, ains, inLen, outs[ct],
                          mtls.fep.usr, mtls.fep.usrLen, nullptr);
        }
        sl.sigs = sigs.array();
        sl.usrPtrs = usrPtrs.array();
        sl.fnPtrs = fnPtrs.array();
        sl.inExts = inExts.array();
        sl.outExts = outExts.array();

        Script *s = kernels[0]->mScript;
        RsdCpuScriptImpl *si = (RsdCpuScriptImpl *)mCtx->lookupScript(s);

        if (si->forEachMtlsSetup(ains, inLen, outs[0], nullptr, 0, nullptr, &mtls)) {

            mtls.script = nullptr;
            mtls.kernel = (void (*)())&scriptGroupRoot;
            mtls.fep.usr = &sl;

            mCtx->launchThreads(ains, inLen, outs[0], nullptr, &mtls);
        }

        for (size_t ct=0; ct < kernels.size(); ct++) {
            Script *s = kernels[ct]->mScript;
            RsdCpuScriptImpl *si = (RsdCpuScriptImpl *)mCtx->lookupScript(s);
            si->postLaunch(kernels[ct]->mSlot, ains, inLen, outs[ct], nullptr, 0,
                           nullptr);
        }
    }
}
