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