• 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 const GLint FramebufferAttachment::kDefaultRenderToTextureSamples = 0;
30 
Target()31 FramebufferAttachment::Target::Target() : mBinding(GL_NONE), mTextureIndex() {}
32 
Target(GLenum binding,const ImageIndex & imageIndex)33 FramebufferAttachment::Target::Target(GLenum binding, const ImageIndex &imageIndex)
34     : mBinding(binding), mTextureIndex(imageIndex)
35 {}
36 
Target(const Target & other)37 FramebufferAttachment::Target::Target(const Target &other)
38     : mBinding(other.mBinding), mTextureIndex(other.mTextureIndex)
39 {}
40 
operator =(const Target & other)41 FramebufferAttachment::Target &FramebufferAttachment::Target::operator=(const Target &other)
42 {
43     this->mBinding      = other.mBinding;
44     this->mTextureIndex = other.mTextureIndex;
45     return *this;
46 }
47 
48 ////// FramebufferAttachment Implementation //////
49 
FramebufferAttachment()50 FramebufferAttachment::FramebufferAttachment()
51     : mType(GL_NONE),
52       mResource(nullptr),
53       mNumViews(kDefaultNumViews),
54       mIsMultiview(false),
55       mBaseViewIndex(kDefaultBaseViewIndex),
56       mRenderToTextureSamples(kDefaultRenderToTextureSamples)
57 {}
58 
FramebufferAttachment(const Context * context,GLenum type,GLenum binding,const ImageIndex & textureIndex,FramebufferAttachmentObject * resource)59 FramebufferAttachment::FramebufferAttachment(const Context *context,
60                                              GLenum type,
61                                              GLenum binding,
62                                              const ImageIndex &textureIndex,
63                                              FramebufferAttachmentObject *resource)
64     : mResource(nullptr)
65 {
66     attach(context, type, binding, textureIndex, resource, kDefaultNumViews, kDefaultBaseViewIndex,
67            false, kDefaultRenderToTextureSamples);
68 }
69 
FramebufferAttachment(FramebufferAttachment && other)70 FramebufferAttachment::FramebufferAttachment(FramebufferAttachment &&other)
71     : FramebufferAttachment()
72 {
73     *this = std::move(other);
74 }
75 
operator =(FramebufferAttachment && other)76 FramebufferAttachment &FramebufferAttachment::operator=(FramebufferAttachment &&other)
77 {
78     std::swap(mType, other.mType);
79     std::swap(mTarget, other.mTarget);
80     std::swap(mResource, other.mResource);
81     std::swap(mNumViews, other.mNumViews);
82     std::swap(mIsMultiview, other.mIsMultiview);
83     std::swap(mBaseViewIndex, other.mBaseViewIndex);
84     std::swap(mRenderToTextureSamples, other.mRenderToTextureSamples);
85     return *this;
86 }
87 
~FramebufferAttachment()88 FramebufferAttachment::~FramebufferAttachment()
89 {
90     ASSERT(!isAttached());
91 }
92 
detach(const Context * context)93 void FramebufferAttachment::detach(const Context *context)
94 {
95     mType = GL_NONE;
96     if (mResource != nullptr)
97     {
98         mResource->onDetach(context);
99         mResource = nullptr;
100     }
101     mNumViews      = kDefaultNumViews;
102     mIsMultiview   = false;
103     mBaseViewIndex = kDefaultBaseViewIndex;
104 
105     // not technically necessary, could omit for performance
106     mTarget = Target();
107 }
108 
attach(const Context * context,GLenum type,GLenum binding,const ImageIndex & textureIndex,FramebufferAttachmentObject * resource,GLsizei numViews,GLuint baseViewIndex,bool isMultiview,GLsizei samples)109 void FramebufferAttachment::attach(const Context *context,
110                                    GLenum type,
111                                    GLenum binding,
112                                    const ImageIndex &textureIndex,
113                                    FramebufferAttachmentObject *resource,
114                                    GLsizei numViews,
115                                    GLuint baseViewIndex,
116                                    bool isMultiview,
117                                    GLsizei samples)
118 {
119     if (resource == nullptr)
120     {
121         detach(context);
122         return;
123     }
124 
125     mType                   = type;
126     mTarget                 = Target(binding, textureIndex);
127     mNumViews               = numViews;
128     mBaseViewIndex          = baseViewIndex;
129     mIsMultiview            = isMultiview;
130     mRenderToTextureSamples = samples;
131     resource->onAttach(context);
132 
133     if (mResource != nullptr)
134     {
135         mResource->onDetach(context);
136     }
137 
138     mResource = resource;
139 }
140 
getRedSize() const141 GLuint FramebufferAttachment::getRedSize() const
142 {
143     return getSize().empty() ? 0 : getFormat().info->redBits;
144 }
145 
getGreenSize() const146 GLuint FramebufferAttachment::getGreenSize() const
147 {
148     return getSize().empty() ? 0 : getFormat().info->greenBits;
149 }
150 
getBlueSize() const151 GLuint FramebufferAttachment::getBlueSize() const
152 {
153     return getSize().empty() ? 0 : getFormat().info->blueBits;
154 }
155 
getAlphaSize() const156 GLuint FramebufferAttachment::getAlphaSize() const
157 {
158     return getSize().empty() ? 0 : getFormat().info->alphaBits;
159 }
160 
getDepthSize() const161 GLuint FramebufferAttachment::getDepthSize() const
162 {
163     return getSize().empty() ? 0 : getFormat().info->depthBits;
164 }
165 
getStencilSize() const166 GLuint FramebufferAttachment::getStencilSize() const
167 {
168     return getSize().empty() ? 0 : getFormat().info->stencilBits;
169 }
170 
getComponentType() const171 GLenum FramebufferAttachment::getComponentType() const
172 {
173     return getFormat().info->componentType;
174 }
175 
getColorEncoding() const176 GLenum FramebufferAttachment::getColorEncoding() const
177 {
178     return getFormat().info->colorEncoding;
179 }
180 
id() const181 GLuint FramebufferAttachment::id() const
182 {
183     return mResource->getId();
184 }
185 
cubeMapFace() const186 TextureTarget FramebufferAttachment::cubeMapFace() const
187 {
188     ASSERT(mType == GL_TEXTURE);
189 
190     const auto &index = mTarget.textureIndex();
191     return index.getType() == TextureType::CubeMap ? index.getTarget() : TextureTarget::InvalidEnum;
192 }
193 
mipLevel() const194 GLint FramebufferAttachment::mipLevel() const
195 {
196     ASSERT(type() == GL_TEXTURE);
197     return mTarget.textureIndex().getLevelIndex();
198 }
199 
layer() const200 GLint FramebufferAttachment::layer() const
201 {
202     ASSERT(mType == GL_TEXTURE);
203 
204     const gl::ImageIndex &index = mTarget.textureIndex();
205     return (index.has3DLayer() ? index.getLayerIndex() : 0);
206 }
207 
isLayered() const208 bool FramebufferAttachment::isLayered() const
209 {
210     return mTarget.textureIndex().isLayered();
211 }
212 
isMultiview() const213 bool FramebufferAttachment::isMultiview() const
214 {
215     return mIsMultiview;
216 }
217 
getBaseViewIndex() const218 GLint FramebufferAttachment::getBaseViewIndex() const
219 {
220     return mBaseViewIndex;
221 }
222 
getTexture() const223 Texture *FramebufferAttachment::getTexture() const
224 {
225     return rx::GetAs<Texture>(mResource);
226 }
227 
getRenderbuffer() const228 Renderbuffer *FramebufferAttachment::getRenderbuffer() const
229 {
230     return rx::GetAs<Renderbuffer>(mResource);
231 }
232 
getSurface() const233 const egl::Surface *FramebufferAttachment::getSurface() const
234 {
235     return rx::GetAs<egl::Surface>(mResource);
236 }
237 
getResource() const238 FramebufferAttachmentObject *FramebufferAttachment::getResource() const
239 {
240     return mResource;
241 }
242 
operator ==(const FramebufferAttachment & other) const243 bool FramebufferAttachment::operator==(const FramebufferAttachment &other) const
244 {
245     if (mResource != other.mResource || mType != other.mType || mNumViews != other.mNumViews ||
246         mIsMultiview != other.mIsMultiview || mBaseViewIndex != other.mBaseViewIndex ||
247         mRenderToTextureSamples != other.mRenderToTextureSamples)
248     {
249         return false;
250     }
251 
252     if (mType == GL_TEXTURE && getTextureImageIndex() != other.getTextureImageIndex())
253     {
254         return false;
255     }
256 
257     return true;
258 }
259 
operator !=(const FramebufferAttachment & other) const260 bool FramebufferAttachment::operator!=(const FramebufferAttachment &other) const
261 {
262     return !(*this == other);
263 }
264 
initState() const265 InitState FramebufferAttachment::initState() const
266 {
267     return mResource ? mResource->initState(mTarget.textureIndex()) : InitState::Initialized;
268 }
269 
initializeContents(const Context * context)270 angle::Result FramebufferAttachment::initializeContents(const Context *context)
271 {
272     ASSERT(mResource);
273     ANGLE_TRY(mResource->initializeContents(context, mTarget.textureIndex()));
274     setInitState(InitState::Initialized);
275     return angle::Result::Continue;
276 }
277 
setInitState(InitState initState) const278 void FramebufferAttachment::setInitState(InitState initState) const
279 {
280     ASSERT(mResource);
281     mResource->setInitState(mTarget.textureIndex(), initState);
282 }
283 
isBoundAsSamplerOrImage(ContextID contextID) const284 bool FramebufferAttachment::isBoundAsSamplerOrImage(ContextID contextID) const
285 {
286     if (mType != GL_TEXTURE)
287     {
288         return false;
289     }
290 
291     const gl::TextureState &textureState = getTexture()->getTextureState();
292     return textureState.isBoundAsImageTexture(contextID) ||
293            textureState.isBoundAsSamplerTexture(contextID);
294 }
295 
296 ////// FramebufferAttachmentObject Implementation //////
297 
FramebufferAttachmentObject()298 FramebufferAttachmentObject::FramebufferAttachmentObject() {}
299 
~FramebufferAttachmentObject()300 FramebufferAttachmentObject::~FramebufferAttachmentObject() {}
301 
getAttachmentRenderTarget(const Context * context,GLenum binding,const ImageIndex & imageIndex,GLsizei samples,rx::FramebufferAttachmentRenderTarget ** rtOut) const302 angle::Result FramebufferAttachmentObject::getAttachmentRenderTarget(
303     const Context *context,
304     GLenum binding,
305     const ImageIndex &imageIndex,
306     GLsizei samples,
307     rx::FramebufferAttachmentRenderTarget **rtOut) const
308 {
309     return getAttachmentImpl()->getAttachmentRenderTarget(context, binding, imageIndex, samples,
310                                                           rtOut);
311 }
312 
initializeContents(const Context * context,const ImageIndex & imageIndex)313 angle::Result FramebufferAttachmentObject::initializeContents(const Context *context,
314                                                               const ImageIndex &imageIndex)
315 {
316     ASSERT(context->isRobustResourceInitEnabled());
317 
318     // Because gl::Texture cannot support tracking individual layer dirtiness, we only handle
319     // initializing entire mip levels for textures with layers
320     if (imageIndex.usesTex3D() && imageIndex.hasLayer())
321     {
322         // Compute the layer count so we get a correct layer index.
323         const gl::Extents &size = getAttachmentSize(imageIndex);
324 
325         ImageIndex fullMipIndex = ImageIndex::MakeFromType(
326             imageIndex.getType(), imageIndex.getLevelIndex(), ImageIndex::kEntireLevel, size.depth);
327         return getAttachmentImpl()->initializeContents(context, fullMipIndex);
328     }
329     else
330     {
331         return getAttachmentImpl()->initializeContents(context, imageIndex);
332     }
333 }
334 
335 }  // namespace gl
336