[PATCH 3/5] wined3d: Use an internal call table for query operations.

Henri Verbeet hverbeet at codeweavers.com
Thu Feb 3 13:14:05 CST 2011


---
 dlls/wined3d/query.c           |  183 ++++++++++++++++++++++------------------
 dlls/wined3d/wined3d_private.h |   12 +++-
 2 files changed, 113 insertions(+), 82 deletions(-)

diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index e2e2fca..ca7f48a 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -284,12 +284,40 @@ static ULONG  WINAPI IWineD3DQueryImpl_Release(IWineD3DQuery *iface) {
     return ref;
 }
 
-static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery *iface,
+static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery *iface,
+        void *data, DWORD data_size, DWORD flags)
+{
+    struct IWineD3DQueryImpl *query = (struct IWineD3DQueryImpl *)iface;
+
+    TRACE("iface %p, data %p, data_size %u, flags %#x.\n",
+            iface, data, data_size, flags);
+
+    return query->query_ops->query_get_data(query, data, data_size, flags);
+}
+
+static DWORD WINAPI IWineD3DQueryImpl_GetDataSize(IWineD3DQuery *iface)
+{
+    struct IWineD3DQueryImpl *query = (struct IWineD3DQueryImpl *)iface;
+
+    TRACE("iface %p.\n", iface);
+
+    return query->data_size;
+}
+
+static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery *iface, DWORD flags)
+{
+    struct IWineD3DQueryImpl *query = (struct IWineD3DQueryImpl *)iface;
+
+    TRACE("iface %p, flags %#x.\n", iface, flags);
+
+    return query->query_ops->query_issue(query, flags);
+}
+
+static HRESULT wined3d_occlusion_query_ops_get_data(struct IWineD3DQueryImpl *query,
         void *pData, DWORD dwSize, DWORD flags)
 {
-    IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
-    struct wined3d_occlusion_query *query = This->extendedData;
-    IWineD3DDeviceImpl *device = This->device;
+    struct wined3d_occlusion_query *oq = query->extendedData;
+    IWineD3DDeviceImpl *device = query->device;
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
     struct wined3d_context *context;
     DWORD* data = pData;
@@ -297,11 +325,12 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery *iface,
     GLuint samples;
     HRESULT res;
 
-    TRACE("(%p) : type D3DQUERY_OCCLUSION, pData %p, dwSize %#x, flags %#x.\n", This, pData, dwSize, flags);
+    TRACE("(%p) : type D3DQUERY_OCCLUSION, pData %p, dwSize %#x, flags %#x.\n", query, pData, dwSize, flags);
 
-    if (!query->context) This->state = QUERY_CREATED;
+    if (!oq->context)
+        query->state = QUERY_CREATED;
 
-    if (This->state == QUERY_CREATED)
+    if (query->state == QUERY_CREATED)
     {
         /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves */
         TRACE("Query wasn't yet started, returning S_OK\n");
@@ -309,7 +338,7 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery *iface,
         return S_OK;
     }
 
-    if (This->state == QUERY_BUILDING)
+    if (query->state == QUERY_BUILDING)
     {
         /* Msdn says this returns an error, but our tests show that S_FALSE is returned */
         TRACE("Query is building, returning S_FALSE\n");
@@ -318,33 +347,33 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery *iface,
 
     if (!gl_info->supported[ARB_OCCLUSION_QUERY])
     {
-        WARN("(%p) : Occlusion queries not supported. Returning 1.\n", This);
+        WARN("%p Occlusion queries not supported. Returning 1.\n", query);
         *data = 1;
         return S_OK;
     }
 
-    if (query->context->tid != GetCurrentThreadId())
+    if (oq->context->tid != GetCurrentThreadId())
     {
-        FIXME("%p Wrong thread, returning 1.\n", This);
+        FIXME("%p Wrong thread, returning 1.\n", query);
         *data = 1;
         return S_OK;
     }
 
-    context = context_acquire(This->device, query->context->current_rt);
+    context = context_acquire(query->device, oq->context->current_rt);
 
     ENTER_GL();
 
-    GL_EXTCALL(glGetQueryObjectuivARB(query->id, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
+    GL_EXTCALL(glGetQueryObjectuivARB(oq->id, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
     checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)");
-    TRACE("(%p) : available %d.\n", This, available);
+    TRACE("available %#x.\n", available);
 
     if (available)
     {
         if (data)
         {
-            GL_EXTCALL(glGetQueryObjectuivARB(query->id, GL_QUERY_RESULT_ARB, &samples));
+            GL_EXTCALL(glGetQueryObjectuivARB(oq->id, GL_QUERY_RESULT_ARB, &samples));
             checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)");
-            TRACE("(%p) : Returning %d samples.\n", This, samples);
+            TRACE("Returning %d samples.\n", samples);
             *data = samples;
         }
         res = S_OK;
@@ -361,25 +390,24 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery *iface,
     return res;
 }
 
-static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery *iface,
+static HRESULT wined3d_event_query_ops_get_data(IWineD3DQueryImpl *query,
         void *pData, DWORD dwSize, DWORD flags)
 {
-    IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
-    struct wined3d_event_query *query = This->extendedData;
+    struct wined3d_event_query *event_query = query->extendedData;
     BOOL *data = pData;
     enum wined3d_event_query_result ret;
 
-    TRACE("(%p) : type D3DQUERY_EVENT, pData %p, dwSize %#x, flags %#x.\n", This, pData, dwSize, flags);
+    TRACE("query %p, pData %p, dwSize %#x, flags %#x.\n", query, pData, dwSize, flags);
 
     if (!pData || !dwSize) return S_OK;
-    if (!query)
+    if (!event_query)
     {
-        WARN("(%p): Event query not supported by GL, reporting GPU idle\n", This);
+        WARN("Event query not supported by GL, reporting GPU idle.\n");
         *data = TRUE;
         return S_OK;
     }
 
-    ret = wined3d_event_query_test(query, This->device);
+    ret = wined3d_event_query_test(event_query, query->device);
     switch(ret)
     {
         case WINED3D_EVENT_QUERY_OK:
@@ -392,7 +420,7 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery *iface,
             break;
 
         case WINED3D_EVENT_QUERY_WRONG_THREAD:
-            FIXME("(%p) Wrong thread, reporting GPU idle.\n", This);
+            FIXME("(%p) Wrong thread, reporting GPU idle.\n", query);
             *data = TRUE;
             break;
 
@@ -404,36 +432,24 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery *iface,
     return S_OK;
 }
 
-static DWORD  WINAPI IWineD3DEventQueryImpl_GetDataSize(IWineD3DQuery* iface){
-    TRACE("(%p) : type D3DQUERY_EVENT\n", iface);
-
-    return sizeof(BOOL);
-}
-
-static DWORD  WINAPI IWineD3DOcclusionQueryImpl_GetDataSize(IWineD3DQuery* iface){
-    TRACE("(%p) : type D3DQUERY_OCCLUSION\n", iface);
-
-    return sizeof(DWORD);
-}
-
 static WINED3DQUERYTYPE  WINAPI IWineD3DQueryImpl_GetType(IWineD3DQuery* iface){
     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
     return This->type;
 }
 
-static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD flags)
+static HRESULT wined3d_event_query_ops_issue(struct IWineD3DQueryImpl *query, DWORD flags)
 {
-    IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
+    TRACE("query %p, flags %#x.\n", query, flags);
 
-    TRACE("(%p) : flags %#x, type D3DQUERY_EVENT\n", This, flags);
+    TRACE("(%p) : flags %#x, type D3DQUERY_EVENT\n", query, flags);
     if (flags & WINED3DISSUE_END)
     {
-        struct wined3d_event_query *query = This->extendedData;
+        struct wined3d_event_query *event_query = query->extendedData;
 
         /* Faked event query support */
-        if (!query) return WINED3D_OK;
+        if (!event_query) return WINED3D_OK;
 
-        wined3d_event_query_issue(query, This->device);
+        wined3d_event_query_issue(event_query, query->device);
     }
     else if (flags & WINED3DISSUE_BEGIN)
     {
@@ -442,40 +458,41 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD f
     }
 
     if (flags & WINED3DISSUE_BEGIN)
-        This->state = QUERY_BUILDING;
+        query->state = QUERY_BUILDING;
     else
-        This->state = QUERY_SIGNALLED;
+        query->state = QUERY_SIGNALLED;
 
     return WINED3D_OK;
 }
 
-static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery *iface, DWORD flags)
+static HRESULT wined3d_occlusion_query_ops_issue(struct IWineD3DQueryImpl *query, DWORD flags)
 {
-    IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
-    IWineD3DDeviceImpl *device = This->device;
+    IWineD3DDeviceImpl *device = query->device;
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
 
+    TRACE("query %p, flags %#x.\n", query, flags);
+
     if (gl_info->supported[ARB_OCCLUSION_QUERY])
     {
-        struct wined3d_occlusion_query *query = This->extendedData;
+        struct wined3d_occlusion_query *oq = query->extendedData;
         struct wined3d_context *context;
 
         /* This is allowed according to msdn and our tests. Reset the query and restart */
         if (flags & WINED3DISSUE_BEGIN)
         {
-            if (This->state == QUERY_BUILDING)
+            if (query->state == QUERY_BUILDING)
             {
-                if (query->context->tid != GetCurrentThreadId())
+                if (oq->context->tid != GetCurrentThreadId())
                 {
                     FIXME("Wrong thread, can't restart query.\n");
 
-                    context_free_occlusion_query(query);
-                    context = context_acquire(This->device, NULL);
-                    context_alloc_occlusion_query(context, query);
+                    context_free_occlusion_query(oq);
+                    context = context_acquire(query->device, NULL);
+                    context_alloc_occlusion_query(context, oq);
                 }
                 else
                 {
-                    context = context_acquire(This->device, query->context->current_rt);
+                    context = context_acquire(query->device, oq->context->current_rt);
 
                     ENTER_GL();
                     GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
@@ -485,13 +502,13 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery *iface, DWO
             }
             else
             {
-                if (query->context) context_free_occlusion_query(query);
-                context = context_acquire(This->device, NULL);
-                context_alloc_occlusion_query(context, query);
+                if (oq->context) context_free_occlusion_query(oq);
+                context = context_acquire(query->device, NULL);
+                context_alloc_occlusion_query(context, oq);
             }
 
             ENTER_GL();
-            GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, query->id));
+            GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, oq->id));
             checkGLcall("glBeginQuery()");
             LEAVE_GL();
 
@@ -503,15 +520,15 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery *iface, DWO
              * our tests show that it returns OK. But OpenGL doesn't like it, so avoid
              * generating an error
              */
-            if (This->state == QUERY_BUILDING)
+            if (query->state == QUERY_BUILDING)
             {
-                if (query->context->tid != GetCurrentThreadId())
+                if (oq->context->tid != GetCurrentThreadId())
                 {
                     FIXME("Wrong thread, can't end query.\n");
                 }
                 else
                 {
-                    context = context_acquire(This->device, query->context->current_rt);
+                    context = context_acquire(query->device, oq->context->current_rt);
 
                     ENTER_GL();
                     GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
@@ -522,42 +539,43 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery *iface, DWO
                 }
             }
         }
-    } else {
-        FIXME("(%p) : Occlusion queries not supported\n", This);
+    }
+    else
+    {
+        FIXME("%p Occlusion queries not supported.\n", query);
     }
 
     if (flags & WINED3DISSUE_BEGIN)
-        This->state = QUERY_BUILDING;
+        query->state = QUERY_BUILDING;
     else
-        This->state = QUERY_SIGNALLED;
+        query->state = QUERY_SIGNALLED;
 
     return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL.    */
 }
 
