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>
8 #include "d3d9_swapchain.h"
13 #include "d3d9_helpers.h"
14 #include "d3d9_device.h"
15 #include "d3d9_cursor.h"
17 #define LOCK_D3DDEVICE9() D3D9BaseObject_LockDevice(&This->BaseObject)
18 #define UNLOCK_D3DDEVICE9() D3D9BaseObject_UnlockDevice(&This->BaseObject)
20 /* Convert a IDirect3DSwapChain9 pointer safely to the internal implementation struct */
21 LPDIRECT3DSWAPCHAIN9_INT
IDirect3DSwapChain9ToImpl(LPDIRECT3DSWAPCHAIN9 iface
)
26 return (LPDIRECT3DSWAPCHAIN9_INT
)((ULONG_PTR
)iface
- FIELD_OFFSET(Direct3DSwapChain9_INT
, lpVtbl
));
29 /* IDirect3DSwapChain9: IUnknown implementation */
30 static HRESULT WINAPI
Direct3DSwapChain9_QueryInterface(LPDIRECT3DSWAPCHAIN9 iface
, REFIID riid
, void** ppvObject
)
32 LPDIRECT3DSWAPCHAIN9_INT This
= IDirect3DSwapChain9ToImpl(iface
);
34 if (IsEqualGUID(riid
, &IID_IUnknown
) || IsEqualGUID(riid
, &IID_IDirect3DSwapChain9
))
36 IUnknown_AddRef(iface
);
37 *ppvObject
= &This
->lpVtbl
;
45 static ULONG WINAPI
Direct3DSwapChain9_AddRef(LPDIRECT3DSWAPCHAIN9 iface
)
47 LPDIRECT3DSWAPCHAIN9_INT This
= IDirect3DSwapChain9ToImpl(iface
);
48 return D3D9BaseObject_AddRef((D3D9BaseObject
*) &This
->BaseObject
.lpVtbl
);
51 static ULONG WINAPI
Direct3DSwapChain9_Release(LPDIRECT3DSWAPCHAIN9 iface
)
53 LPDIRECT3DSWAPCHAIN9_INT This
= IDirect3DSwapChain9ToImpl(iface
);
54 return D3D9BaseObject_Release((D3D9BaseObject
*) &This
->BaseObject
.lpVtbl
);
57 /* IDirect3DSwapChain9 interface */
58 static HRESULT WINAPI
Direct3DSwapChain9_Present(LPDIRECT3DSWAPCHAIN9 iface
, CONST RECT
* pSourceRect
,CONST RECT
* pDestRect
,HWND hDestWindowOverride
,CONST RGNDATA
* pDirtyRegion
,DWORD dwFlags
)
64 static HRESULT WINAPI
Direct3DSwapChain9_GetFrontBufferData(LPDIRECT3DSWAPCHAIN9 iface
, IDirect3DSurface9
* pDestSurface
)
70 static HRESULT WINAPI
Direct3DSwapChain9_GetBackBuffer(LPDIRECT3DSWAPCHAIN9 iface
, UINT iBackBuffer
,D3DBACKBUFFER_TYPE Type
,IDirect3DSurface9
** ppBackBuffer
)
76 static HRESULT WINAPI
Direct3DSwapChain9_GetRasterStatus(LPDIRECT3DSWAPCHAIN9 iface
, D3DRASTER_STATUS
* pRasterStatus
)
82 static HRESULT WINAPI
Direct3DSwapChain9_GetDisplayMode(LPDIRECT3DSWAPCHAIN9 iface
, D3DDISPLAYMODE
* pMode
)
89 * @name IDirect3DSwapChain9::GetDevice
92 * The function Direct3DSwapChain9_GetDevice sets the ppDevice argument
93 * to the device connected to create the swap chain.
95 * @param LPDIRECT3DSWAPCHAIN9 iface
96 * Pointer to a IDirect3DSwapChain9 object returned from IDirect3D9Device::GetSwapChain()
98 * @param IDirect3DDevice9** ppDevice
99 * Pointer to a IDirect3DDevice9* structure to be set to the device object.
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.
107 static HRESULT WINAPI
Direct3DSwapChain9_GetDevice(LPDIRECT3DSWAPCHAIN9 iface
, IDirect3DDevice9
** ppDevice
)
109 LPDIRECT3DSWAPCHAIN9_INT This
= IDirect3DSwapChain9ToImpl(iface
);
112 if (NULL
== ppDevice
)
114 DPRINT1("Invalid ppDevice parameter specified");
116 return D3DERR_INVALIDCALL
;
119 if (FAILED(D3D9BaseObject_GetDevice(&This
->BaseObject
, ppDevice
)))
121 DPRINT1("Invalid This parameter specified");
123 return D3DERR_INVALIDDEVICE
;
131 * @name IDirect3DSwapChain9::GetPresentParameters
134 * The function Direct3DSwapChain9_GetPresentParameters fills the pPresentationParameters
135 * argument with the D3DPRESENT_PARAMETERS parameters that was used to create the swap chain.
137 * @param LPDIRECT3DSWAPCHAIN9 iface
138 * Pointer to a IDirect3DSwapChain9 object returned from IDirect3D9Device::GetSwapChain()
140 * @param D3DPRESENT_PARAMETERS* pPresentationParameters
141 * Pointer to a D3DPRESENT_PARAMETERS structure to be filled with the creation parameters.
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.
148 static HRESULT WINAPI
Direct3DSwapChain9_GetPresentParameters(LPDIRECT3DSWAPCHAIN9 iface
, D3DPRESENT_PARAMETERS
* pPresentationParameters
)
150 LPDIRECT3DSWAPCHAIN9_INT This
= IDirect3DSwapChain9ToImpl(iface
);
153 if (NULL
== pPresentationParameters
)
155 DPRINT1("Invalid pPresentationParameters parameter specified");
157 return D3DERR_INVALIDCALL
;
160 *pPresentationParameters
= This
->PresentParameters
;
166 static IDirect3DSwapChain9Vtbl Direct3DSwapChain9_Vtbl
=
169 Direct3DSwapChain9_QueryInterface
,
170 Direct3DSwapChain9_AddRef
,
171 Direct3DSwapChain9_Release
,
173 /* IDirect3DSwapChain9 */
174 Direct3DSwapChain9_Present
,
175 Direct3DSwapChain9_GetFrontBufferData
,
176 Direct3DSwapChain9_GetBackBuffer
,
177 Direct3DSwapChain9_GetRasterStatus
,
178 Direct3DSwapChain9_GetDisplayMode
,
179 Direct3DSwapChain9_GetDevice
,
180 Direct3DSwapChain9_GetPresentParameters
,
183 Direct3DSwapChain9_INT
* CreateDirect3DSwapChain9(enum REF_TYPE RefType
, struct _Direct3DDevice9_INT
* pBaseDevice
, DWORD ChainIndex
)
185 Direct3DSwapChain9_INT
* pThisSwapChain
;
186 if (FAILED(AlignedAlloc((LPVOID
*)&pThisSwapChain
, sizeof(Direct3DSwapChain9_INT
))))
188 DPRINT1("Could not create Direct3DSwapChain9_INT");
192 InitD3D9BaseObject((D3D9BaseObject
*) &pThisSwapChain
->BaseObject
.lpVtbl
, RefType
, (IUnknown
*) &pBaseDevice
->lpVtbl
);
194 pThisSwapChain
->lpVtbl
= &Direct3DSwapChain9_Vtbl
;
196 pThisSwapChain
->ChainIndex
= ChainIndex
;
197 pThisSwapChain
->AdapterGroupIndex
= ChainIndex
;
198 pThisSwapChain
->pUnknown6BC
= pBaseDevice
->DeviceData
[ChainIndex
].pUnknown6BC
;
199 pThisSwapChain
->pUnknown015c
= (LPVOID
)0xD3D9D3D9;
201 return pThisSwapChain
;
204 VOID
Direct3DSwapChain9_SetDisplayMode(Direct3DSwapChain9_INT
* pThisSwapChain
, D3DPRESENT_PARAMETERS
* pPresentationParameters
)
206 pThisSwapChain
->dwWidth
= pPresentationParameters
->BackBufferWidth
;
207 pThisSwapChain
->dwHeight
= pPresentationParameters
->BackBufferHeight
;
210 HRESULT
Direct3DSwapChain9_Init(Direct3DSwapChain9_INT
* pThisSwapChain
, D3DPRESENT_PARAMETERS
* pPresentationParameters
)
213 DIRECT3DDEVICE9_INT
* pDevice
;
215 for (i
= 0; i
< 256; i
++)
217 pThisSwapChain
->GammaRamp
.red
[i
] =
218 pThisSwapChain
->GammaRamp
.green
[i
] =
219 pThisSwapChain
->GammaRamp
.blue
[i
] = i
;
222 pThisSwapChain
->PresentParameters
= pPresentationParameters
[pThisSwapChain
->ChainIndex
];
223 pThisSwapChain
->SwapEffect
= pPresentationParameters
->SwapEffect
;
224 Direct3DSwapChain9_SetDisplayMode(pThisSwapChain
, &pThisSwapChain
->PresentParameters
);
226 if (FAILED(D3D9BaseObject_GetDeviceInt(&pThisSwapChain
->BaseObject
, &pDevice
)))
228 DPRINT1("Could not get the swapchain device");
229 return DDERR_GENERIC
;
232 pThisSwapChain
->pCursor
= CreateD3D9Cursor(pDevice
, pThisSwapChain
);
233 if (NULL
== pThisSwapChain
->pCursor
)
235 DPRINT1("Could not allocate D3D9Cursor");
236 return DDERR_OUTOFMEMORY
;
239 return Direct3DSwapChain9_Reset(pThisSwapChain
, pPresentationParameters
);
242 HRESULT
Direct3DSwapChain9_Reset(Direct3DSwapChain9_INT
* pThisSwapChain
, D3DPRESENT_PARAMETERS
* pPresentationParameters
)
244 // TODO: Do all the dirty work...
248 VOID
Direct3DSwapChain9_GetGammaRamp(Direct3DSwapChain9_INT
* pThisSwapChain
, D3DGAMMARAMP
* pRamp
)
250 memcpy(pRamp
, &pThisSwapChain
->GammaRamp
, sizeof(D3DGAMMARAMP
));
253 VOID
Direct3DSwapChain9_SetGammaRamp(Direct3DSwapChain9_INT
* pThisSwapChain
, DWORD Flags
, CONST D3DGAMMARAMP
* pRamp
)