/*
 * Copyright (C) 2012 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 "renderstate/Stencil.h"

#include "Caches.h"
#include "Debug.h"
#include "Extensions.h"
#include "Properties.h"

#include <GLES2/gl2ext.h>

namespace android {
namespace uirenderer {

#if DEBUG_STENCIL
#define STENCIL_WRITE_VALUE 0xff
#define STENCIL_MASK_VALUE 0xff
#else
#define STENCIL_WRITE_VALUE 0x1
#define STENCIL_MASK_VALUE 0x1
#endif

Stencil::Stencil()
        : mState(kDisabled) {
}

uint8_t Stencil::getStencilSize() {
    return STENCIL_BUFFER_SIZE;
}

/**
 * This method will return either GL_STENCIL_INDEX4_OES if supported,
 * GL_STENCIL_INDEX8 if not.
 *
 * Layers can't use a single bit stencil because multi-rect ClipArea needs a high enough
 * stencil resolution to represent the summation of multiple intersecting rect geometries.
 */
GLenum Stencil::getLayerStencilFormat() {
#if !DEBUG_STENCIL
    const Extensions& extensions = Caches::getInstance().extensions();
    if (extensions.has4BitStencil()) {
        return GL_STENCIL_INDEX4_OES;
    }
#endif
    return GL_STENCIL_INDEX8;
}

void Stencil::clear() {
    glClearStencil(0);
    glClear(GL_STENCIL_BUFFER_BIT);
}

void Stencil::enableTest(int incrementThreshold) {
    if (mState != kTest) {
        enable();
        if (incrementThreshold > 0) {
            glStencilFunc(GL_EQUAL, incrementThreshold, 0xff);
        } else {
            glStencilFunc(GL_EQUAL, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE);
        }
        // We only want to test, let's keep everything
        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
        glStencilMask(0);
        mState = kTest;
    }
}

void Stencil::enableWrite(int incrementThreshold) {
    if (mState != kWrite) {
        enable();
        if (incrementThreshold > 0) {
            glStencilFunc(GL_ALWAYS, 1, 0xff);
            // The test always passes so the first two values are meaningless
            glStencilOp(GL_INCR, GL_INCR, GL_INCR);
        } else {
            glStencilFunc(GL_ALWAYS, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE);
            // The test always passes so the first two values are meaningless
            glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
        }
        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
        glStencilMask(0xff);
        mState = kWrite;
    }
}

void Stencil::enableDebugTest(GLint value, bool greater) {
    enable();
    glStencilFunc(greater ? GL_LESS : GL_EQUAL, value, 0xffffffff);
    // We only want to test, let's keep everything
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    mState = kTest;
}

void Stencil::enableDebugWrite() {
    if (mState != kWrite) {
        enable();
        glStencilFunc(GL_ALWAYS, 0x1, 0xffffffff);
        // The test always passes so the first two values are meaningless
        glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
        mState = kWrite;
    }
}

void Stencil::enable() {
    if (mState == kDisabled) {
        glEnable(GL_STENCIL_TEST);
    }
}

void Stencil::disable() {
    if (mState != kDisabled) {
        glDisable(GL_STENCIL_TEST);
        mState = kDisabled;
    }
}

void Stencil::dump() {
    ALOGD("Stencil: state %d", mState);
}

}; // namespace uirenderer
}; // namespace android
