2 *IDirect3DSwapChain9 implementation
4 *Copyright 2002-2003 Jason Edmeades
5 *Copyright 2002-2003 Raphael Junqueira
6 *Copyright 2005 Oliver Stieber
7 *Copyright 2007-2008 Stefan Dösinger for CodeWeavers
9 *This library is free software; you can redistribute it and/or
10 *modify it under the terms of the GNU Lesser General Public
11 *License as published by the Free Software Foundation; either
12 *version 2.1 of the License, or (at your option) any later version.
14 *This library is distributed in the hope that it will be useful,
15 *but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 *Lesser General Public License for more details.
19 *You should have received a copy of the GNU Lesser General Public
20 *License along with this library; if not, write to the Free Software
21 *Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wined3d_private.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
29 /* IDirect3DSwapChain IUnknown parts follow: */
30 HRESULT WINAPI IWineD3DBaseSwapChainImpl_QueryInterface(IWineD3DSwapChain *iface, REFIID riid, void **object)
32 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
34 if (IsEqualGUID(riid, &IID_IWineD3DSwapChain)
35 || IsEqualGUID(riid, &IID_IWineD3DBase)
36 || IsEqualGUID(riid, &IID_IUnknown))
38 IUnknown_AddRef(iface);
43 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
49 ULONG WINAPI IWineD3DBaseSwapChainImpl_AddRef(IWineD3DSwapChain *iface) {
50 IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
51 DWORD refCount = InterlockedIncrement(&This->ref);
52 TRACE("(%p) : AddRef increasing from %d\n", This, refCount - 1);
56 /* Do not call while under the GL lock. */
57 ULONG WINAPI IWineD3DBaseSwapChainImpl_Release(IWineD3DSwapChain *iface)
59 IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
61 refCount = InterlockedDecrement(&This->ref);
62 TRACE("(%p) : ReleaseRef to %d\n", This, refCount);
64 if (!refCount) IWineD3DSwapChain_Destroy(iface);
69 void * WINAPI IWineD3DBaseSwapChainImpl_GetParent(IWineD3DSwapChain *iface)
71 TRACE("iface %p.\n", iface);
73 return ((IWineD3DSwapChainImpl *)iface)->parent;
76 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetFrontBufferData(IWineD3DSwapChain *iface, IWineD3DSurface *dst_surface)
78 IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
81 TRACE("iface %p, dst_surface %p.\n", iface, dst_surface);
86 if (This->presentParms.Windowed) {
87 MapWindowPoints(This->win_handle, NULL, &start, 1);
90 IWineD3DSurface_BltFast(dst_surface, start.x, start.y, (IWineD3DSurface *)This->front_buffer, NULL, 0);
94 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetBackBuffer(IWineD3DSwapChain *iface,
95 UINT back_buffer_idx, WINED3DBACKBUFFER_TYPE type, IWineD3DSurface **back_buffer)
97 IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)iface;
99 TRACE("iface %p, back_buffer_idx %u, type %#x, back_buffer %p.\n",
100 iface, back_buffer_idx, type, back_buffer);
102 /* Return invalid if there is no backbuffer array, otherwise it will
103 * crash when ddraw is used (there swapchain->back_buffers is always NULL).
104 * We need this because this function is called from
105 * IWineD3DStateBlockImpl_InitStartupStateBlock() to get the default
106 * scissorrect dimensions. */
107 if (!swapchain->back_buffers || back_buffer_idx >= swapchain->presentParms.BackBufferCount)
109 WARN("Invalid back buffer index.\n");
110 /* Native d3d9 doesn't set NULL here, just as wine's d3d9. But set it
111 * here in wined3d to avoid problems in other libs. */
113 return WINED3DERR_INVALIDCALL;
116 *back_buffer = (IWineD3DSurface *)swapchain->back_buffers[back_buffer_idx];
117 if (*back_buffer) IWineD3DSurface_AddRef(*back_buffer);
119 TRACE("Returning back buffer %p.\n", *back_buffer);
124 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetRasterStatus(IWineD3DSwapChain *iface, WINED3DRASTER_STATUS *pRasterStatus) {
126 /* No OpenGL equivalent */
129 FIXME("iface %p, raster_status %p stub!\n", iface, pRasterStatus);
132 /* Obtaining the raster status is a widely implemented but optional feature.
133 * When this method returns OK then the application Starcraft 2 expects that
134 * the pRasterStatus->InVBlank value differs over time. To prevent Starcraft 2
135 * from running in an infinite loop at startup this method returns INVALIDCALL.
137 return WINED3DERR_INVALIDCALL;
140 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface, WINED3DDISPLAYMODE*pMode) {
141 IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
144 TRACE("(%p)->(%p): Calling GetAdapterDisplayMode\n", This, pMode);
145 hr = IWineD3D_GetAdapterDisplayMode(This->device->wined3d, This->device->adapter->ordinal, pMode);
147 TRACE("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate,
148 pMode->Format, debug_d3dformat(pMode->Format));
152 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice **device)
154 IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
156 *device = (IWineD3DDevice *)This->device;
157 IWineD3DDevice_AddRef(*device);
159 TRACE("(%p) : returning %p\n", This, *device);
163 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetPresentParameters(IWineD3DSwapChain *iface, WINED3DPRESENT_PARAMETERS *pPresentationParameters) {
164 IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
165 TRACE("(%p)\n", This);
167 *pPresentationParameters = This->presentParms;
172 HRESULT WINAPI IWineD3DBaseSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface,
173 DWORD flags, const WINED3DGAMMARAMP *pRamp)
175 IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
178 TRACE("iface %p, flags %#x, ramp %p.\n", iface, flags, pRamp);
180 hDC = GetDC(This->device_window);
181 SetDeviceGammaRamp(hDC, (LPVOID)pRamp);
182 ReleaseDC(This->device_window, hDC);
187 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface, WINED3DGAMMARAMP *pRamp){
189 IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
191 TRACE("(%p) : pRamp@%p\n", This, pRamp);
192 hDC = GetDC(This->device_window);
193 GetDeviceGammaRamp(hDC, pRamp);
194 ReleaseDC(This->device_window, hDC);