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