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,rx::Serial framebufferSerial)59 FramebufferAttachment::FramebufferAttachment(const Context *context,
60 GLenum type,
61 GLenum binding,
62 const ImageIndex &textureIndex,
63 FramebufferAttachmentObject *resource,
64 rx::Serial framebufferSerial)
65 : mResource(nullptr)
66 {
67 attach(context, type, binding, textureIndex, resource, kDefaultNumViews, kDefaultBaseViewIndex,
68 false, kDefaultRenderToTextureSamples, framebufferSerial);
69 }
70
FramebufferAttachment(FramebufferAttachment && other)71 FramebufferAttachment::FramebufferAttachment(FramebufferAttachment &&other)
72 : FramebufferAttachment()
73 {
74 *this = std::move(other);
75 }
76
operator =(FramebufferAttachment && other)77 FramebufferAttachment &FramebufferAttachment::operator=(FramebufferAttachment &&other)
78 {
79 std::swap(mType, other.mType);
80 std::swap(mTarget, other.mTarget);
81 std::swap(mResource, other.mResource);
82 std::swap(mNumViews, other.mNumViews);
83 std::swap(mIsMultiview, other.mIsMultiview);
84 std::swap(mBaseViewIndex, other.mBaseViewIndex);
85 std::swap(mRenderToTextureSamples, other.mRenderToTextureSamples);
86 return *this;
87 }
88
~FramebufferAttachment()89 FramebufferAttachment::~FramebufferAttachment()
90 {
91 ASSERT(!isAttached());
92 }
93
detach(const Context * context,rx::Serial framebufferSerial)94 void FramebufferAttachment::detach(const Context *context, rx::Serial framebufferSerial)
95 {
96 mType = GL_NONE;
97 if (mResource != nullptr)
98 {
99 mResource->onDetach(context, framebufferSerial);
100 mResource = nullptr;
101 }
102 mNumViews = kDefaultNumViews;
103 mIsMultiview = false;
104 mBaseViewIndex = kDefaultBaseViewIndex;
105
106 // not technically necessary, could omit for performance
107 mTarget = Target();
108 }
109
attach(const Context * context,GLenum type,GLenum binding,const ImageIndex & textureIndex,FramebufferAttachmentObject * resource,GLsizei numViews,GLuint baseViewIndex,bool isMultiview,GLsizei samples,rx::Serial framebufferSerial)110 void FramebufferAttachment::attach(const Context *context,
111 GLenum type,
112 GLenum binding,
113 const ImageIndex &textureIndex,
114 FramebufferAttachmentObject *resource,
115 GLsizei numViews,
116 GLuint baseViewIndex,
117 bool isMultiview,
118 GLsizei samples,
119 rx::Serial framebufferSerial)
120 {
121 if (resource == nullptr)
122 {
123 detach(context, framebufferSerial);
124 return;
125 }
126
127 mType = type;
128 mTarget = Target(binding, textureIndex);
129 mNumViews = numViews;
130 mBaseViewIndex = baseViewIndex;
131 mIsMultiview = isMultiview;
132 mRenderToTextureSamples = samples;
133 resource->onAttach(context, framebufferSerial);
134
135 if (mResource != nullptr)
136 {
137 mResource->onDetach(context, framebufferSerial);
138 }
139
140 mResource = resource;
141 }
142
getRedSize() const143 GLuint FramebufferAttachment::getRedSize() const
144 {
145 return getSize().empty() ? 0 : getFormat().info->redBits;
146 }
147
getGreenSize() const148 GLuint FramebufferAttachment::getGreenSize() const
149 {
150 return getSize().empty() ? 0 : getFormat().info->greenBits;
151 }
152
getBlueSize() const153 GLuint FramebufferAttachment::getBlueSize() const
154 {
155 return getSize().empty() ? 0 : getFormat().info->blueBits;
156 }
157
getAlphaSize() const158 GLuint FramebufferAttachment::getAlphaSize() const
159 {
160 return getSize().empty() ? 0 : getFormat().info->alphaBits;
161 }
162
getDepthSize() const163 GLuint FramebufferAttachment::getDepthSize() const
164 {
165 return getSize().empty() ? 0 : getFormat().info->depthBits;
166 }
167
getStencilSize() const168 GLuint FramebufferAttachment::getStencilSize() const
169 {
170 return getSize().empty() ? 0 : getFormat().info->stencilBits;
171 }
172
getComponentType() const173 GLenum FramebufferAttachment::getComponentType() const
174 {
175 return getFormat().info->componentType;
176 }
177
getColorEncoding() const178 GLenum FramebufferAttachment::getColorEncoding() const
179 {
180 return getFormat().info->colorEncoding;
181 }
182
id() const183 GLuint FramebufferAttachment::id() const
184 {
185 return mResource->getId();
186 }
187
cubeMapFace() const188 TextureTarget FramebufferAttachment::cubeMapFace() const
189 {
190 ASSERT(mType == GL_TEXTURE);
191
192 const auto &index = mTarget.textureIndex();
193 return index.getType() == TextureType::CubeMap ? index.getTarget() : TextureTarget::InvalidEnum;
194 }
195
mipLevel() const196 GLint FramebufferAttachment::mipLevel() const
197 {
198 ASSERT(type() == GL_TEXTURE);
199 return mTarget.textureIndex().getLevelIndex();
200 }
201
layer() const202 GLint FramebufferAttachment::layer() const
203 {
204 ASSERT(mType == GL_TEXTURE);
205
206 const gl::ImageIndex &index = mTarget.textureIndex();
207 return (index.has3DLayer() ? index.getLayerIndex() : 0);
208 }
209
isLayered() const210 bool FramebufferAttachment::isLayered() const
211 {
212 return mTarget.textureIndex().isLayered();
213 }
214
isMultiview() const215 bool FramebufferAttachment::isMultiview() const
216 {
217 return mIsMultiview;
218 }
219
getBaseViewIndex() const220 GLint FramebufferAttachment::getBaseViewIndex() const
221 {
222 return mBaseViewIndex;
223 }
224
getTexture() const225 Texture *FramebufferAttachment::getTexture() const
226 {
227 return rx::GetAs<Texture>(mResource);
228 }
229
getRenderbuffer() const230 Renderbuffer *FramebufferAttachment::getRenderbuffer() const
231 {
232 return rx::GetAs<Renderbuffer>(mResource);
233 }
234
getSurface() const235 const egl::Surface *FramebufferAttachment::getSurface() const
236 {
237 return rx::GetAs<egl::Surface>(mResource);
238 }
239
getResource() const240 FramebufferAttachmentObject *FramebufferAttachment::getResource() const
241 {
242 return mResource;
243 }
244
operator ==(const FramebufferAttachment & other) const245 bool FramebufferAttachment::operator==(const FramebufferAttachment &other) const
246 {
247 if (mResource != other.mResource || mType != other.mType || mNumViews != other.mNumViews ||
248 mIsMultiview != other.mIsMultiview || mBaseViewIndex != other.mBaseViewIndex ||
249 mRenderToTextureSamples != other.mRenderToTextureSamples)
250 {
251 return false;
252 }
253
254 if (mType == GL_TEXTURE && getTextureImageIndex() != other.getTextureImageIndex())
255 {
256 return false;
257 }
258
259 return true;
260 }
261
operator !=(const FramebufferAttachment & other) const262 bool FramebufferAttachment::operator!=(const FramebufferAttachment &other) const
263 {
264 return !(*this == other);
265 }
266
initState() const267 InitState FramebufferAttachment::initState() const
268 {
269 return mResource ? mResource->initState(mTarget.textureIndex()) : InitState::Initialized;
270 }
271
initializeContents(const Context * context)272 angle::Result FramebufferAttachment::initializeContents(const Context *context)
273 {
274 ASSERT(mResource);
275 ANGLE_TRY(mResource->initializeContents(context, mTarget.textureIndex()));
276 setInitState(InitState::Initialized);
277 return angle::Result::Continue;
278 }
279
setInitState(InitState initState) const280 void FramebufferAttachment::setInitState(InitState initState) const
281 {
282 ASSERT(mResource);
283 mResource->setInitState(mTarget.textureIndex(), initState);
284 }
285
286 ////// FramebufferAttachmentObject Implementation //////
287
FramebufferAttachmentObject()288 FramebufferAttachmentObject::FramebufferAttachmentObject() {}
289
~FramebufferAttachmentObject()290 FramebufferAttachmentObject::~FramebufferAttachmentObject() {}
291
getAttachmentRenderTarget(const Context * context,GLenum binding,const ImageIndex & imageIndex,GLsizei samples,rx::FramebufferAttachmentRenderTarget ** rtOut) const292 angle::Result FramebufferAttachmentObject::getAttachmentRenderTarget(
293 const Context *context,
294 GLenum binding,
295 const ImageIndex &imageIndex,
296 GLsizei samples,
297 rx::FramebufferAttachmentRenderTarget **rtOut) const
298 {
299 return getAttachmentImpl()->getAttachmentRenderTarget(context, binding, imageIndex, samples,
300 rtOut);
301 }
302
initializeContents(const Context * context,const ImageIndex & imageIndex)303 angle::Result FramebufferAttachmentObject::initializeContents(const Context *context,
304 const ImageIndex &imageIndex)
305 {
306 ASSERT(context->isRobustResourceInitEnabled());
307
308 // Because gl::Texture cannot support tracking individual layer dirtiness, we only handle
309 // initializing entire mip levels for textures with layers
310 if (imageIndex.usesTex3D() && imageIndex.hasLayer())
311 {
312 // Compute the layer count so we get a correct layer index.
313 const gl::Extents &size = getAttachmentSize(imageIndex);
314
315 ImageIndex fullMipIndex = ImageIndex::MakeFromType(
316 imageIndex.getType(), imageIndex.getLevelIndex(), ImageIndex::kEntireLevel, size.depth);
317 return getAttachmentImpl()->initializeContents(context, fullMipIndex);
318 }
319 else
320 {
321 return getAttachmentImpl()->initializeContents(context, imageIndex);
322 }
323 }
324
325 } // namespace gl
326