Allocate D3D queries from a pool for the Display.
This is a workaround for an Intel bug.
The crash looks like this:
0x5f816c53 [d3d9.dll + 0x00036c53] CQuery::~CQuery()
0x5f816bec [d3d9.dll + 0x00036bec] CQuery::`vector deleting
destructor'(unsigned int)
0x5f7e8129 [d3d9.dll + 0x00008129] CBaseObject::~CBaseObject()
0x5f9e19c7 [libglesv2.dll + 0x000319c7] gl::Fence::`vector deleting
destructor'(unsigned int)
0x5f9de78e [libglesv2.dll - context.cpp:975] gl::Context::deleteFence(unsigned
int)
0x5f9e1491 [libglesv2.dll - context.cpp:198] gl::Context::~Context()
0x5f9e182f [libglesv2.dll - context.cpp:3936] glDestroyContext
0x717654ec [libegl.dll -
display.cpp:749] egl::Display::destroyContext(gl::Context *)
0x7176a3da [libegl.dll - libegl.cpp:907] eglDestroyContext
0x64fbaf33 [chrome.dll - gl_context_egl.cc:75] gfx::GLContextEGL::Destroy()
The vendor ID is always 8086 (Intel). Not an XP issue - it's happening on Win
7.
With this change, D3D queries are only released when the display is destroyed or reset or if a very high number of D3D queries have been allocated.
Tested by stepping exercising the NV_fence entry points in a debugger.
Review URL: http://codereview.appspot.com/5534065
git-svn-id: https://angleproject.googlecode.com/svn/trunk@941 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libEGL/Display.cpp b/src/libEGL/Display.cpp
index b9c84c0..1a093ba 100644
--- a/src/libEGL/Display.cpp
+++ b/src/libEGL/Display.cpp
@@ -76,7 +76,6 @@
mDevice = NULL;
mDeviceEx = NULL;
mDeviceWindow = NULL;
- mEventQuery = NULL;
mAdapter = D3DADAPTER_DEFAULT;
@@ -304,10 +303,10 @@
destroyContext(*mContextSet.begin());
}
- if (mEventQuery)
+ while (!mEventQueryPool.empty())
{
- mEventQuery->Release();
- mEventQuery = NULL;
+ mEventQueryPool.back()->Release();
+ mEventQueryPool.pop_back();
}
if (mDevice)
@@ -469,12 +468,6 @@
mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
mDevice->SetRenderState(D3DRS_LASTPIXEL, FALSE);
- // Leave mEventQuery null if CreateQuery fails. This will prevent sync from
- // working correctly but otherwise mEventQuery is expected to be null when
- // queries are not supported.
- ASSERT(!mEventQuery);
- mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &mEventQuery);
-
mSceneStarted = false;
}
@@ -737,10 +730,10 @@
(*surface)->release();
}
- if (mEventQuery)
+ while (!mEventQueryPool.empty())
{
- mEventQuery->Release();
- mEventQuery = NULL;
+ mEventQueryPool.back()->Release();
+ mEventQueryPool.pop_back();
}
if (!resetDevice())
@@ -892,17 +885,18 @@
{
HRESULT result;
- if (!mEventQuery)
+ IDirect3DQuery9* query = allocateEventQuery();
+ if (!query)
{
return;
}
- result = mEventQuery->Issue(D3DISSUE_END);
+ result = query->Issue(D3DISSUE_END);
ASSERT(SUCCEEDED(result));
do
{
- result = mEventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
+ result = query->GetData(NULL, 0, D3DGETDATA_FLUSH);
if(block && result == S_FALSE)
{
@@ -919,9 +913,41 @@
}
while(block && result == S_FALSE);
- if (isDeviceLostError(result))
+ freeEventQuery(query);
+
+ if (isDeviceLostError(result))
+ {
+ notifyDeviceLost();
+ }
+}
+
+IDirect3DQuery9* Display::allocateEventQuery()
+{
+ IDirect3DQuery9 *query = NULL;
+
+ if (mEventQueryPool.empty())
{
- notifyDeviceLost();
+ HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query);
+ ASSERT(SUCCEEDED(result));
+ }
+ else
+ {
+ query = mEventQueryPool.back();
+ mEventQueryPool.pop_back();
+ }
+
+ return query;
+}
+
+void Display::freeEventQuery(IDirect3DQuery9* query)
+{
+ if (mEventQueryPool.size() > 1000)
+ {
+ query->Release();
+ }
+ else
+ {
+ mEventQueryPool.push_back(query);
}
}
@@ -1068,14 +1094,16 @@
bool Display::getEventQuerySupport()
{
- IDirect3DQuery9 *query;
- HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query);
- if (SUCCEEDED(result))
+ IDirect3DQuery9 *query = allocateEventQuery();
+ if (query)
{
- query->Release();
+ freeEventQuery(query);
+ return true;
}
-
- return result != D3DERR_NOTAVAILABLE;
+ else
+ {
+ return false;
+ }
}
D3DPRESENT_PARAMETERS Display::getDefaultPresentParameters()