1cb93a386Sopenharmony_ci// 2cb93a386Sopenharmony_ci// Copyright 2014 The ANGLE Project Authors. All rights reserved. 3cb93a386Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 4cb93a386Sopenharmony_ci// found in the LICENSE file. 5cb93a386Sopenharmony_ci// 6cb93a386Sopenharmony_ci 7cb93a386Sopenharmony_ci// FramebufferAttachment.h: Defines the wrapper class gl::FramebufferAttachment, as well as the 8cb93a386Sopenharmony_ci// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108. 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#ifndef LIBANGLE_FRAMEBUFFERATTACHMENT_H_ 11cb93a386Sopenharmony_ci#define LIBANGLE_FRAMEBUFFERATTACHMENT_H_ 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_ci#include "angle_gl.h" 14cb93a386Sopenharmony_ci#include "common/angleutils.h" 15cb93a386Sopenharmony_ci#include "libANGLE/Error.h" 16cb93a386Sopenharmony_ci#include "libANGLE/ImageIndex.h" 17cb93a386Sopenharmony_ci#include "libANGLE/Observer.h" 18cb93a386Sopenharmony_ci#include "libANGLE/angletypes.h" 19cb93a386Sopenharmony_ci#include "libANGLE/formatutils.h" 20cb93a386Sopenharmony_ci#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h" 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_cinamespace egl 23cb93a386Sopenharmony_ci{ 24cb93a386Sopenharmony_ciclass Surface; 25cb93a386Sopenharmony_ci} 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_cinamespace rx 28cb93a386Sopenharmony_ci{ 29cb93a386Sopenharmony_ci// An implementation-specific object associated with an attachment. 30cb93a386Sopenharmony_ci 31cb93a386Sopenharmony_ciclass FramebufferAttachmentRenderTarget : angle::NonCopyable 32cb93a386Sopenharmony_ci{ 33cb93a386Sopenharmony_ci public: 34cb93a386Sopenharmony_ci FramebufferAttachmentRenderTarget() {} 35cb93a386Sopenharmony_ci virtual ~FramebufferAttachmentRenderTarget() {} 36cb93a386Sopenharmony_ci}; 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ciclass FramebufferAttachmentObjectImpl; 39cb93a386Sopenharmony_ci} // namespace rx 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_cinamespace gl 42cb93a386Sopenharmony_ci{ 43cb93a386Sopenharmony_ciclass FramebufferAttachmentObject; 44cb93a386Sopenharmony_ciclass Renderbuffer; 45cb93a386Sopenharmony_ciclass Texture; 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci// FramebufferAttachment implements a GL framebuffer attachment. 48cb93a386Sopenharmony_ci// Attachments are "light" containers, which store pointers to ref-counted GL objects. 49cb93a386Sopenharmony_ci// We support GL texture (2D/3D/Cube/2D array) and renderbuffer object attachments. 50cb93a386Sopenharmony_ci// Note: Our old naming scheme used the term "Renderbuffer" for both GL renderbuffers and for 51cb93a386Sopenharmony_ci// framebuffer attachments, which confused their usage. 52cb93a386Sopenharmony_ci 53cb93a386Sopenharmony_ciclass FramebufferAttachment final 54cb93a386Sopenharmony_ci{ 55cb93a386Sopenharmony_ci public: 56cb93a386Sopenharmony_ci FramebufferAttachment(); 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_ci FramebufferAttachment(const Context *context, 59cb93a386Sopenharmony_ci GLenum type, 60cb93a386Sopenharmony_ci GLenum binding, 61cb93a386Sopenharmony_ci const ImageIndex &textureIndex, 62cb93a386Sopenharmony_ci FramebufferAttachmentObject *resource, 63cb93a386Sopenharmony_ci rx::Serial framebufferSerial); 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci FramebufferAttachment(FramebufferAttachment &&other); 66cb93a386Sopenharmony_ci FramebufferAttachment &operator=(FramebufferAttachment &&other); 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_ci ~FramebufferAttachment(); 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci void detach(const Context *context, rx::Serial framebufferSerial); 71cb93a386Sopenharmony_ci void attach(const Context *context, 72cb93a386Sopenharmony_ci GLenum type, 73cb93a386Sopenharmony_ci GLenum binding, 74cb93a386Sopenharmony_ci const ImageIndex &textureIndex, 75cb93a386Sopenharmony_ci FramebufferAttachmentObject *resource, 76cb93a386Sopenharmony_ci GLsizei numViews, 77cb93a386Sopenharmony_ci GLuint baseViewIndex, 78cb93a386Sopenharmony_ci bool isMultiview, 79cb93a386Sopenharmony_ci GLsizei samples, 80cb93a386Sopenharmony_ci rx::Serial framebufferSerial); 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci // Helper methods 83cb93a386Sopenharmony_ci GLuint getRedSize() const; 84cb93a386Sopenharmony_ci GLuint getGreenSize() const; 85cb93a386Sopenharmony_ci GLuint getBlueSize() const; 86cb93a386Sopenharmony_ci GLuint getAlphaSize() const; 87cb93a386Sopenharmony_ci GLuint getDepthSize() const; 88cb93a386Sopenharmony_ci GLuint getStencilSize() const; 89cb93a386Sopenharmony_ci GLenum getComponentType() const; 90cb93a386Sopenharmony_ci GLenum getColorEncoding() const; 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ci bool isTextureWithId(TextureID textureId) const 93cb93a386Sopenharmony_ci { 94cb93a386Sopenharmony_ci return mType == GL_TEXTURE && id() == textureId.value; 95cb93a386Sopenharmony_ci } 96cb93a386Sopenharmony_ci bool isExternalTexture() const 97cb93a386Sopenharmony_ci { 98cb93a386Sopenharmony_ci return mType == GL_TEXTURE && getTextureImageIndex().getType() == gl::TextureType::External; 99cb93a386Sopenharmony_ci } 100cb93a386Sopenharmony_ci bool isRenderbufferWithId(GLuint renderbufferId) const 101cb93a386Sopenharmony_ci { 102cb93a386Sopenharmony_ci return mType == GL_RENDERBUFFER && id() == renderbufferId; 103cb93a386Sopenharmony_ci } 104cb93a386Sopenharmony_ci 105cb93a386Sopenharmony_ci GLenum getBinding() const { return mTarget.binding(); } 106cb93a386Sopenharmony_ci GLuint id() const; 107cb93a386Sopenharmony_ci 108cb93a386Sopenharmony_ci // These methods are only legal to call on Texture attachments 109cb93a386Sopenharmony_ci const ImageIndex &getTextureImageIndex() const; 110cb93a386Sopenharmony_ci TextureTarget cubeMapFace() const; 111cb93a386Sopenharmony_ci GLint mipLevel() const; 112cb93a386Sopenharmony_ci GLint layer() const; 113cb93a386Sopenharmony_ci bool isLayered() const; 114cb93a386Sopenharmony_ci 115cb93a386Sopenharmony_ci GLsizei getNumViews() const { return mNumViews; } 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_ci bool isMultiview() const; 118cb93a386Sopenharmony_ci GLint getBaseViewIndex() const; 119cb93a386Sopenharmony_ci 120cb93a386Sopenharmony_ci bool isRenderToTexture() const; 121cb93a386Sopenharmony_ci GLsizei getRenderToTextureSamples() const; 122cb93a386Sopenharmony_ci 123cb93a386Sopenharmony_ci // The size of the underlying resource the attachment points to. The 'depth' value will 124cb93a386Sopenharmony_ci // correspond to a 3D texture depth or the layer count of a 2D array texture. For Surfaces and 125cb93a386Sopenharmony_ci // Renderbuffers, it will always be 1. 126cb93a386Sopenharmony_ci Extents getSize() const; 127cb93a386Sopenharmony_ci Format getFormat() const; 128cb93a386Sopenharmony_ci GLsizei getSamples() const; 129cb93a386Sopenharmony_ci // This will always return the actual sample count of the attachment even if 130cb93a386Sopenharmony_ci // render_to_texture extension is active on this FBattachment object. 131cb93a386Sopenharmony_ci GLsizei getResourceSamples() const; 132cb93a386Sopenharmony_ci GLenum type() const { return mType; } 133cb93a386Sopenharmony_ci bool isAttached() const { return mType != GL_NONE; } 134cb93a386Sopenharmony_ci bool isRenderable(const Context *context) const; 135cb93a386Sopenharmony_ci bool isYUV() const; 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_ci Renderbuffer *getRenderbuffer() const; 138cb93a386Sopenharmony_ci Texture *getTexture() const; 139cb93a386Sopenharmony_ci const egl::Surface *getSurface() const; 140cb93a386Sopenharmony_ci FramebufferAttachmentObject *getResource() const; 141cb93a386Sopenharmony_ci InitState initState() const; 142cb93a386Sopenharmony_ci angle::Result initializeContents(const Context *context); 143cb93a386Sopenharmony_ci void setInitState(InitState initState) const; 144cb93a386Sopenharmony_ci 145cb93a386Sopenharmony_ci // "T" must be static_castable from FramebufferAttachmentRenderTarget 146cb93a386Sopenharmony_ci template <typename T> 147cb93a386Sopenharmony_ci angle::Result getRenderTarget(const Context *context, GLsizei samples, T **rtOut) const 148cb93a386Sopenharmony_ci { 149cb93a386Sopenharmony_ci static_assert(std::is_base_of<rx::FramebufferAttachmentRenderTarget, T>(), 150cb93a386Sopenharmony_ci "Invalid RenderTarget class."); 151cb93a386Sopenharmony_ci return getRenderTargetImpl( 152cb93a386Sopenharmony_ci context, samples, reinterpret_cast<rx::FramebufferAttachmentRenderTarget **>(rtOut)); 153cb93a386Sopenharmony_ci } 154cb93a386Sopenharmony_ci 155cb93a386Sopenharmony_ci bool operator==(const FramebufferAttachment &other) const; 156cb93a386Sopenharmony_ci bool operator!=(const FramebufferAttachment &other) const; 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_ci static const GLsizei kDefaultNumViews; 159cb93a386Sopenharmony_ci static const GLint kDefaultBaseViewIndex; 160cb93a386Sopenharmony_ci static const GLint kDefaultRenderToTextureSamples; 161cb93a386Sopenharmony_ci 162cb93a386Sopenharmony_ci private: 163cb93a386Sopenharmony_ci angle::Result getRenderTargetImpl(const Context *context, 164cb93a386Sopenharmony_ci GLsizei samples, 165cb93a386Sopenharmony_ci rx::FramebufferAttachmentRenderTarget **rtOut) const; 166cb93a386Sopenharmony_ci 167cb93a386Sopenharmony_ci // A framebuffer attachment points to one of three types of resources: Renderbuffers, 168cb93a386Sopenharmony_ci // Textures and egl::Surface. The "Target" struct indicates which part of the 169cb93a386Sopenharmony_ci // object an attachment references. For the three types: 170cb93a386Sopenharmony_ci // - a Renderbuffer has a unique renderable target, and needs no target index 171cb93a386Sopenharmony_ci // - a Texture has targets for every image and uses an ImageIndex 172cb93a386Sopenharmony_ci // - a Surface has targets for Color and Depth/Stencil, and uses the attachment binding 173cb93a386Sopenharmony_ci class Target 174cb93a386Sopenharmony_ci { 175cb93a386Sopenharmony_ci public: 176cb93a386Sopenharmony_ci Target(); 177cb93a386Sopenharmony_ci Target(GLenum binding, const ImageIndex &imageIndex); 178cb93a386Sopenharmony_ci Target(const Target &other); 179cb93a386Sopenharmony_ci Target &operator=(const Target &other); 180cb93a386Sopenharmony_ci 181cb93a386Sopenharmony_ci GLenum binding() const { return mBinding; } 182cb93a386Sopenharmony_ci const ImageIndex &textureIndex() const { return mTextureIndex; } 183cb93a386Sopenharmony_ci 184cb93a386Sopenharmony_ci private: 185cb93a386Sopenharmony_ci GLenum mBinding; 186cb93a386Sopenharmony_ci ImageIndex mTextureIndex; 187cb93a386Sopenharmony_ci }; 188cb93a386Sopenharmony_ci 189cb93a386Sopenharmony_ci GLenum mType; 190cb93a386Sopenharmony_ci Target mTarget; 191cb93a386Sopenharmony_ci FramebufferAttachmentObject *mResource; 192cb93a386Sopenharmony_ci GLsizei mNumViews; 193cb93a386Sopenharmony_ci bool mIsMultiview; 194cb93a386Sopenharmony_ci GLint mBaseViewIndex; 195cb93a386Sopenharmony_ci // A single-sampled texture can be attached to a framebuffer either as single-sampled or as 196cb93a386Sopenharmony_ci // multisampled-render-to-texture. In the latter case, |mRenderToTextureSamples| will contain 197cb93a386Sopenharmony_ci // the number of samples. For renderbuffers, the number of samples is inherited from the 198cb93a386Sopenharmony_ci // renderbuffer itself. 199cb93a386Sopenharmony_ci // 200cb93a386Sopenharmony_ci // Note that textures cannot change storage between single and multisample once attached to a 201cb93a386Sopenharmony_ci // framebuffer. Renderbuffers instead can, and caching the number of renderbuffer samples here 202cb93a386Sopenharmony_ci // can lead to stale data. 203cb93a386Sopenharmony_ci GLsizei mRenderToTextureSamples; 204cb93a386Sopenharmony_ci}; 205cb93a386Sopenharmony_ci 206cb93a386Sopenharmony_ci// A base class for objects that FBO Attachments may point to. 207cb93a386Sopenharmony_ciclass FramebufferAttachmentObject : public angle::Subject, public angle::ObserverInterface 208cb93a386Sopenharmony_ci{ 209cb93a386Sopenharmony_ci public: 210cb93a386Sopenharmony_ci FramebufferAttachmentObject(); 211cb93a386Sopenharmony_ci ~FramebufferAttachmentObject() override; 212cb93a386Sopenharmony_ci 213cb93a386Sopenharmony_ci virtual Extents getAttachmentSize(const ImageIndex &imageIndex) const = 0; 214cb93a386Sopenharmony_ci virtual Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const = 0; 215cb93a386Sopenharmony_ci virtual GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const = 0; 216cb93a386Sopenharmony_ci virtual bool isRenderable(const Context *context, 217cb93a386Sopenharmony_ci GLenum binding, 218cb93a386Sopenharmony_ci const ImageIndex &imageIndex) const = 0; 219cb93a386Sopenharmony_ci virtual bool isYUV() const = 0; 220cb93a386Sopenharmony_ci virtual bool hasProtectedContent() const = 0; 221cb93a386Sopenharmony_ci 222cb93a386Sopenharmony_ci virtual void onAttach(const Context *context, rx::Serial framebufferSerial) = 0; 223cb93a386Sopenharmony_ci virtual void onDetach(const Context *context, rx::Serial framebufferSerial) = 0; 224cb93a386Sopenharmony_ci virtual GLuint getId() const = 0; 225cb93a386Sopenharmony_ci 226cb93a386Sopenharmony_ci // These are used for robust resource initialization. 227cb93a386Sopenharmony_ci virtual InitState initState(const ImageIndex &imageIndex) const = 0; 228cb93a386Sopenharmony_ci virtual void setInitState(const ImageIndex &imageIndex, InitState initState) = 0; 229cb93a386Sopenharmony_ci 230cb93a386Sopenharmony_ci angle::Result getAttachmentRenderTarget(const Context *context, 231cb93a386Sopenharmony_ci GLenum binding, 232cb93a386Sopenharmony_ci const ImageIndex &imageIndex, 233cb93a386Sopenharmony_ci GLsizei samples, 234cb93a386Sopenharmony_ci rx::FramebufferAttachmentRenderTarget **rtOut) const; 235cb93a386Sopenharmony_ci 236cb93a386Sopenharmony_ci angle::Result initializeContents(const Context *context, const ImageIndex &imageIndex); 237cb93a386Sopenharmony_ci 238cb93a386Sopenharmony_ci protected: 239cb93a386Sopenharmony_ci virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0; 240cb93a386Sopenharmony_ci}; 241cb93a386Sopenharmony_ci 242cb93a386Sopenharmony_ciinline const ImageIndex &FramebufferAttachment::getTextureImageIndex() const 243cb93a386Sopenharmony_ci{ 244cb93a386Sopenharmony_ci ASSERT(type() == GL_TEXTURE); 245cb93a386Sopenharmony_ci return mTarget.textureIndex(); 246cb93a386Sopenharmony_ci} 247cb93a386Sopenharmony_ci 248cb93a386Sopenharmony_ciinline Extents FramebufferAttachment::getSize() const 249cb93a386Sopenharmony_ci{ 250cb93a386Sopenharmony_ci ASSERT(mResource); 251cb93a386Sopenharmony_ci return mResource->getAttachmentSize(mTarget.textureIndex()); 252cb93a386Sopenharmony_ci} 253cb93a386Sopenharmony_ci 254cb93a386Sopenharmony_ciinline Format FramebufferAttachment::getFormat() const 255cb93a386Sopenharmony_ci{ 256cb93a386Sopenharmony_ci ASSERT(mResource); 257cb93a386Sopenharmony_ci return mResource->getAttachmentFormat(mTarget.binding(), mTarget.textureIndex()); 258cb93a386Sopenharmony_ci} 259cb93a386Sopenharmony_ci 260cb93a386Sopenharmony_ciinline GLsizei FramebufferAttachment::getSamples() const 261cb93a386Sopenharmony_ci{ 262cb93a386Sopenharmony_ci return isRenderToTexture() ? getRenderToTextureSamples() : getResourceSamples(); 263cb93a386Sopenharmony_ci} 264cb93a386Sopenharmony_ci 265cb93a386Sopenharmony_ciinline GLsizei FramebufferAttachment::getResourceSamples() const 266cb93a386Sopenharmony_ci{ 267cb93a386Sopenharmony_ci ASSERT(mResource); 268cb93a386Sopenharmony_ci return mResource->getAttachmentSamples(mTarget.textureIndex()); 269cb93a386Sopenharmony_ci} 270cb93a386Sopenharmony_ci 271cb93a386Sopenharmony_ciinline angle::Result FramebufferAttachment::getRenderTargetImpl( 272cb93a386Sopenharmony_ci const Context *context, 273cb93a386Sopenharmony_ci GLsizei samples, 274cb93a386Sopenharmony_ci rx::FramebufferAttachmentRenderTarget **rtOut) const 275cb93a386Sopenharmony_ci{ 276cb93a386Sopenharmony_ci ASSERT(mResource); 277cb93a386Sopenharmony_ci return mResource->getAttachmentRenderTarget(context, mTarget.binding(), mTarget.textureIndex(), 278cb93a386Sopenharmony_ci samples, rtOut); 279cb93a386Sopenharmony_ci} 280cb93a386Sopenharmony_ci 281cb93a386Sopenharmony_ciinline bool FramebufferAttachment::isRenderable(const Context *context) const 282cb93a386Sopenharmony_ci{ 283cb93a386Sopenharmony_ci ASSERT(mResource); 284cb93a386Sopenharmony_ci return mResource->isRenderable(context, mTarget.binding(), mTarget.textureIndex()); 285cb93a386Sopenharmony_ci} 286cb93a386Sopenharmony_ci 287cb93a386Sopenharmony_ciinline bool FramebufferAttachment::isYUV() const 288cb93a386Sopenharmony_ci{ 289cb93a386Sopenharmony_ci ASSERT(mResource); 290cb93a386Sopenharmony_ci return mResource->isYUV(); 291cb93a386Sopenharmony_ci} 292cb93a386Sopenharmony_ci 293cb93a386Sopenharmony_ci} // namespace gl 294cb93a386Sopenharmony_ci 295cb93a386Sopenharmony_ci#endif // LIBANGLE_FRAMEBUFFERATTACHMENT_H_ 296