ResourceManager.cpp (13804B)
1 // 2 // Copyright 2002 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 // ResourceManager.cpp: Implements the the ResourceManager classes, which handle allocation and 8 // lifetime of GL objects. 9 10 #include "libANGLE/ResourceManager.h" 11 12 #include "libANGLE/Buffer.h" 13 #include "libANGLE/Context.h" 14 #include "libANGLE/Fence.h" 15 #include "libANGLE/MemoryObject.h" 16 #include "libANGLE/Program.h" 17 #include "libANGLE/ProgramPipeline.h" 18 #include "libANGLE/Query.h" 19 #include "libANGLE/Renderbuffer.h" 20 #include "libANGLE/Sampler.h" 21 #include "libANGLE/Semaphore.h" 22 #include "libANGLE/Shader.h" 23 #include "libANGLE/Texture.h" 24 #include "libANGLE/renderer/ContextImpl.h" 25 26 namespace gl 27 { 28 29 namespace 30 { 31 32 template <typename ResourceType, typename IDType> 33 IDType AllocateEmptyObject(HandleAllocator *handleAllocator, 34 ResourceMap<ResourceType, IDType> *objectMap) 35 { 36 IDType handle = PackParam<IDType>(handleAllocator->allocate()); 37 objectMap->assign(handle, nullptr); 38 return handle; 39 } 40 41 } // anonymous namespace 42 43 ResourceManagerBase::ResourceManagerBase() : mRefCount(1) {} 44 45 ResourceManagerBase::~ResourceManagerBase() = default; 46 47 void ResourceManagerBase::addRef() 48 { 49 mRefCount++; 50 } 51 52 void ResourceManagerBase::release(const Context *context) 53 { 54 if (--mRefCount == 0) 55 { 56 reset(context); 57 delete this; 58 } 59 } 60 61 template <typename ResourceType, typename ImplT, typename IDType> 62 TypedResourceManager<ResourceType, ImplT, IDType>::~TypedResourceManager() 63 { 64 ASSERT(mObjectMap.empty()); 65 } 66 67 template <typename ResourceType, typename ImplT, typename IDType> 68 void TypedResourceManager<ResourceType, ImplT, IDType>::reset(const Context *context) 69 { 70 this->mHandleAllocator.reset(); 71 for (const auto &resource : mObjectMap) 72 { 73 if (resource.second) 74 { 75 ImplT::DeleteObject(context, resource.second); 76 } 77 } 78 mObjectMap.clear(); 79 } 80 81 template <typename ResourceType, typename ImplT, typename IDType> 82 void TypedResourceManager<ResourceType, ImplT, IDType>::deleteObject(const Context *context, 83 IDType handle) 84 { 85 ResourceType *resource = nullptr; 86 if (!mObjectMap.erase(handle, &resource)) 87 { 88 return; 89 } 90 91 // Requires an explicit this-> because of C++ template rules. 92 this->mHandleAllocator.release(GetIDValue(handle)); 93 94 if (resource) 95 { 96 ImplT::DeleteObject(context, resource); 97 } 98 } 99 100 template class TypedResourceManager<Buffer, BufferManager, BufferID>; 101 template class TypedResourceManager<Texture, TextureManager, TextureID>; 102 template class TypedResourceManager<Renderbuffer, RenderbufferManager, RenderbufferID>; 103 template class TypedResourceManager<Sampler, SamplerManager, SamplerID>; 104 template class TypedResourceManager<Sync, SyncManager, GLuint>; 105 template class TypedResourceManager<Framebuffer, FramebufferManager, FramebufferID>; 106 template class TypedResourceManager<ProgramPipeline, ProgramPipelineManager, ProgramPipelineID>; 107 108 // BufferManager Implementation. 109 BufferManager::~BufferManager() = default; 110 111 // static 112 Buffer *BufferManager::AllocateNewObject(rx::GLImplFactory *factory, BufferID handle) 113 { 114 Buffer *buffer = new Buffer(factory, handle); 115 buffer->addRef(); 116 return buffer; 117 } 118 119 // static 120 void BufferManager::DeleteObject(const Context *context, Buffer *buffer) 121 { 122 buffer->release(context); 123 } 124 125 BufferID BufferManager::createBuffer() 126 { 127 return AllocateEmptyObject(&mHandleAllocator, &mObjectMap); 128 } 129 130 Buffer *BufferManager::getBuffer(BufferID handle) const 131 { 132 return mObjectMap.query(handle); 133 } 134 135 // ShaderProgramManager Implementation. 136 137 ShaderProgramManager::ShaderProgramManager() {} 138 139 ShaderProgramManager::~ShaderProgramManager() 140 { 141 ASSERT(mPrograms.empty()); 142 ASSERT(mShaders.empty()); 143 } 144 145 void ShaderProgramManager::reset(const Context *context) 146 { 147 while (!mPrograms.empty()) 148 { 149 deleteProgram(context, {mPrograms.begin()->first}); 150 } 151 mPrograms.clear(); 152 while (!mShaders.empty()) 153 { 154 deleteShader(context, {mShaders.begin()->first}); 155 } 156 mShaders.clear(); 157 } 158 159 ShaderProgramID ShaderProgramManager::createShader(rx::GLImplFactory *factory, 160 const gl::Limitations &rendererLimitations, 161 ShaderType type) 162 { 163 ASSERT(type != ShaderType::InvalidEnum); 164 ShaderProgramID handle = ShaderProgramID{mHandleAllocator.allocate()}; 165 mShaders.assign(handle, new Shader(this, factory, rendererLimitations, type, handle)); 166 return handle; 167 } 168 169 void ShaderProgramManager::deleteShader(const Context *context, ShaderProgramID shader) 170 { 171 deleteObject(context, &mShaders, shader); 172 } 173 174 Shader *ShaderProgramManager::getShader(ShaderProgramID handle) const 175 { 176 return mShaders.query(handle); 177 } 178 179 ShaderProgramID ShaderProgramManager::createProgram(rx::GLImplFactory *factory) 180 { 181 ShaderProgramID handle = ShaderProgramID{mHandleAllocator.allocate()}; 182 mPrograms.assign(handle, new Program(factory, this, handle)); 183 return handle; 184 } 185 186 void ShaderProgramManager::deleteProgram(const gl::Context *context, ShaderProgramID program) 187 { 188 deleteObject(context, &mPrograms, program); 189 } 190 191 template <typename ObjectType, typename IDType> 192 void ShaderProgramManager::deleteObject(const Context *context, 193 ResourceMap<ObjectType, IDType> *objectMap, 194 IDType id) 195 { 196 ObjectType *object = objectMap->query(id); 197 if (!object) 198 { 199 return; 200 } 201 202 if (object->getRefCount() == 0) 203 { 204 mHandleAllocator.release(id.value); 205 object->onDestroy(context); 206 objectMap->erase(id, &object); 207 } 208 else 209 { 210 object->flagForDeletion(); 211 } 212 } 213 214 // TextureManager Implementation. 215 216 TextureManager::~TextureManager() = default; 217 218 // static 219 Texture *TextureManager::AllocateNewObject(rx::GLImplFactory *factory, 220 TextureID handle, 221 TextureType type) 222 { 223 Texture *texture = new Texture(factory, handle, type); 224 texture->addRef(); 225 return texture; 226 } 227 228 // static 229 void TextureManager::DeleteObject(const Context *context, Texture *texture) 230 { 231 texture->release(context); 232 } 233 234 TextureID TextureManager::createTexture() 235 { 236 return AllocateEmptyObject(&mHandleAllocator, &mObjectMap); 237 } 238 239 void TextureManager::signalAllTexturesDirty() const 240 { 241 for (const auto &texture : mObjectMap) 242 { 243 if (texture.second) 244 { 245 // We don't know if the Texture needs init, but that's ok, since it will only force 246 // a re-check, and will not initialize the pixels if it's not needed. 247 texture.second->signalDirtyStorage(InitState::MayNeedInit); 248 } 249 } 250 } 251 252 void TextureManager::enableHandleAllocatorLogging() 253 { 254 mHandleAllocator.enableLogging(true); 255 } 256 257 // RenderbufferManager Implementation. 258 259 RenderbufferManager::~RenderbufferManager() = default; 260 261 // static 262 Renderbuffer *RenderbufferManager::AllocateNewObject(rx::GLImplFactory *factory, 263 RenderbufferID handle) 264 { 265 Renderbuffer *renderbuffer = new Renderbuffer(factory, handle); 266 renderbuffer->addRef(); 267 return renderbuffer; 268 } 269 270 // static 271 void RenderbufferManager::DeleteObject(const Context *context, Renderbuffer *renderbuffer) 272 { 273 renderbuffer->release(context); 274 } 275 276 RenderbufferID RenderbufferManager::createRenderbuffer() 277 { 278 return {AllocateEmptyObject(&mHandleAllocator, &mObjectMap)}; 279 } 280 281 Renderbuffer *RenderbufferManager::getRenderbuffer(RenderbufferID handle) const 282 { 283 return mObjectMap.query(handle); 284 } 285 286 // SamplerManager Implementation. 287 288 SamplerManager::~SamplerManager() = default; 289 290 // static 291 Sampler *SamplerManager::AllocateNewObject(rx::GLImplFactory *factory, SamplerID handle) 292 { 293 Sampler *sampler = new Sampler(factory, handle); 294 sampler->addRef(); 295 return sampler; 296 } 297 298 // static 299 void SamplerManager::DeleteObject(const Context *context, Sampler *sampler) 300 { 301 sampler->release(context); 302 } 303 304 SamplerID SamplerManager::createSampler() 305 { 306 return AllocateEmptyObject(&mHandleAllocator, &mObjectMap); 307 } 308 309 Sampler *SamplerManager::getSampler(SamplerID handle) const 310 { 311 return mObjectMap.query(handle); 312 } 313 314 bool SamplerManager::isSampler(SamplerID sampler) const 315 { 316 return mObjectMap.contains(sampler); 317 } 318 319 // SyncManager Implementation. 320 321 SyncManager::~SyncManager() = default; 322 323 // static 324 void SyncManager::DeleteObject(const Context *context, Sync *sync) 325 { 326 sync->release(context); 327 } 328 329 GLuint SyncManager::createSync(rx::GLImplFactory *factory) 330 { 331 GLuint handle = mHandleAllocator.allocate(); 332 Sync *sync = new Sync(factory, handle); 333 sync->addRef(); 334 mObjectMap.assign(handle, sync); 335 return handle; 336 } 337 338 Sync *SyncManager::getSync(GLuint handle) const 339 { 340 return mObjectMap.query(handle); 341 } 342 343 // FramebufferManager Implementation. 344 345 FramebufferManager::~FramebufferManager() = default; 346 347 // static 348 Framebuffer *FramebufferManager::AllocateNewObject(rx::GLImplFactory *factory, 349 FramebufferID handle, 350 const Context *context) 351 { 352 // Make sure the caller isn't using a reserved handle. 353 ASSERT(handle != Framebuffer::kDefaultDrawFramebufferHandle); 354 return new Framebuffer(context, factory, handle); 355 } 356 357 // static 358 void FramebufferManager::DeleteObject(const Context *context, Framebuffer *framebuffer) 359 { 360 framebuffer->onDestroy(context); 361 delete framebuffer; 362 } 363 364 FramebufferID FramebufferManager::createFramebuffer() 365 { 366 return AllocateEmptyObject(&mHandleAllocator, &mObjectMap); 367 } 368 369 Framebuffer *FramebufferManager::getFramebuffer(FramebufferID handle) const 370 { 371 return mObjectMap.query(handle); 372 } 373 374 void FramebufferManager::setDefaultFramebuffer(Framebuffer *framebuffer) 375 { 376 ASSERT(framebuffer == nullptr || framebuffer->isDefault()); 377 mObjectMap.assign(Framebuffer::kDefaultDrawFramebufferHandle, framebuffer); 378 } 379 380 Framebuffer *FramebufferManager::getDefaultFramebuffer() const 381 { 382 return getFramebuffer(Framebuffer::kDefaultDrawFramebufferHandle); 383 } 384 385 void FramebufferManager::invalidateFramebufferCompletenessCache() const 386 { 387 for (const auto &framebuffer : mObjectMap) 388 { 389 if (framebuffer.second) 390 { 391 framebuffer.second->invalidateCompletenessCache(); 392 } 393 } 394 } 395 396 // ProgramPipelineManager Implementation. 397 398 ProgramPipelineManager::~ProgramPipelineManager() = default; 399 400 // static 401 ProgramPipeline *ProgramPipelineManager::AllocateNewObject(rx::GLImplFactory *factory, 402 ProgramPipelineID handle) 403 { 404 ProgramPipeline *pipeline = new ProgramPipeline(factory, handle); 405 pipeline->addRef(); 406 return pipeline; 407 } 408 409 // static 410 void ProgramPipelineManager::DeleteObject(const Context *context, ProgramPipeline *pipeline) 411 { 412 pipeline->release(context); 413 } 414 415 ProgramPipelineID ProgramPipelineManager::createProgramPipeline() 416 { 417 return AllocateEmptyObject(&mHandleAllocator, &mObjectMap); 418 } 419 420 ProgramPipeline *ProgramPipelineManager::getProgramPipeline(ProgramPipelineID handle) const 421 { 422 return mObjectMap.query(handle); 423 } 424 425 // MemoryObjectManager Implementation. 426 427 MemoryObjectManager::MemoryObjectManager() {} 428 429 MemoryObjectManager::~MemoryObjectManager() 430 { 431 ASSERT(mMemoryObjects.empty()); 432 } 433 434 void MemoryObjectManager::reset(const Context *context) 435 { 436 while (!mMemoryObjects.empty()) 437 { 438 deleteMemoryObject(context, {mMemoryObjects.begin()->first}); 439 } 440 mMemoryObjects.clear(); 441 } 442 443 MemoryObjectID MemoryObjectManager::createMemoryObject(rx::GLImplFactory *factory) 444 { 445 MemoryObjectID handle = MemoryObjectID{mHandleAllocator.allocate()}; 446 MemoryObject *memoryObject = new MemoryObject(factory, handle); 447 memoryObject->addRef(); 448 mMemoryObjects.assign(handle, memoryObject); 449 return handle; 450 } 451 452 void MemoryObjectManager::deleteMemoryObject(const Context *context, MemoryObjectID handle) 453 { 454 MemoryObject *memoryObject = nullptr; 455 if (!mMemoryObjects.erase(handle, &memoryObject)) 456 { 457 return; 458 } 459 460 // Requires an explicit this-> because of C++ template rules. 461 this->mHandleAllocator.release(handle.value); 462 463 if (memoryObject) 464 { 465 memoryObject->release(context); 466 } 467 } 468 469 MemoryObject *MemoryObjectManager::getMemoryObject(MemoryObjectID handle) const 470 { 471 return mMemoryObjects.query(handle); 472 } 473 474 // SemaphoreManager Implementation. 475 476 SemaphoreManager::SemaphoreManager() {} 477 478 SemaphoreManager::~SemaphoreManager() 479 { 480 ASSERT(mSemaphores.empty()); 481 } 482 483 void SemaphoreManager::reset(const Context *context) 484 { 485 while (!mSemaphores.empty()) 486 { 487 deleteSemaphore(context, {mSemaphores.begin()->first}); 488 } 489 mSemaphores.clear(); 490 } 491 492 SemaphoreID SemaphoreManager::createSemaphore(rx::GLImplFactory *factory) 493 { 494 SemaphoreID handle = SemaphoreID{mHandleAllocator.allocate()}; 495 Semaphore *semaphore = new Semaphore(factory, handle); 496 semaphore->addRef(); 497 mSemaphores.assign(handle, semaphore); 498 return handle; 499 } 500 501 void SemaphoreManager::deleteSemaphore(const Context *context, SemaphoreID handle) 502 { 503 Semaphore *semaphore = nullptr; 504 if (!mSemaphores.erase(handle, &semaphore)) 505 { 506 return; 507 } 508 509 // Requires an explicit this-> because of C++ template rules. 510 this->mHandleAllocator.release(handle.value); 511 512 if (semaphore) 513 { 514 semaphore->release(context); 515 } 516 } 517 518 Semaphore *SemaphoreManager::getSemaphore(SemaphoreID handle) const 519 { 520 return mSemaphores.query(handle); 521 } 522 } // namespace gl