• 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/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:
FramebufferAttachmentRenderTarget()34     FramebufferAttachmentRenderTarget() {}
~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::UniqueSerial framebufferSerial);
64 
65     FramebufferAttachment(FramebufferAttachment &&other);
66     FramebufferAttachment &operator=(FramebufferAttachment &&other);
67 
68     ~FramebufferAttachment();
69 
70     void detach(const Context *context, rx::UniqueSerial 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::UniqueSerial 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 
isTextureWithId(TextureID textureId)92     bool isTextureWithId(TextureID textureId) const
93     {
94         return mType == GL_TEXTURE && id() == textureId.value;
95     }
isExternalTexture()96     bool isExternalTexture() const
97     {
98         return mType == GL_TEXTURE && getTextureImageIndex().getType() == gl::TextureType::External;
99     }
isRenderbufferWithId(GLuint renderbufferId)100     bool isRenderbufferWithId(GLuint renderbufferId) const
101     {
102         return mType == GL_RENDERBUFFER && id() == renderbufferId;
103     }
104 
getBinding()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 
getNumViews()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;
type()132     GLenum type() const { return mType; }
isAttached()133     bool isAttached() const { return mType != GL_NONE; }
134     bool isRenderable(const Context *context) const;
135     bool isYUV() const;
136     // Checks whether the attachment is an external image such as AHB or dmabuf, where
137     // synchronization is done without individually naming the objects that are involved.  This
138     // excludes Vulkan images (EXT_external_objects) as they are individually listed during
139     // synchronization.
140     //
141     // This function is used to disable optimizations that involve deferring operations, as there is
142     // no efficient way to perform those deferred operations on sync if the specific objects are
143     // unknown.
144     bool isExternalImageWithoutIndividualSync() const;
145     bool hasFrontBufferUsage() const;
146     bool hasFoveatedRendering() const;
147     const gl::FoveationState *getFoveationState() const;
148 
149     Renderbuffer *getRenderbuffer() const;
150     Texture *getTexture() const;
151     const egl::Surface *getSurface() const;
152     FramebufferAttachmentObject *getResource() const;
153     InitState initState() const;
154     angle::Result initializeContents(const Context *context) const;
155     void setInitState(InitState initState) const;
156 
157     // "T" must be static_castable from FramebufferAttachmentRenderTarget
158     template <typename T>
getRenderTarget(const Context * context,GLsizei samples,T ** rtOut)159     angle::Result getRenderTarget(const Context *context, GLsizei samples, T **rtOut) const
160     {
161         static_assert(std::is_base_of<rx::FramebufferAttachmentRenderTarget, T>(),
162                       "Invalid RenderTarget class.");
163         return getRenderTargetImpl(
164             context, samples, reinterpret_cast<rx::FramebufferAttachmentRenderTarget **>(rtOut));
165     }
166 
167     bool operator==(const FramebufferAttachment &other) const;
168     bool operator!=(const FramebufferAttachment &other) const;
169 
170     static const GLsizei kDefaultNumViews;
171     static const GLint kDefaultBaseViewIndex;
172     static const GLint kDefaultRenderToTextureSamples;
173 
174   private:
175     bool isSpecified() const;
176 
177     angle::Result getRenderTargetImpl(const Context *context,
178                                       GLsizei samples,
179                                       rx::FramebufferAttachmentRenderTarget **rtOut) const;
180 
181     // A framebuffer attachment points to one of three types of resources: Renderbuffers,
182     // Textures and egl::Surface. The "Target" struct indicates which part of the
183     // object an attachment references. For the three types:
184     //   - a Renderbuffer has a unique renderable target, and needs no target index
185     //   - a Texture has targets for every image and uses an ImageIndex
186     //   - a Surface has targets for Color and Depth/Stencil, and uses the attachment binding
187     class Target
188     {
189       public:
190         Target();
191         Target(GLenum binding, const ImageIndex &imageIndex);
192         Target(const Target &other);
193         Target &operator=(const Target &other);
194 
binding()195         GLenum binding() const { return mBinding; }
textureIndex()196         const ImageIndex &textureIndex() const { return mTextureIndex; }
197 
198       private:
199         GLenum mBinding;
200         ImageIndex mTextureIndex;
201     };
202 
203     GLenum mType;
204     Target mTarget;
205     FramebufferAttachmentObject *mResource;
206     GLsizei mNumViews;
207     bool mIsMultiview;
208     GLint mBaseViewIndex;
209     // A single-sampled texture can be attached to a framebuffer either as single-sampled or as
210     // multisampled-render-to-texture.  In the latter case, |mRenderToTextureSamples| will contain
211     // the number of samples.  For renderbuffers, the number of samples is inherited from the
212     // renderbuffer itself.
213     //
214     // Note that textures cannot change storage between single and multisample once attached to a
215     // framebuffer.  Renderbuffers instead can, and caching the number of renderbuffer samples here
216     // can lead to stale data.
217     GLsizei mRenderToTextureSamples;
218 };
219 
220 // A base class for objects that FBO Attachments may point to.
221 class FramebufferAttachmentObject : public angle::Subject, public angle::ObserverInterface
222 {
223   public:
224     FramebufferAttachmentObject();
225     ~FramebufferAttachmentObject() override;
226 
227     virtual bool isAttachmentSpecified(const ImageIndex &imageIndex) const                 = 0;
228     virtual Extents getAttachmentSize(const ImageIndex &imageIndex) const                  = 0;
229     virtual Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const = 0;
230     virtual GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const               = 0;
231     virtual bool isRenderable(const Context *context,
232                               GLenum binding,
233                               const ImageIndex &imageIndex) const                          = 0;
234     virtual bool isYUV() const                                                             = 0;
235     virtual bool isExternalImageWithoutIndividualSync() const                              = 0;
236     virtual bool hasFrontBufferUsage() const                                               = 0;
237     virtual bool hasProtectedContent() const                                               = 0;
238     virtual bool hasFoveatedRendering() const                                              = 0;
239     virtual const gl::FoveationState *getFoveationState() const                            = 0;
240 
241     virtual void onAttach(const Context *context, rx::UniqueSerial framebufferSerial) = 0;
242     virtual void onDetach(const Context *context, rx::UniqueSerial framebufferSerial) = 0;
243     virtual GLuint getId() const                                                      = 0;
244 
245     // These are used for robust resource initialization.
246     virtual InitState initState(GLenum binding, const ImageIndex &imageIndex) const = 0;
247     virtual void setInitState(GLenum binding,
248                               const ImageIndex &imageIndex,
249                               InitState initState)                                  = 0;
250 
251     angle::Result getAttachmentRenderTarget(const Context *context,
252                                             GLenum binding,
253                                             const ImageIndex &imageIndex,
254                                             GLsizei samples,
255                                             rx::FramebufferAttachmentRenderTarget **rtOut) const;
256 
257     angle::Result initializeContents(const Context *context,
258                                      GLenum binding,
259                                      const ImageIndex &imageIndex);
260 
261   protected:
262     virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0;
263 };
264 
getTextureImageIndex()265 inline const ImageIndex &FramebufferAttachment::getTextureImageIndex() const
266 {
267     ASSERT(type() == GL_TEXTURE);
268     return mTarget.textureIndex();
269 }
270 
isSpecified()271 inline bool FramebufferAttachment::isSpecified() const
272 {
273     ASSERT(mResource);
274     return mResource->isAttachmentSpecified(mTarget.textureIndex());
275 }
276 
getSize()277 inline Extents FramebufferAttachment::getSize() const
278 {
279     ASSERT(mResource);
280     return mResource->getAttachmentSize(mTarget.textureIndex());
281 }
282 
getFormat()283 inline Format FramebufferAttachment::getFormat() const
284 {
285     ASSERT(mResource);
286     return mResource->getAttachmentFormat(mTarget.binding(), mTarget.textureIndex());
287 }
288 
getSamples()289 inline GLsizei FramebufferAttachment::getSamples() const
290 {
291     return isRenderToTexture() ? getRenderToTextureSamples() : getResourceSamples();
292 }
293 
getResourceSamples()294 inline GLsizei FramebufferAttachment::getResourceSamples() const
295 {
296     ASSERT(mResource);
297     return mResource->getAttachmentSamples(mTarget.textureIndex());
298 }
299 
getRenderTargetImpl(const Context * context,GLsizei samples,rx::FramebufferAttachmentRenderTarget ** rtOut)300 inline angle::Result FramebufferAttachment::getRenderTargetImpl(
301     const Context *context,
302     GLsizei samples,
303     rx::FramebufferAttachmentRenderTarget **rtOut) const
304 {
305     ASSERT(mResource);
306     return mResource->getAttachmentRenderTarget(context, mTarget.binding(), mTarget.textureIndex(),
307                                                 samples, rtOut);
308 }
309 
isRenderable(const Context * context)310 inline bool FramebufferAttachment::isRenderable(const Context *context) const
311 {
312     ASSERT(mResource);
313     return mResource->isRenderable(context, mTarget.binding(), mTarget.textureIndex());
314 }
315 
isYUV()316 inline bool FramebufferAttachment::isYUV() const
317 {
318     ASSERT(mResource);
319     return mResource->isYUV();
320 }
321 
isExternalImageWithoutIndividualSync()322 inline bool FramebufferAttachment::isExternalImageWithoutIndividualSync() const
323 {
324     ASSERT(mResource);
325     return mResource->isExternalImageWithoutIndividualSync();
326 }
327 
hasFrontBufferUsage()328 inline bool FramebufferAttachment::hasFrontBufferUsage() const
329 {
330     ASSERT(mResource);
331     return mResource->hasFrontBufferUsage();
332 }
333 
hasFoveatedRendering()334 inline bool FramebufferAttachment::hasFoveatedRendering() const
335 {
336     ASSERT(mResource);
337     return mResource->hasFoveatedRendering();
338 }
339 
getFoveationState()340 inline const gl::FoveationState *FramebufferAttachment::getFoveationState() const
341 {
342     ASSERT(mResource);
343     return mResource->getFoveationState();
344 }
345 }  // namespace gl
346 
347 #endif  // LIBANGLE_FRAMEBUFFERATTACHMENT_H_
348