// Copyright 2017 The NXT Authors
//
// 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 "backend/opengl/DepthStencilStateGL.h"

#include "backend/opengl/PersistentPipelineStateGL.h"
#include "common/Assert.h"

namespace backend { namespace opengl {

    namespace {
        GLuint OpenGLCompareFunction(nxt::CompareFunction compareFunction) {
            switch (compareFunction) {
                case nxt::CompareFunction::Never:
                    return GL_NEVER;
                case nxt::CompareFunction::Less:
                    return GL_LESS;
                case nxt::CompareFunction::LessEqual:
                    return GL_LEQUAL;
                case nxt::CompareFunction::Greater:
                    return GL_GREATER;
                case nxt::CompareFunction::GreaterEqual:
                    return GL_GEQUAL;
                case nxt::CompareFunction::NotEqual:
                    return GL_NOTEQUAL;
                case nxt::CompareFunction::Equal:
                    return GL_EQUAL;
                case nxt::CompareFunction::Always:
                    return GL_ALWAYS;
                default:
                    UNREACHABLE();
            }
        }

        GLuint OpenGLStencilOperation(nxt::StencilOperation stencilOperation) {
            switch (stencilOperation) {
                case nxt::StencilOperation::Keep:
                    return GL_KEEP;
                case nxt::StencilOperation::Zero:
                    return GL_ZERO;
                case nxt::StencilOperation::Replace:
                    return GL_REPLACE;
                case nxt::StencilOperation::Invert:
                    return GL_INVERT;
                case nxt::StencilOperation::IncrementClamp:
                    return GL_INCR;
                case nxt::StencilOperation::DecrementClamp:
                    return GL_DECR;
                case nxt::StencilOperation::IncrementWrap:
                    return GL_INCR_WRAP;
                case nxt::StencilOperation::DecrementWrap:
                    return GL_DECR_WRAP;
                default:
                    UNREACHABLE();
            }
        }
    }  // namespace

    DepthStencilState::DepthStencilState(DepthStencilStateBuilder* builder)
        : DepthStencilStateBase(builder) {
    }

    void DepthStencilState::ApplyNow(PersistentPipelineState& persistentPipelineState) const {
        auto& depthInfo = GetDepth();

        // Depth writes only occur if depth is enabled
        if (depthInfo.compareFunction == nxt::CompareFunction::Always &&
            !depthInfo.depthWriteEnabled) {
            glDisable(GL_DEPTH_TEST);
        } else {
            glEnable(GL_DEPTH_TEST);
        }

        if (depthInfo.depthWriteEnabled) {
            glDepthMask(GL_TRUE);
        } else {
            glDepthMask(GL_FALSE);
        }

        glDepthFunc(OpenGLCompareFunction(depthInfo.compareFunction));

        if (StencilTestEnabled()) {
            glEnable(GL_STENCIL_TEST);
        } else {
            glDisable(GL_STENCIL_TEST);
        }

        auto& stencilInfo = GetStencil();

        GLenum backCompareFunction = OpenGLCompareFunction(stencilInfo.back.compareFunction);
        GLenum frontCompareFunction = OpenGLCompareFunction(stencilInfo.front.compareFunction);
        persistentPipelineState.SetStencilFuncsAndMask(backCompareFunction, frontCompareFunction,
                                                       stencilInfo.readMask);

        glStencilOpSeparate(GL_BACK, OpenGLStencilOperation(stencilInfo.back.stencilFail),
                            OpenGLStencilOperation(stencilInfo.back.depthFail),
                            OpenGLStencilOperation(stencilInfo.back.depthStencilPass));
        glStencilOpSeparate(GL_FRONT, OpenGLStencilOperation(stencilInfo.front.stencilFail),
                            OpenGLStencilOperation(stencilInfo.front.depthFail),
                            OpenGLStencilOperation(stencilInfo.front.depthStencilPass));

        glStencilMask(stencilInfo.writeMask);
    }

}}  // namespace backend::opengl
