jscript: Added Object.toString for host objects implementation.
[wine] / dlls / d3d9 / vertexbuffer.c
1 /*
2  * IDirect3DVertexBuffer9 implementation
3  *
4  * Copyright 2002-2004 Jason Edmeades
5  * Copyright 2002-2004 Raphael Junqueira
6  * Copyright 2005 Oliver Stieber
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22
23 #include "config.h"
24 #include "d3d9_private.h"
25
26 WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
27
28 /* IDirect3DVertexBuffer9 IUnknown parts follow: */
29 static HRESULT WINAPI IDirect3DVertexBuffer9Impl_QueryInterface(LPDIRECT3DVERTEXBUFFER9 iface, REFIID riid, LPVOID* ppobj) {
30     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
31
32     if (IsEqualGUID(riid, &IID_IUnknown)
33         || IsEqualGUID(riid, &IID_IDirect3DResource9)
34         || IsEqualGUID(riid, &IID_IDirect3DVertexBuffer9)) {
35         IDirect3DVertexBuffer9_AddRef(iface);
36         *ppobj = This;
37         return S_OK;
38     }
39
40     WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
41     *ppobj = NULL;
42     return E_NOINTERFACE;
43 }
44
45 static ULONG WINAPI IDirect3DVertexBuffer9Impl_AddRef(LPDIRECT3DVERTEXBUFFER9 iface) {
46     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
47     ULONG ref = InterlockedIncrement(&This->ref);
48
49     TRACE("(%p) : AddRef from %d\n", This, ref - 1);
50
51     if (ref == 1)
52     {
53         IDirect3DDevice9Ex_AddRef(This->parentDevice);
54         wined3d_mutex_lock();
55         IWineD3DBuffer_AddRef(This->wineD3DVertexBuffer);
56         wined3d_mutex_unlock();
57     }
58
59     return ref;
60 }
61
62 static ULONG WINAPI IDirect3DVertexBuffer9Impl_Release(LPDIRECT3DVERTEXBUFFER9 iface) {
63     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
64     ULONG ref = InterlockedDecrement(&This->ref);
65
66     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
67
68     if (ref == 0) {
69         IDirect3DDevice9Ex_Release(This->parentDevice);
70         wined3d_mutex_lock();
71         IWineD3DBuffer_Release(This->wineD3DVertexBuffer);
72         wined3d_mutex_unlock();
73     }
74     return ref;
75 }
76
77 /* IDirect3DVertexBuffer9 IDirect3DResource9 Interface follow: */
78 static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetDevice(LPDIRECT3DVERTEXBUFFER9 iface, IDirect3DDevice9** ppDevice) {
79     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
80     IWineD3DDevice *wined3d_device;
81     HRESULT hr;
82     TRACE("(%p) Relay\n", This);
83
84     wined3d_mutex_lock();
85     hr = IWineD3DBuffer_GetDevice(This->wineD3DVertexBuffer, &wined3d_device);
86     if (SUCCEEDED(hr))
87     {
88         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
89         IWineD3DDevice_Release(wined3d_device);
90     }
91     wined3d_mutex_unlock();
92
93     return hr;
94 }
95
96 static HRESULT WINAPI IDirect3DVertexBuffer9Impl_SetPrivateData(LPDIRECT3DVERTEXBUFFER9 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
97     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
98     HRESULT hr;
99
100     TRACE("(%p) Relay\n", This);
101
102     wined3d_mutex_lock();
103     hr = IWineD3DBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
104     wined3d_mutex_unlock();
105
106     return hr;
107 }
108
109 static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetPrivateData(LPDIRECT3DVERTEXBUFFER9 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
110     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
111     HRESULT hr;
112     TRACE("(%p) Relay\n", This);
113
114     wined3d_mutex_lock();
115     hr = IWineD3DBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
116     wined3d_mutex_unlock();
117
118     return hr;
119 }
120
121 static HRESULT WINAPI IDirect3DVertexBuffer9Impl_FreePrivateData(LPDIRECT3DVERTEXBUFFER9 iface, REFGUID refguid) {
122     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
123     HRESULT hr;
124     TRACE("(%p) Relay\n", This);
125
126     wined3d_mutex_lock();
127     hr = IWineD3DBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
128     wined3d_mutex_unlock();
129
130     return hr;
131 }
132
133 static DWORD WINAPI IDirect3DVertexBuffer9Impl_SetPriority(LPDIRECT3DVERTEXBUFFER9 iface, DWORD PriorityNew) {
134     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
135     HRESULT hr;
136     TRACE("(%p) Relay\n", This);
137
138     wined3d_mutex_lock();
139     hr = IWineD3DBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
140     wined3d_mutex_unlock();
141
142     return hr;
143 }
144
145 static DWORD WINAPI IDirect3DVertexBuffer9Impl_GetPriority(LPDIRECT3DVERTEXBUFFER9 iface) {
146     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
147     HRESULT hr;
148     TRACE("(%p) Relay\n", This);
149
150     wined3d_mutex_lock();
151     hr = IWineD3DBuffer_GetPriority(This->wineD3DVertexBuffer);
152     wined3d_mutex_unlock();
153
154     return hr;
155 }
156
157 static void WINAPI IDirect3DVertexBuffer9Impl_PreLoad(LPDIRECT3DVERTEXBUFFER9 iface) {
158     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
159     TRACE("(%p) Relay\n", This);
160
161     wined3d_mutex_lock();
162     IWineD3DBuffer_PreLoad(This->wineD3DVertexBuffer);
163     wined3d_mutex_unlock();
164 }
165
166 static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer9Impl_GetType(LPDIRECT3DVERTEXBUFFER9 iface) {
167     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
168     TRACE("(%p)\n", This);
169
170     return D3DRTYPE_VERTEXBUFFER;
171 }
172
173 /* IDirect3DVertexBuffer9 Interface follow: */
174 static HRESULT WINAPI IDirect3DVertexBuffer9Impl_Lock(LPDIRECT3DVERTEXBUFFER9 iface, UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags) {
175     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
176     HRESULT hr;
177     TRACE("(%p) Relay\n", This);
178
179     wined3d_mutex_lock();
180     hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags);
181     wined3d_mutex_unlock();
182
183     return hr;
184 }
185
186 static HRESULT WINAPI IDirect3DVertexBuffer9Impl_Unlock(LPDIRECT3DVERTEXBUFFER9 iface) {
187     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
188     HRESULT hr;
189     TRACE("(%p) Relay\n", This);
190
191     wined3d_mutex_lock();
192     hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer);
193     wined3d_mutex_unlock();
194
195     return hr;
196 }
197
198 static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetDesc(LPDIRECT3DVERTEXBUFFER9 iface, D3DVERTEXBUFFER_DESC* pDesc) {
199     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
200     HRESULT hr;
201     WINED3DBUFFER_DESC desc;
202     TRACE("(%p) Relay\n", This);
203
204     wined3d_mutex_lock();
205     hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &desc);
206     wined3d_mutex_unlock();
207
208     if (SUCCEEDED(hr)) {
209         pDesc->Format = D3DFMT_VERTEXDATA;
210         pDesc->Usage = desc.Usage;
211         pDesc->Pool = desc.Pool;
212         pDesc->Size = desc.Size;
213         pDesc->Type = D3DRTYPE_VERTEXBUFFER;
214         pDesc->FVF = This->fvf;
215     }
216
217
218     return hr;
219 }
220
221 static const IDirect3DVertexBuffer9Vtbl Direct3DVertexBuffer9_Vtbl =
222 {
223     /* IUnknown */
224     IDirect3DVertexBuffer9Impl_QueryInterface,
225     IDirect3DVertexBuffer9Impl_AddRef,
226     IDirect3DVertexBuffer9Impl_Release,
227     /* IDirect3DResource9 */
228     IDirect3DVertexBuffer9Impl_GetDevice,
229     IDirect3DVertexBuffer9Impl_SetPrivateData,
230     IDirect3DVertexBuffer9Impl_GetPrivateData,
231     IDirect3DVertexBuffer9Impl_FreePrivateData,
232     IDirect3DVertexBuffer9Impl_SetPriority,
233     IDirect3DVertexBuffer9Impl_GetPriority,
234     IDirect3DVertexBuffer9Impl_PreLoad,
235     IDirect3DVertexBuffer9Impl_GetType,
236     /* IDirect3DVertexBuffer9 */
237     IDirect3DVertexBuffer9Impl_Lock,
238     IDirect3DVertexBuffer9Impl_Unlock,
239     IDirect3DVertexBuffer9Impl_GetDesc
240 };
241
242 static void STDMETHODCALLTYPE d3d9_vertexbuffer_wined3d_object_destroyed(void *parent)
243 {
244     HeapFree(GetProcessHeap(), 0, parent);
245 }
246
247 static const struct wined3d_parent_ops d3d9_vertexbuffer_wined3d_parent_ops =
248 {
249     d3d9_vertexbuffer_wined3d_object_destroyed,
250 };
251
252 HRESULT vertexbuffer_init(IDirect3DVertexBuffer9Impl *buffer, IDirect3DDevice9Impl *device,
253         UINT size, UINT usage, DWORD fvf, D3DPOOL pool)
254 {
255     HRESULT hr;
256
257     buffer->lpVtbl = &Direct3DVertexBuffer9_Vtbl;
258     buffer->ref = 1;
259     buffer->fvf = fvf;
260
261     wined3d_mutex_lock();
262     hr = IWineD3DDevice_CreateVertexBuffer(device->WineD3DDevice, size,
263             usage & WINED3DUSAGE_MASK, 0, (WINED3DPOOL)pool, &buffer->wineD3DVertexBuffer,
264             (IUnknown *)buffer, &d3d9_vertexbuffer_wined3d_parent_ops);
265     wined3d_mutex_unlock();
266     if (FAILED(hr))
267     {
268         WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
269         return hr;
270     }
271
272     buffer->parentDevice = (IDirect3DDevice9Ex *)device;
273     IDirect3DDevice9Ex_AddRef(buffer->parentDevice);
274
275     return D3D_OK;
276 }