Move query and sync support to Renderer
Trac #21727
git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1331 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/renderer/Renderer.cpp b/src/libGLESv2/renderer/Renderer.cpp
index e2d5400..6f3ae0b 100644
--- a/src/libGLESv2/renderer/Renderer.cpp
+++ b/src/libGLESv2/renderer/Renderer.cpp
@@ -11,6 +11,8 @@
#include "common/debug.h"
#include "libGLESv2/utilities.h"
+#include "libEGL/Display.h"
+
// Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
#define REF_RAST 0
@@ -25,8 +27,9 @@
namespace renderer
{
-Renderer::Renderer(HMODULE hModule, HDC hDc): mDc(hDc)
+Renderer::Renderer(egl::Display *display, HMODULE hModule, HDC hDc): mDc(hDc)
{
+ mDisplay = display;
mD3d9Module = hModule;
mD3d9 = NULL;
@@ -48,6 +51,8 @@
Renderer::~Renderer()
{
+ releaseDeviceResources();
+
if (mDevice)
{
// If the device is lost, reset it first to prevent leaving the driver in an unstable state
@@ -266,6 +271,89 @@
}
}
+// D3D9_REPLACE
+void Renderer::sync(bool block)
+{
+ HRESULT result;
+
+ IDirect3DQuery9* query = allocateEventQuery();
+ if (!query)
+ {
+ return;
+ }
+
+ result = query->Issue(D3DISSUE_END);
+ ASSERT(SUCCEEDED(result));
+
+ do
+ {
+ result = query->GetData(NULL, 0, D3DGETDATA_FLUSH);
+
+ if(block && result == S_FALSE)
+ {
+ // Keep polling, but allow other threads to do something useful first
+ Sleep(0);
+ // explicitly check for device loss
+ // some drivers seem to return S_FALSE even if the device is lost
+ // instead of D3DERR_DEVICELOST like they should
+ if (testDeviceLost())
+ {
+ result = D3DERR_DEVICELOST;
+ }
+ }
+ }
+ while(block && result == S_FALSE);
+
+ freeEventQuery(query);
+
+ if (isDeviceLostError(result))
+ {
+ mDisplay->notifyDeviceLost();
+ }
+}
+
+// D3D9_REPLACE
+IDirect3DQuery9* Renderer::allocateEventQuery()
+{
+ IDirect3DQuery9 *query = NULL;
+
+ if (mEventQueryPool.empty())
+ {
+ HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query);
+ ASSERT(SUCCEEDED(result));
+ }
+ else
+ {
+ query = mEventQueryPool.back();
+ mEventQueryPool.pop_back();
+ }
+
+ return query;
+}
+
+// D3D9_REPLACE
+void Renderer::freeEventQuery(IDirect3DQuery9* query)
+{
+ if (mEventQueryPool.size() > 1000)
+ {
+ query->Release();
+ }
+ else
+ {
+ mEventQueryPool.push_back(query);
+ }
+}
+
+void Renderer::releaseDeviceResources()
+{
+ while (!mEventQueryPool.empty())
+ {
+ mEventQueryPool.back()->Release();
+ mEventQueryPool.pop_back();
+ }
+}
+
+
void Renderer::markDeviceLost()
{
mDeviceLost = true;
@@ -331,6 +419,8 @@
bool Renderer::resetDevice()
{
+ releaseDeviceResources();
+
D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
HRESULT result = D3D_OK;
@@ -511,7 +601,6 @@
bool Renderer::getEventQuerySupport()
{
-#if 0 // D3D9_REPLACE
IDirect3DQuery9 *query = allocateEventQuery();
if (query)
{
@@ -522,7 +611,6 @@
{
return false;
}
-#endif
return true;
}