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/libEGL/Display.cpp b/src/libEGL/Display.cpp
index 9f2ea70..c856b2a 100644
--- a/src/libEGL/Display.cpp
+++ b/src/libEGL/Display.cpp
@@ -101,7 +101,7 @@
         return false;
     }
 
-    mRenderer = glCreateRenderer(hModule, mDc);
+    mRenderer = glCreateRenderer(this, hModule, mDc);
     EGLint status = EGL_BAD_ALLOC;
     if (mRenderer)
         status = mRenderer->initialize();
@@ -230,12 +230,6 @@
         destroyContext(*mContextSet.begin());
     }
 
-    while (!mEventQueryPool.empty())
-    {
-        mEventQueryPool.back()->Release();
-        mEventQueryPool.pop_back();
-    }
-
     mVertexShaderCache.clear();
     mPixelShaderCache.clear();
 
@@ -503,12 +497,6 @@
         (*surface)->release();
     }
 
-    while (!mEventQueryPool.empty())
-    {
-        mEventQueryPool.back()->Release();
-        mEventQueryPool.pop_back();
-    }
-
     mVertexShaderCache.clear();
     mPixelShaderCache.clear();
 
@@ -592,80 +580,6 @@
     return mMaxSwapInterval;
 }
 
-// D3D9_REPLACE
-void Display::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 (mRenderer->testDeviceLost())
-            {
-                result = D3DERR_DEVICELOST;
-            }
-        }
-    }
-    while(block && result == S_FALSE);
-
-    freeEventQuery(query);
-
-    if (isDeviceLostError(result))
-    {
-        notifyDeviceLost();
-    }
-}
-
-// D3D9_REPLACE
-IDirect3DQuery9* Display::allocateEventQuery()
-{
-    IDirect3DQuery9 *query = NULL;
-
-    if (mEventQueryPool.empty())
-    {
-        HRESULT result = mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_EVENT, &query);
-        ASSERT(SUCCEEDED(result));
-    }
-    else
-    {
-        query = mEventQueryPool.back();
-        mEventQueryPool.pop_back();
-    }
-
-    return query;
-}
-
-// D3D9_REPLACE
-void Display::freeEventQuery(IDirect3DQuery9* query)
-{
-    if (mEventQueryPool.size() > 1000)
-    {
-        query->Release();
-    }
-    else
-    {
-        mEventQueryPool.push_back(query);
-    }
-}
-
-
 void Display::initExtensionString()
 {
     HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
diff --git a/src/libEGL/Display.h b/src/libEGL/Display.h
index fe390f2..9fa5d7f 100644
--- a/src/libEGL/Display.h
+++ b/src/libEGL/Display.h
@@ -59,9 +59,6 @@
     EGLint getMaxSwapInterval();
 
     renderer::Renderer *getRenderer() { return mRenderer; };
-    virtual void sync(bool block);
-    virtual IDirect3DQuery9* allocateEventQuery();
-    virtual void freeEventQuery(IDirect3DQuery9* query);
 
     virtual void notifyDeviceLost();
 
@@ -80,9 +77,6 @@
     EGLNativeDisplayType mDisplayId;
     const HDC mDc;
 
-    // A pool of event queries that are currently unused.
-    std::vector<IDirect3DQuery9*> mEventQueryPool;
-
     VertexShaderCache mVertexShaderCache;
     PixelShaderCache mPixelShaderCache;
 
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 32caaa0..b1ba5a6 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -956,7 +956,7 @@
 {
     GLuint handle = mFenceHandleAllocator.allocate();
 
-    mFenceMap[handle] = new Fence(mDisplay);
+    mFenceMap[handle] = new Fence(mRenderer);
 
     return handle;
 }
@@ -1344,7 +1344,7 @@
     {
         if (!query->second && create)
         {
-            query->second = new Query(handle, type);
+            query->second = new Query(mRenderer, handle, type);
             query->second->addRef();
         }
         return query->second;
@@ -3212,7 +3212,7 @@
 // Implements glFlush when block is false, glFinish when block is true
 void Context::sync(bool block)
 {
-    mDisplay->sync(block);
+    mRenderer->sync(block);
 }
 
 void Context::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex)
@@ -4500,9 +4500,9 @@
     return gl::getContext();
 }
 
