Edit

kc3-lang/angle/src/libANGLE/FramebufferAttachment.cpp

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2018-11-29 18:16:17
    Hash : 7c985f5c
    Message : Make angle::Result an enum. This moves away from a class type to a value type. This should improve performance when using angle::Result as a return value. Previously the generated code would return a pointer instead of a value. Improves performance in the most targeted microbenchmark by 10%. In more realistic scanarios it will have a smaller improvement. Also simplifies the class implementation and usage. Includes some unrelated code generation changes. Bug: angleproject:2491 Change-Id: Ifcf86870bf1c00a2f73c39ea6e4f05ca705050aa Reviewed-on: https://chromium-review.googlesource.com/c/1356139 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org>

  • src/libANGLE/FramebufferAttachment.cpp
  • //
    // 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();
    }
    
    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;
    }
    
    angle::Result FramebufferAttachment::initializeContents(const Context *context)
    {
        ASSERT(mResource);
        ANGLE_TRY(mResource->initializeContents(context, mTarget.textureIndex()));
        setInitState(InitState::Initialized);
        return angle::Result::Continue;
    }
    
    void FramebufferAttachment::setInitState(InitState initState) const
    {
        ASSERT(mResource);
        mResource->setInitState(mTarget.textureIndex(), initState);
    }
    
    ////// FramebufferAttachmentObject Implementation //////
    
    FramebufferAttachmentObject::FramebufferAttachmentObject() {}
    
    FramebufferAttachmentObject::~FramebufferAttachmentObject() {}
    
    angle::Result FramebufferAttachmentObject::getAttachmentRenderTarget(
        const Context *context,
        GLenum binding,
        const ImageIndex &imageIndex,
        rx::FramebufferAttachmentRenderTarget **rtOut) const
    {
        return getAttachmentImpl()->getAttachmentRenderTarget(context, binding, imageIndex, rtOut);
    }
    
    angle::Result 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 if (imageIndex.getType() == TextureType::_2DMultisampleArray && imageIndex.hasLayer())
        {
            ImageIndex fullMipIndex = ImageIndex::Make2DMultisampleArray(ImageIndex::kEntireLevel);
            return getAttachmentImpl()->initializeContents(context, fullMipIndex);
        }
        else
        {
            return getAttachmentImpl()->initializeContents(context, imageIndex);
        }
    }
    
    }  // namespace gl