xref: /reactos/dll/directx/d3d9/d3d9_swapchain.c (revision 3f976713)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS ReactX
4  * FILE:            dll/directx/d3d9/d3d9_swapchain.c
5  * PURPOSE:         Direct3D9's swap chain object
6  * PROGRAMERS:      Gregor Gullwi <gbrunmar (dot) ros (at) gmail (dot) com>
7  */
8 #include "d3d9_swapchain.h"
9 
10 #include <debug.h>
11 #include <ddraw.h>
12 
13 #include "d3d9_helpers.h"
14 #include "d3d9_device.h"
15 #include "d3d9_cursor.h"
16 
17 #define LOCK_D3DDEVICE9()   D3D9BaseObject_LockDevice(&This->BaseObject)
18 #define UNLOCK_D3DDEVICE9() D3D9BaseObject_UnlockDevice(&This->BaseObject)
19 
20 /* Convert a IDirect3DSwapChain9 pointer safely to the internal implementation struct */
21 LPDIRECT3DSWAPCHAIN9_INT IDirect3DSwapChain9ToImpl(LPDIRECT3DSWAPCHAIN9 iface)
22 {
23     if (NULL == iface)
24         return NULL;
25 
26     return (LPDIRECT3DSWAPCHAIN9_INT)((ULONG_PTR)iface - FIELD_OFFSET(Direct3DSwapChain9_INT, lpVtbl));
27 }
28 
29 /* IDirect3DSwapChain9: IUnknown implementation */
30 static HRESULT WINAPI Direct3DSwapChain9_QueryInterface(LPDIRECT3DSWAPCHAIN9 iface, REFIID riid, void** ppvObject)
31 {
32     LPDIRECT3DSWAPCHAIN9_INT This = IDirect3DSwapChain9ToImpl(iface);
33 
34     if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirect3DSwapChain9))
35     {
36         IUnknown_AddRef(iface);
37         *ppvObject = &This->lpVtbl;
38         return S_OK;
39     }
40 
41     *ppvObject = NULL;
42     return E_NOINTERFACE;
43 }
44 
45 static ULONG WINAPI Direct3DSwapChain9_AddRef(LPDIRECT3DSWAPCHAIN9 iface)
46 {
47     LPDIRECT3DSWAPCHAIN9_INT This = IDirect3DSwapChain9ToImpl(iface);
48     return D3D9BaseObject_AddRef((D3D9BaseObject*) &This->BaseObject.lpVtbl);
49 }
50 
51 static ULONG WINAPI Direct3DSwapChain9_Release(LPDIRECT3DSWAPCHAIN9 iface)
52 {
53     LPDIRECT3DSWAPCHAIN9_INT This = IDirect3DSwapChain9ToImpl(iface);
54     return D3D9BaseObject_Release((D3D9BaseObject*) &This->BaseObject.lpVtbl);
55 }
56 
57 /* IDirect3DSwapChain9 interface */
58 static HRESULT WINAPI Direct3DSwapChain9_Present(LPDIRECT3DSWAPCHAIN9 iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion,DWORD dwFlags)
59 {
60     UNIMPLEMENTED
61     return D3D_OK;
62 }
63 
64 static HRESULT WINAPI Direct3DSwapChain9_GetFrontBufferData(LPDIRECT3DSWAPCHAIN9 iface, IDirect3DSurface9* pDestSurface)
65 {
66     UNIMPLEMENTED
67     return D3D_OK;
68 }
69 
70 static HRESULT WINAPI Direct3DSwapChain9_GetBackBuffer(LPDIRECT3DSWAPCHAIN9 iface, UINT iBackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface9** ppBackBuffer)
71 {
72     UNIMPLEMENTED
73     return D3D_OK;
74 }
75 
76 static HRESULT WINAPI Direct3DSwapChain9_GetRasterStatus(LPDIRECT3DSWAPCHAIN9 iface, D3DRASTER_STATUS* pRasterStatus)
77 {
78     UNIMPLEMENTED
79     return D3D_OK;
80 }
81 
82 static HRESULT WINAPI Direct3DSwapChain9_GetDisplayMode(LPDIRECT3DSWAPCHAIN9 iface, D3DDISPLAYMODE* pMode)
83 {
84     UNIMPLEMENTED
85     return D3D_OK;
86 }
87 
88 /*++
89 * @name IDirect3DSwapChain9::GetDevice
90 * @implemented
91 *
92 * The function Direct3DSwapChain9_GetDevice sets the ppDevice argument
93 * to the device connected to create the swap chain.
94 *
95 * @param LPDIRECT3DSWAPCHAIN9 iface
96 * Pointer to a IDirect3DSwapChain9 object returned from IDirect3D9Device::GetSwapChain()
97 *
98 * @param IDirect3DDevice9** ppDevice
99 * Pointer to a IDirect3DDevice9* structure to be set to the device object.
100 *
101 * @return HRESULT
102 * If the method successfully sets the ppDevice value, the return value is D3D_OK.
103 * If ppDevice is a bad pointer the return value will be D3DERR_INVALIDCALL.
104 * If the swap chain didn't contain any device, the return value will be D3DERR_INVALIDDEVICE.
105 *
106 */
107 static HRESULT WINAPI Direct3DSwapChain9_GetDevice(LPDIRECT3DSWAPCHAIN9 iface, IDirect3DDevice9** ppDevice)
108 {
109     LPDIRECT3DSWAPCHAIN9_INT This = IDirect3DSwapChain9ToImpl(iface);
110     LOCK_D3DDEVICE9();
111 
112     if (NULL == ppDevice)
113     {
114         DPRINT1("Invalid ppDevice parameter specified");
115         UNLOCK_D3DDEVICE9();
116         return D3DERR_INVALIDCALL;
117     }
118 
119     if (FAILED(D3D9BaseObject_GetDevice(&This->BaseObject, ppDevice)))
120     {
121         DPRINT1("Invalid This parameter specified");
122         UNLOCK_D3DDEVICE9();
123         return D3DERR_INVALIDDEVICE;
124     }
125 
126     UNLOCK_D3DDEVICE9();
127     return D3D_OK;
128 }
129 
130 /*++
131 * @name IDirect3DSwapChain9::GetPresentParameters
132 * @implemented
133 *
134 * The function Direct3DSwapChain9_GetPresentParameters fills the pPresentationParameters
135 * argument with the D3DPRESENT_PARAMETERS parameters that was used to create the swap chain.
136 *
137 * @param LPDIRECT3DSWAPCHAIN9 iface
138 * Pointer to a IDirect3DSwapChain9 object returned from IDirect3D9Device::GetSwapChain()
139 *
140 * @param D3DPRESENT_PARAMETERS* pPresentationParameters
141 * Pointer to a D3DPRESENT_PARAMETERS structure to be filled with the creation parameters.
142 *
143 * @return HRESULT
144 * If the method successfully fills the pPresentationParameters structure, the return value is D3D_OK.
145 * If pPresentationParameters is a bad pointer the return value will be D3DERR_INVALIDCALL.
146 *
147 */
148 static HRESULT WINAPI Direct3DSwapChain9_GetPresentParameters(LPDIRECT3DSWAPCHAIN9 iface, D3DPRESENT_PARAMETERS* pPresentationParameters)
149 {
150     LPDIRECT3DSWAPCHAIN9_INT This = IDirect3DSwapChain9ToImpl(iface);
151     LOCK_D3DDEVICE9();
152 
153     if (NULL == pPresentationParameters)
154     {
155         DPRINT1("Invalid pPresentationParameters parameter specified");
156         UNLOCK_D3DDEVICE9();
157         return D3DERR_INVALIDCALL;
158     }
159 
160     *pPresentationParameters = This->PresentParameters;
161 
162     UNLOCK_D3DDEVICE9();
163     return D3D_OK;
164 }
165 
166 static IDirect3DSwapChain9Vtbl Direct3DSwapChain9_Vtbl =
167 {
168     /* IUnknown */
169     Direct3DSwapChain9_QueryInterface,
170     Direct3DSwapChain9_AddRef,
171     Direct3DSwapChain9_Release,
172 
173     /* IDirect3DSwapChain9 */
174     Direct3DSwapChain9_Present,
175     Direct3DSwapChain9_GetFrontBufferData,
176     Direct3DSwapChain9_GetBackBuffer,
177     Direct3DSwapChain9_GetRasterStatus,
178     Direct3DSwapChain9_GetDisplayMode,
179     Direct3DSwapChain9_GetDevice,
180     Direct3DSwapChain9_GetPresentParameters,
181 };
182 
183 Direct3DSwapChain9_INT* CreateDirect3DSwapChain9(enum REF_TYPE RefType, struct _Direct3DDevice9_INT* pBaseDevice, DWORD ChainIndex)
184 {
185     Direct3DSwapChain9_INT* pThisSwapChain;
186     if (FAILED(AlignedAlloc((LPVOID*)&pThisSwapChain, sizeof(Direct3DSwapChain9_INT))))
187     {
188         DPRINT1("Could not create Direct3DSwapChain9_INT");
189         return NULL;
190     }
191 
192     InitD3D9BaseObject((D3D9BaseObject*) &pThisSwapChain->BaseObject.lpVtbl, RefType, (IUnknown*) &pBaseDevice->lpVtbl);
193 
194     pThisSwapChain->lpVtbl = &Direct3DSwapChain9_Vtbl;
195 
196     pThisSwapChain->ChainIndex = ChainIndex;
197     pThisSwapChain->AdapterGroupIndex = ChainIndex;
198     pThisSwapChain->pUnknown6BC = pBaseDevice->DeviceData[ChainIndex].pUnknown6BC;
199     pThisSwapChain->pUnknown015c = (LPVOID)0xD3D9D3D9;
200 
201     return pThisSwapChain;
202 }
203 
204 VOID Direct3DSwapChain9_SetDisplayMode(Direct3DSwapChain9_INT* pThisSwapChain, D3DPRESENT_PARAMETERS* pPresentationParameters)
205 {
206     pThisSwapChain->dwWidth = pPresentationParameters->BackBufferWidth;
207     pThisSwapChain->dwHeight = pPresentationParameters->BackBufferHeight;
208 }
209 
210 HRESULT Direct3DSwapChain9_Init(Direct3DSwapChain9_INT* pThisSwapChain, D3DPRESENT_PARAMETERS* pPresentationParameters)
211 {
212     int i;
213     DIRECT3DDEVICE9_INT* pDevice;
214 
215     for (i = 0; i < 256; i++)
216     {
217         pThisSwapChain->GammaRamp.red[i] =
218             pThisSwapChain->GammaRamp.green[i] =
219             pThisSwapChain->GammaRamp.blue[i] = i;
220     }
221 
222     pThisSwapChain->PresentParameters = pPresentationParameters[pThisSwapChain->ChainIndex];
223     pThisSwapChain->SwapEffect = pPresentationParameters->SwapEffect;
224     Direct3DSwapChain9_SetDisplayMode(pThisSwapChain, &pThisSwapChain->PresentParameters);
225 
226     if (FAILED(D3D9BaseObject_GetDeviceInt(&pThisSwapChain->BaseObject, &pDevice)))
227     {
228         DPRINT1("Could not get the swapchain device");
229         return DDERR_GENERIC;
230     }
231 
232     pThisSwapChain->pCursor = CreateD3D9Cursor(pDevice, pThisSwapChain);
233     if (NULL == pThisSwapChain->pCursor)
234     {
235         DPRINT1("Could not allocate D3D9Cursor");
236         return DDERR_OUTOFMEMORY;
237     }
238 
239     return Direct3DSwapChain9_Reset(pThisSwapChain, pPresentationParameters);
240 }
241 
242 HRESULT Direct3DSwapChain9_Reset(Direct3DSwapChain9_INT* pThisSwapChain, D3DPRESENT_PARAMETERS* pPresentationParameters)
243 {
244     // TODO: Do all the dirty work...
245     return D3D_OK;
246 }
247 
248 VOID Direct3DSwapChain9_GetGammaRamp(Direct3DSwapChain9_INT* pThisSwapChain, D3DGAMMARAMP* pRamp)
249 {
250     memcpy(pRamp, &pThisSwapChain->GammaRamp, sizeof(D3DGAMMARAMP));
251 }
252 
253 VOID Direct3DSwapChain9_SetGammaRamp(Direct3DSwapChain9_INT* pThisSwapChain, DWORD Flags, CONST D3DGAMMARAMP* pRamp)
254 {
255     UNIMPLEMENTED
256 }
257