Module: wine Branch: master Commit: 23094bfad83ac6109b681d7a9faad387d4a9e7c0 URL: http://source.winehq.org/git/wine.git/?a=commit;h=23094bfad83ac6109b681d7a9f...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Mon Jan 19 10:39:06 2009 +0100
dxgi: Allow dxgi_surface to be aggregated.
---
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, +};