FramebufferAttachment.cpp (10685B)
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 31 FramebufferAttachment::Target::Target() : mBinding(GL_NONE), mTextureIndex() {} 32 33 FramebufferAttachment::Target::Target(GLenum binding, const ImageIndex &imageIndex) 34 : mBinding(binding), mTextureIndex(imageIndex) 35 {} 36 37 FramebufferAttachment::Target::Target(const Target &other) 38 : mBinding(other.mBinding), mTextureIndex(other.mTextureIndex) 39 {} 40 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 50 FramebufferAttachment::FramebufferAttachment() 51 : mType(GL_NONE), 52 mResource(nullptr), 53 mNumViews(kDefaultNumViews), 54 mIsMultiview(false), 55 mBaseViewIndex(kDefaultBaseViewIndex), 56 mRenderToTextureSamples(kDefaultRenderToTextureSamples) 57 {} 58 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 71 FramebufferAttachment::FramebufferAttachment(FramebufferAttachment &&other) 72 : FramebufferAttachment() 73 { 74 *this = std::move(other); 75 } 76 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 89 FramebufferAttachment::~FramebufferAttachment() 90 { 91 ASSERT(!isAttached()); 92 } 93 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 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 = type == GL_RENDERBUFFER ? kDefaultRenderToTextureSamples : samples; 133 resource->onAttach(context, framebufferSerial); 134 135 if (mResource != nullptr) 136 { 137 mResource->onDetach(context, framebufferSerial); 138 } 139 140 mResource = resource; 141 } 142 143 GLuint FramebufferAttachment::getRedSize() const 144 { 145 return getSize().empty() ? 0 : getFormat().info->redBits; 146 } 147 148 GLuint FramebufferAttachment::getGreenSize() const 149 { 150 return getSize().empty() ? 0 : getFormat().info->greenBits; 151 } 152 153 GLuint FramebufferAttachment::getBlueSize() const 154 { 155 return getSize().empty() ? 0 : getFormat().info->blueBits; 156 } 157 158 GLuint FramebufferAttachment::getAlphaSize() const 159 { 160 return getSize().empty() ? 0 : getFormat().info->alphaBits; 161 } 162 163 GLuint FramebufferAttachment::getDepthSize() const 164 { 165 return getSize().empty() ? 0 : getFormat().info->depthBits; 166 } 167 168 GLuint FramebufferAttachment::getStencilSize() const 169 { 170 return getSize().empty() ? 0 : getFormat().info->stencilBits; 171 } 172 173 GLenum FramebufferAttachment::getComponentType() const 174 { 175 return getFormat().info->componentType; 176 } 177 178 GLenum FramebufferAttachment::getColorEncoding() const 179 { 180 return getFormat().info->colorEncoding; 181 } 182 183 GLuint FramebufferAttachment::id() const 184 { 185 return mResource->getId(); 186 } 187 188 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 196 GLint FramebufferAttachment::mipLevel() const 197 { 198 ASSERT(type() == GL_TEXTURE); 199 return mTarget.textureIndex().getLevelIndex(); 200 } 201 202 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 210 bool FramebufferAttachment::isLayered() const 211 { 212 return mTarget.textureIndex().isLayered(); 213 } 214 215 bool FramebufferAttachment::isMultiview() const 216 { 217 return mIsMultiview; 218 } 219 220 GLint FramebufferAttachment::getBaseViewIndex() const 221 { 222 return mBaseViewIndex; 223 } 224 225 bool FramebufferAttachment::isRenderToTexture() const 226 { 227 ASSERT(mRenderToTextureSamples == kDefaultRenderToTextureSamples || mType == GL_TEXTURE); 228 229 if (mType == GL_RENDERBUFFER) 230 { 231 return getRenderbuffer()->getMultisamplingMode() == 232 MultisamplingMode::MultisampledRenderToTexture; 233 } 234 return mRenderToTextureSamples != kDefaultRenderToTextureSamples; 235 } 236 237 GLsizei FramebufferAttachment::getRenderToTextureSamples() const 238 { 239 ASSERT(mRenderToTextureSamples == kDefaultRenderToTextureSamples || mType == GL_TEXTURE); 240 241 if (mType == GL_RENDERBUFFER) 242 { 243 return getRenderbuffer()->getState().getSamples(); 244 } 245 return mRenderToTextureSamples; 246 } 247 248 Texture *FramebufferAttachment::getTexture() const 249 { 250 return rx::GetAs<Texture>(mResource); 251 } 252 253 Renderbuffer *FramebufferAttachment::getRenderbuffer() const 254 { 255 return rx::GetAs<Renderbuffer>(mResource); 256 } 257 258 const egl::Surface *FramebufferAttachment::getSurface() const 259 { 260 return rx::GetAs<egl::Surface>(mResource); 261 } 262 263 FramebufferAttachmentObject *FramebufferAttachment::getResource() const 264 { 265 return mResource; 266 } 267 268 bool FramebufferAttachment::operator==(const FramebufferAttachment &other) const 269 { 270 if (mResource != other.mResource || mType != other.mType || mNumViews != other.mNumViews || 271 mIsMultiview != other.mIsMultiview || mBaseViewIndex != other.mBaseViewIndex || 272 mRenderToTextureSamples != other.mRenderToTextureSamples) 273 { 274 return false; 275 } 276 277 if (mType == GL_TEXTURE && getTextureImageIndex() != other.getTextureImageIndex()) 278 { 279 return false; 280 } 281 282 return true; 283 } 284 285 bool FramebufferAttachment::operator!=(const FramebufferAttachment &other) const 286 { 287 return !(*this == other); 288 } 289 290 InitState FramebufferAttachment::initState() const 291 { 292 return mResource ? mResource->initState(mTarget.binding(), mTarget.textureIndex()) 293 : InitState::Initialized; 294 } 295 296 angle::Result FramebufferAttachment::initializeContents(const Context *context) 297 { 298 ASSERT(mResource); 299 ANGLE_TRY(mResource->initializeContents(context, mTarget.binding(), mTarget.textureIndex())); 300 setInitState(InitState::Initialized); 301 return angle::Result::Continue; 302 } 303 304 void FramebufferAttachment::setInitState(InitState initState) const 305 { 306 ASSERT(mResource); 307 mResource->setInitState(mTarget.binding(), mTarget.textureIndex(), initState); 308 } 309 310 ////// FramebufferAttachmentObject Implementation ////// 311 312 FramebufferAttachmentObject::FramebufferAttachmentObject() {} 313 314 FramebufferAttachmentObject::~FramebufferAttachmentObject() {} 315 316 angle::Result FramebufferAttachmentObject::getAttachmentRenderTarget( 317 const Context *context, 318 GLenum binding, 319 const ImageIndex &imageIndex, 320 GLsizei samples, 321 rx::FramebufferAttachmentRenderTarget **rtOut) const 322 { 323 return getAttachmentImpl()->getAttachmentRenderTarget(context, binding, imageIndex, samples, 324 rtOut); 325 } 326 327 angle::Result FramebufferAttachmentObject::initializeContents(const Context *context, 328 GLenum binding, 329 const ImageIndex &imageIndex) 330 { 331 ASSERT(context->isRobustResourceInitEnabled()); 332 333 // Because gl::Texture cannot support tracking individual layer dirtiness, we only handle 334 // initializing entire mip levels for textures with layers 335 if (imageIndex.usesTex3D() && imageIndex.hasLayer()) 336 { 337 // Compute the layer count so we get a correct layer index. 338 const gl::Extents &size = getAttachmentSize(imageIndex); 339 340 ImageIndex fullMipIndex = ImageIndex::MakeFromType( 341 imageIndex.getType(), imageIndex.getLevelIndex(), ImageIndex::kEntireLevel, size.depth); 342 return getAttachmentImpl()->initializeContents(context, binding, fullMipIndex); 343 } 344 else 345 { 346 return getAttachmentImpl()->initializeContents(context, binding, imageIndex); 347 } 348 } 349 350 } // namespace gl