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()