Add destroy hooks for several GL objects.
These hooks allow the back-end renderer to free object resources
without having to store pointers to shared device handles for
each and every object. This will allow us to save memory on
back-ends that really care about memory overhead.
There is a downside in that there is more boilerplate in passing
gl::Context handles around everywhere.
BUG=angleproject:1684
Change-Id: I89463bba8d23f92920e8956650cb73c7fc6d66b7
Reviewed-on: https://chromium-review.googlesource.com/426401
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/ResourceManager.cpp b/src/libANGLE/ResourceManager.cpp
index c7defac..c60db2c 100644
--- a/src/libANGLE/ResourceManager.cpp
+++ b/src/libANGLE/ResourceManager.cpp
@@ -54,10 +54,11 @@
}
template <typename HandleAllocatorType>
-void ResourceManagerBase<HandleAllocatorType>::release()
+void ResourceManagerBase<HandleAllocatorType>::release(const Context *context)
{
if (--mRefCount == 0)
{
+ reset(context);
delete this;
}
}
@@ -65,14 +66,23 @@
template <typename ResourceType, typename HandleAllocatorType, typename ImplT>
TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::~TypedResourceManager()
{
- while (!mObjectMap.empty())
- {
- deleteObject(mObjectMap.begin()->first);
- }
+ ASSERT(mObjectMap.empty());
}
template <typename ResourceType, typename HandleAllocatorType, typename ImplT>
-void TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::deleteObject(GLuint handle)
+void TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::reset(const Context *context)
+{
+ while (!mObjectMap.empty())
+ {
+ deleteObject(context, mObjectMap.begin()->first);
+ }
+ mObjectMap.clear();
+}
+
+template <typename ResourceType, typename HandleAllocatorType, typename ImplT>
+void TypedResourceManager<ResourceType, HandleAllocatorType, ImplT>::deleteObject(
+ const Context *context,
+ GLuint handle)
{
auto objectIter = mObjectMap.find(handle);
if (objectIter == mObjectMap.end())
@@ -82,6 +92,7 @@
if (objectIter->second != nullptr)
{
+ objectIter->second->destroy(context);
ImplT::DeleteObject(objectIter->second);
}
@@ -181,14 +192,22 @@
ShaderProgramManager::~ShaderProgramManager()
{
+ ASSERT(mPrograms.empty());
+ ASSERT(mShaders.empty());
+}
+
+void ShaderProgramManager::reset(const Context *context)
+{
while (!mPrograms.empty())
{
- deleteProgram(mPrograms.begin()->first);
+ deleteProgram(context, mPrograms.begin()->first);
}
+ mPrograms.clear();
while (!mShaders.empty())
{
- deleteShader(mShaders.begin()->first);
+ deleteShader(context, mShaders.begin()->first);
}
+ mShaders.clear();
}
GLuint ShaderProgramManager::createShader(rx::GLImplFactory *factory,
@@ -201,9 +220,9 @@
return handle;
}
-void ShaderProgramManager::deleteShader(GLuint shader)
+void ShaderProgramManager::deleteShader(const Context *context, GLuint shader)
{
- deleteObject(&mShaders, shader);
+ deleteObject(context, &mShaders, shader);
}
Shader *ShaderProgramManager::getShader(GLuint handle) const
@@ -218,9 +237,9 @@
return handle;
}
-void ShaderProgramManager::deleteProgram(GLuint program)
+void ShaderProgramManager::deleteProgram(const gl::Context *context, GLuint program)
{
- deleteObject(&mPrograms, program);
+ deleteObject(context, &mPrograms, program);
}
Program *ShaderProgramManager::getProgram(GLuint handle) const
@@ -229,7 +248,9 @@
}
template <typename ObjectType>
-void ShaderProgramManager::deleteObject(ResourceMap<ObjectType> *objectMap, GLuint id)
+void ShaderProgramManager::deleteObject(const Context *context,
+ ResourceMap<ObjectType> *objectMap,
+ GLuint id)
{
auto iter = objectMap->find(id);
if (iter == objectMap->end())
@@ -241,6 +262,7 @@
if (object->getRefCount() == 0)
{
mHandleAllocator.release(id);
+ object->destroy(context);
SafeDelete(object);
objectMap->erase(iter);
}
@@ -421,10 +443,16 @@
PathManager::~PathManager()
{
+ ASSERT(mPaths.empty());
+}
+
+void PathManager::reset(const Context *context)
+{
for (auto path : mPaths)
{
SafeDelete(path.second);
}
+ mPaths.clear();
}
// FramebufferManager Implementation.