• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/formatutils.h"
19 #include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h"
20 
21 namespace egl
22 {
23 class Surface;
24 }
25 
26 namespace rx
27 {
28 // An implementation-specific object associated with an attachment.
29 
30 class FramebufferAttachmentRenderTarget : angle::NonCopyable
31 {
32   public:
FramebufferAttachmentRenderTarget()33     FramebufferAttachmentRenderTarget() {}
~FramebufferAttachmentRenderTarget()34     virtual ~FramebufferAttachmentRenderTarget() {}
35 };
36 
37 class FramebufferAttachmentObjectImpl;
38 }  // namespace rx
39 
40 namespace gl
41 {
42 class FramebufferAttachmentObject;
43 class Renderbuffer;
44 class Texture;
45 
46 enum class InitState
47 {
48     MayNeedInit,
49     Initialized,
50 };
51 
52 // FramebufferAttachment implements a GL framebuffer attachment.
53 // Attachments are "light" containers, which store pointers to ref-counted GL objects.
54 // We support GL texture (2D/3D/Cube/2D array) and renderbuffer object attachments.
55 // Note: Our old naming scheme used the term "Renderbuffer" for both GL renderbuffers and for
56 // framebuffer attachments, which confused their usage.
57 
58 class FramebufferAttachment final
59 {
60   public:
61     FramebufferAttachment();
62 
63     FramebufferAttachment(const Context *context,
64                           GLenum type,
65                           GLenum binding,
66                           const ImageIndex &textureIndex,
67                           FramebufferAttachmentObject *resource);
68 
69     FramebufferAttachment(FramebufferAttachment &&other);
70     FramebufferAttachment &operator=(FramebufferAttachment &&other);
71 
72     ~FramebufferAttachment();
73 
74     void detach(const Context *context);
75     void attach(const Context *context,
76                 GLenum type,
77                 GLenum binding,
78                 const ImageIndex &textureIndex,
79                 FramebufferAttachmentObject *resource,
80                 GLsizei numViews,
81                 GLuint baseViewIndex,
82                 bool isMultiview);
83 
84     // Helper methods
85     GLuint getRedSize() const;
86     GLuint getGreenSize() const;
87     GLuint getBlueSize() const;
88     GLuint getAlphaSize() const;
89     GLuint getDepthSize() const;
90     GLuint getStencilSize() const;
91     GLenum getComponentType() const;
92     GLenum getColorEncoding() const;
93 
isTextureWithId(GLuint textureId)94     bool isTextureWithId(GLuint textureId) const
95     {
96         return mType == GL_TEXTURE && id() == textureId;
97     }
isRenderbufferWithId(GLuint renderbufferId)98     bool isRenderbufferWithId(GLuint renderbufferId) const
99     {
100         return mType == GL_RENDERBUFFER && id() == renderbufferId;
101     }
102 
getBinding()103     GLenum getBinding() const { return mTarget.binding(); }
104     GLuint id() const;
105 
106     // These methods are only legal to call on Texture attachments
107     const ImageIndex &getTextureImageIndex() const;
108     TextureTarget cubeMapFace() const;
109     GLint mipLevel() const;
110     GLint layer() const;
111     bool isLayered() const;
112 
getNumViews()113     GLsizei getNumViews() const { return mNumViews; }
114 
115     bool isMultiview() const;
116     GLint getBaseViewIndex() const;
117 
118     // The size of the underlying resource the attachment points to. The 'depth' value will
119     // correspond to a 3D texture depth or the layer count of a 2D array texture. For Surfaces and
120     // Renderbuffers, it will always be 1.
121     Extents getSize() const;
122     Format getFormat() const;
123     GLsizei getSamples() const;
type()124     GLenum type() const { return mType; }
isAttached()125     bool isAttached() const { return mType != GL_NONE; }
126     bool isRenderable(const Context *context) const;
127 
128     Renderbuffer *getRenderbuffer() const;
129     Texture *getTexture() const;
130     const egl::Surface *getSurface() const;
131     FramebufferAttachmentObject *getResource() const;
132     InitState initState() const;
133     angle::Result initializeContents(const Context *context);
134     void setInitState(InitState initState) const;
135 
136     // "T" must be static_castable from FramebufferAttachmentRenderTarget
137     template <typename T>
getRenderTarget(const Context * context,T ** rtOut)138     angle::Result getRenderTarget(const Context *context, T **rtOut) const
139     {
140         static_assert(std::is_base_of<rx::FramebufferAttachmentRenderTarget, T>(),
141                       "Invalid RenderTarget class.");
142         return getRenderTargetImpl(
143             context, reinterpret_cast<rx::FramebufferAttachmentRenderTarget **>(rtOut));
144     }
145 
146     bool operator==(const FramebufferAttachment &other) const;
147     bool operator!=(const FramebufferAttachment &other) const;
148 
149     static const GLsizei kDefaultNumViews;
150     static const GLint kDefaultBaseViewIndex;
151 
152   private:
153     angle::Result getRenderTargetImpl(const Context *context,
154                                       rx::FramebufferAttachmentRenderTarget **rtOut) const;
155 
156     // A framebuffer attachment points to one of three types of resources: Renderbuffers,
157     // Textures and egl::Surface. The "Target" struct indicates which part of the
158     // object an attachment references. For the three types:
159     //   - a Renderbuffer has a unique renderable target, and needs no target index
160     //   - a Texture has targets for every image and uses an ImageIndex
161     //   - a Surface has targets for Color and Depth/Stencil, and uses the attachment binding
162     class Target
163     {
164       public:
165         Target();
166         Target(GLenum binding, const ImageIndex &imageIndex);
167         Target(const Target &other);
168         Target &operator=(const Target &other);
169 
binding()170         GLenum binding() const { return mBinding; }
textureIndex()171         const ImageIndex &textureIndex() const { return mTextureIndex; }
172 
173       private:
174         GLenum mBinding;
175         ImageIndex mTextureIndex;
176     };
177 
178     GLenum mType;
179     Target mTarget;
180     FramebufferAttachmentObject *mResource;
181     GLsizei mNumViews;
182     bool mIsMultiview;
183     GLint mBaseViewIndex;
184 };
185 
186 // A base class for objects that FBO Attachments may point to.
187 class FramebufferAttachmentObject : public angle::Subject
188 {
189   public:
190     FramebufferAttachmentObject();
191     ~FramebufferAttachmentObject() override;
192 
193     virtual Extents getAttachmentSize(const ImageIndex &imageIndex) const                  = 0;
194     virtual Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const = 0;
195     virtual GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const               = 0;
196     virtual bool isRenderable(const Context *context,
197                               GLenum binding,
198                               const ImageIndex &imageIndex) const                          = 0;
199 
200     virtual void onAttach(const Context *context) = 0;
201     virtual void onDetach(const Context *context) = 0;
202     virtual GLuint getId() const                  = 0;
203 
204     // These are used for robust resource initialization.
205     virtual InitState initState(const ImageIndex &imageIndex) const              = 0;
206     virtual void setInitState(const ImageIndex &imageIndex, InitState initState) = 0;
207 
208     angle::Result getAttachmentRenderTarget(const Context *context,
209                                             GLenum binding,
210                                             const ImageIndex &imageIndex,
211                                             rx::FramebufferAttachmentRenderTarget **rtOut) const;
212 
213     angle::Result initializeContents(const Context *context, const ImageIndex &imageIndex);
214 
215   protected:
216     virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0;
217 };
218 
getTextureImageIndex()219 inline const ImageIndex &FramebufferAttachment::getTextureImageIndex() const
220 {
221     ASSERT(type() == GL_TEXTURE);
222     return mTarget.textureIndex();
223 }
224 
getSize()225 inline Extents FramebufferAttachment::getSize() const
226 {
227     ASSERT(mResource);
228     return mResource->getAttachmentSize(mTarget.textureIndex());
229 }
230 
getFormat()231 inline Format FramebufferAttachment::getFormat() const
232 {
233     ASSERT(mResource);
234     return mResource->getAttachmentFormat(mTarget.binding(), mTarget.textureIndex());
235 }
236 
getSamples()237 inline GLsizei FramebufferAttachment::getSamples() const
238 {
239     ASSERT(mResource);
240     return mResource->getAttachmentSamples(mTarget.textureIndex());
241 }
242 
getRenderTargetImpl(const Context * context,rx::FramebufferAttachmentRenderTarget ** rtOut)243 inline angle::Result FramebufferAttachment::getRenderTargetImpl(
244     const Context *context,
245     rx::FramebufferAttachmentRenderTarget **rtOut) const
246 {
247     ASSERT(mResource);
248     return mResource->getAttachmentRenderTarget(context, mTarget.binding(), mTarget.textureIndex(),
249                                                 rtOut);
250 }
251 
isRenderable(const Context * context)252 inline bool FramebufferAttachment::isRenderable(const Context *context) const
253 {
254     ASSERT(mResource);
255     return mResource->isRenderable(context, mTarget.binding(), mTarget.textureIndex());
256 }
257 
258 }  // namespace gl
259 
260 #endif  // LIBANGLE_FRAMEBUFFERATTACHMENT_H_
261