/*
 * 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 "Debug.h"
#include "Extensions.h"
#include "Properties.h"
#include "Stencil.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;
}

GLenum Stencil::getSmallestStencilFormat() {
#if !DEBUG_STENCIL
    const Extensions& extensions = Extensions::getInstance();
    if (extensions.has1BitStencil()) {
        return GL_STENCIL_INDEX1_OES;
    } else 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() {
    if (mState != kTest) {
        enable();
        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);
        mState = kTest;
    }
}

void Stencil::enableWrite() {
    if (mState != kWrite) {
        enable();
        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);
        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;
    }
}

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