-static const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl =
+static const struct wined3d_query_ops event_query_ops =
 {
-    /*** IUnknown methods ***/
-    IWineD3DQueryImpl_QueryInterface,
-    IWineD3DQueryImpl_AddRef,
-    IWineD3DQueryImpl_Release,
-    /*** IWineD3Dquery methods ***/
-    IWineD3DEventQueryImpl_GetData,
-    IWineD3DEventQueryImpl_GetDataSize,
-    IWineD3DQueryImpl_GetType,
-    IWineD3DEventQueryImpl_Issue
+    wined3d_event_query_ops_get_data,
+    wined3d_event_query_ops_issue,
+};
+
+static const struct wined3d_query_ops occlusion_query_ops =
+{
+    wined3d_occlusion_query_ops_get_data,
+    wined3d_occlusion_query_ops_issue,
 };
 
-static const IWineD3DQueryVtbl IWineD3DOcclusionQuery_Vtbl =
+static const struct IWineD3DQueryVtbl IWineD3DQuery_Vtbl =
 {
     /*** IUnknown methods ***/
     IWineD3DQueryImpl_QueryInterface,
     IWineD3DQueryImpl_AddRef,
     IWineD3DQueryImpl_Release,
     /*** IWineD3Dquery methods ***/
-    IWineD3DOcclusionQueryImpl_GetData,
-    IWineD3DOcclusionQueryImpl_GetDataSize,
+    IWineD3DQueryImpl_GetData,
+    IWineD3DQueryImpl_GetDataSize,
     IWineD3DQueryImpl_GetType,
-    IWineD3DOcclusionQueryImpl_Issue
+    IWineD3DQueryImpl_Issue,
 };
 
 HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, WINED3DQUERYTYPE type)
