/*
 * 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 "rsdCore.h"
#include "rsdProgramStore.h"

#include "rsContext.h"
#include "rsProgramStore.h"

#include <GLES/gl.h>
#include <GLES/glext.h>


using namespace android;
using namespace android::renderscript;

struct DrvProgramStore {
    GLenum blendSrc;
    GLenum blendDst;
    bool blendEnable;

    GLenum depthFunc;
    bool depthTestEnable;
};

bool rsdProgramStoreInit(const Context *rsc, const ProgramStore *ps) {
    DrvProgramStore *drv = (DrvProgramStore *)calloc(1, sizeof(DrvProgramStore));
    if (drv == nullptr) {
        return false;
    }

    ps->mHal.drv = drv;
    drv->depthTestEnable = true;

    switch (ps->mHal.state.depthFunc) {
    case RS_DEPTH_FUNC_ALWAYS:
        drv->depthTestEnable = false;
        drv->depthFunc = GL_ALWAYS;
        break;
    case RS_DEPTH_FUNC_LESS:
        drv->depthFunc = GL_LESS;
        break;
    case RS_DEPTH_FUNC_LEQUAL:
        drv->depthFunc = GL_LEQUAL;
        break;
    case RS_DEPTH_FUNC_GREATER:
        drv->depthFunc = GL_GREATER;
        break;
    case RS_DEPTH_FUNC_GEQUAL:
        drv->depthFunc = GL_GEQUAL;
        break;
    case RS_DEPTH_FUNC_EQUAL:
        drv->depthFunc = GL_EQUAL;
        break;
    case RS_DEPTH_FUNC_NOTEQUAL:
        drv->depthFunc = GL_NOTEQUAL;
        break;
    default:
        ALOGE("Unknown depth function.");
        goto error;
    }



    drv->blendEnable = true;
    if ((ps->mHal.state.blendSrc == RS_BLEND_SRC_ONE) &&
        (ps->mHal.state.blendDst == RS_BLEND_DST_ZERO)) {
        drv->blendEnable = false;
    }

    switch (ps->mHal.state.blendSrc) {
    case RS_BLEND_SRC_ZERO:
        drv->blendSrc = GL_ZERO;
        break;
    case RS_BLEND_SRC_ONE:
        drv->blendSrc = GL_ONE;
        break;
    case RS_BLEND_SRC_DST_COLOR:
        drv->blendSrc = GL_DST_COLOR;
        break;
    case RS_BLEND_SRC_ONE_MINUS_DST_COLOR:
        drv->blendSrc = GL_ONE_MINUS_DST_COLOR;
        break;
    case RS_BLEND_SRC_SRC_ALPHA:
        drv->blendSrc = GL_SRC_ALPHA;
        break;
    case RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA:
        drv->blendSrc = GL_ONE_MINUS_SRC_ALPHA;
        break;
    case RS_BLEND_SRC_DST_ALPHA:
        drv->blendSrc = GL_DST_ALPHA;
        break;
    case RS_BLEND_SRC_ONE_MINUS_DST_ALPHA:
        drv->blendSrc = GL_ONE_MINUS_DST_ALPHA;
        break;
    case RS_BLEND_SRC_SRC_ALPHA_SATURATE:
        drv->blendSrc = GL_SRC_ALPHA_SATURATE;
        break;
    default:
        rsc->setError(RS_ERROR_FATAL_DRIVER, "Unknown blend src mode.");
        goto error;
    }

    switch (ps->mHal.state.blendDst) {
    case RS_BLEND_DST_ZERO:
        drv->blendDst = GL_ZERO;
        break;
    case RS_BLEND_DST_ONE:
        drv->blendDst = GL_ONE;
        break;
    case RS_BLEND_DST_SRC_COLOR:
        drv->blendDst = GL_SRC_COLOR;
        break;
    case RS_BLEND_DST_ONE_MINUS_SRC_COLOR:
        drv->blendDst = GL_ONE_MINUS_SRC_COLOR;
        break;
    case RS_BLEND_DST_SRC_ALPHA:
        drv->blendDst = GL_SRC_ALPHA;
        break;
    case RS_BLEND_DST_ONE_MINUS_SRC_ALPHA:
        drv->blendDst = GL_ONE_MINUS_SRC_ALPHA;
        break;
    case RS_BLEND_DST_DST_ALPHA:
        drv->blendDst = GL_DST_ALPHA;
        break;
    case RS_BLEND_DST_ONE_MINUS_DST_ALPHA:
        drv->blendDst = GL_ONE_MINUS_DST_ALPHA;
        break;
    default:
        rsc->setError(RS_ERROR_FATAL_DRIVER, "Unknown blend dst mode.");
        goto error;
    }

    return true;

error:
    free(drv);
    ps->mHal.drv = nullptr;
    return false;
}

void rsdProgramStoreSetActive(const Context *rsc, const ProgramStore *ps) {
    DrvProgramStore *drv = (DrvProgramStore *)ps->mHal.drv;

    RSD_CALL_GL(glColorMask, ps->mHal.state.colorRWriteEnable,
                ps->mHal.state.colorGWriteEnable,
                ps->mHal.state.colorBWriteEnable,
                ps->mHal.state.colorAWriteEnable);

    if (drv->blendEnable) {
        RSD_CALL_GL(glEnable, GL_BLEND);
        RSD_CALL_GL(glBlendFunc, drv->blendSrc, drv->blendDst);
    } else {
        RSD_CALL_GL(glDisable, GL_BLEND);
    }

    if (rsc->mUserSurfaceConfig.depthMin > 0) {
        RSD_CALL_GL(glDepthMask, ps->mHal.state.depthWriteEnable);
        if (drv->depthTestEnable || ps->mHal.state.depthWriteEnable) {
            RSD_CALL_GL(glEnable, GL_DEPTH_TEST);
            RSD_CALL_GL(glDepthFunc, drv->depthFunc);
        } else {
            RSD_CALL_GL(glDisable, GL_DEPTH_TEST);
        }
    } else {
        RSD_CALL_GL(glDepthMask, false);
        RSD_CALL_GL(glDisable, GL_DEPTH_TEST);
    }

    /*
    if (rsc->mUserSurfaceConfig.stencilMin > 0) {
    } else {
        glStencilMask(0);
        glDisable(GL_STENCIL_TEST);
    }
    */

    if (ps->mHal.state.ditherEnable) {
        RSD_CALL_GL(glEnable, GL_DITHER);
    } else {
        RSD_CALL_GL(glDisable, GL_DITHER);
    }
}

void rsdProgramStoreDestroy(const Context *rsc, const ProgramStore *ps) {
    free(ps->mHal.drv);
    ps->mHal.drv = nullptr;
}


