Add a ResourceMap class for faster GL resource maps.
This gives a very fast query time for handles that are within a fixed
range. For WebGL, where we don't allow create-on-bind, this will be
100% of the time, unless we create a very large number of resources.
It is implemented as a two-tier map - the first uses a flat array to
index into a handle buffer. The second tier uses a map for out-of-
range values.
BUG=angleproject:1458
Change-Id: I421bb3725cf523918cdfdbfaab035ad0dd3bf82d
Reviewed-on: https://chromium-review.googlesource.com/544684
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index be1325e..a7fb2b4 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -409,6 +409,7 @@
{
SafeDelete(fence.second);
}
+ mFenceNVMap.clear();
for (auto query : mQueryMap)
{
@@ -417,6 +418,7 @@
query.second->release(this);
}
}
+ mQueryMap.clear();
for (auto vertexArray : mVertexArrayMap)
{
@@ -425,6 +427,7 @@
vertexArray.second->onDestroy(this);
}
}
+ mVertexArrayMap.clear();
for (auto transformFeedback : mTransformFeedbackMap)
{
@@ -433,6 +436,7 @@
transformFeedback.second->release(this);
}
}
+ mTransformFeedbackMap.clear();
for (auto &zeroTexture : mZeroTextures)
{
@@ -606,8 +610,8 @@
GLuint Context::createVertexArray()
{
- GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
- mVertexArrayMap[vertexArray] = nullptr;
+ GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
+ mVertexArrayMap.assign(vertexArray, nullptr);
return vertexArray;
}
@@ -618,8 +622,8 @@
GLuint Context::createTransformFeedback()
{
- GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
- mTransformFeedbackMap[transformFeedback] = nullptr;
+ GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
+ mTransformFeedbackMap.assign(transformFeedback, nullptr);
return transformFeedback;
}
@@ -632,9 +636,7 @@
GLuint Context::createFenceNV()
{
GLuint handle = mFenceNVHandleAllocator.allocate();
-
- mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
-
+ mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV()));
return handle;
}
@@ -642,9 +644,7 @@
GLuint Context::createQuery()
{
GLuint handle = mQueryHandleAllocator.allocate();
-
- mQueryMap[handle] = nullptr;
-
+ mQueryMap.assign(handle, nullptr);
return handle;
}
@@ -790,17 +790,15 @@
void Context::deleteVertexArray(GLuint vertexArray)
{
- auto iter = mVertexArrayMap.find(vertexArray);
- if (iter != mVertexArrayMap.end())
+ VertexArray *vertexArrayObject = nullptr;
+ if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
{
- VertexArray *vertexArrayObject = iter->second;
if (vertexArrayObject != nullptr)
{
detachVertexArray(vertexArray);
vertexArrayObject->onDestroy(this);
}
- mVertexArrayMap.erase(iter);
mVertexArrayHandleAllocator.release(vertexArray);
}
}
@@ -822,17 +820,15 @@
return;
}
- auto iter = mTransformFeedbackMap.find(transformFeedback);
- if (iter != mTransformFeedbackMap.end())
+ TransformFeedback *transformFeedbackObject = nullptr;
+ if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
{
- TransformFeedback *transformFeedbackObject = iter->second;
if (transformFeedbackObject != nullptr)
{
detachTransformFeedback(transformFeedback);
transformFeedbackObject->release(this);
}
- mTransformFeedbackMap.erase(iter);
mTransformFeedbackAllocator.release(transformFeedback);
}
}
@@ -849,27 +845,24 @@
void Context::deleteFenceNV(GLuint fence)
{
- auto fenceObject = mFenceNVMap.find(fence);
-
- if (fenceObject != mFenceNVMap.end())
+ FenceNV *fenceObject = nullptr;
+ if (mFenceNVMap.erase(fence, &fenceObject))
{
- mFenceNVHandleAllocator.release(fenceObject->first);
- delete fenceObject->second;
- mFenceNVMap.erase(fenceObject);
+ mFenceNVHandleAllocator.release(fence);
+ delete fenceObject;
}
}
void Context::deleteQuery(GLuint query)
{
- auto queryObject = mQueryMap.find(query);
- if (queryObject != mQueryMap.end())
+ Query *queryObject = nullptr;
+ if (mQueryMap.erase(query, &queryObject))
{
- mQueryHandleAllocator.release(queryObject->first);
- if (queryObject->second)
+ mQueryHandleAllocator.release(query);
+ if (queryObject)
{
- queryObject->second->release(this);
+ queryObject->release(this);
}
- mQueryMap.erase(queryObject);
}
}
@@ -896,8 +889,7 @@
VertexArray *Context::getVertexArray(GLuint handle) const
{
- auto vertexArray = mVertexArrayMap.find(handle);
- return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
+ return mVertexArrayMap.query(handle);
}
Sampler *Context::getSampler(GLuint handle) const
@@ -907,8 +899,7 @@
TransformFeedback *Context::getTransformFeedback(GLuint handle) const
{
- auto iter = mTransformFeedbackMap.find(handle);
- return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
+ return mTransformFeedbackMap.query(handle);
}
LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
@@ -1270,41 +1261,29 @@
FenceNV *Context::getFenceNV(GLuint handle)
{
- auto fence = mFenceNVMap.find(handle);
-
- if (fence == mFenceNVMap.end())
- {
- return nullptr;
- }
- else
- {
- return fence->second;
- }
+ return mFenceNVMap.query(handle);
}
Query *Context::getQuery(GLuint handle, bool create, GLenum type)
{
- auto query = mQueryMap.find(handle);
-
- if (query == mQueryMap.end())
+ if (!mQueryMap.contains(handle))
{
return nullptr;
}
- else
+
+ Query *query = mQueryMap.query(handle);
+ if (!query && create)
{
- if (!query->second && create)
- {
- query->second = new Query(mImplementation->createQuery(type), handle);
- query->second->addRef();
- }
- return query->second;
+ query = new Query(mImplementation->createQuery(type), handle);
+ query->addRef();
+ mQueryMap.assign(handle, query);
}
+ return query;
}
Query *Context::getQuery(GLuint handle) const
{
- auto iter = mQueryMap.find(handle);
- return (iter != mQueryMap.end()) ? iter->second : nullptr;
+ return mQueryMap.query(handle);
}
Texture *Context::getTargetTexture(GLenum target) const
@@ -2309,7 +2288,7 @@
vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
- mVertexArrayMap[vertexArrayHandle] = vertexArray;
+ mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
}
return vertexArray;
@@ -2324,7 +2303,7 @@
transformFeedback =
new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
transformFeedback->addRef();
- mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
+ mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
}
return transformFeedback;
@@ -2332,14 +2311,14 @@
bool Context::isVertexArrayGenerated(GLuint vertexArray)
{
- ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
- return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
+ ASSERT(mVertexArrayMap.contains(0));
+ return mVertexArrayMap.contains(vertexArray);
}
bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
{
- ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
- return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
+ ASSERT(mTransformFeedbackMap.contains(0));
+ return mTransformFeedbackMap.contains(transformFeedback);
}
void Context::detachTexture(GLuint texture)