tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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