/*
 * 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 == NULL) {
        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:
        LOGE("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:
        LOGE("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:
        LOGE("Unknown blend dst mode.");
        goto error;
    }

    return true;

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

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

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

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

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

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

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

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


