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 22namespace egl 23{ 24class Surface; 25} 26 27namespace rx 28{ 29// An implementation-specific object associated with an attachment. 30 31class FramebufferAttachmentRenderTarget : angle::NonCopyable 32{ 33 public: 34 FramebufferAttachmentRenderTarget() {} 35 virtual ~FramebufferAttachmentRenderTarget() {} 36}; 37 38class FramebufferAttachmentObjectImpl; 39} // namespace rx 40 41namespace gl 42{ 43class FramebufferAttachmentObject; 44class Renderbuffer; 45class 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 53class 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 137 Renderbuffer *getRenderbuffer() const; 138 Texture *getTexture() const; 139 const egl::Surface *getSurface() const; 140 FramebufferAttachmentObject *getResource() const; 141 InitState initState() const; 142 angle::Result initializeContents(const Context *context); 143 void setInitState(InitState initState) const; 144 145 // "T" must be static_castable from FramebufferAttachmentRenderTarget 146 template <typename T> 147 angle::Result getRenderTarget(const Context *context, GLsizei samples, T **rtOut) const 148 { 149 static_assert(std::is_base_of<rx::FramebufferAttachmentRenderTarget, T>(), 150 "Invalid RenderTarget class."); 151 return getRenderTargetImpl( 152 context, samples, reinterpret_cast<rx::FramebufferAttachmentRenderTarget **>(rtOut)); 153 } 154 155 bool operator==(const FramebufferAttachment &other) const; 156 bool operator!=(const FramebufferAttachment &other) const; 157 158 static const GLsizei kDefaultNumViews; 159 static const GLint kDefaultBaseViewIndex; 160 static const GLint kDefaultRenderToTextureSamples; 161 162 private: 163 angle::Result getRenderTargetImpl(const Context *context, 164 GLsizei samples, 165 rx::FramebufferAttachmentRenderTarget **rtOut) const; 166 167 // A framebuffer attachment points to one of three types of resources: Renderbuffers, 168 // Textures and egl::Surface. The "Target" struct indicates which part of the 169 // object an attachment references. For the three types: 170 // - a Renderbuffer has a unique renderable target, and needs no target index 171 // - a Texture has targets for every image and uses an ImageIndex 172 // - a Surface has targets for Color and Depth/Stencil, and uses the attachment binding 173 class Target 174 { 175 public: 176 Target(); 177 Target(GLenum binding, const ImageIndex &imageIndex); 178 Target(const Target &other); 179 Target &operator=(const Target &other); 180 181 GLenum binding() const { return mBinding; } 182 const ImageIndex &textureIndex() const { return mTextureIndex; } 183 184 private: 185 GLenum mBinding; 186 ImageIndex mTextureIndex; 187 }; 188 189 GLenum mType; 190 Target mTarget; 191 FramebufferAttachmentObject *mResource; 192 GLsizei mNumViews; 193 bool mIsMultiview; 194 GLint mBaseViewIndex; 195 // A single-sampled texture can be attached to a framebuffer either as single-sampled or as 196 // multisampled-render-to-texture. In the latter case, |mRenderToTextureSamples| will contain 197 // the number of samples. For renderbuffers, the number of samples is inherited from the 198 // renderbuffer itself. 199 // 200 // Note that textures cannot change storage between single and multisample once attached to a 201 // framebuffer. Renderbuffers instead can, and caching the number of renderbuffer samples here 202 // can lead to stale data. 203 GLsizei mRenderToTextureSamples; 204}; 205 206// A base class for objects that FBO Attachments may point to. 207class FramebufferAttachmentObject : public angle::Subject, public angle::ObserverInterface 208{ 209 public: 210 FramebufferAttachmentObject(); 211 ~FramebufferAttachmentObject() override; 212 213 virtual Extents getAttachmentSize(const ImageIndex &imageIndex) const = 0; 214 virtual Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const = 0; 215 virtual GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const = 0; 216 virtual bool isRenderable(const Context *context, 217 GLenum binding, 218 const ImageIndex &imageIndex) const = 0; 219 virtual bool isYUV() const = 0; 220 virtual bool hasProtectedContent() const = 0; 221 222 virtual void onAttach(const Context *context, rx::Serial framebufferSerial) = 0; 223 virtual void onDetach(const Context *context, rx::Serial framebufferSerial) = 0; 224 virtual GLuint getId() const = 0; 225 226 // These are used for robust resource initialization. 227 virtual InitState initState(const ImageIndex &imageIndex) const = 0; 228 virtual void setInitState(const ImageIndex &imageIndex, InitState initState) = 0; 229 230 angle::Result getAttachmentRenderTarget(const Context *context, 231 GLenum binding, 232 const ImageIndex &imageIndex, 233 GLsizei samples, 234 rx::FramebufferAttachmentRenderTarget **rtOut) const; 235 236 angle::Result initializeContents(const Context *context, const ImageIndex &imageIndex); 237 238 protected: 239 virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0; 240}; 241 242inline const ImageIndex &FramebufferAttachment::getTextureImageIndex() const 243{ 244 ASSERT(type() == GL_TEXTURE); 245 return mTarget.textureIndex(); 246} 247 248inline Extents FramebufferAttachment::getSize() const 249{ 250 ASSERT(mResource); 251 return mResource->getAttachmentSize(mTarget.textureIndex()); 252} 253 254inline Format FramebufferAttachment::getFormat() const 255{ 256 ASSERT(mResource); 257 return mResource->getAttachmentFormat(mTarget.binding(), mTarget.textureIndex()); 258} 259 260inline GLsizei FramebufferAttachment::getSamples() const 261{ 262 return isRenderToTexture() ? getRenderToTextureSamples() : getResourceSamples(); 263} 264 265inline GLsizei FramebufferAttachment::getResourceSamples() const 266{ 267 ASSERT(mResource); 268 return mResource->getAttachmentSamples(mTarget.textureIndex()); 269} 270 271inline angle::Result FramebufferAttachment::getRenderTargetImpl( 272 const Context *context, 273 GLsizei samples, 274 rx::FramebufferAttachmentRenderTarget **rtOut) const 275{ 276 ASSERT(mResource); 277 return mResource->getAttachmentRenderTarget(context, mTarget.binding(), mTarget.textureIndex(), 278 samples, rtOut); 279} 280 281inline bool FramebufferAttachment::isRenderable(const Context *context) const 282{ 283 ASSERT(mResource); 284 return mResource->isRenderable(context, mTarget.binding(), mTarget.textureIndex()); 285} 286 287inline bool FramebufferAttachment::isYUV() const 288{ 289 ASSERT(mResource); 290 return mResource->isYUV(); 291} 292 293} // namespace gl 294 295#endif // LIBANGLE_FRAMEBUFFERATTACHMENT_H_ 296