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