VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/surface.c@ 23571

Last change on this file since 23571 was 23571, checked in by vboxsync, 15 years ago

crOpenGL: update to wine 1.1.30

  • Property svn:eol-style set to native
File size: 12.7 KB
Line 
1/*
2 * IDirect3DSurface9 implementation
3 *
4 * Copyright 2002-2005 Jason Edmeades
5 * Raphael Junqueira
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22/*
23 * Sun LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
24 * other than GPL or LGPL is available it will apply instead, Sun elects to use only
25 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
26 * a choice of LGPL license versions is made available with the language indicating
27 * that LGPLv2 or any later version may be used, or where a choice of which version
28 * of the LGPL is applied is otherwise unspecified.
29 */
30
31#include "config.h"
32#include "d3d9_private.h"
33
34WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
35
36/* IDirect3DSurface9 IUnknown parts follow: */
37static HRESULT WINAPI IDirect3DSurface9Impl_QueryInterface(LPDIRECT3DSURFACE9 iface, REFIID riid, LPVOID* ppobj) {
38 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
39
40 if (IsEqualGUID(riid, &IID_IUnknown)
41 || IsEqualGUID(riid, &IID_IDirect3DResource9)
42 || IsEqualGUID(riid, &IID_IDirect3DSurface9)) {
43 IDirect3DSurface9_AddRef(iface);
44 *ppobj = This;
45 return S_OK;
46 }
47
48 WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
49 *ppobj = NULL;
50 return E_NOINTERFACE;
51}
52
53static ULONG WINAPI IDirect3DSurface9Impl_AddRef(LPDIRECT3DSURFACE9 iface) {
54 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
55
56 TRACE("(%p)\n", This);
57
58 if (This->forwardReference) {
59 /* Forward refcounting */
60 TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference);
61 return IUnknown_AddRef(This->forwardReference);
62 } else {
63 /* No container, handle our own refcounting */
64 ULONG ref = InterlockedIncrement(&This->ref);
65 if (ref == 1)
66 {
67 if (This->parentDevice) IDirect3DDevice9Ex_AddRef(This->parentDevice);
68 wined3d_mutex_lock();
69 IWineD3DSurface_AddRef(This->wineD3DSurface);
70 wined3d_mutex_unlock();
71 }
72 TRACE("(%p) : AddRef from %d\n", This, ref - 1);
73
74 return ref;
75 }
76
77}
78
79static ULONG WINAPI IDirect3DSurface9Impl_Release(LPDIRECT3DSURFACE9 iface) {
80 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
81
82 TRACE("(%p)\n", This);
83
84 if (This->forwardReference) {
85 /* Forward to the containerParent */
86 TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference);
87 return IUnknown_Release(This->forwardReference);
88 } else {
89 /* No container, handle our own refcounting */
90 ULONG ref = InterlockedDecrement(&This->ref);
91 TRACE("(%p) : ReleaseRef to %d\n", This, ref);
92
93 if (ref == 0) {
94 if (This->parentDevice) IDirect3DDevice9Ex_Release(This->parentDevice);
95 wined3d_mutex_lock();
96 IWineD3DSurface_Release(This->wineD3DSurface);
97 wined3d_mutex_unlock();
98 }
99
100 return ref;
101 }
102}
103
104/* IDirect3DSurface9 IDirect3DResource9 Interface follow: */
105static HRESULT WINAPI IDirect3DSurface9Impl_GetDevice(LPDIRECT3DSURFACE9 iface, IDirect3DDevice9** ppDevice) {
106 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
107 IWineD3DDevice *wined3d_device;
108 HRESULT hr;
109 TRACE("(%p)->(%p)\n", This, ppDevice);
110
111 wined3d_mutex_lock();
112 hr = IWineD3DSurface_GetDevice(This->wineD3DSurface, &wined3d_device);
113 if (SUCCEEDED(hr))
114 {
115 IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
116 IWineD3DDevice_Release(wined3d_device);
117 }
118 wined3d_mutex_unlock();
119
120 return hr;
121}
122
123static HRESULT WINAPI IDirect3DSurface9Impl_SetPrivateData(LPDIRECT3DSURFACE9 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
124 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
125 HRESULT hr;
126 TRACE("(%p) Relay\n", This);
127
128 wined3d_mutex_lock();
129 hr = IWineD3DSurface_SetPrivateData(This->wineD3DSurface, refguid, pData, SizeOfData, Flags);
130 wined3d_mutex_unlock();
131
132 return hr;
133}
134
135static HRESULT WINAPI IDirect3DSurface9Impl_GetPrivateData(LPDIRECT3DSURFACE9 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
136 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
137 HRESULT hr;
138 TRACE("(%p) Relay\n", This);
139
140 wined3d_mutex_lock();
141 hr = IWineD3DSurface_GetPrivateData(This->wineD3DSurface, refguid, pData, pSizeOfData);
142 wined3d_mutex_unlock();
143
144 return hr;
145}
146
147static HRESULT WINAPI IDirect3DSurface9Impl_FreePrivateData(LPDIRECT3DSURFACE9 iface, REFGUID refguid) {
148 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
149 HRESULT hr;
150 TRACE("(%p) Relay\n", This);
151
152 wined3d_mutex_lock();
153 hr = IWineD3DSurface_FreePrivateData(This->wineD3DSurface, refguid);
154 wined3d_mutex_unlock();
155
156 return hr;
157}
158
159static DWORD WINAPI IDirect3DSurface9Impl_SetPriority(LPDIRECT3DSURFACE9 iface, DWORD PriorityNew) {
160 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
161 HRESULT hr;
162 TRACE("(%p) Relay\n", This);
163
164 wined3d_mutex_lock();
165 hr = IWineD3DSurface_SetPriority(This->wineD3DSurface, PriorityNew);
166 wined3d_mutex_unlock();
167
168 return hr;
169}
170
171static DWORD WINAPI IDirect3DSurface9Impl_GetPriority(LPDIRECT3DSURFACE9 iface) {
172 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
173 HRESULT hr;
174 TRACE("(%p) Relay\n", This);
175
176 wined3d_mutex_lock();
177 hr = IWineD3DSurface_GetPriority(This->wineD3DSurface);
178 wined3d_mutex_unlock();
179
180 return hr;
181}
182
183static void WINAPI IDirect3DSurface9Impl_PreLoad(LPDIRECT3DSURFACE9 iface) {
184 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
185 TRACE("(%p) Relay\n", This);
186
187 wined3d_mutex_lock();
188 IWineD3DSurface_PreLoad(This->wineD3DSurface);
189 wined3d_mutex_unlock();
190}
191
192static D3DRESOURCETYPE WINAPI IDirect3DSurface9Impl_GetType(LPDIRECT3DSURFACE9 iface) {
193 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
194 D3DRESOURCETYPE ret;
195 TRACE("(%p) Relay\n", This);
196
197 wined3d_mutex_lock();
198 ret = IWineD3DSurface_GetType(This->wineD3DSurface);
199 wined3d_mutex_unlock();
200
201 return ret;
202}
203
204/* IDirect3DSurface9 Interface follow: */
205static HRESULT WINAPI IDirect3DSurface9Impl_GetContainer(LPDIRECT3DSURFACE9 iface, REFIID riid, void** ppContainer) {
206 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
207 HRESULT res;
208
209 TRACE("(This %p, riid %s, ppContainer %p)\n", This, debugstr_guid(riid), ppContainer);
210
211 if (!This->container) return E_NOINTERFACE;
212
213 if (!ppContainer) {
214 ERR("Called without a valid ppContainer\n");
215 }
216
217 res = IUnknown_QueryInterface(This->container, riid, ppContainer);
218
219 TRACE("Returning ppContainer %p, *ppContainer %p\n", ppContainer, *ppContainer);
220
221 return res;
222}
223
224static HRESULT WINAPI IDirect3DSurface9Impl_GetDesc(LPDIRECT3DSURFACE9 iface, D3DSURFACE_DESC* pDesc) {
225 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
226 WINED3DSURFACE_DESC wined3ddesc;
227 HRESULT hr;
228 TRACE("(%p) Relay\n", This);
229
230 wined3d_mutex_lock();
231 hr = IWineD3DSurface_GetDesc(This->wineD3DSurface, &wined3ddesc);
232 wined3d_mutex_unlock();
233
234 if (SUCCEEDED(hr))
235 {
236 pDesc->Format = d3dformat_from_wined3dformat(wined3ddesc.format);
237 pDesc->Type = wined3ddesc.resource_type;
238 pDesc->Usage = wined3ddesc.usage;
239 pDesc->Pool = wined3ddesc.pool;
240 pDesc->MultiSampleType = wined3ddesc.multisample_type;
241 pDesc->MultiSampleQuality = wined3ddesc.multisample_quality;
242 pDesc->Width = wined3ddesc.width;
243 pDesc->Height = wined3ddesc.height;
244 }
245
246 return hr;
247}
248
249static HRESULT WINAPI IDirect3DSurface9Impl_LockRect(LPDIRECT3DSURFACE9 iface, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
250 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
251 HRESULT hr;
252 TRACE("(%p) Relay\n", This);
253
254 wined3d_mutex_lock();
255 TRACE("(%p) calling IWineD3DSurface_LockRect %p %p %p %d\n", This, This->wineD3DSurface, pLockedRect, pRect, Flags);
256 hr = IWineD3DSurface_LockRect(This->wineD3DSurface, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
257 wined3d_mutex_unlock();
258
259 return hr;
260}
261
262static HRESULT WINAPI IDirect3DSurface9Impl_UnlockRect(LPDIRECT3DSURFACE9 iface) {
263 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
264 HRESULT hr;
265 TRACE("(%p) Relay\n", This);
266
267 wined3d_mutex_lock();
268 hr = IWineD3DSurface_UnlockRect(This->wineD3DSurface);
269 wined3d_mutex_unlock();
270
271 switch(hr)
272 {
273 case WINEDDERR_NOTLOCKED: return D3DERR_INVALIDCALL;
274 default: return hr;
275 }
276}
277
278static HRESULT WINAPI IDirect3DSurface9Impl_GetDC(LPDIRECT3DSURFACE9 iface, HDC* phdc) {
279 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
280 HRESULT hr;
281 TRACE("(%p) Relay\n", This);
282
283 if(!This->getdc_supported)
284 {
285 WARN("Surface does not support GetDC, returning D3DERR_INVALIDCALL\n");
286 /* Don't touch the DC */
287 return D3DERR_INVALIDCALL;
288 }
289
290 wined3d_mutex_lock();
291 hr = IWineD3DSurface_GetDC(This->wineD3DSurface, phdc);
292 wined3d_mutex_unlock();
293
294 return hr;
295}
296
297static HRESULT WINAPI IDirect3DSurface9Impl_ReleaseDC(LPDIRECT3DSURFACE9 iface, HDC hdc) {
298 IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
299 HRESULT hr;
300 TRACE("(%p) Relay\n", This);
301
302 wined3d_mutex_lock();
303 hr = IWineD3DSurface_ReleaseDC(This->wineD3DSurface, hdc);
304 wined3d_mutex_unlock();
305
306 switch(hr) {
307 case WINEDDERR_NODC: return WINED3DERR_INVALIDCALL;
308 default: return hr;
309 }
310}
311
312static const IDirect3DSurface9Vtbl Direct3DSurface9_Vtbl =
313{
314 /* IUnknown */
315 IDirect3DSurface9Impl_QueryInterface,
316 IDirect3DSurface9Impl_AddRef,
317 IDirect3DSurface9Impl_Release,
318 /* IDirect3DResource9 */
319 IDirect3DSurface9Impl_GetDevice,
320 IDirect3DSurface9Impl_SetPrivateData,
321 IDirect3DSurface9Impl_GetPrivateData,
322 IDirect3DSurface9Impl_FreePrivateData,
323 IDirect3DSurface9Impl_SetPriority,
324 IDirect3DSurface9Impl_GetPriority,
325 IDirect3DSurface9Impl_PreLoad,
326 IDirect3DSurface9Impl_GetType,
327 /* IDirect3DSurface9 */
328 IDirect3DSurface9Impl_GetContainer,
329 IDirect3DSurface9Impl_GetDesc,
330 IDirect3DSurface9Impl_LockRect,
331 IDirect3DSurface9Impl_UnlockRect,
332 IDirect3DSurface9Impl_GetDC,
333 IDirect3DSurface9Impl_ReleaseDC
334};
335
336static void STDMETHODCALLTYPE surface_wined3d_object_destroyed(void *parent)
337{
338 HeapFree(GetProcessHeap(), 0, parent);
339}
340
341static const struct wined3d_parent_ops d3d9_surface_wined3d_parent_ops =
342{
343 surface_wined3d_object_destroyed,
344};
345
346HRESULT surface_init(IDirect3DSurface9Impl *surface, IDirect3DDevice9Impl *device,
347 UINT width, UINT height, D3DFORMAT format, BOOL lockable, BOOL discard, UINT level,
348 DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality)
349{
350 HRESULT hr;
351
352 surface->lpVtbl = &Direct3DSurface9_Vtbl;
353 surface->ref = 1;
354
355 switch (format)
356 {
357 case D3DFMT_A8R8G8B8:
358 case D3DFMT_X8R8G8B8:
359 case D3DFMT_R5G6B5:
360 case D3DFMT_X1R5G5B5:
361 case D3DFMT_A1R5G5B5:
362 case D3DFMT_R8G8B8:
363 surface->getdc_supported = TRUE;
364 break;
365
366 default:
367 surface->getdc_supported = FALSE;
368 break;
369 }
370
371 /* FIXME: Check MAX bounds of MultisampleQuality. */
372 if (multisample_quality > 0)
373 {
374 FIXME("Multisample quality set to %u, substituting 0.\n", multisample_quality);
375 multisample_quality = 0;
376 }
377
378 wined3d_mutex_lock();
379 hr = IWineD3DDevice_CreateSurface(device->WineD3DDevice, width, height, wined3dformat_from_d3dformat(format),
380 lockable, discard, level, &surface->wineD3DSurface, usage & WINED3DUSAGE_MASK, (WINED3DPOOL)pool,
381 multisample_type, multisample_quality, SURFACE_OPENGL, (IUnknown *)surface,
382 &d3d9_surface_wined3d_parent_ops);
383 wined3d_mutex_unlock();
384 if (FAILED(hr))
385 {
386 WARN("Failed to create wined3d surface, hr %#x.\n", hr);
387 return hr;
388 }
389
390 surface->parentDevice = (IDirect3DDevice9Ex *)device;
391 IDirect3DDevice9Ex_AddRef(surface->parentDevice);
392
393 return D3D_OK;
394}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette