diff options
Diffstat (limited to 'gfx/angle/src/libANGLE/ResourceManager.cpp')
-rwxr-xr-x | gfx/angle/src/libANGLE/ResourceManager.cpp | 562 |
1 files changed, 562 insertions, 0 deletions
diff --git a/gfx/angle/src/libANGLE/ResourceManager.cpp b/gfx/angle/src/libANGLE/ResourceManager.cpp new file mode 100755 index 000000000..cfb965d92 --- /dev/null +++ b/gfx/angle/src/libANGLE/ResourceManager.cpp @@ -0,0 +1,562 @@ +// +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ResourceManager.cpp: Implements the gl::ResourceManager class, which tracks and +// retrieves objects which may be shared by multiple Contexts. + +#include "libANGLE/ResourceManager.h" + +#include "libANGLE/Buffer.h" +#include "libANGLE/Fence.h" +#include "libANGLE/Path.h" +#include "libANGLE/Program.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/Sampler.h" +#include "libANGLE/Shader.h" +#include "libANGLE/Texture.h" +#include "libANGLE/renderer/GLImplFactory.h" + +namespace gl +{ +ResourceManager::ResourceManager() : mRefCount(1) +{ +} + +ResourceManager::~ResourceManager() +{ + while (!mBufferMap.empty()) + { + deleteBuffer(mBufferMap.begin()->first); + } + + while (!mProgramMap.empty()) + { + deleteProgram(mProgramMap.begin()->first); + } + + while (!mShaderMap.empty()) + { + deleteShader(mShaderMap.begin()->first); + } + + while (!mRenderbufferMap.empty()) + { + deleteRenderbuffer(mRenderbufferMap.begin()->first); + } + + while (!mTextureMap.empty()) + { + deleteTexture(mTextureMap.begin()->first); + } + + while (!mSamplerMap.empty()) + { + deleteSampler(mSamplerMap.begin()->first); + } + + while (!mFenceSyncMap.empty()) + { + deleteFenceSync(mFenceSyncMap.begin()->first); + } + + for (auto it = mPathMap.begin(); it != mPathMap.end(); ++it) + { + const auto *p = it->second; + delete p; + } +} + +void ResourceManager::addRef() +{ + mRefCount++; +} + +void ResourceManager::release() +{ + if (--mRefCount == 0) + { + delete this; + } +} + +// Returns an unused buffer name +GLuint ResourceManager::createBuffer() +{ + GLuint handle = mBufferHandleAllocator.allocate(); + + mBufferMap[handle] = nullptr; + + return handle; +} + +// Returns an unused shader/program name +GLuint ResourceManager::createShader(rx::GLImplFactory *factory, + const gl::Limitations &rendererLimitations, + GLenum type) +{ + ASSERT(type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER || type == GL_COMPUTE_SHADER); + GLuint handle = mProgramShaderHandleAllocator.allocate(); + + mShaderMap[handle] = new Shader(this, factory, rendererLimitations, type, handle); + + return handle; +} + +// Returns an unused program/shader name +GLuint ResourceManager::createProgram(rx::GLImplFactory *factory) +{ + GLuint handle = mProgramShaderHandleAllocator.allocate(); + + mProgramMap[handle] = new Program(factory, this, handle); + + return handle; +} + +// Returns an unused texture name +GLuint ResourceManager::createTexture() +{ + GLuint handle = mTextureHandleAllocator.allocate(); + + mTextureMap[handle] = nullptr; + + return handle; +} + +// Returns an unused renderbuffer name +GLuint ResourceManager::createRenderbuffer() +{ + GLuint handle = mRenderbufferHandleAllocator.allocate(); + + mRenderbufferMap[handle] = nullptr; + + return handle; +} + +// Returns an unused sampler name +GLuint ResourceManager::createSampler() +{ + GLuint handle = mSamplerHandleAllocator.allocate(); + + mSamplerMap[handle] = nullptr; + + return handle; +} + +// Returns the next unused fence name, and allocates the fence +GLuint ResourceManager::createFenceSync(rx::GLImplFactory *factory) +{ + GLuint handle = mFenceSyncHandleAllocator.allocate(); + + FenceSync *fenceSync = new FenceSync(factory->createFenceSync(), handle); + fenceSync->addRef(); + mFenceSyncMap[handle] = fenceSync; + + return handle; +} + +ErrorOrResult<GLuint> ResourceManager::createPaths(rx::GLImplFactory *factory, GLsizei range) +{ + // Allocate client side handles. + const GLuint client = mPathHandleAllocator.allocateRange(static_cast<GLuint>(range)); + if (client == HandleRangeAllocator::kInvalidHandle) + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate path handle range."); + + const auto &paths = factory->createPaths(range); + if (paths.empty()) + { + mPathHandleAllocator.releaseRange(client, range); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate path objects."); + } + + auto hint = mPathMap.begin(); + + for (GLsizei i = 0; i < range; ++i) + { + const auto impl = paths[static_cast<unsigned>(i)]; + const auto id = client + i; + hint = mPathMap.insert(hint, std::make_pair(id, new Path(impl))); + } + return client; +} + +void ResourceManager::deleteBuffer(GLuint buffer) +{ + auto bufferObject = mBufferMap.find(buffer); + + if (bufferObject != mBufferMap.end()) + { + mBufferHandleAllocator.release(bufferObject->first); + if (bufferObject->second) bufferObject->second->release(); + mBufferMap.erase(bufferObject); + } +} + +void ResourceManager::deleteShader(GLuint shader) +{ + auto shaderObject = mShaderMap.find(shader); + + if (shaderObject != mShaderMap.end()) + { + if (shaderObject->second->getRefCount() == 0) + { + mProgramShaderHandleAllocator.release(shaderObject->first); + delete shaderObject->second; + mShaderMap.erase(shaderObject); + } + else + { + shaderObject->second->flagForDeletion(); + } + } +} + +void ResourceManager::deleteProgram(GLuint program) +{ + auto programObject = mProgramMap.find(program); + + if (programObject != mProgramMap.end()) + { + if (programObject->second->getRefCount() == 0) + { + mProgramShaderHandleAllocator.release(programObject->first); + delete programObject->second; + mProgramMap.erase(programObject); + } + else + { + programObject->second->flagForDeletion(); + } + } +} + +void ResourceManager::deleteTexture(GLuint texture) +{ + auto textureObject = mTextureMap.find(texture); + + if (textureObject != mTextureMap.end()) + { + mTextureHandleAllocator.release(textureObject->first); + if (textureObject->second) textureObject->second->release(); + mTextureMap.erase(textureObject); + } +} + +void ResourceManager::deleteRenderbuffer(GLuint renderbuffer) +{ + auto renderbufferObject = mRenderbufferMap.find(renderbuffer); + + if (renderbufferObject != mRenderbufferMap.end()) + { + mRenderbufferHandleAllocator.release(renderbufferObject->first); + if (renderbufferObject->second) renderbufferObject->second->release(); + mRenderbufferMap.erase(renderbufferObject); + } +} + +void ResourceManager::deleteSampler(GLuint sampler) +{ + auto samplerObject = mSamplerMap.find(sampler); + + if (samplerObject != mSamplerMap.end()) + { + mSamplerHandleAllocator.release(samplerObject->first); + if (samplerObject->second) samplerObject->second->release(); + mSamplerMap.erase(samplerObject); + } +} + +void ResourceManager::deleteFenceSync(GLuint fenceSync) +{ + auto fenceObjectIt = mFenceSyncMap.find(fenceSync); + + if (fenceObjectIt != mFenceSyncMap.end()) + { + mFenceSyncHandleAllocator.release(fenceObjectIt->first); + if (fenceObjectIt->second) fenceObjectIt->second->release(); + mFenceSyncMap.erase(fenceObjectIt); + } +} + +void ResourceManager::deletePaths(GLuint first, GLsizei range) +{ + for (GLsizei i = 0; i < range; ++i) + { + const auto id = first + i; + const auto it = mPathMap.find(id); + if (it == mPathMap.end()) + continue; + Path *p = it->second; + delete p; + mPathMap.erase(it); + } + mPathHandleAllocator.releaseRange(first, static_cast<GLuint>(range)); +} + +Buffer *ResourceManager::getBuffer(unsigned int handle) +{ + auto buffer = mBufferMap.find(handle); + + if (buffer == mBufferMap.end()) + { + return nullptr; + } + else + { + return buffer->second; + } +} + +Shader *ResourceManager::getShader(unsigned int handle) const +{ + auto shader = mShaderMap.find(handle); + + if (shader == mShaderMap.end()) + { + return nullptr; + } + else + { + return shader->second; + } +} + +Texture *ResourceManager::getTexture(unsigned int handle) +{ + if (handle == 0) + return nullptr; + + auto texture = mTextureMap.find(handle); + + if (texture == mTextureMap.end()) + { + return nullptr; + } + else + { + return texture->second; + } +} + +Program *ResourceManager::getProgram(unsigned int handle) const +{ + auto program = mProgramMap.find(handle); + + if (program == mProgramMap.end()) + { + return nullptr; + } + else + { + return program->second; + } +} + +Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle) +{ + auto renderbuffer = mRenderbufferMap.find(handle); + + if (renderbuffer == mRenderbufferMap.end()) + { + return nullptr; + } + else + { + return renderbuffer->second; + } +} + +Sampler *ResourceManager::getSampler(unsigned int handle) +{ + auto sampler = mSamplerMap.find(handle); + + if (sampler == mSamplerMap.end()) + { + return nullptr; + } + else + { + return sampler->second; + } +} + +FenceSync *ResourceManager::getFenceSync(unsigned int handle) +{ + auto fenceObjectIt = mFenceSyncMap.find(handle); + + if (fenceObjectIt == mFenceSyncMap.end()) + { + return nullptr; + } + else + { + return fenceObjectIt->second; + } +} + +const Path *ResourceManager::getPath(GLuint handle) const +{ + auto it = mPathMap.find(handle); + if (it == std::end(mPathMap)) + return nullptr; + return it->second; +} + +Path *ResourceManager::getPath(GLuint handle) +{ + auto it = mPathMap.find(handle); + if (it == std::end(mPathMap)) + return nullptr; + + return it->second; +} + +bool ResourceManager::hasPath(GLuint handle) const +{ + return mPathHandleAllocator.isUsed(handle); +} + +void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer) +{ + mRenderbufferMap[handle] = buffer; +} + +Buffer *ResourceManager::checkBufferAllocation(rx::GLImplFactory *factory, GLuint handle) +{ + if (handle == 0) + { + return nullptr; + } + + auto bufferMapIt = mBufferMap.find(handle); + bool handleAllocated = (bufferMapIt != mBufferMap.end()); + + if (handleAllocated && bufferMapIt->second != nullptr) + { + return bufferMapIt->second; + } + + Buffer *buffer = new Buffer(factory, handle); + buffer->addRef(); + + if (handleAllocated) + { + bufferMapIt->second = buffer; + } + else + { + mBufferHandleAllocator.reserve(handle); + mBufferMap[handle] = buffer; + } + + return buffer; +} + +Texture *ResourceManager::checkTextureAllocation(rx::GLImplFactory *factory, + GLuint handle, + GLenum type) +{ + if (handle == 0) + { + return nullptr; + } + + auto textureMapIt = mTextureMap.find(handle); + bool handleAllocated = (textureMapIt != mTextureMap.end()); + + if (handleAllocated && textureMapIt->second != nullptr) + { + return textureMapIt->second; + } + + Texture *texture = new Texture(factory, handle, type); + texture->addRef(); + + if (handleAllocated) + { + textureMapIt->second = texture; + } + else + { + mTextureHandleAllocator.reserve(handle); + mTextureMap[handle] = texture; + } + + return texture; +} + +Renderbuffer *ResourceManager::checkRenderbufferAllocation(rx::GLImplFactory *factory, + GLuint handle) +{ + if (handle == 0) + { + return nullptr; + } + + auto renderbufferMapIt = mRenderbufferMap.find(handle); + bool handleAllocated = (renderbufferMapIt != mRenderbufferMap.end()); + + if (handleAllocated && renderbufferMapIt->second != nullptr) + { + return renderbufferMapIt->second; + } + + Renderbuffer *renderbuffer = new Renderbuffer(factory->createRenderbuffer(), handle); + renderbuffer->addRef(); + + if (handleAllocated) + { + renderbufferMapIt->second = renderbuffer; + } + else + { + mRenderbufferHandleAllocator.reserve(handle); + mRenderbufferMap[handle] = renderbuffer; + } + + return renderbuffer; +} + +Sampler *ResourceManager::checkSamplerAllocation(rx::GLImplFactory *factory, GLuint samplerHandle) +{ + // Samplers cannot be created via Bind + if (samplerHandle == 0) + { + return nullptr; + } + + Sampler *sampler = getSampler(samplerHandle); + + if (!sampler) + { + sampler = new Sampler(factory, samplerHandle); + mSamplerMap[samplerHandle] = sampler; + sampler->addRef(); + } + + return sampler; +} + +bool ResourceManager::isSampler(GLuint sampler) +{ + return mSamplerMap.find(sampler) != mSamplerMap.end(); +} + +bool ResourceManager::isTextureGenerated(GLuint texture) const +{ + return texture == 0 || mTextureMap.find(texture) != mTextureMap.end(); +} + +bool ResourceManager::isBufferGenerated(GLuint buffer) const +{ + return buffer == 0 || mBufferMap.find(buffer) != mBufferMap.end(); +} + +bool ResourceManager::isRenderbufferGenerated(GLuint renderbuffer) const +{ + return renderbuffer == 0 || mRenderbufferMap.find(renderbuffer) != mRenderbufferMap.end(); +} + +} // namespace gl |