// // 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/Renderbuffer.h" #include "libANGLE/Surface.h" #include "libANGLE/Texture.h" #include "libANGLE/formatutils.h" #include "libANGLE/renderer/FramebufferImpl.h" #include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h" namespace gl { ////// FramebufferAttachment::Target Implementation ////// FramebufferAttachment::Target::Target() : mBinding(GL_NONE), mTextureIndex(ImageIndex::MakeInvalid()) { } 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) { } FramebufferAttachment::FramebufferAttachment(GLenum type, GLenum binding, const ImageIndex &textureIndex, FramebufferAttachmentObject *resource) : mResource(nullptr) { attach(type, binding, textureIndex, resource); } FramebufferAttachment::FramebufferAttachment(const FramebufferAttachment &other) : mResource(nullptr) { attach(other.mType, other.mTarget.binding(), other.mTarget.textureIndex(), other.mResource); } FramebufferAttachment &FramebufferAttachment::operator=(const FramebufferAttachment &other) { attach(other.mType, other.mTarget.binding(), other.mTarget.textureIndex(), other.mResource); return *this; } FramebufferAttachment::~FramebufferAttachment() { detach(); } void FramebufferAttachment::detach() { mType = GL_NONE; if (mResource != nullptr) { mResource->onDetach(); mResource = nullptr; } // not technically necessary, could omit for performance mTarget = Target(); } void FramebufferAttachment::attach(GLenum type, GLenum binding, const ImageIndex &textureIndex, FramebufferAttachmentObject *resource) { mType = type; mTarget = Target(binding, textureIndex); if (resource) { resource->onAttach(); } if (mResource != nullptr) { mResource->onDetach(); } 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(); } GLenum FramebufferAttachment::cubeMapFace() const { ASSERT(mType == GL_TEXTURE); const auto &index = mTarget.textureIndex(); return IsCubeMapTextureTarget(index.type) ? index.type : GL_NONE; } GLint FramebufferAttachment::mipLevel() const { ASSERT(type() == GL_TEXTURE); return mTarget.textureIndex().mipIndex; } GLint FramebufferAttachment::layer() const { ASSERT(mType == GL_TEXTURE); const auto &index = mTarget.textureIndex(); if (index.type == GL_TEXTURE_2D_ARRAY || index.type == GL_TEXTURE_3D) { return index.layerIndex; } return 0; } Texture *FramebufferAttachment::getTexture() const { return rx::GetAs(mResource); } Renderbuffer *FramebufferAttachment::getRenderbuffer() const { return rx::GetAs(mResource); } const egl::Surface *FramebufferAttachment::getSurface() const { return rx::GetAs(mResource); } bool FramebufferAttachment::operator==(const FramebufferAttachment &other) const { if (mResource != other.mResource || mType != other.mType) { return false; } if (mType == GL_TEXTURE && getTextureImageIndex() != other.getTextureImageIndex()) { return false; } return true; } bool FramebufferAttachment::operator!=(const FramebufferAttachment &other) const { return !(*this == other); } Error FramebufferAttachmentObject::getAttachmentRenderTarget( const FramebufferAttachment::Target &target, rx::FramebufferAttachmentRenderTarget **rtOut) const { return getAttachmentImpl()->getAttachmentRenderTarget(target, rtOut); } angle::BroadcastChannel *FramebufferAttachmentObject::getDirtyChannel() { return &mDirtyChannel; } } // namespace gl