dxgi: Allow dxgi_surface to be aggregated.

This commit is contained in:
Henri Verbeet 2009-01-19 10:39:06 +01:00 committed by Alexandre Julliard
parent bb0e940e16
commit 23094bfad8
3 changed files with 51 additions and 8 deletions

View File

@ -164,7 +164,9 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_CreateSurface(IWineDXGIDevice *ifac
} }
object->vtbl = &dxgi_surface_vtbl; object->vtbl = &dxgi_surface_vtbl;
object->inner_unknown_vtbl = &dxgi_surface_inner_unknown_vtbl;
object->refcount = 1; object->refcount = 1;
object->outer_unknown = (IUnknown *)&object->inner_unknown_vtbl;
surface[i] = (IDXGISurface *)object; surface[i] = (IDXGISurface *)object;
TRACE("Created IDXGISurface %p (%u/%u)\n", object, i + 1, surface_count); TRACE("Created IDXGISurface %p (%u/%u)\n", object, i + 1, surface_count);

View File

@ -81,9 +81,12 @@ struct dxgi_swapchain
/* IDXGISurface */ /* IDXGISurface */
extern const struct IDXGISurfaceVtbl dxgi_surface_vtbl; extern const struct IDXGISurfaceVtbl dxgi_surface_vtbl;
extern const struct IUnknownVtbl dxgi_surface_inner_unknown_vtbl;
struct dxgi_surface struct dxgi_surface
{ {
const struct IDXGISurfaceVtbl *vtbl; const struct IDXGISurfaceVtbl *vtbl;
const struct IUnknownVtbl *inner_unknown_vtbl;
IUnknown *outer_unknown;
LONG refcount; LONG refcount;
}; };

View File

@ -24,10 +24,17 @@
WINE_DEFAULT_DEBUG_CHANNEL(dxgi); 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); TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
if (IsEqualGUID(riid, &IID_IDXGISurface) if (IsEqualGUID(riid, &IID_IDXGISurface)
@ -35,8 +42,8 @@ static HRESULT STDMETHODCALLTYPE dxgi_surface_QueryInterface(IDXGISurface *iface
|| IsEqualGUID(riid, &IID_IDXGIObject) || IsEqualGUID(riid, &IID_IDXGIObject)
|| IsEqualGUID(riid, &IID_IUnknown)) || IsEqualGUID(riid, &IID_IUnknown))
{ {
IUnknown_AddRef(iface); IUnknown_AddRef((IUnknown *)This);
*object = iface; *object = This;
return S_OK; return S_OK;
} }
@ -46,9 +53,9 @@ static HRESULT STDMETHODCALLTYPE dxgi_surface_QueryInterface(IDXGISurface *iface
return E_NOINTERFACE; 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); ULONG refcount = InterlockedIncrement(&This->refcount);
TRACE("%p increasing refcount to %u\n", 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; 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); ULONG refcount = InterlockedDecrement(&This->refcount);
TRACE("%p decreasing refcount to %u\n", 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; 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 */ /* IDXGIObject methods */
static HRESULT STDMETHODCALLTYPE dxgi_surface_SetPrivateData(IDXGISurface *iface, static HRESULT STDMETHODCALLTYPE dxgi_surface_SetPrivateData(IDXGISurface *iface,
@ -153,3 +183,11 @@ const struct IDXGISurfaceVtbl dxgi_surface_vtbl =
dxgi_surface_Map, dxgi_surface_Map,
dxgi_surface_Unmap, 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,
};