//
// 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;
    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
