diff options
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp')
-rw-r--r-- | gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp b/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp new file mode 100644 index 0000000000..6a3e88051f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp @@ -0,0 +1,350 @@ +// +// 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::Serial 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::Serial 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::Serial 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 getSize().empty() ? 0 : getFormat().info->redBits; +} + +GLuint FramebufferAttachment::getGreenSize() const +{ + return getSize().empty() ? 0 : getFormat().info->greenBits; +} + +GLuint FramebufferAttachment::getBlueSize() const +{ + return getSize().empty() ? 0 : getFormat().info->blueBits; +} + +GLuint FramebufferAttachment::getAlphaSize() const +{ + return getSize().empty() ? 0 : getFormat().info->alphaBits; +} + +GLuint FramebufferAttachment::getDepthSize() const +{ + return getSize().empty() ? 0 : getFormat().info->depthBits; +} + +GLuint FramebufferAttachment::getStencilSize() const +{ + return getSize().empty() ? 0 : 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(); +} + +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 +{ + 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) +{ + 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 |