| // | |
| // 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.h: Defines the wrapper class gl::FramebufferAttachment, as well as the | |
| // objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108. | |
| #ifndef LIBANGLE_FRAMEBUFFERATTACHMENT_H_ | |
| #define LIBANGLE_FRAMEBUFFERATTACHMENT_H_ | |
| #include "angle_gl.h" | |
| #include "common/angleutils.h" | |
| #include "libANGLE/Error.h" | |
| #include "libANGLE/ImageIndex.h" | |
| #include "libANGLE/RefCountObject.h" | |
| namespace egl | |
| { | |
| class Surface; | |
| } | |
| namespace rx | |
| { | |
| // An implementation-specific object associated with an attachment. | |
| class FramebufferAttachmentRenderTarget : angle::NonCopyable | |
| { | |
| public: | |
| FramebufferAttachmentRenderTarget() {} | |
| virtual ~FramebufferAttachmentRenderTarget() {} | |
| }; | |
| class FramebufferAttachmentObjectImpl; | |
| } | |
| namespace gl | |
| { | |
| class FramebufferAttachmentObject; | |
| class Renderbuffer; | |
| class Texture; | |
| // FramebufferAttachment implements a GL framebuffer attachment. | |
| // Attachments are "light" containers, which store pointers to ref-counted GL objects. | |
| // We support GL texture (2D/3D/Cube/2D array) and renderbuffer object attachments. | |
| // Note: Our old naming scheme used the term "Renderbuffer" for both GL renderbuffers and for | |
| // framebuffer attachments, which confused their usage. | |
| class FramebufferAttachment final | |
| { | |
| public: | |
| FramebufferAttachment(); | |
| FramebufferAttachment(GLenum type, | |
| GLenum binding, | |
| const ImageIndex &textureIndex, | |
| FramebufferAttachmentObject *resource); | |
| FramebufferAttachment(const FramebufferAttachment &other) | |
| : mType(other.mType), | |
| mTarget(other.mTarget) | |
| { | |
| mResource.set(other.mResource.get()); | |
| } | |
| FramebufferAttachment &operator=(const FramebufferAttachment &other) | |
| { | |
| mType = other.mType; | |
| mTarget = other.mTarget; | |
| mResource.set(other.mResource.get()); | |
| return *this; | |
| } | |
| ~FramebufferAttachment(); | |
| // A framebuffer attachment points to one of three types of resources: Renderbuffers, | |
| // Textures and egl::Surface. The "Target" struct indicates which part of the | |
| // object an attachment references. For the three types: | |
| // - a Renderbuffer has a unique renderable target, and needs no target index | |
| // - a Texture has targets for every image and uses an ImageIndex | |
| // - a Surface has targets for Color and Depth/Stencil, and uses the attachment binding | |
| class Target | |
| { | |
| public: | |
| Target(GLenum binding, const ImageIndex &imageIndex); | |
| Target(const Target &other); | |
| Target &operator=(const Target &other); | |
| GLenum binding() const { return mBinding; } | |
| const ImageIndex &textureIndex() const { return mTextureIndex; } | |
| private: | |
| GLenum mBinding; | |
| ImageIndex mTextureIndex; | |
| }; | |
| void detach(); | |
| void attach(GLenum type, | |
| GLenum binding, | |
| const ImageIndex &textureIndex, | |
| FramebufferAttachmentObject *resource); | |
| // Helper methods | |
| GLuint getRedSize() const; | |
| GLuint getGreenSize() const; | |
| GLuint getBlueSize() const; | |
| GLuint getAlphaSize() const; | |
| GLuint getDepthSize() const; | |
| GLuint getStencilSize() const; | |
| GLenum getComponentType() const; | |
| GLenum getColorEncoding() const; | |
| bool isTextureWithId(GLuint textureId) const { return mType == GL_TEXTURE && id() == textureId; } | |
| bool isRenderbufferWithId(GLuint renderbufferId) const { return mType == GL_RENDERBUFFER && id() == renderbufferId; } | |
| GLenum getBinding() const { return mTarget.binding(); } | |
| GLuint id() const { return mResource.id(); } | |
| // These methods are only legal to call on Texture attachments | |
| const ImageIndex &getTextureImageIndex() const; | |
| GLenum cubeMapFace() const; | |
| GLint mipLevel() const; | |
| GLint layer() const; | |
| GLsizei getWidth() const; | |
| GLsizei getHeight() const; | |
| GLenum getInternalFormat() const; | |
| GLsizei getSamples() const; | |
| GLenum type() const { return mType; } | |
| bool isAttached() const { return mType != GL_NONE; } | |
| Renderbuffer *getRenderbuffer() const; | |
| Texture *getTexture() const; | |
| const egl::Surface *getSurface() const; | |
| // "T" must be static_castable from FramebufferAttachmentRenderTarget | |
| template <typename T> | |
| gl::Error getRenderTarget(T **rtOut) const | |
| { | |
| // Cast through the pointer-to-pointer type | |
| rx::FramebufferAttachmentRenderTarget *rtPtr = nullptr; | |
| gl::Error error = getRenderTarget(&rtPtr); | |
| *rtOut = static_cast<T*>(rtPtr); | |
| return error; | |
| } | |
| private: | |
| gl::Error getRenderTarget(rx::FramebufferAttachmentRenderTarget **rtOut) const; | |
| GLenum mType; | |
| Target mTarget; | |
| BindingPointer<FramebufferAttachmentObject> mResource; | |
| }; | |
| // A base class for objects that FBO Attachments may point to. | |
| class FramebufferAttachmentObject : public RefCountObject | |
| { | |
| public: | |
| FramebufferAttachmentObject(GLuint id) : RefCountObject(id) {} | |
| virtual GLsizei getAttachmentWidth(const FramebufferAttachment::Target &target) const = 0; | |
| virtual GLsizei getAttachmentHeight(const FramebufferAttachment::Target &target) const = 0; | |
| virtual GLenum getAttachmentInternalFormat(const FramebufferAttachment::Target &target) const = 0; | |
| virtual GLsizei getAttachmentSamples(const FramebufferAttachment::Target &target) const = 0; | |
| Error getAttachmentRenderTarget(const FramebufferAttachment::Target &target, | |
| rx::FramebufferAttachmentRenderTarget **rtOut) const; | |
| protected: | |
| virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0; | |
| }; | |
| inline GLsizei FramebufferAttachment::getWidth() const | |
| { | |
| return mResource->getAttachmentWidth(mTarget); | |
| } | |
| inline GLsizei FramebufferAttachment::getHeight() const | |
| { | |
| return mResource->getAttachmentHeight(mTarget); | |
| } | |
| inline GLenum FramebufferAttachment::getInternalFormat() const | |
| { | |
| return mResource->getAttachmentInternalFormat(mTarget); | |
| } | |
| inline GLsizei FramebufferAttachment::getSamples() const | |
| { | |
| return mResource->getAttachmentSamples(mTarget); | |
| } | |
| inline gl::Error FramebufferAttachment::getRenderTarget(rx::FramebufferAttachmentRenderTarget **rtOut) const | |
| { | |
| return mResource->getAttachmentRenderTarget(mTarget, rtOut); | |
| } | |
| } // namespace gl | |
| namespace rx | |
| { | |
| class FramebufferAttachmentObjectImpl : angle::NonCopyable | |
| { | |
| public: | |
| FramebufferAttachmentObjectImpl() {} | |
| virtual ~FramebufferAttachmentObjectImpl() {} | |
| virtual gl::Error getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, | |
| FramebufferAttachmentRenderTarget **rtOut) = 0; | |
| }; | |
| } // namespace rx | |
| namespace gl | |
| { | |
| inline Error FramebufferAttachmentObject::getAttachmentRenderTarget( | |
| const FramebufferAttachment::Target &target, | |
| rx::FramebufferAttachmentRenderTarget **rtOut) const | |
| { | |
| return getAttachmentImpl()->getAttachmentRenderTarget(target, rtOut); | |
| } | |
| } | |
| #endif // LIBANGLE_FRAMEBUFFERATTACHMENT_H_ |