//
// Copyright 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
{

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

const GLsizei FramebufferAttachment::kDefaultNumViews             = 1;
const GLint FramebufferAttachment::kDefaultBaseViewIndex          = 0;
const GLint FramebufferAttachment::kDefaultRenderToTextureSamples = 0;

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),
      mIsMultiview(false),
      mBaseViewIndex(kDefaultBaseViewIndex),
      mRenderToTextureSamples(kDefaultRenderToTextureSamples)
{}

FramebufferAttachment::FramebufferAttachment(const Context *context,
                                             GLenum type,
                                             GLenum binding,
                                             const ImageIndex &textureIndex,
                                             FramebufferAttachmentObject *resource,
                                             rx::UniqueSerial framebufferSerial)
    : mResource(nullptr)
{
    attach(context, type, binding, textureIndex, resource, kDefaultNumViews, kDefaultBaseViewIndex,
           false, kDefaultRenderToTextureSamples, framebufferSerial);
}

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(mIsMultiview, other.mIsMultiview);
    std::swap(mBaseViewIndex, other.mBaseViewIndex);
    std::swap(mRenderToTextureSamples, other.mRenderToTextureSamples);
    return *this;
}

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

void FramebufferAttachment::detach(const Context *context, rx::UniqueSerial framebufferSerial)
{
    mType = GL_NONE;
    if (mResource != nullptr)
    {
        mResource->onDetach(context, framebufferSerial);
        mResource = nullptr;
    }
    mNumViews      = kDefaultNumViews;
    mIsMultiview   = false;
    mBaseViewIndex = kDefaultBaseViewIndex;

    // 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,
                                   bool isMultiview,
                                   GLsizei samples,
                                   rx::UniqueSerial framebufferSerial)
{
    if (resource == nullptr)
    {
        detach(context, framebufferSerial);
        return;
    }

    mType                   = type;
    mTarget                 = Target(binding, textureIndex);
    mNumViews               = numViews;
    mBaseViewIndex          = baseViewIndex;
    mIsMultiview            = isMultiview;
    mRenderToTextureSamples = type == GL_RENDERBUFFER ? kDefaultRenderToTextureSamples : samples;
    if (mIsMultiview)
    {
        // Multiview framebuffer attachments can only be created through:
        // 1) glFramebufferTextureMultiviewOVR
        // 2) glNamedFramebufferTextureMultiviewOVR
        // 3) glFramebufferTextureMultisampleMultiviewOVR
        // All of the above method require the attachment to be texture, not renderbuffer.
        ASSERT(type != GL_RENDERBUFFER);
    }
    resource->onAttach(context, framebufferSerial);

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

    mResource = resource;
}

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

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

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

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

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

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

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

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

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

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();
}

bool FramebufferAttachment::isMultiview() const
{
    return mIsMultiview;
}

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

bool FramebufferAttachment::isRenderToTexture() const
{
    ASSERT(mRenderToTextureSamples == kDefaultRenderToTextureSamples || mType == GL_TEXTURE);

    if (mType == GL_RENDERBUFFER)
    {
        return getRenderbuffer()->getMultisamplingMode() ==
               MultisamplingMode::MultisampledRenderToTexture;
    }
    return mRenderToTextureSamples != kDefaultRenderToTextureSamples;
}

GLsizei FramebufferAttachment::getRenderToTextureSamples() const
{
    if (!isRenderToTexture())
    {
        return 0;
    }

    ASSERT(mRenderToTextureSamples == kDefaultRenderToTextureSamples || mType == GL_TEXTURE);

    if (mType == GL_RENDERBUFFER)
    {
        return getRenderbuffer()->getState().getSamples();
    }
    return mRenderToTextureSamples;
}

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 ||
        mIsMultiview != other.mIsMultiview || mBaseViewIndex != other.mBaseViewIndex ||
        mRenderToTextureSamples != other.mRenderToTextureSamples)
    {
        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.binding(), mTarget.textureIndex())
                     : InitState::Initialized;
}

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

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

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

FramebufferAttachmentObject::FramebufferAttachmentObject() {}

FramebufferAttachmentObject::~FramebufferAttachmentObject() {}

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

angle::Result FramebufferAttachmentObject::initializeContents(const Context *context,
                                                              GLenum binding,
                                                              const ImageIndex &imageIndex)
{
    ASSERT(context->isRobustResourceInitEnabled());

    // Because gl::Texture cannot support tracking individual layer dirtiness, we only handle
    // initializing entire mip levels for textures with layers
    if (imageIndex.usesTex3D() && imageIndex.hasLayer())
    {
        // Compute the layer count so we get a correct layer index.
        const gl::Extents &size = getAttachmentSize(imageIndex);

        ImageIndex fullMipIndex = ImageIndex::MakeFromType(
            imageIndex.getType(), imageIndex.getLevelIndex(), ImageIndex::kEntireLevel, size.depth);
        return getAttachmentImpl()->initializeContents(context, binding, fullMipIndex);
    }
    else
    {
        return getAttachmentImpl()->initializeContents(context, binding, imageIndex);
    }
}

}  // namespace gl
