/*
 * 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 "rsProgramRaster.h"

using namespace android;
using namespace android::renderscript;


ProgramRaster::ProgramRaster(Context *rsc, bool pointSprite, RsCullMode cull)
    : ProgramBase(rsc) {

    memset(&mHal, 0, sizeof(mHal));
    mHal.state.pointSprite = pointSprite;
    mHal.state.cull = cull;
    rsc->mHal.funcs.raster.init(rsc, this);
}

void ProgramRaster::preDestroy() const {
    auto &rasters = mRSC->mStateRaster.mRasterPrograms;

    for (auto prIter = rasters.begin(), endIter = rasters.end();
         prIter != endIter; prIter++) {

        if (this == *prIter) {
            rasters.erase(prIter);
            return;
        }
    }
}

ProgramRaster::~ProgramRaster() {
    mRSC->mHal.funcs.raster.destroy(mRSC, this);
}

void ProgramRaster::setup(const Context *rsc, ProgramRasterState *state) {
    if (state->mLast.get() == this && !mDirty) {
        return;
    }
    state->mLast.set(this);
    mDirty = false;

    rsc->mHal.funcs.raster.setActive(rsc, this);
}

void ProgramRaster::serialize(Context *rsc, OStream *stream) const {
}

ProgramRaster *ProgramRaster::createFromStream(Context *rsc, IStream *stream) {
    return nullptr;
}

ProgramRasterState::ProgramRasterState() {
}

ProgramRasterState::~ProgramRasterState() {
}

void ProgramRasterState::init(Context *rsc) {
    mDefault.set(ProgramRaster::getProgramRaster(rsc, false, RS_CULL_BACK).get());
}

void ProgramRasterState::deinit(Context *rsc) {
    mDefault.clear();
    mLast.clear();
}

ObjectBaseRef<ProgramRaster> ProgramRaster::getProgramRaster(Context *rsc,
                                                             bool pointSprite,
                                                             RsCullMode cull) {
    ObjectBaseRef<ProgramRaster> returnRef;
    ObjectBase::asyncLock();
    for (uint32_t ct = 0; ct < rsc->mStateRaster.mRasterPrograms.size(); ct++) {
        ProgramRaster *existing = rsc->mStateRaster.mRasterPrograms[ct];
        if (existing->mHal.state.pointSprite != pointSprite) continue;
        if (existing->mHal.state.cull != cull) continue;
        returnRef.set(existing);
        ObjectBase::asyncUnlock();
        return returnRef;
    }
    ObjectBase::asyncUnlock();

    ProgramRaster *pr = new ProgramRaster(rsc, pointSprite, cull);
    returnRef.set(pr);

    ObjectBase::asyncLock();
    rsc->mStateRaster.mRasterPrograms.push_back(pr);
    ObjectBase::asyncUnlock();

    return returnRef;
}

namespace android {
namespace renderscript {

RsProgramRaster rsi_ProgramRasterCreate(Context * rsc, bool pointSprite, RsCullMode cull) {
    ObjectBaseRef<ProgramRaster> pr = ProgramRaster::getProgramRaster(rsc, pointSprite, cull);
    pr->incUserRef();
    return pr.get();
}

}
}
