Commit 3fc6893c by Alexis Hetu Committed by Alexis Hétu

Prevent glDeleteQueries from deleting a live Query

glDeleteQueries() instantly deletes all the es2::Query objects passed as arguments to this function. If some of these queries are still being used by the renderer, this will result in a use after free error. To solve this issue, sw::Query is now a also ref counted object. Bug chromium:904714 Change-Id: Ic1d5781bbf1724d8d07936fd49c8a172dc3d9fd4 Reviewed-on: https://swiftshader-review.googlesource.com/c/22548Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent d5f14892
......@@ -41,7 +41,7 @@ namespace D3D9
{
device->removeQuery(query);
delete query;
query->release();
}
}
......@@ -202,7 +202,7 @@ namespace D3D9
return INVALIDCALL();
}
bool signaled = !query || query->reference == 0;
bool signaled = !query || query->isReady();
if(size && signaled)
{
......
......@@ -32,7 +32,7 @@ Query::Query(GLuint name, GLenum type) : NamedObject(name)
Query::~Query()
{
delete mQuery;
mQuery->release();
}
void Query::begin()
......@@ -140,7 +140,7 @@ GLboolean Query::testQuery()
{
if(mQuery != nullptr && mStatus != GL_TRUE)
{
if(!mQuery->building && mQuery->reference == 0)
if(!mQuery->building && mQuery->isReady())
{
unsigned int resultSum = mQuery->data;
mStatus = GL_TRUE;
......
......@@ -96,6 +96,27 @@ namespace sw
int threadIndex;
};
Query::Query(Type type) : building(false), data(0), type(type), reference(1)
{
}
void Query::addRef()
{
++reference; // Atomic
}
void Query::release()
{
int ref = reference--; // Atomic
ASSERT(ref >= 0);
if(ref == 0)
{
delete this;
}
}
DrawCall::DrawCall()
{
queries = 0;
......@@ -325,7 +346,7 @@ namespace sw
{
if(includePrimitivesWrittenQueries || (query->type != Query::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN))
{
++query->reference; // Atomic
query->addRef();
draw->queries->push_back(query);
}
}
......@@ -1013,7 +1034,7 @@ namespace sw
break;
}
--query->reference; // Atomic
query->release();
}
delete draw.queries;
......
......@@ -89,26 +89,35 @@ namespace sw
{
enum Type { FRAGMENTS_PASSED, TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN };
Query(Type type) : building(false), reference(0), data(0), type(type)
{
}
Query(Type type);
void addRef();
void release();
void begin()
inline void begin()
{
building = true;
data = 0;
}
void end()
inline void end()
{
building = false;
}
inline bool isReady() const
{
return (reference == 1);
}
bool building;
AtomicInt reference;
AtomicInt data;
const Type type;
private:
~Query() {} // Only delete a query within the release() function
AtomicInt reference;
};
struct DrawData
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment