2005-06-23 13:05:24 +02:00
/*
* IDirect3DSwapChain9 implementation
*
* Copyright 2002 - 2003 Jason Edmeades
* Copyright 2002 - 2003 Raphael Junqueira
* Copyright 2005 Oliver Stieber
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
2006-05-18 14:49:52 +02:00
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
2005-06-23 13:05:24 +02:00
*/
# include "config.h"
# include "wined3d_private.h"
/* TODO: move to shared header (or context manager )*/
/* x11drv GDI escapes */
# define X11DRV_ESCAPE 6789
enum x11drv_escape_codes
{
X11DRV_GET_DISPLAY , /* get X11 display for a DC */
X11DRV_GET_DRAWABLE , /* get current drawable for a DC */
X11DRV_GET_FONT , /* get current X font for a DC */
} ;
/* retrieve the X display to use on a given DC */
inline static Display * get_display ( HDC hdc )
{
Display * display ;
enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY ;
if ( ! ExtEscape ( hdc , X11DRV_ESCAPE , sizeof ( escape ) , ( LPCSTR ) & escape ,
sizeof ( display ) , ( LPSTR ) & display ) ) display = NULL ;
return display ;
}
2005-07-13 16:15:54 +02:00
/*TODO: some of the additional parameters may be required to
2005-06-23 13:05:24 +02:00
set the gamma ramp ( for some weird reason microsoft have left swap gammaramp in device
but it operates on a swapchain , it may be a good idea to move it to IWineD3DSwapChain for IWineD3D ) */
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
WINE_DEFAULT_DEBUG_CHANNEL ( d3d ) ;
2006-07-05 18:35:21 +02:00
WINE_DECLARE_DEBUG_CHANNEL ( fps ) ;
2005-06-23 13:05:24 +02:00
/* IDirect3DSwapChain IUnknown parts follow: */
2006-06-10 13:15:32 +02:00
static ULONG WINAPI IWineD3DSwapChainImpl_AddRef ( IWineD3DSwapChain * iface ) {
2005-06-23 13:05:24 +02:00
IWineD3DSwapChainImpl * This = ( IWineD3DSwapChainImpl * ) iface ;
DWORD refCount = InterlockedIncrement ( & This - > ref ) ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : AddRef increasing from %d \n " , This , refCount - 1 ) ;
2005-06-23 13:05:24 +02:00
return refCount ;
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DSwapChainImpl_QueryInterface ( IWineD3DSwapChain * iface , REFIID riid , LPVOID * ppobj )
2005-06-23 13:05:24 +02:00
{
IWineD3DSwapChainImpl * This = ( IWineD3DSwapChainImpl * ) iface ;
2005-11-10 13:14:56 +01:00
TRACE ( " (%p)->(%s,%p) \n " , This , debugstr_guid ( riid ) , ppobj ) ;
2005-06-23 13:05:24 +02:00
if ( IsEqualGUID ( riid , & IID_IUnknown )
2006-02-06 11:32:41 +01:00
| | IsEqualGUID ( riid , & IID_IWineD3DBase )
2005-06-23 13:05:24 +02:00
| | IsEqualGUID ( riid , & IID_IWineD3DSwapChain ) ) {
IWineD3DSwapChainImpl_AddRef ( iface ) ;
if ( ppobj = = NULL ) {
ERR ( " Query interface called but now data allocated \n " ) ;
return E_NOINTERFACE ;
}
* ppobj = This ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-07-13 16:15:54 +02:00
}
2006-04-25 23:59:12 +02:00
* ppobj = NULL ;
2005-06-23 13:05:24 +02:00
return E_NOINTERFACE ;
}
2006-06-10 13:15:32 +02:00
static ULONG WINAPI IWineD3DSwapChainImpl_Release ( IWineD3DSwapChain * iface ) {
2005-06-23 13:05:24 +02:00
IWineD3DSwapChainImpl * This = ( IWineD3DSwapChainImpl * ) iface ;
2005-07-13 16:15:54 +02:00
DWORD refCount ;
2005-06-23 13:05:24 +02:00
refCount = InterlockedDecrement ( & This - > ref ) ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : ReleaseRef to %d \n " , This , refCount ) ;
2005-06-23 13:05:24 +02:00
if ( refCount = = 0 ) {
2006-12-05 00:29:14 +01:00
IWineD3DSwapChain_Destroy ( iface , D3DCB_DefaultDestroySurface ) ;
2005-06-23 13:05:24 +02:00
}
return refCount ;
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DSwapChainImpl_GetParent ( IWineD3DSwapChain * iface , IUnknown * * ppParent ) {
2005-06-23 13:05:24 +02:00
IWineD3DSwapChainImpl * This = ( IWineD3DSwapChainImpl * ) iface ;
* ppParent = This - > parent ;
IUnknown_AddRef ( * ppParent ) ;
TRACE ( " (%p) returning %p \n " , This , * ppParent ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-06-23 13:05:24 +02:00
}
/*IWineD3DSwapChain parts follow: */
2006-12-05 00:29:14 +01:00
static void WINAPI IWineD3DSwapChainImpl_Destroy ( IWineD3DSwapChain * iface , D3DCB_DESTROYSURFACEFN D3DCB_DestroyRenderTarget ) {
IWineD3DSwapChainImpl * This = ( IWineD3DSwapChainImpl * ) iface ;
/* release the ref to the front and back buffer parents */
if ( This - > frontBuffer ) {
IWineD3DSurface_SetContainer ( This - > frontBuffer , 0 ) ;
if ( D3DCB_DestroyRenderTarget ( This - > frontBuffer ) > 0 ) {
FIXME ( " (%p) Something's still holding the front buffer \n " , This ) ;
}
}
if ( This - > backBuffer ) {
int i ;
for ( i = 0 ; i < This - > presentParms . BackBufferCount ; i + + ) {
IWineD3DSurface_SetContainer ( This - > backBuffer [ i ] , 0 ) ;
if ( D3DCB_DestroyRenderTarget ( This - > backBuffer [ i ] ) > 0 ) {
FIXME ( " (%p) Something's still holding the back buffer \n " , This ) ;
}
}
}
/* Clean up the context */
/* check that we are the current context first */
if ( glXGetCurrentContext ( ) = = This - > glCtx ) {
glXMakeCurrent ( This - > display , None , NULL ) ;
}
glXDestroyContext ( This - > display , This - > glCtx ) ;
/* IUnknown_Release(This->parent); This should only apply to the primary swapchain,
all others are created by the caller , so releasing the parent should cause
the child to be released , not the other way around !
*/
HeapFree ( GetProcessHeap ( ) , 0 , This ) ;
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DSwapChainImpl_Present ( IWineD3DSwapChain * iface , CONST RECT * pSourceRect , CONST RECT * pDestRect , HWND hDestWindowOverride , CONST RGNDATA * pDirtyRegion , DWORD dwFlags ) {
2005-06-23 13:05:24 +02:00
IWineD3DSwapChainImpl * This = ( IWineD3DSwapChainImpl * ) iface ;
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
ENTER_GL ( ) ;
2006-07-23 00:03:33 +02:00
/* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */
2006-07-27 17:39:03 +02:00
if ( This - > wineD3DDevice - > bCursorVisible & & This - > wineD3DDevice - > cursorTexture ) {
IWineD3DSurfaceImpl cursor ;
2006-07-23 00:03:33 +02:00
RECT destRect = { This - > wineD3DDevice - > xScreenSpace - This - > wineD3DDevice - > xHotSpot ,
This - > wineD3DDevice - > yScreenSpace - This - > wineD3DDevice - > yHotSpot ,
2006-07-27 17:39:03 +02:00
This - > wineD3DDevice - > xScreenSpace + This - > wineD3DDevice - > cursorWidth - This - > wineD3DDevice - > xHotSpot ,
This - > wineD3DDevice - > yScreenSpace + This - > wineD3DDevice - > cursorHeight - This - > wineD3DDevice - > yHotSpot } ;
TRACE ( " Rendering the cursor. Creating fake surface at %p \n " , & cursor ) ;
/* Build a fake surface to call the Blitting code. It is not possible to use the interface passed by
* the application because we are only supposed to copy the information out . Using a fake surface
* allows to use the Blitting engine and avoid copying the whole texture - > render target blitting code .
*/
memset ( & cursor , 0 , sizeof ( cursor ) ) ;
cursor . lpVtbl = & IWineD3DSurface_Vtbl ;
cursor . resource . ref = 1 ;
cursor . resource . wineD3DDevice = This - > wineD3DDevice ;
cursor . resource . pool = WINED3DPOOL_SCRATCH ;
cursor . resource . format = WINED3DFMT_A8R8G8B8 ;
cursor . resource . resourceType = WINED3DRTYPE_SURFACE ;
cursor . glDescription . textureName = This - > wineD3DDevice - > cursorTexture ;
cursor . glDescription . target = GL_TEXTURE_2D ;
cursor . glDescription . level = 0 ;
cursor . currentDesc . Width = This - > wineD3DDevice - > cursorWidth ;
cursor . currentDesc . Height = This - > wineD3DDevice - > cursorHeight ;
cursor . glRect . left = 0 ;
cursor . glRect . top = 0 ;
cursor . glRect . right = cursor . currentDesc . Width ;
cursor . glRect . bottom = cursor . currentDesc . Height ;
/* The cursor must have pow2 sizes */
cursor . pow2Width = cursor . currentDesc . Width ;
cursor . pow2Height = cursor . currentDesc . Height ;
2006-07-23 00:03:33 +02:00
/* DDBLT_KEYSRC will cause BltOverride to enable the alpha test with GL_NOTEQUAL, 0.0,
* which is exactly what we want : - )
*/
2006-10-19 18:45:17 +02:00
if ( This - > presentParms . Windowed ) {
MapWindowPoints ( NULL , This - > win_handle , ( LPPOINT ) & destRect , 2 ) ;
}
2006-07-27 17:39:03 +02:00
IWineD3DSurface_Blt ( This - > backBuffer [ 0 ] , & destRect , ( IWineD3DSurface * ) & cursor , NULL , DDBLT_KEYSRC , NULL ) ;
2006-07-23 00:03:33 +02:00
}
2005-06-23 13:05:24 +02:00
if ( pSourceRect | | pDestRect ) FIXME ( " Unhandled present options %p/%p \n " , pSourceRect , pDestRect ) ;
/* TODO: If only source rect or dest rect are supplied then clip the window to match */
TRACE ( " preseting display %p, drawable %ld \n " , This - > display , This - > drawable ) ;
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
/* Don't call checkGLcall, as glGetError is not applicable here */
if ( hDestWindowOverride & & This - > win_handle ! = hDestWindowOverride ) {
/* Set this swapchain up to point to the new destination.. */
# ifdef USE_CONTEXT_MANAGER
/* TODO: use a context mamager */
# endif
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
/* FIXME: Never access */
IWineD3DSwapChainImpl * swapChainImpl ;
IWineD3DDevice_GetSwapChain ( ( IWineD3DDevice * ) This - > wineD3DDevice , 0 , ( IWineD3DSwapChain * * ) & swapChainImpl ) ;
2005-09-12 16:12:46 +02:00
FIXME ( " Unable to render to a destination window %p \n " , hDestWindowOverride ) ;
2005-06-23 13:05:24 +02:00
if ( This = = swapChainImpl ) {
/* FIXME: this will be fixed by moving to a context management system */
2005-07-11 12:59:41 +02:00
FIXME ( " Cannot change the target of the implicit swapchain \n " ) ;
2005-06-23 13:05:24 +02:00
} else {
HDC hDc ;
XVisualInfo template ;
int num ;
Display * oldDisplay = This - > display ;
GLXContext oldContext = This - > glCtx ;
2005-07-13 16:15:54 +02:00
IUnknown * tmp ;
2005-06-23 13:05:24 +02:00
GLXContext currentContext ;
Drawable currentDrawable ;
hDc = GetDC ( hDestWindowOverride ) ;
2005-07-13 16:15:54 +02:00
This - > win_handle = hDestWindowOverride ;
2005-06-23 13:05:24 +02:00
This - > win = ( Window ) GetPropA ( hDestWindowOverride , " __wine_x11_whole_window " ) ;
2005-11-10 13:14:56 +01:00
TRACE ( " Creating a new context for the window %p \n " , hDestWindowOverride ) ;
2005-06-23 13:05:24 +02:00
ENTER_GL ( ) ;
TRACE ( " Desctroying context %p %p \n " , This - > display , This - > render_ctx ) ;
LEAVE_GL ( ) ;
ENTER_GL ( ) ;
This - > display = get_display ( hDc ) ;
TRACE ( " Got display%p for %p %p \n " , This - > display , hDc , hDestWindowOverride ) ;
ReleaseDC ( hDestWindowOverride , hDc ) ;
template . visualid = ( VisualID ) GetPropA ( GetDesktopWindow ( ) , " __wine_x11_visual_id " ) ;
This - > visInfo = XGetVisualInfo ( This - > display , VisualIDMask , & template , & num ) ;
if ( NULL = = This - > visInfo ) {
2005-07-13 16:15:54 +02:00
ERR ( " cannot really get XVisual \n " ) ;
2005-06-23 13:05:24 +02:00
LEAVE_GL ( ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_NOTAVAILABLE ;
2005-06-23 13:05:24 +02:00
}
2005-07-11 12:59:41 +02:00
/* Now we have problems? well not really we just need to know what the implicit context is */
2005-06-23 13:05:24 +02:00
/* now destroy the old context and create a new one (we should really copy the buffers over, and do the whole make current thing! */
/* destroy the active context?*/
TRACE ( " Creating new context for %p %p %p \n " , This - > display , This - > visInfo , swapChainImpl - > glCtx ) ;
This - > glCtx = glXCreateContext ( This - > display , This - > visInfo , swapChainImpl - > glCtx , GL_TRUE ) ;
if ( NULL = = This - > glCtx ) {
2005-07-13 16:15:54 +02:00
ERR ( " cannot create glxContext \n " ) ;
2005-06-23 13:05:24 +02:00
}
This - > drawable = This - > win ;
This - > render_ctx = This - > glCtx ;
2005-07-11 12:59:41 +02:00
/* Setup some default states TODO: apply the stateblock to the new context */
2005-06-23 13:05:24 +02:00
/** save current context and drawable **/
currentContext = glXGetCurrentContext ( ) ;
currentDrawable = glXGetCurrentDrawable ( ) ;
if ( glXMakeCurrent ( This - > display , This - > win , This - > glCtx ) = = False ) {
ERR ( " Error in setting current context (display %p context %p drawable %ld)! \n " , This - > display , This - > glCtx , This - > win ) ;
}
checkGLcall ( " glXMakeCurrent " ) ;
/* Clear the screen */
glClearColor ( 0.0 , 0.0 , 0.0 , 0.0 ) ;
checkGLcall ( " glClearColor " ) ;
glClearIndex ( 0 ) ;
glClearDepth ( 1 ) ;
glClearStencil ( 0 ) ;
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ) ;
checkGLcall ( " glClear " ) ;
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
glColor3f ( 1.0 , 1.0 , 1.0 ) ;
checkGLcall ( " glColor3f " ) ;
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
glEnable ( GL_LIGHTING ) ;
checkGLcall ( " glEnable " ) ;
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
glLightModeli ( GL_LIGHT_MODEL_LOCAL_VIEWER , GL_TRUE ) ;
checkGLcall ( " glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); " ) ;
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_COMBINE_EXT ) ;
checkGLcall ( " glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); " ) ;
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
glLightModeli ( GL_LIGHT_MODEL_COLOR_CONTROL , GL_SEPARATE_SPECULAR_COLOR ) ;
checkGLcall ( " glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); " ) ;
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
/* If this swapchain is currently the active context then make this swapchain active */
2006-12-19 19:25:22 +01:00
if ( IWineD3DSurface_GetContainer ( This - > wineD3DDevice - > render_targets [ 0 ] , & IID_IWineD3DSwapChain , ( void * * ) & tmp ) = = WINED3D_OK ) {
2005-06-23 13:05:24 +02:00
if ( tmp ! = ( IUnknown * ) This ) {
glXMakeCurrent ( This - > display , currentDrawable , currentContext ) ;
checkGLcall ( " glXMakeCurrent " ) ;
}
IUnknown_Release ( tmp ) ;
} else {
/* reset the context */
glXMakeCurrent ( This - > display , currentDrawable , currentContext ) ;
2005-07-13 16:15:54 +02:00
checkGLcall ( " glXMakeCurrent " ) ;
2005-06-23 13:05:24 +02:00
}
/* delete the old contxt*/
glXDestroyContext ( oldDisplay , oldContext ) ; /* Should this happen on an active context? seems a bad idea */
LEAVE_GL ( ) ;
}
2006-11-30 13:33:11 +01:00
IWineD3DSwapChain_Release ( ( IWineD3DSwapChain * ) swapChainImpl ) ;
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
}
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
/* TODO: The slow way, save the data to memory, create a new context for the destination window, transfer the data cleanup, it may be a good idea to the move this swapchain over to the using the target winows context so that it runs faster in feature. */
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
glXSwapBuffers ( This - > display , This - > drawable ) ; /* TODO: cycle through the swapchain buffers */
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
TRACE ( " glXSwapBuffers called, Starting new frame \n " ) ;
/* FPS support */
2006-07-05 18:35:21 +02:00
if ( TRACE_ON ( fps ) )
2005-06-23 13:05:24 +02:00
{
static long prev_time , frames ;
DWORD time = GetTickCount ( ) ;
frames + + ;
/* every 1.5 seconds */
if ( time - prev_time > 1500 ) {
2006-07-05 18:35:21 +02:00
TRACE_ ( fps ) ( " @ approx %.2ffps \n " , 1000.0 * frames / ( time - prev_time ) ) ;
2005-06-23 13:05:24 +02:00
prev_time = time ;
frames = 0 ;
}
}
# if defined(FRAME_DEBUGGING)
{
if ( GetFileAttributesA ( " C: \\ D3DTRACE " ) ! = INVALID_FILE_ATTRIBUTES ) {
if ( ! isOn ) {
isOn = TRUE ;
FIXME ( " Enabling D3D Trace \n " ) ;
__WINE_SET_DEBUGGING ( __WINE_DBCL_TRACE , __wine_dbch_d3d , 1 ) ;
# if defined(SHOW_FRAME_MAKEUP)
FIXME ( " Singe Frame snapshots Starting \n " ) ;
isDumpingFrames = TRUE ;
glClear ( GL_COLOR_BUFFER_BIT ) ;
# endif
# if defined(SINGLE_FRAME_DEBUGGING)
} else {
# if defined(SHOW_FRAME_MAKEUP)
FIXME ( " Singe Frame snapshots Finishing \n " ) ;
isDumpingFrames = FALSE ;
# endif
FIXME ( " Singe Frame trace complete \n " ) ;
DeleteFileA ( " C: \\ D3DTRACE " ) ;
__WINE_SET_DEBUGGING ( __WINE_DBCL_TRACE , __wine_dbch_d3d , 0 ) ;
# endif
}
} else {
if ( isOn ) {
isOn = FALSE ;
# if defined(SHOW_FRAME_MAKEUP)
FIXME ( " Single Frame snapshots Finishing \n " ) ;
isDumpingFrames = FALSE ;
# endif
FIXME ( " Disabling D3D Trace \n " ) ;
__WINE_SET_DEBUGGING ( __WINE_DBCL_TRACE , __wine_dbch_d3d , 0 ) ;
}
}
}
# endif
LEAVE_GL ( ) ;
/* Although this is not strictly required, a simple demo showed this does occur
on ( at least non - debug ) d3d */
2006-04-10 18:26:46 +02:00
if ( This - > presentParms . SwapEffect = = WINED3DSWAPEFFECT_DISCARD ) {
2005-07-13 16:15:54 +02:00
TRACE ( " Clearing \n " ) ;
2005-06-23 13:05:24 +02:00
2006-10-31 09:17:43 +01:00
IWineD3DDevice_Clear ( ( IWineD3DDevice * ) This - > wineD3DDevice , 0 , NULL , WINED3DCLEAR_STENCIL | WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_TARGET , 0x00 , 1.0 , 0 ) ;
2005-06-23 13:05:24 +02:00
2005-11-17 12:05:12 +01:00
} else {
TRACE ( " Clearing z/stencil buffer \n " ) ;
2006-10-31 09:17:43 +01:00
IWineD3DDevice_Clear ( ( IWineD3DDevice * ) This - > wineD3DDevice , 0 , NULL , WINED3DCLEAR_STENCIL | WINED3DCLEAR_ZBUFFER , 0x00 , 1.0 , 0 ) ;
2005-06-23 13:05:24 +02:00
}
2005-11-17 12:05:12 +01:00
2006-07-17 23:01:32 +02:00
if ( ! ( ( ( IWineD3DSurfaceImpl * ) This - > frontBuffer ) - > Flags & SFLAG_GLDIRTY ) | |
! ( ( ( IWineD3DSurfaceImpl * ) This - > backBuffer [ 0 ] ) - > Flags & SFLAG_GLDIRTY ) ) {
/* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying */
IWineD3DSurfaceImpl * front = ( IWineD3DSurfaceImpl * ) This - > frontBuffer ;
IWineD3DSurfaceImpl * back = ( IWineD3DSurfaceImpl * ) This - > backBuffer [ 0 ] ;
BOOL frontdirty = front - > Flags & SFLAG_GLDIRTY ;
BOOL backdirty = back - > Flags & SFLAG_GLDIRTY ;
/* Flip the DC */
{
HDC tmp ;
tmp = front - > hDC ;
front - > hDC = back - > hDC ;
back - > hDC = tmp ;
}
/* Flip the DIBsection */
{
HBITMAP tmp ;
tmp = front - > dib . DIBsection ;
front - > dib . DIBsection = back - > dib . DIBsection ;
back - > dib . DIBsection = tmp ;
}
/* Flip the surface data */
{
void * tmp ;
tmp = front - > dib . bitmap_data ;
front - > dib . bitmap_data = back - > dib . bitmap_data ;
back - > dib . bitmap_data = tmp ;
tmp = front - > resource . allocatedMemory ;
front - > resource . allocatedMemory = back - > resource . allocatedMemory ;
back - > resource . allocatedMemory = tmp ;
}
/* client_memory should not be different, but just in case */
{
BOOL tmp ;
tmp = front - > dib . client_memory ;
front - > dib . client_memory = back - > dib . client_memory ;
back - > dib . client_memory = tmp ;
}
if ( frontdirty ) back - > Flags | = SFLAG_GLDIRTY ;
else back - > Flags & = ~ SFLAG_GLDIRTY ;
if ( backdirty ) front - > Flags | = SFLAG_GLDIRTY ;
else front - > Flags & = ~ SFLAG_GLDIRTY ;
}
2006-06-04 16:42:57 +02:00
2005-11-17 12:05:12 +01:00
TRACE ( " returning \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-06-23 13:05:24 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DSwapChainImpl_GetFrontBufferData ( IWineD3DSwapChain * iface , IWineD3DSurface * pDestSurface ) {
2005-06-23 13:05:24 +02:00
IWineD3DSwapChainImpl * This = ( IWineD3DSwapChainImpl * ) iface ;
2006-10-19 19:13:14 +02:00
POINT start ;
2005-07-13 16:15:54 +02:00
2005-11-10 13:14:56 +01:00
TRACE ( " (%p) : iface(%p) pDestSurface(%p) \n " , This , iface , pDestSurface ) ;
2006-10-19 19:13:14 +02:00
start . x = 0 ;
start . y = 0 ;
if ( This - > presentParms . Windowed ) {
MapWindowPoints ( This - > win_handle , NULL , & start , 1 ) ;
}
2005-08-23 21:59:27 +02:00
#if 0 /* TODO: make sure that this swapchains context is active */
IWineD3DDevice_ActivateSwapChainContext ( This - > wineD3DDevice , iface ) ;
# endif
2006-10-19 19:13:14 +02:00
IWineD3DSurface_BltFast ( pDestSurface , start . x , start . y , This - > frontBuffer , NULL , 0 ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-06-23 13:05:24 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DSwapChainImpl_GetBackBuffer ( IWineD3DSwapChain * iface , UINT iBackBuffer , WINED3DBACKBUFFER_TYPE Type , IWineD3DSurface * * ppBackBuffer ) {
2005-06-23 13:05:24 +02:00
2005-07-13 16:15:54 +02:00
IWineD3DSwapChainImpl * This = ( IWineD3DSwapChainImpl * ) iface ;
2005-06-23 13:05:24 +02:00
if ( iBackBuffer > This - > presentParms . BackBufferCount - 1 ) {
2006-05-24 11:34:30 +02:00
TRACE ( " Back buffer count out of range \n " ) ;
/* Native d3d9 doesn't set NULL here, just as wine's d3d9. But set it here
* in wined3d to avoid problems in other libs
*/
* ppBackBuffer = NULL ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-06-23 13:05:24 +02:00
}
2006-06-15 12:54:19 +02:00
* ppBackBuffer = This - > backBuffer [ iBackBuffer ] ;
TRACE ( " (%p) : BackBuf %d Type %d returning %p \n " , This , iBackBuffer , Type , * ppBackBuffer ) ;
2006-11-30 13:33:52 +01:00
/* Note inc ref on returned surface */
if ( * ppBackBuffer ) IWineD3DSurface_AddRef ( * ppBackBuffer ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DSwapChainImpl_GetRasterStatus ( IWineD3DSwapChain * iface , WINED3DRASTER_STATUS * pRasterStatus ) {
2005-07-13 16:15:54 +02:00
IWineD3DSwapChainImpl * This = ( IWineD3DSwapChainImpl * ) iface ;
2005-08-27 11:58:53 +02:00
static BOOL showFixmes = TRUE ;
2005-06-23 13:05:24 +02:00
pRasterStatus - > InVBlank = TRUE ;
pRasterStatus - > ScanLine = 0 ;
2005-08-27 11:58:53 +02:00
/* No openGL equivalent */
if ( showFixmes ) {
FIXME ( " (%p) : stub (once) \n " , This ) ;
showFixmes = FALSE ;
}
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-06-23 13:05:24 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DSwapChainImpl_GetDisplayMode ( IWineD3DSwapChain * iface , WINED3DDISPLAYMODE * pMode ) {
2005-07-13 16:15:54 +02:00
IWineD3DSwapChainImpl * This = ( IWineD3DSwapChainImpl * ) iface ;
2005-06-23 13:05:24 +02:00
HDC hdc ;
int bpp = 0 ;
pMode - > Width = GetSystemMetrics ( SM_CXSCREEN ) ;
pMode - > Height = GetSystemMetrics ( SM_CYSCREEN ) ;
pMode - > RefreshRate = 85 ; /* FIXME: How to identify? */
2007-01-02 17:16:36 +01:00
hdc = GetDC ( 0 ) ;
2005-06-23 13:05:24 +02:00
bpp = GetDeviceCaps ( hdc , BITSPIXEL ) ;
2007-01-02 17:16:36 +01:00
ReleaseDC ( 0 , hdc ) ;
2005-06-23 13:05:24 +02:00
switch ( bpp ) {
2006-10-11 03:51:13 +02:00
case 8 : pMode - > Format = WINED3DFMT_R8G8B8 ; break ;
case 16 : pMode - > Format = WINED3DFMT_R5G6B5 ; break ;
case 24 : /*pMode->Format = WINED3DFMT_R8G8B8; break; */ /* 32bpp and 24bpp can be aliased for X */
case 32 : pMode - > Format = WINED3DFMT_A8R8G8B8 ; break ;
2005-07-13 16:15:54 +02:00
default :
2005-06-23 13:05:24 +02:00
FIXME ( " Unrecognized display mode format \n " ) ;
2006-10-11 03:51:13 +02:00
pMode - > Format = WINED3DFMT_UNKNOWN ;
2005-06-23 13:05:24 +02:00
}
TRACE ( " (%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s) \n " , This , pMode - > Width , pMode - > Height , pMode - > RefreshRate ,
pMode - > Format , debug_d3dformat ( pMode - > Format ) ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-06-23 13:05:24 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DSwapChainImpl_GetDevice ( IWineD3DSwapChain * iface , IWineD3DDevice * * ppDevice ) {
2005-07-13 16:15:54 +02:00
IWineD3DSwapChainImpl * This = ( IWineD3DSwapChainImpl * ) iface ;
2005-06-23 13:05:24 +02:00
* ppDevice = ( IWineD3DDevice * ) This - > wineD3DDevice ;
2005-07-13 16:15:54 +02:00
/* Note Calling this method will increase the internal reference count
2005-06-23 13:05:24 +02:00
on the IDirect3DDevice9 interface . */
IWineD3DDevice_AddRef ( * ppDevice ) ;
TRACE ( " (%p) : returning %p \n " , This , * ppDevice ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-06-23 13:05:24 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DSwapChainImpl_GetPresentParameters ( IWineD3DSwapChain * iface , WINED3DPRESENT_PARAMETERS * pPresentationParameters ) {
2005-06-23 13:05:24 +02:00
IWineD3DSwapChainImpl * This = ( IWineD3DSwapChainImpl * ) iface ;
2006-03-09 00:49:11 +01:00
TRACE ( " (%p) \n " , This ) ;
* pPresentationParameters - > BackBufferWidth = This - > presentParms . BackBufferWidth ;
* pPresentationParameters - > BackBufferHeight = This - > presentParms . BackBufferHeight ;
* pPresentationParameters - > BackBufferFormat = This - > presentParms . BackBufferFormat ;
* pPresentationParameters - > BackBufferCount = This - > presentParms . BackBufferCount ;
* pPresentationParameters - > MultiSampleType = This - > presentParms . MultiSampleType ;
* pPresentationParameters - > MultiSampleQuality = This - > presentParms . MultiSampleQuality ;
* pPresentationParameters - > SwapEffect = This - > presentParms . SwapEffect ;
* pPresentationParameters - > hDeviceWindow = This - > presentParms . hDeviceWindow ;
* pPresentationParameters - > Windowed = This - > presentParms . Windowed ;
* pPresentationParameters - > EnableAutoDepthStencil = This - > presentParms . EnableAutoDepthStencil ;
* pPresentationParameters - > Flags = This - > presentParms . Flags ;
* pPresentationParameters - > FullScreen_RefreshRateInHz = This - > presentParms . FullScreen_RefreshRateInHz ;
* pPresentationParameters - > PresentationInterval = This - > presentParms . PresentationInterval ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-06-23 13:05:24 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DSwapChainImpl_SetGammaRamp ( IWineD3DSwapChain * iface , DWORD Flags , CONST WINED3DGAMMARAMP * pRamp ) {
2005-06-23 13:05:24 +02:00
IWineD3DSwapChainImpl * This = ( IWineD3DSwapChainImpl * ) iface ;
HDC hDC ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : pRamp@%p flags(%d) \n " , This , pRamp , Flags ) ;
2005-06-23 13:05:24 +02:00
hDC = GetDC ( This - > win_handle ) ;
SetDeviceGammaRamp ( hDC , ( LPVOID ) pRamp ) ;
ReleaseDC ( This - > win_handle , hDC ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DSwapChainImpl_GetGammaRamp ( IWineD3DSwapChain * iface , WINED3DGAMMARAMP * pRamp ) {
2005-06-23 13:05:24 +02:00
IWineD3DSwapChainImpl * This = ( IWineD3DSwapChainImpl * ) iface ;
HDC hDC ;
TRACE ( " (%p) : pRamp@%p \n " , This , pRamp ) ;
hDC = GetDC ( This - > win_handle ) ;
GetDeviceGammaRamp ( hDC , pRamp ) ;
ReleaseDC ( This - > win_handle , hDC ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-07-13 16:15:54 +02:00
2005-06-23 13:05:24 +02:00
}
2006-12-14 15:47:59 +01:00
const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
2005-06-23 13:05:24 +02:00
{
2005-07-13 16:15:54 +02:00
/* IUnknown */
2005-06-23 13:05:24 +02:00
IWineD3DSwapChainImpl_QueryInterface ,
IWineD3DSwapChainImpl_AddRef ,
IWineD3DSwapChainImpl_Release ,
2005-07-13 16:15:54 +02:00
/* IWineD3DSwapChain */
2005-06-23 13:05:24 +02:00
IWineD3DSwapChainImpl_GetParent ,
2006-12-05 00:29:14 +01:00
IWineD3DSwapChainImpl_Destroy ,
2005-06-23 13:05:24 +02:00
IWineD3DSwapChainImpl_GetDevice ,
IWineD3DSwapChainImpl_Present ,
IWineD3DSwapChainImpl_GetFrontBufferData ,
IWineD3DSwapChainImpl_GetBackBuffer ,
IWineD3DSwapChainImpl_GetRasterStatus ,
IWineD3DSwapChainImpl_GetDisplayMode ,
IWineD3DSwapChainImpl_GetPresentParameters ,
IWineD3DSwapChainImpl_SetGammaRamp ,
2005-07-13 16:15:54 +02:00
IWineD3DSwapChainImpl_GetGammaRamp
2005-06-23 13:05:24 +02:00
} ;