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