@@ -573,7 +591,8 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, WINED3D
                 WARN("Unsupported in local OpenGL implementation: ARB_OCCLUSION_QUERY.\n");
                 return WINED3DERR_NOTAVAILABLE;
             }
-            query->lpVtbl = &IWineD3DOcclusionQuery_Vtbl;
+            query->query_ops = &occlusion_query_ops;
+            query->data_size = sizeof(DWORD);
             query->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_occlusion_query));
             if (!query->extendedData)
             {
@@ -593,7 +612,8 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, WINED3D
                  * lowering performance. */
                 FIXME("Event query: Unimplemented, but pretending to be supported.\n");
             }
-            query->lpVtbl = &IWineD3DEventQuery_Vtbl;
+            query->query_ops = &event_query_ops;
+            query->data_size = sizeof(BOOL);
             query->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct wined3d_event_query));
             if (!query->extendedData)
             {
@@ -619,6 +639,7 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, WINED3D
             return WINED3DERR_NOTAVAILABLE;
     }
 
+    query->lpVtbl = &IWineD3DQuery_Vtbl;
     query->type = type;
     query->state = QUERY_CREATED;
     query->device = device;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 34fdc3f..33d830d 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2467,6 +2467,15 @@ enum query_state {
     QUERY_SIGNALLED,
     QUERY_BUILDING
 };
+
+struct IWineD3DQueryImpl;
+
+struct wined3d_query_ops
+{
+    HRESULT (*query_get_data)(struct IWineD3DQueryImpl *query, void *data, DWORD data_size, DWORD flags);
+    HRESULT (*query_issue)(struct IWineD3DQueryImpl *query, DWORD flags);
+};
+
 /*****************************************************************************
  * IWineD3DQueryImpl implementation structure (extends IUnknown)
  */
@@ -2475,12 +2484,13 @@ typedef struct IWineD3DQueryImpl
     const IWineD3DQueryVtbl  *lpVtbl;
     LONG                      ref;     /* Note: Ref counting not required */
 
+    const struct wined3d_query_ops *query_ops;
     IWineD3DDeviceImpl *device;
 
     /* IWineD3DQuery fields */
     enum query_state         state;
     WINED3DQUERYTYPE         type;
-    /* TODO: Think about using a IUnknown instead of a void* */
+    DWORD data_size;
     void                     *extendedData;
 } IWineD3DQueryImpl;
 
-- 
1.7.3.4




More information about the wine-patches mailing list