dxgi: Allow dxgi_surface to be aggregated.

Henri Verbeet hverbeet at codeweavers.com
Mon Jan 19 03:39:06 CST 2009


---
 dlls/dxgi/device.c       |    2 +
 dlls/dxgi/dxgi_private.h |    3 ++
 dlls/dxgi/surface.c      |   54 +++++++++++++++++++++++++++++++++++++++------
 3 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c
index 28bc9be..235e1f7 100644
--- a/dlls/dxgi/device.c
+++ b/dlls/dxgi/device.c
@@ -164,7 +164,9 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_CreateSurface(IWineDXGIDevice *ifac
         }
 
         object->vtbl = &dxgi_surface_vtbl;
+        object->inner_unknown_vtbl = &dxgi_surface_inner_unknown_vtbl;
         object->refcount = 1;
+        object->outer_unknown = (IUnknown *)&object->inner_unknown_vtbl;
         surface[i] = (IDXGISurface *)object;
 
         TRACE("Created IDXGISurface %p (%u/%u)\n", object, i + 1, surface_count);
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index d19b9b1..4e6901c 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -81,9 +81,12 @@ struct dxgi_swapchain
 
 /* IDXGISurface */
 extern const struct IDXGISurfaceVtbl dxgi_surface_vtbl;
+extern const struct IUnknownVtbl dxgi_surface_inner_unknown_vtbl;
 struct dxgi_surface
 {
     const struct IDXGISurfaceVtbl *vtbl;
+    const struct IUnknownVtbl *inner_unknown_vtbl;
+    IUnknown *outer_unknown;
     LONG refcount;
 };
 
diff --git a/dlls/dxgi/surface.c b/dlls/dxgi/surface.c
index 82db08b..bdbeaf3 100644
--- a/dlls/dxgi/surface.c
+++ b/dlls/dxgi/surface.c
@@ -24,10 +24,17 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(dxgi);
 
-/* IUnknown methods */
+/* Inner IUnknown methods */
 
-static HRESULT STDMETHODCALLTYPE dxgi_surface_QueryInterface(IDXGISurface *iface, REFIID riid, void **object)
+static inline struct dxgi_surface *dxgi_surface_from_inner_unknown(IUnknown *iface)
+{
+    return (struct dxgi_surface *)((char*)iface - FIELD_OFFSET(struct dxgi_surface, inner_unknown_vtbl));
+}
+
+static HRESULT STDMETHODCALLTYPE dxgi_surface_inner_QueryInterface(IUnknown *iface, REFIID riid, void **object)
 {
+    struct dxgi_surface *This = dxgi_surface_from_inner_unknown(iface);
+
     TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
 
     if (IsEqualGUID(riid, &IID_IDXGISurface)
@@ -35,8 +42,8 @@ static HRESULT STDMETHODCALLTYPE dxgi_surface_QueryInterface(IDXGISurface *iface
             || IsEqualGUID(riid, &IID_IDXGIObject)
             || IsEqualGUID(riid, &IID_IUnknown))
     {
-        IUnknown_AddRef(iface);
-        *object = iface;
+        IUnknown_AddRef((IUnknown *)This);
+        *object = This;
         return S_OK;
     }
 
@@ -46,9 +53,9 @@ static HRESULT STDMETHODCALLTYPE dxgi_surface_QueryInterface(IDXGISurface *iface
     return E_NOINTERFACE;
 }
 
-static ULONG STDMETHODCALLTYPE dxgi_surface_AddRef(IDXGISurface *iface)
+static ULONG STDMETHODCALLTYPE dxgi_surface_inner_AddRef(IUnknown *iface)
 {
-    struct dxgi_surface *This = (struct dxgi_surface *)iface;
+    struct dxgi_surface *This = dxgi_surface_from_inner_unknown(iface);
     ULONG refcount = InterlockedIncrement(&This->refcount);
 
     TRACE("%p increasing refcount to %u\n", This, refcount);
@@ -56,9 +63,9 @@ static ULONG STDMETHODCALLTYPE dxgi_surface_AddRef(IDXGISurface *iface)
     return refcount;
 }
 
-static ULONG STDMETHODCALLTYPE dxgi_surface_Release(IDXGISurface *iface)
+static ULONG STDMETHODCALLTYPE dxgi_surface_inner_Release(IUnknown *iface)
 {
-    struct dxgi_surface *This = (struct dxgi_surface *)iface;
+    struct dxgi_surface *This = dxgi_surface_from_inner_unknown(iface);
     ULONG refcount = InterlockedDecrement(&This->refcount);
 
     TRACE("%p decreasing refcount to %u\n", This, refcount);
@@ -71,6 +78,29 @@ static ULONG STDMETHODCALLTYPE dxgi_surface_Release(IDXGISurface *iface)
     return refcount;
 }
 
+/* IUnknown methods */
+
+static HRESULT STDMETHODCALLTYPE dxgi_surface_QueryInterface(IDXGISurface *iface, REFIID riid, void **object)
+{
+    struct dxgi_surface *This = (struct dxgi_surface *)iface;
+    TRACE("Forwarding to outer IUnknown\n");
+    return IUnknown_QueryInterface(This->outer_unknown, riid, object);
+}
+
+static ULONG STDMETHODCALLTYPE dxgi_surface_AddRef(IDXGISurface *iface)
+{
+    struct dxgi_surface *This = (struct dxgi_surface *)iface;
+    TRACE("Forwarding to outer IUnknown\n");
+    return IUnknown_AddRef(This->outer_unknown);
+}
+
+static ULONG STDMETHODCALLTYPE dxgi_surface_Release(IDXGISurface *iface)
+{
+    struct dxgi_surface *This = (struct dxgi_surface *)iface;
+    TRACE("Forwarding to outer IUnknown\n");
+    return IUnknown_Release(This->outer_unknown);
+}
+
 /* IDXGIObject methods */
 
 static HRESULT STDMETHODCALLTYPE dxgi_surface_SetPrivateData(IDXGISurface *iface,
@@ -153,3 +183,11 @@ const struct IDXGISurfaceVtbl dxgi_surface_vtbl =
     dxgi_surface_Map,
     dxgi_surface_Unmap,
 };
+
+const struct IUnknownVtbl dxgi_surface_inner_unknown_vtbl =
+{
+    /* IUnknown methods */
+    dxgi_surface_inner_QueryInterface,
+    dxgi_surface_inner_AddRef,
+    dxgi_surface_inner_Release,
+};
-- 
1.6.0.6



--------------040303040500020500040106--



More information about the wine-patches mailing list