We have a piece of software that is programmed against the DirextX 7 SDK (that is, the code uses LPDIRECTDRAWSURFACE7 , etc.) and works in full screen mode. The main task is to place something on the screen in response to external triggers in a reliable way. This works very well in Windows XP: bsically, the software waits for some kind of trigger and at startup creates a new frame, places it in the backbuffer, and then tells DX about the translation of the buffers. The result is an approximate delay between the trigger and when the frame is effectively displayed on the screen, it depends on the video card and drivers, 3 frames or 50 ms for a 60 Hz screen. This is tested on various systems, all running NVidia cards. On some systems with higher end cards, we get even 2 frames.
However, when starting the same software in Windows 7 (without any other installed software), we will not be able to get less than 5 frames. A value somewhere in the OS pipeline or the driver or both have 2 additional frames, which is almost unacceptable for the application. We tried to disable the composition aero / desktop / different driver versions / different video cards, but to no avail.
- Where is it from? is this documented somewhere?
- Is there an easy way to fix it? I know that DirectX 7 is deprecated, but when updating to compile again a later version can be a ton of work, so another type of fix will be nice. Maybe some flag that can be set in the code?
edit the code here that seems relevant:
Creating front / back surfaces:
ddraw7->SetCooperativeLevel( GetSafeHwnd(), DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_MULTITHREADED ) DDSURFACEDESC2 desc; ZeroMemory( &desc, sizeof(desc) ); desc.dwSize = sizeof( desc ); desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM; desc.dwBackBufferCount = 1; ddraw7->CreateSurface( &desc, &primsurf, 0 ) DDSCAPS2 surfcaps; ZeroMemory( &surfcaps,sizeof( surfcaps ) ); surfcaps.dwCaps = DDSCAPS_BACKBUFFER; primsurf->GetAttachedSurface( &surfcaps, &backsurf );
Creating surfaces used to render frames before drawing them:
DDSURFACEDESC2 desc; ZeroMemory( &desc, sizeof(desc) ); desc.dwSize = sizeof(desc); desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS ; desc.dwWidth = w; desc.dwHeight = h; desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; desc.ddpfPixelFormat.dwSize = sizeof( DDPIXELFORMAT ); desc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8; LPDIRECTDRAWSURFACE7 surf; HRESULT r=ddraw7->CreateSurface( &desc, &surf, 0 )
Rendering loop in OnIdle :