summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/ResourceManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/ResourceManager.cpp')
-rw-r--r--src/3rdparty/angle/src/libANGLE/ResourceManager.cpp603
1 files changed, 315 insertions, 288 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/ResourceManager.cpp b/src/3rdparty/angle/src/libANGLE/ResourceManager.cpp
index dc9dad1e9f..79eb7e5f42 100644
--- a/src/3rdparty/angle/src/libANGLE/ResourceManager.cpp
+++ b/src/3rdparty/angle/src/libANGLE/ResourceManager.cpp
@@ -1,456 +1,483 @@
//
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2016 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.
+// ResourceManager.cpp: Implements the the ResourceManager classes, which handle allocation and
+// lifetime of GL objects.
#include "libANGLE/ResourceManager.h"
#include "libANGLE/Buffer.h"
+#include "libANGLE/Fence.h"
+#include "libANGLE/Path.h"
#include "libANGLE/Program.h"
+#include "libANGLE/ProgramPipeline.h"
#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Sampler.h"
#include "libANGLE/Shader.h"
#include "libANGLE/Texture.h"
-#include "libANGLE/Sampler.h"
-#include "libANGLE/Fence.h"
-#include "libANGLE/renderer/Renderer.h"
+#include "libANGLE/renderer/GLImplFactory.h"
namespace gl
{
-ResourceManager::ResourceManager(rx::ImplFactory *factory)
- : mFactory(factory),
- mRefCount(1)
+
+namespace
+{
+
+template <typename ResourceType>
+GLuint AllocateEmptyObject(HandleAllocator *handleAllocator, ResourceMap<ResourceType> *objectMap)
{
+ GLuint handle = handleAllocator->allocate();
+ objectMap->assign(handle, nullptr);
+ return handle;
}
-ResourceManager::~ResourceManager()
+} // anonymous namespace
+
+template <typename HandleAllocatorType>
+ResourceManagerBase<HandleAllocatorType>::ResourceManagerBase() : mRefCount(1)
{
- while (!mBufferMap.empty())
- {
- deleteBuffer(mBufferMap.begin()->first);
- }
+}
- while (!mProgramMap.empty())
- {
- deleteProgram(mProgramMap.begin()->first);
- }
+template <typename HandleAllocatorType>
+void ResourceManagerBase<HandleAllocatorType>::addRef()
+{
+ mRefCount++;
+}
- while (!mShaderMap.empty())
+template <typename HandleAllocatorType>
+void ResourceManagerBase<HandleAllocatorType>::release(const Context *context)
+{
+ if (--mRefCount == 0)
{
- deleteShader(mShaderMap.begin()->first);
+ reset(context);
+ delete this;
}
+}
- while (!mRenderbufferMap.empty())
- {
- deleteRenderbuffer(mRenderbufferMap.begin()->first);
- }
+template <typename ResourceType, typename HandleAllocatorType, typename ImplT>
+TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::~TypedResourceManager()
+{
+ ASSERT(mObjectMap.empty());
+}
- while (!mTextureMap.empty())
+template <typename ResourceType, typename HandleAllocatorType, typename ImplT>
+void TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::reset(const Context *context)
+{
+ this->mHandleAllocator.reset();
+ for (const auto &resource : mObjectMap)
{
- deleteTexture(mTextureMap.begin()->first);
+ if (resource.second)
+ {
+ ImplT::DeleteObject(context, resource.second);
+ }
}
+ mObjectMap.clear();
+}
- while (!mSamplerMap.empty())
+template <typename ResourceType, typename HandleAllocatorType, typename ImplT>
+void TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::deleteObject(
+ const Context *context,
+ GLuint handle)
+{
+ ResourceType *resource = nullptr;
+ if (!mObjectMap.erase(handle, &resource))
{
- deleteSampler(mSamplerMap.begin()->first);
+ return;
}
- while (!mFenceSyncMap.empty())
+ // Requires an explicit this-> because of C++ template rules.
+ this->mHandleAllocator.release(handle);
+
+ if (resource)
{
- deleteFenceSync(mFenceSyncMap.begin()->first);
+ ImplT::DeleteObject(context, resource);
}
}
-void ResourceManager::addRef()
+template class ResourceManagerBase<HandleAllocator>;
+template class ResourceManagerBase<HandleRangeAllocator>;
+template class TypedResourceManager<Buffer, HandleAllocator, BufferManager>;
+template class TypedResourceManager<Texture, HandleAllocator, TextureManager>;
+template class TypedResourceManager<Renderbuffer, HandleAllocator, RenderbufferManager>;
+template class TypedResourceManager<Sampler, HandleAllocator, SamplerManager>;
+template class TypedResourceManager<Sync, HandleAllocator, SyncManager>;
+template class TypedResourceManager<Framebuffer, HandleAllocator, FramebufferManager>;
+template class TypedResourceManager<ProgramPipeline, HandleAllocator, ProgramPipelineManager>;
+
+// BufferManager Implementation.
+
+// static
+Buffer *BufferManager::AllocateNewObject(rx::GLImplFactory *factory, GLuint handle)
{
- mRefCount++;
+ Buffer *buffer = new Buffer(factory, handle);
+ buffer->addRef();
+ return buffer;
}
-void ResourceManager::release()
+// static
+void BufferManager::DeleteObject(const Context *context, Buffer *buffer)
{
- if (--mRefCount == 0)
- {
- delete this;
- }
+ buffer->release(context);
}
-// Returns an unused buffer name
-GLuint ResourceManager::createBuffer()
+GLuint BufferManager::createBuffer()
{
- GLuint handle = mBufferHandleAllocator.allocate();
+ return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
+}
- mBufferMap[handle] = NULL;
+Buffer *BufferManager::getBuffer(GLuint handle) const
+{
+ return mObjectMap.query(handle);
+}
- return handle;
+// ShaderProgramManager Implementation.
+
+ShaderProgramManager::ShaderProgramManager()
+{
}
-// Returns an unused shader/program name
-GLuint ResourceManager::createShader(const gl::Limitations &rendererLimitations, GLenum type)
+ShaderProgramManager::~ShaderProgramManager()
{
- GLuint handle = mProgramShaderHandleAllocator.allocate();
+ ASSERT(mPrograms.empty());
+ ASSERT(mShaders.empty());
+}
- if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER)
+void ShaderProgramManager::reset(const Context *context)
+{
+ while (!mPrograms.empty())
{
- mShaderMap[handle] = new Shader(this, mFactory, rendererLimitations, type, handle);
+ deleteProgram(context, mPrograms.begin()->first);
}
- else UNREACHABLE();
-
- return handle;
+ mPrograms.clear();
+ while (!mShaders.empty())
+ {
+ deleteShader(context, mShaders.begin()->first);
+ }
+ mShaders.clear();
}
-// Returns an unused program/shader name
-GLuint ResourceManager::createProgram()
+GLuint ShaderProgramManager::createShader(rx::GLImplFactory *factory,
+ const gl::Limitations &rendererLimitations,
+ GLenum type)
{
- GLuint handle = mProgramShaderHandleAllocator.allocate();
-
- mProgramMap[handle] = new Program(mFactory, this, handle);
-
+ ASSERT(type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER || type == GL_COMPUTE_SHADER ||
+ type == GL_GEOMETRY_SHADER_EXT);
+ GLuint handle = mHandleAllocator.allocate();
+ mShaders.assign(handle, new Shader(this, factory, rendererLimitations, type, handle));
return handle;
}
-// Returns an unused texture name
-GLuint ResourceManager::createTexture()
+void ShaderProgramManager::deleteShader(const Context *context, GLuint shader)
{
- GLuint handle = mTextureHandleAllocator.allocate();
-
- mTextureMap[handle] = NULL;
-
- return handle;
+ deleteObject(context, &mShaders, shader);
}
-// Returns an unused renderbuffer name
-GLuint ResourceManager::createRenderbuffer()
+Shader *ShaderProgramManager::getShader(GLuint handle) const
{
- GLuint handle = mRenderbufferHandleAllocator.allocate();
-
- mRenderbufferMap[handle] = NULL;
-
- return handle;
+ return mShaders.query(handle);
}
-// Returns an unused sampler name
-GLuint ResourceManager::createSampler()
+GLuint ShaderProgramManager::createProgram(rx::GLImplFactory *factory)
{
- GLuint handle = mSamplerHandleAllocator.allocate();
-
- mSamplerMap[handle] = NULL;
-
+ GLuint handle = mHandleAllocator.allocate();
+ mPrograms.assign(handle, new Program(factory, this, handle));
return handle;
}
-// Returns the next unused fence name, and allocates the fence
-GLuint ResourceManager::createFenceSync()
+void ShaderProgramManager::deleteProgram(const gl::Context *context, GLuint program)
{
- GLuint handle = mFenceSyncHandleAllocator.allocate();
-
- FenceSync *fenceSync = new FenceSync(mFactory->createFenceSync(), handle);
- fenceSync->addRef();
- mFenceSyncMap[handle] = fenceSync;
+ deleteObject(context, &mPrograms, program);
+}
- return handle;
+Program *ShaderProgramManager::getProgram(GLuint handle) const
+{
+ return mPrograms.query(handle);
}
-void ResourceManager::deleteBuffer(GLuint buffer)
+template <typename ObjectType>
+void ShaderProgramManager::deleteObject(const Context *context,
+ ResourceMap<ObjectType> *objectMap,
+ GLuint id)
{
- BufferMap::iterator bufferObject = mBufferMap.find(buffer);
+ ObjectType *object = objectMap->query(id);
+ if (!object)
+ {
+ return;
+ }
- if (bufferObject != mBufferMap.end())
+ if (object->getRefCount() == 0)
+ {
+ mHandleAllocator.release(id);
+ object->onDestroy(context);
+ objectMap->erase(id, &object);
+ }
+ else
{
- mBufferHandleAllocator.release(bufferObject->first);
- if (bufferObject->second) bufferObject->second->release();
- mBufferMap.erase(bufferObject);
+ object->flagForDeletion();
}
}
-void ResourceManager::deleteShader(GLuint shader)
+// TextureManager Implementation.
+
+// static
+Texture *TextureManager::AllocateNewObject(rx::GLImplFactory *factory, GLuint handle, GLenum target)
{
- ShaderMap::iterator shaderObject = mShaderMap.find(shader);
+ Texture *texture = new Texture(factory, handle, target);
+ texture->addRef();
+ return texture;
+}
- if (shaderObject != mShaderMap.end())
- {
- if (shaderObject->second->getRefCount() == 0)
- {
- mProgramShaderHandleAllocator.release(shaderObject->first);
- delete shaderObject->second;
- mShaderMap.erase(shaderObject);
- }
- else
- {
- shaderObject->second->flagForDeletion();
- }
- }
+// static
+void TextureManager::DeleteObject(const Context *context, Texture *texture)
+{
+ texture->release(context);
}
-void ResourceManager::deleteProgram(GLuint program)
+GLuint TextureManager::createTexture()
{
- ProgramMap::iterator programObject = mProgramMap.find(program);
+ return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
+}
+
+Texture *TextureManager::getTexture(GLuint handle) const
+{
+ ASSERT(mObjectMap.query(0) == nullptr);
+ return mObjectMap.query(handle);
+}
- if (programObject != mProgramMap.end())
+void TextureManager::signalAllTexturesDirty() const
+{
+ for (const auto &texture : mObjectMap)
{
- if (programObject->second->getRefCount() == 0)
+ if (texture.second)
{
- mProgramShaderHandleAllocator.release(programObject->first);
- delete programObject->second;
- mProgramMap.erase(programObject);
- }
- else
- {
- programObject->second->flagForDeletion();
+ // We don't know if the Texture needs init, but that's ok, since it will only force
+ // a re-check, and will not initialize the pixels if it's not needed.
+ texture.second->signalDirty(InitState::MayNeedInit);
}
}
}
-void ResourceManager::deleteTexture(GLuint texture)
-{
- TextureMap::iterator textureObject = mTextureMap.find(texture);
+// RenderbufferManager Implementation.
- if (textureObject != mTextureMap.end())
- {
- mTextureHandleAllocator.release(textureObject->first);
- if (textureObject->second) textureObject->second->release();
- mTextureMap.erase(textureObject);
- }
+// static
+Renderbuffer *RenderbufferManager::AllocateNewObject(rx::GLImplFactory *factory, GLuint handle)
+{
+ Renderbuffer *renderbuffer = new Renderbuffer(factory->createRenderbuffer(), handle);
+ renderbuffer->addRef();
+ return renderbuffer;
}
-void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
+// static
+void RenderbufferManager::DeleteObject(const Context *context, Renderbuffer *renderbuffer)
{
- RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
+ renderbuffer->release(context);
+}
- if (renderbufferObject != mRenderbufferMap.end())
- {
- mRenderbufferHandleAllocator.release(renderbufferObject->first);
- if (renderbufferObject->second) renderbufferObject->second->release();
- mRenderbufferMap.erase(renderbufferObject);
- }
+GLuint RenderbufferManager::createRenderbuffer()
+{
+ return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
}
-void ResourceManager::deleteSampler(GLuint sampler)
+Renderbuffer *RenderbufferManager::getRenderbuffer(GLuint handle) const
{
- auto samplerObject = mSamplerMap.find(sampler);
+ return mObjectMap.query(handle);
+}
- if (samplerObject != mSamplerMap.end())
- {
- mSamplerHandleAllocator.release(samplerObject->first);
- if (samplerObject->second) samplerObject->second->release();
- mSamplerMap.erase(samplerObject);
- }
+// SamplerManager Implementation.
+
+// static
+Sampler *SamplerManager::AllocateNewObject(rx::GLImplFactory *factory, GLuint handle)
+{
+ Sampler *sampler = new Sampler(factory, handle);
+ sampler->addRef();
+ return sampler;
}
-void ResourceManager::deleteFenceSync(GLuint fenceSync)
+// static
+void SamplerManager::DeleteObject(const Context *context, Sampler *sampler)
{
- auto fenceObjectIt = mFenceSyncMap.find(fenceSync);
+ sampler->release(context);
+}
- if (fenceObjectIt != mFenceSyncMap.end())
- {
- mFenceSyncHandleAllocator.release(fenceObjectIt->first);
- if (fenceObjectIt->second) fenceObjectIt->second->release();
- mFenceSyncMap.erase(fenceObjectIt);
- }
+GLuint SamplerManager::createSampler()
+{
+ return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
}
-Buffer *ResourceManager::getBuffer(unsigned int handle)
+Sampler *SamplerManager::getSampler(GLuint handle) const
{
- BufferMap::iterator buffer = mBufferMap.find(handle);
+ return mObjectMap.query(handle);
+}
- if (buffer == mBufferMap.end())
- {
- return NULL;
- }
- else
- {
- return buffer->second;
- }
+bool SamplerManager::isSampler(GLuint sampler) const
+{
+ return mObjectMap.contains(sampler);
}
-Shader *ResourceManager::getShader(unsigned int handle)
+// SyncManager Implementation.
+
+// static
+void SyncManager::DeleteObject(const Context *context, Sync *sync)
{
- ShaderMap::iterator shader = mShaderMap.find(handle);
+ sync->release(context);
+}
- if (shader == mShaderMap.end())
- {
- return NULL;
- }
- else
- {
- return shader->second;
- }
+GLuint SyncManager::createSync(rx::GLImplFactory *factory)
+{
+ GLuint handle = mHandleAllocator.allocate();
+ Sync *sync = new Sync(factory->createSync(), handle);
+ sync->addRef();
+ mObjectMap.assign(handle, sync);
+ return handle;
}
-Texture *ResourceManager::getTexture(unsigned int handle)
+Sync *SyncManager::getSync(GLuint handle) const
{
- if (handle == 0) return NULL;
+ return mObjectMap.query(handle);
+}
- TextureMap::iterator texture = mTextureMap.find(handle);
+// PathManager Implementation.
- if (texture == mTextureMap.end())
- {
- return NULL;
- }
- else
- {
- return texture->second;
- }
+PathManager::PathManager()
+{
}
-Program *ResourceManager::getProgram(unsigned int handle) const
+ErrorOrResult<GLuint> PathManager::createPaths(rx::GLImplFactory *factory, GLsizei range)
{
- ProgramMap::const_iterator program = mProgramMap.find(handle);
+ // Allocate client side handles.
+ const GLuint client = mHandleAllocator.allocateRange(static_cast<GLuint>(range));
+ if (client == HandleRangeAllocator::kInvalidHandle)
+ return OutOfMemory() << "Failed to allocate path handle range.";
- if (program == mProgramMap.end())
+ const auto &paths = factory->createPaths(range);
+ if (paths.empty())
{
- return NULL;
+ mHandleAllocator.releaseRange(client, range);
+ return OutOfMemory() << "Failed to allocate path objects.";
}
- else
+
+ for (GLsizei i = 0; i < range; ++i)
{
- return program->second;
+ rx::PathImpl *impl = paths[static_cast<unsigned>(i)];
+ const auto id = client + i;
+ mPaths.assign(id, new Path(impl));
}
+ return client;
}
-Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
+void PathManager::deletePaths(GLuint first, GLsizei range)
{
- RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
-
- if (renderbuffer == mRenderbufferMap.end())
+ for (GLsizei i = 0; i < range; ++i)
{
- return NULL;
- }
- else
- {
- return renderbuffer->second;
+ const auto id = first + i;
+ Path *p = nullptr;
+ if (!mPaths.erase(id, &p))
+ continue;
+ delete p;
}
+ mHandleAllocator.releaseRange(first, static_cast<GLuint>(range));
}
-Sampler *ResourceManager::getSampler(unsigned int handle)
+Path *PathManager::getPath(GLuint handle) const
{
- auto sampler = mSamplerMap.find(handle);
+ return mPaths.query(handle);
+}
- if (sampler == mSamplerMap.end())
- {
- return NULL;
- }
- else
- {
- return sampler->second;
- }
+bool PathManager::hasPath(GLuint handle) const
+{
+ return mHandleAllocator.isUsed(handle);
}
-FenceSync *ResourceManager::getFenceSync(unsigned int handle)
+PathManager::~PathManager()
{
- auto fenceObjectIt = mFenceSyncMap.find(handle);
+ ASSERT(mPaths.empty());
+}
- if (fenceObjectIt == mFenceSyncMap.end())
- {
- return NULL;
- }
- else
+void PathManager::reset(const Context *context)
+{
+ for (auto path : mPaths)
{
- return fenceObjectIt->second;
+ SafeDelete(path.second);
}
+ mPaths.clear();
}
-void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
+// FramebufferManager Implementation.
+
+// static
+Framebuffer *FramebufferManager::AllocateNewObject(rx::GLImplFactory *factory,
+ GLuint handle,
+ const Caps &caps)
{
- mRenderbufferMap[handle] = buffer;
+ return new Framebuffer(caps, factory, handle);
}
-void ResourceManager::checkBufferAllocation(GLuint handle)
+// static
+void FramebufferManager::DeleteObject(const Context *context, Framebuffer *framebuffer)
{
- if (handle != 0)
+ // Default framebuffer are owned by their respective Surface
+ if (framebuffer->id() != 0)
{
- auto bufferMapIt = mBufferMap.find(handle);
- bool handleAllocated = (bufferMapIt != mBufferMap.end());
-
- if (handleAllocated && bufferMapIt->second != nullptr)
- {
- return;
- }
-
- Buffer *buffer = new Buffer(mFactory->createBuffer(), handle);
- buffer->addRef();
-
- if (handleAllocated)
- {
- bufferMapIt->second = buffer;
- }
- else
- {
- mBufferHandleAllocator.reserve(handle);
- mBufferMap[handle] = buffer;
- }
+ framebuffer->onDestroy(context);
+ delete framebuffer;
}
}
-void ResourceManager::checkTextureAllocation(GLuint handle, GLenum type)
+GLuint FramebufferManager::createFramebuffer()
{
- if (handle != 0)
- {
- auto textureMapIt = mTextureMap.find(handle);
- bool handleAllocated = (textureMapIt != mTextureMap.end());
-
- if (handleAllocated && textureMapIt->second != nullptr)
- {
- return;
- }
+ return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
+}
- Texture *texture = new Texture(mFactory->createTexture(type), handle, type);
- texture->addRef();
+Framebuffer *FramebufferManager::getFramebuffer(GLuint handle) const
+{
+ return mObjectMap.query(handle);
+}
- if (handleAllocated)
- {
- textureMapIt->second = texture;
- }
- else
- {
- mTextureHandleAllocator.reserve(handle);
- mTextureMap[handle] = texture;
- }
- }
+void FramebufferManager::setDefaultFramebuffer(Framebuffer *framebuffer)
+{
+ ASSERT(framebuffer == nullptr || framebuffer->id() == 0);
+ mObjectMap.assign(0, framebuffer);
}
-void ResourceManager::checkRenderbufferAllocation(GLuint handle)
+void FramebufferManager::invalidateFramebufferComplenessCache() const
{
- if (handle != 0)
+ for (const auto &framebuffer : mObjectMap)
{
- auto renderbufferMapIt = mRenderbufferMap.find(handle);
- bool handleAllocated = (renderbufferMapIt != mRenderbufferMap.end());
-
- if (handleAllocated && renderbufferMapIt->second != nullptr)
+ if (framebuffer.second)
{
- return;
+ framebuffer.second->invalidateCompletenessCache();
}
+ }
+}
- Renderbuffer *renderbuffer = new Renderbuffer(mFactory->createRenderbuffer(), handle);
- renderbuffer->addRef();
+// ProgramPipelineManager Implementation.
- if (handleAllocated)
- {
- renderbufferMapIt->second = renderbuffer;
- }
- else
- {
- mRenderbufferHandleAllocator.reserve(handle);
- mRenderbufferMap[handle] = renderbuffer;
- }
- }
+// static
+ProgramPipeline *ProgramPipelineManager::AllocateNewObject(rx::GLImplFactory *factory,
+ GLuint handle)
+{
+ ProgramPipeline *pipeline = new ProgramPipeline(factory, handle);
+ pipeline->addRef();
+ return pipeline;
}
-void ResourceManager::checkSamplerAllocation(GLuint sampler)
+// static
+void ProgramPipelineManager::DeleteObject(const Context *context, ProgramPipeline *pipeline)
{
- if (sampler != 0 && !getSampler(sampler))
- {
- Sampler *samplerObject = new Sampler(mFactory, sampler);
- mSamplerMap[sampler] = samplerObject;
- samplerObject->addRef();
- // Samplers cannot be created via Bind
- }
+ pipeline->release(context);
}
-bool ResourceManager::isSampler(GLuint sampler)
+GLuint ProgramPipelineManager::createProgramPipeline()
{
- return mSamplerMap.find(sampler) != mSamplerMap.end();
+ return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
}
+ProgramPipeline *ProgramPipelineManager::getProgramPipeline(GLuint handle) const
+{
+ return mObjectMap.query(handle);
}
+
+} // namespace gl