1b8e80941Smrg/* 2b8e80941Smrg * Copyright 2011 Joakim Sindholt <opensource@zhasha.com> 3b8e80941Smrg * 4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 6b8e80941Smrg * to deal in the Software without restriction, including without limitation 7b8e80941Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 8b8e80941Smrg * license, and/or sell copies of the Software, and to permit persons to whom 9b8e80941Smrg * the Software is furnished to do so, subject to the following conditions: 10b8e80941Smrg * 11b8e80941Smrg * The above copyright notice and this permission notice (including the next 12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the 13b8e80941Smrg * Software. 14b8e80941Smrg * 15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18b8e80941Smrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19b8e80941Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20b8e80941Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21b8e80941Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22b8e80941Smrg 23b8e80941Smrg#ifndef _NINE_IUNKNOWN_H_ 24b8e80941Smrg#define _NINE_IUNKNOWN_H_ 25b8e80941Smrg 26b8e80941Smrg#include "pipe/p_compiler.h" 27b8e80941Smrg 28b8e80941Smrg#include "util/u_atomic.h" 29b8e80941Smrg#include "util/u_memory.h" 30b8e80941Smrg 31b8e80941Smrg#include "guid.h" 32b8e80941Smrg#include "nine_flags.h" 33b8e80941Smrg#include "nine_debug.h" 34b8e80941Smrg#include "nine_quirk.h" 35b8e80941Smrg 36b8e80941Smrg#include "d3d9.h" 37b8e80941Smrg 38b8e80941Smrgstruct Nine9; 39b8e80941Smrgstruct NineDevice9; 40b8e80941Smrg 41b8e80941Smrgstruct NineUnknown 42b8e80941Smrg{ 43b8e80941Smrg /* pointer to vtable (can be overriden outside gallium nine) */ 44b8e80941Smrg void *vtable; 45b8e80941Smrg /* pointer to internal vtable */ 46b8e80941Smrg void *vtable_internal; 47b8e80941Smrg 48b8e80941Smrg int32_t refs; /* external reference count */ 49b8e80941Smrg int32_t bind; /* internal bind count */ 50b8e80941Smrg boolean forward; /* whether to forward references to the container */ 51b8e80941Smrg 52b8e80941Smrg /* container: for surfaces and volumes only. 53b8e80941Smrg * Can be a texture, a volume texture or a swapchain. 54b8e80941Smrg * forward is set to false for the swapchain case. 55b8e80941Smrg * If forward is set, refs are passed to the container if forward is set 56b8e80941Smrg * and the container has bind increased if the object has non null bind. */ 57b8e80941Smrg struct NineUnknown *container; 58b8e80941Smrg struct NineDevice9 *device; /* referenced if (refs) */ 59b8e80941Smrg 60b8e80941Smrg const GUID **guids; /* for QueryInterface */ 61b8e80941Smrg 62b8e80941Smrg /* for [GS]etPrivateData/FreePrivateData */ 63b8e80941Smrg struct util_hash_table *pdata; 64b8e80941Smrg 65b8e80941Smrg void (*dtor)(void *data); /* top-level dtor */ 66b8e80941Smrg}; 67b8e80941Smrgstatic inline struct NineUnknown * 68b8e80941SmrgNineUnknown( void *data ) 69b8e80941Smrg{ 70b8e80941Smrg return (struct NineUnknown *)data; 71b8e80941Smrg} 72b8e80941Smrg 73b8e80941Smrg/* Use this instead of a shitload of arguments: */ 74b8e80941Smrgstruct NineUnknownParams 75b8e80941Smrg{ 76b8e80941Smrg void *vtable; 77b8e80941Smrg const GUID **guids; 78b8e80941Smrg void (*dtor)(void *data); 79b8e80941Smrg struct NineUnknown *container; 80b8e80941Smrg struct NineDevice9 *device; 81b8e80941Smrg bool start_with_bind_not_ref; 82b8e80941Smrg}; 83b8e80941Smrg 84b8e80941SmrgHRESULT 85b8e80941SmrgNineUnknown_ctor( struct NineUnknown *This, 86b8e80941Smrg struct NineUnknownParams *pParams ); 87b8e80941Smrg 88b8e80941Smrgvoid 89b8e80941SmrgNineUnknown_dtor( struct NineUnknown *This ); 90b8e80941Smrg 91b8e80941Smrg/*** Direct3D public methods ***/ 92b8e80941Smrg 93b8e80941SmrgHRESULT NINE_WINAPI 94b8e80941SmrgNineUnknown_QueryInterface( struct NineUnknown *This, 95b8e80941Smrg REFIID riid, 96b8e80941Smrg void **ppvObject ); 97b8e80941Smrg 98b8e80941SmrgULONG NINE_WINAPI 99b8e80941SmrgNineUnknown_AddRef( struct NineUnknown *This ); 100b8e80941Smrg 101b8e80941SmrgULONG NINE_WINAPI 102b8e80941SmrgNineUnknown_Release( struct NineUnknown *This ); 103b8e80941Smrg 104b8e80941SmrgULONG NINE_WINAPI 105b8e80941SmrgNineUnknown_ReleaseWithDtorLock( struct NineUnknown *This ); 106b8e80941Smrg 107b8e80941SmrgHRESULT NINE_WINAPI 108b8e80941SmrgNineUnknown_GetDevice( struct NineUnknown *This, 109b8e80941Smrg IDirect3DDevice9 **ppDevice ); 110b8e80941Smrg 111b8e80941SmrgHRESULT NINE_WINAPI 112b8e80941SmrgNineUnknown_SetPrivateData( struct NineUnknown *This, 113b8e80941Smrg REFGUID refguid, 114b8e80941Smrg const void *pData, 115b8e80941Smrg DWORD SizeOfData, 116b8e80941Smrg DWORD Flags ); 117b8e80941Smrg 118b8e80941SmrgHRESULT NINE_WINAPI 119b8e80941SmrgNineUnknown_GetPrivateData( struct NineUnknown *This, 120b8e80941Smrg REFGUID refguid, 121b8e80941Smrg void *pData, 122b8e80941Smrg DWORD *pSizeOfData ); 123b8e80941Smrg 124b8e80941SmrgHRESULT NINE_WINAPI 125b8e80941SmrgNineUnknown_FreePrivateData( struct NineUnknown *This, 126b8e80941Smrg REFGUID refguid ); 127b8e80941Smrg 128b8e80941Smrg/*** Nine private methods ***/ 129b8e80941Smrg 130b8e80941Smrgstatic inline void 131b8e80941SmrgNineUnknown_Destroy( struct NineUnknown *This ) 132b8e80941Smrg{ 133b8e80941Smrg assert(!(This->refs | This->bind)); 134b8e80941Smrg This->dtor(This); 135b8e80941Smrg} 136b8e80941Smrg 137b8e80941Smrgstatic inline UINT 138b8e80941SmrgNineUnknown_Bind( struct NineUnknown *This ) 139b8e80941Smrg{ 140b8e80941Smrg UINT b = p_atomic_inc_return(&This->bind); 141b8e80941Smrg assert(b); 142b8e80941Smrg 143b8e80941Smrg if (b == 1 && This->forward) 144b8e80941Smrg NineUnknown_Bind(This->container); 145b8e80941Smrg 146b8e80941Smrg return b; 147b8e80941Smrg} 148b8e80941Smrg 149b8e80941Smrgstatic inline UINT 150b8e80941SmrgNineUnknown_Unbind( struct NineUnknown *This ) 151b8e80941Smrg{ 152b8e80941Smrg UINT b = p_atomic_dec_return(&This->bind); 153b8e80941Smrg 154b8e80941Smrg if (b == 0 && This->forward) 155b8e80941Smrg NineUnknown_Unbind(This->container); 156b8e80941Smrg else if (b == 0 && This->refs == 0 && !This->container) 157b8e80941Smrg This->dtor(This); 158b8e80941Smrg 159b8e80941Smrg return b; 160b8e80941Smrg} 161b8e80941Smrg 162b8e80941Smrgstatic inline void 163b8e80941SmrgNineUnknown_ConvertRefToBind( struct NineUnknown *This ) 164b8e80941Smrg{ 165b8e80941Smrg NineUnknown_Bind(This); 166b8e80941Smrg NineUnknown_Release(This); 167b8e80941Smrg} 168b8e80941Smrg 169b8e80941Smrg/* Detach from container. */ 170b8e80941Smrgstatic inline void 171b8e80941SmrgNineUnknown_Detach( struct NineUnknown *This ) 172b8e80941Smrg{ 173b8e80941Smrg assert(This->container && !This->forward); 174b8e80941Smrg 175b8e80941Smrg This->container = NULL; 176b8e80941Smrg if (!(This->refs | This->bind)) 177b8e80941Smrg This->dtor(This); 178b8e80941Smrg} 179b8e80941Smrg 180b8e80941Smrg#endif /* _NINE_IUNKNOWN_H_ */ 181