summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/libANGLE/ResourceManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/libANGLE/ResourceManager.cpp')
-rwxr-xr-xgfx/angle/src/libANGLE/ResourceManager.cpp562
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