• 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.cpp: the gl::FramebufferAttachment class and its derived classes
8 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
9 
10 #include "libANGLE/FramebufferAttachment.h"
11 
12 #include "common/utilities.h"
13 #include "libANGLE/Config.h"
14 #include "libANGLE/Context.h"
15 #include "libANGLE/Renderbuffer.h"
16 #include "libANGLE/Surface.h"
17 #include "libANGLE/Texture.h"
18 #include "libANGLE/formatutils.h"
19 #include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h"
20 #include "libANGLE/renderer/FramebufferImpl.h"
21 
22 namespace gl
23 {
24 
25 ////// FramebufferAttachment::Target Implementation //////
26 
27 const GLsizei FramebufferAttachment::kDefaultNumViews    = 1;
28 const GLint FramebufferAttachment::kDefaultBaseViewIndex = 0;
29 
Target()30 FramebufferAttachment::Target::Target() : mBinding(GL_NONE), mTextureIndex() {}
31 
Target(GLenum binding,const ImageIndex & imageIndex)32 FramebufferAttachment::Target::Target(GLenum binding, const ImageIndex &imageIndex)
33     : mBinding(binding), mTextureIndex(imageIndex)
34 {}
35 
Target(const Target & other)36 FramebufferAttachment::Target::Target(const Target &other)
37     : mBinding(other.mBinding), mTextureIndex(other.mTextureIndex)
38 {}
39 
operator =(const Target & other)40 FramebufferAttachment::Target &FramebufferAttachment::Target::operator=(const Target &other)
41 {
42     this->mBinding      = other.mBinding;
43     this->mTextureIndex = other.mTextureIndex;
44     return *this;
45 }
46 
47 ////// FramebufferAttachment Implementation //////
48 
FramebufferAttachment()49 FramebufferAttachment::FramebufferAttachment()
50     : mType(GL_NONE),
51       mResource(nullptr),
52       mNumViews(kDefaultNumViews),
53       mIsMultiview(false),
54       mBaseViewIndex(kDefaultBaseViewIndex)
55 {}
56 
FramebufferAttachment(const Context * context,GLenum type,GLenum binding,const ImageIndex & textureIndex,FramebufferAttachmentObject * resource)57 FramebufferAttachment::FramebufferAttachment(const Context *context,
58                                              GLenum type,
59                                              GLenum binding,
60                                              const ImageIndex &textureIndex,
61                                              FramebufferAttachmentObject *resource)
62     : mResource(nullptr)
63 {
64     attach(context, type, binding, textureIndex, resource, kDefaultNumViews, kDefaultBaseViewIndex,
65            false);
66 }
67 
FramebufferAttachment(FramebufferAttachment && other)68 FramebufferAttachment::FramebufferAttachment(FramebufferAttachment &&other)
69     : FramebufferAttachment()
70 {
71     *this = std::move(other);
72 }
73 
operator =(FramebufferAttachment && other)74 FramebufferAttachment &FramebufferAttachment::operator=(FramebufferAttachment &&other)
75 {
76     std::swap(mType, other.mType);
77     std::swap(mTarget, other.mTarget);
78     std::swap(mResource, other.mResource);
79     std::swap(mNumViews, other.mNumViews);
80     std::swap(mIsMultiview, other.mIsMultiview);
81     std::swap(mBaseViewIndex, other.mBaseViewIndex);
82     return *this;
83 }
84 
~FramebufferAttachment()85 FramebufferAttachment::~FramebufferAttachment()
86 {
87     ASSERT(!isAttached());
88 }
89 
detach(const Context * context)90 void FramebufferAttachment::detach(const Context *context)
91 {
92     mType = GL_NONE;
93     if (mResource != nullptr)
94     {
95         mResource->onDetach(context);
96         mResource = nullptr;
97     }
98     mNumViews      = kDefaultNumViews;
99     mIsMultiview   = false;
100     mBaseViewIndex = kDefaultBaseViewIndex;
101 
102     // not technically necessary, could omit for performance
103     mTarget = Target();
104 }
105 
attach(const Context * context,GLenum type,GLenum binding,const ImageIndex & textureIndex,FramebufferAttachmentObject * resource,GLsizei numViews,GLuint baseViewIndex,bool isMultiview)106 void FramebufferAttachment::attach(const Context *context,
107                                    GLenum type,
108                                    GLenum binding,
109                                    const ImageIndex &textureIndex,
110                                    FramebufferAttachmentObject *resource,
111                                    GLsizei numViews,
112                                    GLuint baseViewIndex,
113                                    bool isMultiview)
114 {
115     if (resource == nullptr)
116     {
117         detach(context);
118         return;
119     }
120 
121     mType          = type;
122     mTarget        = Target(binding, textureIndex);
123     mNumViews      = numViews;
124     mBaseViewIndex = baseViewIndex;
125     mIsMultiview   = isMultiview;
126     resource->onAttach(context);
127 
128     if (mResource != nullptr)
129     {
130         mResource->onDetach(context);
131     }
132 
133     mResource = resource;
134 }
135 
getRedSize() const136 GLuint FramebufferAttachment::getRedSize() const
137 {
138     return getFormat().info->redBits;
139 }
140 
getGreenSize() const141 GLuint FramebufferAttachment::getGreenSize() const
142 {
143     return getFormat().info->greenBits;
144 }
145 
getBlueSize() const146 GLuint FramebufferAttachment::getBlueSize() const
147 {
148     return getFormat().info->blueBits;
149 }
150 
getAlphaSize() const151 GLuint FramebufferAttachment::getAlphaSize() const
152 {
153     return getFormat().info->alphaBits;
154 }
155 
getDepthSize() const156 GLuint FramebufferAttachment::getDepthSize() const
157 {
158     return getFormat().info->depthBits;
159 }
160 
getStencilSize() const161 GLuint FramebufferAttachment::getStencilSize() const
162 {
163     return getFormat().info->stencilBits;
164 }
165 
getComponentType() const166 GLenum FramebufferAttachment::getComponentType() const
167 {
168     return getFormat().info->componentType;
169 }
170 
getColorEncoding() const171 GLenum FramebufferAttachment::getColorEncoding() const
172 {
173     return getFormat().info->colorEncoding;
174 }
175 
id() const176 GLuint FramebufferAttachment::id() const
177 {
178     return mResource->getId();
179 }
180 
cubeMapFace() const181 TextureTarget FramebufferAttachment::cubeMapFace() const
182 {
183     ASSERT(mType == GL_TEXTURE);
184 
185     const auto &index = mTarget.textureIndex();
186     return index.getType() == TextureType::CubeMap ? index.getTarget() : TextureTarget::InvalidEnum;
187 }
188 
mipLevel() const189 GLint FramebufferAttachment::mipLevel() const
190 {
191     ASSERT(type() == GL_TEXTURE);
192     return mTarget.textureIndex().getLevelIndex();
193 }
194 
layer() const195 GLint FramebufferAttachment::layer() const
196 {
197     ASSERT(mType == GL_TEXTURE);
198 
199     const gl::ImageIndex &index = mTarget.textureIndex();
200     return (index.has3DLayer() ? index.getLayerIndex() : 0);
201 }
202 
isLayered() const203 bool FramebufferAttachment::isLayered() const
204 {
205     return mTarget.textureIndex().isLayered();
206 }
207 
isMultiview() const208 bool FramebufferAttachment::isMultiview() const
209 {
210     return mIsMultiview;
211 }
212 
getBaseViewIndex() const213 GLint FramebufferAttachment::getBaseViewIndex() const
214 {
215     return mBaseViewIndex;
216 }
217 
getTexture() const218 Texture *FramebufferAttachment::getTexture() const
219 {
220     return rx::GetAs<Texture>(mResource);
221 }
222 
getRenderbuffer() const223 Renderbuffer *FramebufferAttachment::getRenderbuffer() const
224 {
225     return rx::GetAs<Renderbuffer>(mResource);
226 }
227 
getSurface() const228 const egl::Surface *FramebufferAttachment::getSurface() const
229 {
230     return rx::GetAs<egl::Surface>(mResource);
231 }
232 
getResource() const233 FramebufferAttachmentObject *FramebufferAttachment::getResource() const
234 {
235     return mResource;
236 }
237 
operator ==(const FramebufferAttachment & other) const238 bool FramebufferAttachment::operator==(const FramebufferAttachment &other) const
239 {
240     if (mResource != other.mResource || mType != other.mType || mNumViews != other.mNumViews ||
241         mIsMultiview != other.mIsMultiview || mBaseViewIndex != other.mBaseViewIndex)
242     {
243         return false;
244     }
245 
246     if (mType == GL_TEXTURE && getTextureImageIndex() != other.getTextureImageIndex())
247     {
248         return false;
249     }
250 
251     return true;
252 }
253 
operator !=(const FramebufferAttachment & other) const254 bool FramebufferAttachment::operator!=(const FramebufferAttachment &other) const
255 {
256     return !(*this == other);
257 }
258 
initState() const259 InitState FramebufferAttachment::initState() const
260 {
261     return mResource ? mResource->initState(mTarget.textureIndex()) : InitState::Initialized;
262 }
263 
initializeContents(const Context * context)264 angle::Result FramebufferAttachment::initializeContents(const Context *context)
265 {
266     ASSERT(mResource);
267     ANGLE_TRY(mResource->initializeContents(context, mTarget.textureIndex()));
268     setInitState(InitState::Initialized);
269     return angle::Result::Continue;
270 }
271 
setInitState(InitState initState) const272 void FramebufferAttachment::setInitState(InitState initState) const
273 {
274     ASSERT(mResource);
275     mResource->setInitState(mTarget.textureIndex(), initState);
276 }
277 
278 ////// FramebufferAttachmentObject Implementation //////
279 
FramebufferAttachmentObject()280 FramebufferAttachmentObject::FramebufferAttachmentObject() {}
281 
~FramebufferAttachmentObject()282 FramebufferAttachmentObject::~FramebufferAttachmentObject() {}
283 
getAttachmentRenderTarget(const Context * context,GLenum binding,const ImageIndex & imageIndex,rx::FramebufferAttachmentRenderTarget ** rtOut) const284 angle::Result FramebufferAttachmentObject::getAttachmentRenderTarget(
285     const Context *context,
286     GLenum binding,
287     const ImageIndex &imageIndex,
288     rx::FramebufferAttachmentRenderTarget **rtOut) const
289 {
290     return getAttachmentImpl()->getAttachmentRenderTarget(context, binding, imageIndex, rtOut);
291 }
292 
initializeContents(const Context * context,const ImageIndex & imageIndex)293 angle::Result FramebufferAttachmentObject::initializeContents(const Context *context,
294                                                               const ImageIndex &imageIndex)
295 {
296     ASSERT(context->isRobustResourceInitEnabled());
297 
298     // Because gl::Texture cannot support tracking individual layer dirtiness, we only handle
299     // initializing entire mip levels for 2D array textures.
300     if (imageIndex.getType() == TextureType::_2DArray && imageIndex.hasLayer())
301     {
302         ImageIndex fullMipIndex =
303             ImageIndex::Make2DArray(imageIndex.getLevelIndex(), ImageIndex::kEntireLevel);
304         return getAttachmentImpl()->initializeContents(context, fullMipIndex);
305     }
306     else if (imageIndex.getType() == TextureType::_2DMultisampleArray && imageIndex.hasLayer())
307     {
308         ImageIndex fullMipIndex = ImageIndex::Make2DMultisampleArray(ImageIndex::kEntireLevel);
309         return getAttachmentImpl()->initializeContents(context, fullMipIndex);
310     }
311     else
312     {
313         return getAttachmentImpl()->initializeContents(context, imageIndex);
314     }
315 }
316 
317 }  // namespace gl
318