-renderer::Renderer *glCreateRenderer(HMODULE hModule, HDC hDc)
+renderer::Renderer *glCreateRenderer(egl::Display *display, HMODULE hModule, HDC hDc)
 {
-    return new renderer::Renderer(hModule, hDc);
+    return new renderer::Renderer(display, hModule, hDc);
 }
 
 void glDestroyRenderer(renderer::Renderer *renderer)
diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h
index e885605..e4e5caf 100644
--- a/src/libGLESv2/Context.h
+++ b/src/libGLESv2/Context.h
@@ -680,7 +680,7 @@
 void glDestroyContext(gl::Context *context);
 void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface);
 gl::Context *glGetCurrentContext();
-renderer::Renderer *glCreateRenderer(HMODULE hModule, HDC hDc);
+renderer::Renderer *glCreateRenderer(egl::Display *display, HMODULE hModule, HDC hDc);
 void glDestroyRenderer(renderer::Renderer *renderer);
 
 __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname);
diff --git a/src/libGLESv2/Fence.cpp b/src/libGLESv2/Fence.cpp
index 14d1239..aad8cd3 100644
--- a/src/libGLESv2/Fence.cpp
+++ b/src/libGLESv2/Fence.cpp
@@ -13,9 +13,9 @@
 namespace gl
 {
 
-Fence::Fence(egl::Display* display)
+Fence::Fence(renderer::Renderer *renderer)
 {
-    mDisplay = display;
+    mRenderer = renderer;
     mQuery = NULL;
     mCondition = GL_NONE;
     mStatus = GL_FALSE;
@@ -25,7 +25,7 @@
 {
     if (mQuery != NULL)
     {
-        mDisplay->freeEventQuery(mQuery);
+        mRenderer->freeEventQuery(mQuery);
     }
 }
 
@@ -36,11 +36,12 @@
     return mQuery != NULL;
 }
 
+// D3D9_REPLACE
 void Fence::setFence(GLenum condition)
 {
     if (!mQuery)
     {
-        mQuery = mDisplay->allocateEventQuery();
+        mQuery = mRenderer->allocateEventQuery();
         if (!mQuery)
         {
             return error(GL_OUT_OF_MEMORY);
@@ -54,6 +55,7 @@
     mStatus = GL_FALSE;
 }
 
+// D3D9_REPLACE
 GLboolean Fence::testFence()
 {
     if (mQuery == NULL)
@@ -106,7 +108,7 @@
                 return;
             }
             
-            HRESULT result = mQuery->GetData(NULL, 0, 0);
+            HRESULT result = mQuery->GetData(NULL, 0, 0); // D3D9_REPLACE
             
             if (checkDeviceLost(result))
             {
diff --git a/src/libGLESv2/Fence.h b/src/libGLESv2/Fence.h
index 9626cb0..5ecaf54 100644
--- a/src/libGLESv2/Fence.h
+++ b/src/libGLESv2/Fence.h
@@ -14,11 +14,7 @@
 #include <d3d9.h>
 
 #include "common/angleutils.h"
-
-namespace egl
-{
-class Display;
-}
+#include "libGLESv2/renderer/Renderer.h"
 
 namespace gl
 {
@@ -26,7 +22,7 @@
 class Fence
 {
   public:
-    explicit Fence(egl::Display* display);
+    explicit Fence(renderer::Renderer *renderer);
     virtual ~Fence();
 
     GLboolean isFence();
@@ -38,8 +34,8 @@
   private:
     DISALLOW_COPY_AND_ASSIGN(Fence);
 
-    egl::Display* mDisplay;
-    IDirect3DQuery9* mQuery;
+    renderer::Renderer *mRenderer;
+    IDirect3DQuery9* mQuery;  // D3D9_REPLACE
     GLenum mCondition;
     GLboolean mStatus;
 };
diff --git a/src/libGLESv2/Query.cpp b/src/libGLESv2/Query.cpp
index b6fa1de..dd6280d 100644
--- a/src/libGLESv2/Query.cpp
+++ b/src/libGLESv2/Query.cpp
@@ -13,8 +13,9 @@
 namespace gl
 {
 
-Query::Query(GLuint id, GLenum type) : RefCountObject(id)
+Query::Query(renderer::Renderer *renderer, GLuint id, GLenum type) : RefCountObject(id)
 { 
+    mRenderer = renderer;
     mQuery = NULL;
     mStatus = GL_FALSE;
     mResult = GL_FALSE;
@@ -35,7 +36,7 @@
     if (mQuery == NULL)
     {
         // D3D9_REPLACE
-        if (FAILED(getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery)))
+        if (FAILED(mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery)))
         {
             return error(GL_OUT_OF_MEMORY);
         }
@@ -69,9 +70,9 @@
             // 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 (gl::getDisplay()->getRenderer()->testDeviceLost()) // D3D9_REPLACE
+            if (mRenderer->testDeviceLost())
             {
-                gl::getDisplay()->notifyDeviceLost();
+                gl::getDisplay()->notifyDeviceLost(); // D3D9_REPLACE
                 return error(GL_OUT_OF_MEMORY, 0);
             }
         }
diff --git a/src/libGLESv2/Query.h b/src/libGLESv2/Query.h
index 79357a0..cf4b769 100644
--- a/src/libGLESv2/Query.h
+++ b/src/libGLESv2/Query.h
@@ -15,6 +15,7 @@
 
 #include "common/angleutils.h"
 #include "common/RefCountObject.h"
+#include "libGLESv2/renderer/Renderer.h"
 
 namespace gl
 {
@@ -22,7 +23,7 @@
 class Query : public RefCountObject
 {
   public:
-    Query(GLuint id, GLenum type);
+    Query(renderer::Renderer *renderer, GLuint id, GLenum type);
     virtual ~Query();
 
     void begin();
@@ -35,9 +36,11 @@
   private:
     DISALLOW_COPY_AND_ASSIGN(Query);
 
+    renderer::Renderer *mRenderer;
+
     GLboolean testQuery();
 
-    IDirect3DQuery9* mQuery;
+    IDirect3DQuery9* mQuery; // D3D9_REPLACE
     GLenum mType;
     GLboolean mStatus;
     GLint mResult;
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;
 }
 
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index f27b129..857109e 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -10,6 +10,9 @@
 #ifndef LIBGLESV2_RENDERER_RENDERER_H_
 #define LIBGLESV2_RENDERER_RENDERER_H_
 
+#include <set>
+#include <vector>
+
 #include "common/angleutils.h"
 #define GL_APICALL
 #include <GLES2/gl2.h>
@@ -32,13 +35,18 @@
     return MAKEWORD(minorVersion, majorVersion);
 }
 
+namespace egl
+{
+class Display;
+}
+
 namespace renderer
 {
 
 class Renderer
 {
   public:
-    Renderer(HMODULE hModule, HDC hDc);
+    Renderer(egl::Display *display, HMODULE hModule, HDC hDc);
     virtual ~Renderer();
 
     virtual EGLint initialize();
@@ -47,6 +55,10 @@
     virtual void startScene();
     virtual void endScene();
 
+    virtual void sync(bool block);
+    virtual IDirect3DQuery9* allocateEventQuery();
+    virtual void freeEventQuery(IDirect3DQuery9* query);
+
 #if 0
     // resource creation
     virtual void *createVertexShader(const DWORD *function, size_t length);
@@ -103,11 +115,13 @@
   private:
     DISALLOW_COPY_AND_ASSIGN(Renderer);
 
+    egl::Display *mDisplay;
     const HDC mDc;
     HMODULE mD3d9Module;
 
     void initializeDevice();
     D3DPRESENT_PARAMETERS getDefaultPresentParameters();
+    void releaseDeviceResources();
 
     UINT mAdapter;
     D3DDEVTYPE mDeviceType;
@@ -124,6 +138,9 @@
 
     bool mSceneStarted;
     bool mSupportsNonPower2Textures;
+
+    // A pool of event queries that are currently unused.
+    std::vector<IDirect3DQuery9*> mEventQueryPool;
 };
 
 }