Commit d2f02c2a by Ian Ewell Committed by Commit Bot

Fix a memory leak in the Query11 class.

The destructor did not release D3D objects that could be in the mPendingQueries list when the destructor is called. This fix now iterates through the list and releases them. BUG=angleproject:1325 Change-Id: Ia3bd2a8a611f8dbf85051ab5bfea18ab72038af5 Reviewed-on: https://chromium-review.googlesource.com/329426Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Ian Ewell <ewell@google.com>
parent 14ed667f
...@@ -44,17 +44,27 @@ GLuint64 MergeQueryResults(GLenum type, GLuint64 currentResult, GLuint64 newResu ...@@ -44,17 +44,27 @@ GLuint64 MergeQueryResults(GLenum type, GLuint64 currentResult, GLuint64 newResu
namespace rx namespace rx
{ {
Query11::QueryState::QueryState()
: query(nullptr), beginTimestamp(nullptr), endTimestamp(nullptr), finished(false)
{
}
Query11::QueryState::~QueryState()
{
SafeRelease(beginTimestamp);
SafeRelease(endTimestamp);
SafeRelease(query);
}
Query11::Query11(Renderer11 *renderer, GLenum type) Query11::Query11(Renderer11 *renderer, GLenum type)
: QueryImpl(type), mResult(0), mResultSum(0), mRenderer(renderer) : QueryImpl(type), mResult(0), mResultSum(0), mRenderer(renderer)
{ {
mActiveQuery = std::unique_ptr<QueryState>(new QueryState());
} }
Query11::~Query11() Query11::~Query11()
{ {
mRenderer->getStateManager()->onDeleteQueryObject(this); mRenderer->getStateManager()->onDeleteQueryObject(this);
SafeRelease(mActiveQuery.beginTimestamp);
SafeRelease(mActiveQuery.endTimestamp);
SafeRelease(mActiveQuery.query);
} }
gl::Error Query11::begin() gl::Error Query11::begin()
...@@ -74,14 +84,14 @@ gl::Error Query11::queryCounter() ...@@ -74,14 +84,14 @@ gl::Error Query11::queryCounter()
// This doesn't do anything for D3D11 as we don't support timestamps // This doesn't do anything for D3D11 as we don't support timestamps
ASSERT(getType() == GL_TIMESTAMP_EXT); ASSERT(getType() == GL_TIMESTAMP_EXT);
mResultSum = 0; mResultSum = 0;
mPendingQueries.push_back(QueryState()); mPendingQueries.push_back(std::unique_ptr<QueryState>(new QueryState()));
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
template <typename T> template <typename T>
gl::Error Query11::getResultBase(T *params) gl::Error Query11::getResultBase(T *params)
{ {
ASSERT(mActiveQuery.query == nullptr); ASSERT(mActiveQuery->query == nullptr);
gl::Error error = flush(true); gl::Error error = flush(true);
if (error.isError()) if (error.isError())
...@@ -129,20 +139,20 @@ gl::Error Query11::isResultAvailable(bool *available) ...@@ -129,20 +139,20 @@ gl::Error Query11::isResultAvailable(bool *available)
gl::Error Query11::pause() gl::Error Query11::pause()
{ {
if (mActiveQuery.query != nullptr) if (mActiveQuery->query != nullptr)
{ {
ID3D11DeviceContext *context = mRenderer->getDeviceContext(); ID3D11DeviceContext *context = mRenderer->getDeviceContext();
// If we are doing time elapsed query the end timestamp // If we are doing time elapsed query the end timestamp
if (getType() == GL_TIME_ELAPSED_EXT) if (getType() == GL_TIME_ELAPSED_EXT)
{ {
context->End(mActiveQuery.endTimestamp); context->End(mActiveQuery->endTimestamp);
} }
context->End(mActiveQuery.query); context->End(mActiveQuery->query);
mPendingQueries.push_back(mActiveQuery); mPendingQueries.push_back(std::move(mActiveQuery));
mActiveQuery = QueryState(); mActiveQuery = std::unique_ptr<QueryState>(new QueryState());
} }
return flush(false); return flush(false);
...@@ -150,7 +160,7 @@ gl::Error Query11::pause() ...@@ -150,7 +160,7 @@ gl::Error Query11::pause()
gl::Error Query11::resume() gl::Error Query11::resume()
{ {
if (mActiveQuery.query == nullptr) if (mActiveQuery->query == nullptr)
{ {
gl::Error error = flush(false); gl::Error error = flush(false);
if (error.isError()) if (error.isError())
...@@ -164,7 +174,7 @@ gl::Error Query11::resume() ...@@ -164,7 +174,7 @@ gl::Error Query11::resume()
ID3D11Device *device = mRenderer->getDevice(); ID3D11Device *device = mRenderer->getDevice();
HRESULT result = device->CreateQuery(&queryDesc, &mActiveQuery.query); HRESULT result = device->CreateQuery(&queryDesc, &mActiveQuery->query);
if (FAILED(result)) if (FAILED(result))
{ {
return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.",
...@@ -177,13 +187,13 @@ gl::Error Query11::resume() ...@@ -177,13 +187,13 @@ gl::Error Query11::resume()
D3D11_QUERY_DESC desc; D3D11_QUERY_DESC desc;
desc.Query = D3D11_QUERY_TIMESTAMP; desc.Query = D3D11_QUERY_TIMESTAMP;
desc.MiscFlags = 0; desc.MiscFlags = 0;
result = device->CreateQuery(&desc, &mActiveQuery.beginTimestamp); result = device->CreateQuery(&desc, &mActiveQuery->beginTimestamp);
if (FAILED(result)) if (FAILED(result))
{ {
return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.",
result); result);
} }
result = device->CreateQuery(&desc, &mActiveQuery.endTimestamp); result = device->CreateQuery(&desc, &mActiveQuery->endTimestamp);
if (FAILED(result)) if (FAILED(result))
{ {
return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.",
...@@ -193,12 +203,12 @@ gl::Error Query11::resume() ...@@ -193,12 +203,12 @@ gl::Error Query11::resume()
ID3D11DeviceContext *context = mRenderer->getDeviceContext(); ID3D11DeviceContext *context = mRenderer->getDeviceContext();
context->Begin(mActiveQuery.query); context->Begin(mActiveQuery->query);
// If we are doing time elapsed, query the begin timestamp // If we are doing time elapsed, query the begin timestamp
if (getType() == GL_TIME_ELAPSED_EXT) if (getType() == GL_TIME_ELAPSED_EXT)
{ {
context->End(mActiveQuery.beginTimestamp); context->End(mActiveQuery->beginTimestamp);
} }
} }
...@@ -209,7 +219,7 @@ gl::Error Query11::flush(bool force) ...@@ -209,7 +219,7 @@ gl::Error Query11::flush(bool force)
{ {
while (!mPendingQueries.empty()) while (!mPendingQueries.empty())
{ {
QueryState *query = &mPendingQueries.front(); QueryState *query = mPendingQueries.front().get();
do do
{ {
...@@ -225,9 +235,6 @@ gl::Error Query11::flush(bool force) ...@@ -225,9 +235,6 @@ gl::Error Query11::flush(bool force)
} while (!query->finished); } while (!query->finished);
mResultSum = MergeQueryResults(getType(), mResultSum, mResult); mResultSum = MergeQueryResults(getType(), mResultSum, mResult);
SafeRelease(query->beginTimestamp);
SafeRelease(query->endTimestamp);
SafeRelease(query->query);
mPendingQueries.pop_front(); mPendingQueries.pop_front();
} }
......
...@@ -36,12 +36,11 @@ class Query11 : public QueryImpl ...@@ -36,12 +36,11 @@ class Query11 : public QueryImpl
gl::Error resume(); gl::Error resume();
private: private:
struct QueryState struct QueryState final : public angle::NonCopyable
{ {
QueryState() QueryState();
: query(nullptr), beginTimestamp(nullptr), endTimestamp(nullptr), finished(false) ~QueryState();
{
}
ID3D11Query *query; ID3D11Query *query;
ID3D11Query *beginTimestamp; ID3D11Query *beginTimestamp;
ID3D11Query *endTimestamp; ID3D11Query *endTimestamp;
...@@ -59,8 +58,8 @@ class Query11 : public QueryImpl ...@@ -59,8 +58,8 @@ class Query11 : public QueryImpl
Renderer11 *mRenderer; Renderer11 *mRenderer;
QueryState mActiveQuery; std::unique_ptr<QueryState> mActiveQuery;
std::deque<QueryState> mPendingQueries; std::deque<std::unique_ptr<QueryState>> mPendingQueries;
}; };
} }
......
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