//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// FramebufferAttachment.cpp: the gl::FramebufferAttachment class and its derived classes
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.

#include "libANGLE/FramebufferAttachment.h"

#include "common/utilities.h"
#include "libANGLE/Config.h"
#include "libANGLE/Context.h"
#include "libANGLE/Renderbuffer.h"
#include "libANGLE/Surface.h"
#include "libANGLE/Texture.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h"
#include "libANGLE/renderer/FramebufferImpl.h"

namespace gl
{

namespace
{

std::vector<Offset> TransformViewportOffsetArrayToVectorOfOffsets(const GLint *viewportOffsets,
                                                                  GLsizei numViews)
{
    const size_t numViewsAsSizeT = static_cast<size_t>(numViews);
    std::vector<Offset> offsetVector;
    offsetVector.reserve(numViewsAsSizeT);
    for (size_t i = 0u; i < numViewsAsSizeT; ++i)
    {
        offsetVector.emplace_back(Offset(viewportOffsets[i * 2u], viewportOffsets[i * 2u + 1u], 0));
    }
    return offsetVector;
}

}  // namespace

////// FramebufferAttachment::Target Implementation //////

const GLsizei FramebufferAttachment::kDefaultNumViews         = 1;
const GLenum FramebufferAttachment::kDefaultMultiviewLayout   = GL_NONE;
const GLint FramebufferAttachment::kDefaultBaseViewIndex      = 0;
const GLint FramebufferAttachment::kDefaultViewportOffsets[2] = {0};

std::vector<Offset> FramebufferAttachment::GetDefaultViewportOffsetVector()
{
    return TransformViewportOffsetArrayToVectorOfOffsets(
        FramebufferAttachment::kDefaultViewportOffsets, FramebufferAttachment::kDefaultNumViews);
}

FramebufferAttachment::Target::Target() : mBinding(GL_NONE), mTextureIndex()
{
}

FramebufferAttachment::Target::Target(GLenum binding, const ImageIndex &imageIndex)
    : mBinding(binding),
      mTextureIndex(imageIndex)
{
}

FramebufferAttachment::Target::Target(const Target &other)
    : mBinding(other.mBinding),
      mTextureIndex(other.mTextureIndex)
{
}

FramebufferAttachment::Target &FramebufferAttachment::Target::operator=(const Target &other)
{
    this->mBinding = other.mBinding;
    this->mTextureIndex = other.mTextureIndex;
    return *this;
}

////// FramebufferAttachment Implementation //////

FramebufferAttachment::FramebufferAttachment()
    : mType(GL_NONE),
      mResource(nullptr),
      mNumViews(kDefaultNumViews),
      mMultiviewLayout(kDefaultMultiviewLayout),
      mBaseViewIndex(kDefaultBaseViewIndex),
      mViewportOffsets(GetDefaultViewportOffsetVector())
{
}

FramebufferAttachment::FramebufferAttachment(const Context *context,
                                             GLenum type,
                                             GLenum binding,
                                             const ImageIndex &textureIndex,
                                             FramebufferAttachmentObject *resource)
    : mResource(nullptr)
{
    attach(context, type, binding, textureIndex, resource, kDefaultNumViews, kDefaultBaseViewIndex,
           kDefaultMultiviewLayout, kDefaultViewportOffsets);
}

FramebufferAttachment::FramebufferAttachment(FramebufferAttachment &&other)
    : FramebufferAttachment()
{
    *this = std::move(other);
}

FramebufferAttachment &FramebufferAttachment::operator=(FramebufferAttachment &&other)
{
    std::swap(mType, other.mType);
    std::swap(mTarget, other.mTarget);
    std::swap(mResource, other.mResource);
    std::swap(mNumViews, other.mNumViews);
    std::swap(mMultiviewLayout, other.mMultiviewLayout);
    std::swap(mBaseViewIndex, other.mBaseViewIndex);
    std::swap(mViewportOffsets, other.mViewportOffsets);
    return *this;
}

FramebufferAttachment::~FramebufferAttachment()
{
    ASSERT(!isAttached());
}

void FramebufferAttachment::detach(const Context *context)
{
    mType = GL_NONE;
    if (mResource != nullptr)
    {
        mResource->onDetach(context);
        mResource = nullptr;
    }
    mNumViews        = kDefaultNumViews;
    mMultiviewLayout = kDefaultMultiviewLayout;
    mBaseViewIndex   = kDefaultBaseViewIndex;
    mViewportOffsets = GetDefaultViewportOffsetVector();

    // not technically necessary, could omit for performance
    mTarget = Target();
}

void FramebufferAttachment::attach(const Context *context,
                                   GLenum type,
                                   GLenum binding,
                                   const ImageIndex &textureIndex,
                                   FramebufferAttachmentObject *resource,
                                   GLsizei numViews,
                                   GLuint baseViewIndex,
                                   GLenum multiviewLayout,
                                   const GLint *viewportOffsets)
{
    if (resource == nullptr)
    {
        detach(context);
        return;
    }

    mType = type;
    mTarget = Target(binding, textureIndex);
    mNumViews        = numViews;
    mBaseViewIndex   = baseViewIndex;
    mMultiviewLayout = multiviewLayout;
    if (multiviewLayout == GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE)
    {
        mViewportOffsets = TransformViewportOffsetArrayToVectorOfOffsets(viewportOffsets, numViews);
    }
    else
    {
        mViewportOffsets = GetDefaultViewportOffsetVector();
    }
    resource->onAttach(context);

    if (mResource != nullptr)
    {
        mResource->onDetach(context);
    }

    mResource = resource;
}

GLuint FramebufferAttachment::getRedSize() const
{
    return getFormat().info->redBits;
}

GLuint FramebufferAttachment::getGreenSize() const
{
    return getFormat().info->greenBits;
}

GLuint FramebufferAttachment::getBlueSize() const
{
    return getFormat().info->blueBits;
}

GLuint FramebufferAttachment::getAlphaSize() const
{
    return getFormat().info->alphaBits;
}

GLuint FramebufferAttachment::getDepthSize() const
{
    return getFormat().info->depthBits;
}

GLuint FramebufferAttachment::getStencilSize() const
{
    return getFormat().info->stencilBits;
}

GLenum FramebufferAttachment::getComponentType() const
{
    return getFormat().info->componentType;
}

GLenum FramebufferAttachment::getColorEncoding() const
{
    return getFormat().info->colorEncoding;
}

GLuint FramebufferAttachment::id() const
{
    return mResource->getId();
}

const ImageIndex &FramebufferAttachment::getTextureImageIndex() const
{
    ASSERT(type() == GL_TEXTURE);
    return mTarget.textureIndex();
}

TextureTarget FramebufferAttachment::cubeMapFace() const
{
    ASSERT(mType == GL_TEXTURE);

    const auto &index = mTarget.textureIndex();
    return index.getType() == TextureType::CubeMap ? index.getTarget() : TextureTarget::InvalidEnum;
}

GLint FramebufferAttachment::mipLevel() const
{
    ASSERT(type() == GL_TEXTURE);
    return mTarget.textureIndex().getLevelIndex();
}

GLint FramebufferAttachment::layer() const
{
    ASSERT(mType == GL_TEXTURE);

    const gl::ImageIndex &index = mTarget.textureIndex();
    return (index.has3DLayer() ? index.getLayerIndex() : 0);
}

bool FramebufferAttachment::isLayered() const
{
    return mTarget.textureIndex().isLayered();
}

GLsizei FramebufferAttachment::getNumViews() const
{
    return mNumViews;
}

GLenum FramebufferAttachment::getMultiviewLayout() const
{
    return mMultiviewLayout;
}

GLint FramebufferAttachment::getBaseViewIndex() const
{
    return mBaseViewIndex;
}

const std::vector<Offset> &FramebufferAttachment::getMultiviewViewportOffsets() const
{
    return mViewportOffsets;
}

Texture *FramebufferAttachment::getTexture() const
{
    return rx::GetAs<Texture>(mResource);
}

Renderbuffer *FramebufferAttachment::getRenderbuffer() const
{
    return rx::GetAs<Renderbuffer>(mResource);
}

const egl::Surface *FramebufferAttachment::getSurface() const
{
    return rx::GetAs<egl::Surface>(mResource);
}

FramebufferAttachmentObject *FramebufferAttachment::getResource() const
{
    return mResource;
}

bool FramebufferAttachment::operator==(const FramebufferAttachment &other) const
{
    if (mResource != other.mResource || mType != other.mType || mNumViews != other.mNumViews ||
        mMultiviewLayout != other.mMultiviewLayout || mBaseViewIndex != other.mBaseViewIndex ||
        mViewportOffsets != other.mViewportOffsets)
    {
        return false;
    }

    if (mType == GL_TEXTURE && getTextureImageIndex() != other.getTextureImageIndex())
    {
        return false;
    }

    return true;
}

bool FramebufferAttachment::operator!=(const FramebufferAttachment &other) const
{
    return !(*this == other);
}

InitState FramebufferAttachment::initState() const
{
    return mResource ? mResource->initState(mTarget.textureIndex()) : InitState::Initialized;
}

Error FramebufferAttachment::initializeContents(const Context *context)
{
    ASSERT(mResource);
    ANGLE_TRY(mResource->initializeContents(context, mTarget.textureIndex()));
    setInitState(InitState::Initialized);
    return NoError();
}

void FramebufferAttachment::setInitState(InitState initState) const
{
    ASSERT(mResource);
    mResource->setInitState(mTarget.textureIndex(), initState);
}

////// FramebufferAttachmentObject Implementation //////

FramebufferAttachmentObject::FramebufferAttachmentObject()
{
}

FramebufferAttachmentObject::~FramebufferAttachmentObject()
{
}

Error FramebufferAttachmentObject::getAttachmentRenderTarget(
    const Context *context,
    GLenum binding,
    const ImageIndex &imageIndex,
    rx::FramebufferAttachmentRenderTarget **rtOut) const
{
    return getAttachmentImpl()->getAttachmentRenderTarget(context, binding, imageIndex, rtOut);
}

void FramebufferAttachmentObject::onStorageChange(const gl::Context *context) const
{
    return getAttachmentImpl()->onStateChange(context, angle::SubjectMessage::STORAGE_CHANGED);
}

angle::Subject *FramebufferAttachmentObject::getSubject() const
{
    return getAttachmentImpl();
}

Error FramebufferAttachmentObject::initializeContents(const Context *context,
                                                      const ImageIndex &imageIndex)
{
    ASSERT(context->isRobustResourceInitEnabled());

    // Because gl::Texture cannot support tracking individual layer dirtiness, we only handle
    // initializing entire mip levels for 2D array textures.
    if (imageIndex.getType() == TextureType::_2DArray && imageIndex.hasLayer())
    {
        ImageIndex fullMipIndex =
            ImageIndex::Make2DArray(imageIndex.getLevelIndex(), ImageIndex::kEntireLevel);
        return getAttachmentImpl()->initializeContents(context, fullMipIndex);
    }
    else
    {
        return getAttachmentImpl()->initializeContents(context, imageIndex);
    }
}

}  // namespace gl
