// Copyright 2017 The Dawn 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 "dawn_native/RenderPassDescriptor.h"

#include "common/Assert.h"
#include "common/BitSetIterator.h"
#include "dawn_native/Device.h"
#include "dawn_native/Texture.h"

namespace dawn_native {

    // RenderPassDescriptor

    RenderPassDescriptorBase::RenderPassDescriptorBase(RenderPassDescriptorBuilder* builder)
        : mColorAttachmentsSet(builder->mColorAttachmentsSet),
          mColorAttachments(builder->mColorAttachments),
          mDepthStencilAttachmentSet(builder->mDepthStencilAttachmentSet),
          mDepthStencilAttachment(builder->mDepthStencilAttachment),
          mWidth(builder->mWidth),
          mHeight(builder->mHeight) {
    }

    std::bitset<kMaxColorAttachments> RenderPassDescriptorBase::GetColorAttachmentMask() const {
        return mColorAttachmentsSet;
    }

    bool RenderPassDescriptorBase::HasDepthStencilAttachment() const {
        return mDepthStencilAttachmentSet;
    }

    const RenderPassColorAttachmentInfo& RenderPassDescriptorBase::GetColorAttachment(
        uint32_t attachment) const {
        ASSERT(attachment < kMaxColorAttachments);
        ASSERT(mColorAttachmentsSet[attachment]);

        return mColorAttachments[attachment];
    }

    RenderPassColorAttachmentInfo& RenderPassDescriptorBase::GetColorAttachment(
        uint32_t attachment) {
        ASSERT(attachment < kMaxColorAttachments);
        ASSERT(mColorAttachmentsSet[attachment]);

        return mColorAttachments[attachment];
    }

    const RenderPassDepthStencilAttachmentInfo&
    RenderPassDescriptorBase::GetDepthStencilAttachment() const {
        ASSERT(mDepthStencilAttachmentSet);

        return mDepthStencilAttachment;
    }

    RenderPassDepthStencilAttachmentInfo& RenderPassDescriptorBase::GetDepthStencilAttachment() {
        ASSERT(mDepthStencilAttachmentSet);

        return mDepthStencilAttachment;
    }

    uint32_t RenderPassDescriptorBase::GetWidth() const {
        return mWidth;
    }

    uint32_t RenderPassDescriptorBase::GetHeight() const {
        return mHeight;
    }

    // RenderPassDescriptorBuilder

    RenderPassDescriptorBuilder::RenderPassDescriptorBuilder(DeviceBase* device) : Builder(device) {
    }

    RenderPassDescriptorBase* RenderPassDescriptorBuilder::GetResultImpl() {
        auto CheckOrSetSize = [this](const TextureViewBase* attachment) -> bool {
            if (this->mWidth == 0) {
                ASSERT(this->mHeight == 0);

                this->mWidth = attachment->GetTexture()->GetWidth();
                this->mHeight = attachment->GetTexture()->GetHeight();
                ASSERT(this->mWidth != 0 && this->mHeight != 0);

                return true;
            }

            ASSERT(this->mWidth != 0 && this->mHeight != 0);
            return this->mWidth == attachment->GetTexture()->GetWidth() &&
                   this->mHeight == attachment->GetTexture()->GetHeight();
        };

        uint32_t attachmentCount = 0;
        for (uint32_t i : IterateBitSet(mColorAttachmentsSet)) {
            attachmentCount++;
            if (!CheckOrSetSize(mColorAttachments[i].view.Get())) {
                HandleError("Attachment size mismatch");
                return nullptr;
            }
        }

        if (mDepthStencilAttachmentSet) {
            attachmentCount++;
            if (!CheckOrSetSize(mDepthStencilAttachment.view.Get())) {
                HandleError("Attachment size mismatch");
                return nullptr;
            }
        }

        if (attachmentCount == 0) {
            HandleError("Should have at least one attachment");
            return nullptr;
        }

        return mDevice->CreateRenderPassDescriptor(this);
    }

    void RenderPassDescriptorBuilder::SetColorAttachment(uint32_t attachment,
                                                         TextureViewBase* textureView,
                                                         dawn::LoadOp loadOp) {
        if (attachment >= kMaxColorAttachments) {
            HandleError("Setting color attachment out of bounds");
            return;
        }

        if (TextureFormatHasDepthOrStencil(textureView->GetTexture()->GetFormat())) {
            HandleError("Using depth stencil texture as color attachment");
            return;
        }

        mColorAttachmentsSet.set(attachment);
        mColorAttachments[attachment].loadOp = loadOp;
        mColorAttachments[attachment].view = textureView;
    }

    void RenderPassDescriptorBuilder::SetColorAttachmentClearColor(uint32_t attachment,
                                                                   float clearR,
                                                                   float clearG,
                                                                   float clearB,
                                                                   float clearA) {
        if (attachment >= kMaxColorAttachments) {
            HandleError("Setting color attachment out of bounds");
            return;
        }

        mColorAttachments[attachment].clearColor[0] = clearR;
        mColorAttachments[attachment].clearColor[1] = clearG;
        mColorAttachments[attachment].clearColor[2] = clearB;
        mColorAttachments[attachment].clearColor[3] = clearA;
    }

    void RenderPassDescriptorBuilder::SetDepthStencilAttachment(TextureViewBase* textureView,
                                                                dawn::LoadOp depthLoadOp,
                                                                dawn::LoadOp stencilLoadOp) {
        if (!TextureFormatHasDepthOrStencil(textureView->GetTexture()->GetFormat())) {
            HandleError("Using color texture as depth stencil attachment");
            return;
        }

        mDepthStencilAttachmentSet = true;
        mDepthStencilAttachment.depthLoadOp = depthLoadOp;
        mDepthStencilAttachment.stencilLoadOp = stencilLoadOp;
        mDepthStencilAttachment.view = textureView;
    }

    void RenderPassDescriptorBuilder::SetDepthStencilAttachmentClearValue(float clearDepth,
                                                                          uint32_t clearStencil) {
        mDepthStencilAttachment.clearDepth = clearDepth;
        mDepthStencilAttachment.clearStencil = clearStencil;
    }

}  // namespace dawn_native
