Questions about PRIMARYSURFACE screen capture with DirectDraw
- From: Infinitesimal <fire.wisp@xxxxxxxxx>
- Date: Tue, 02 Oct 2007 01:03:38 -0000
I've implemented a screen capture function using DirectDraw which
obtains the video memory pointer by locking the primary surface (code
below) and I have some questions regarding the behaviour I am seeing.
First off, the memcpy that I am doing to move data off the surface's
data pointer is pretty slow -- a 1280x800 memcpy takes nearly 600ms.
Even a 300x300 window takes at least 100ms. Compared to GDI-based
bitblt this is very slow and compared to a standard memcpy pretty
painful....
Question: Is this due to my video hardware ? What is the memory
model of this operation ?
Another puzzle is that many different media player's (some Windows
Media Player content and other players like VNC) content still comes
up black. I had thought that by using the primary surface based
capture I was getting a hold of the direct video memory that the
screen is drawn on to before being painted by the video hardware.
Clearly I am missing something.
Question: What is the model for video sources and windows being
painted on the desktop and displayed via the video card ? Is there
actually a final video memory buffer that contains all of this that I
can get a pointer to somehow ? If so is it reasonably efficient ?
A kind of related oddity is a failure trying to capture a "magnifier"
type of control. Its a pretty simple GDI based control that creates a
window with the WS_EX_TOPMOST style. With the GDI-based method I
ended up having to enumerate through all the windows with this style
and blit it over the desktop screenshot in order to capture it
properly. Unfortunately I am seeing the same issue with the DirectDraw
approach in that its not appearing in the data copied from the primary
surface.
Again -- This behaviour suggests that the primary surface buffer isn't
a final video buffer that the desktop is being drawn into before
display... so what's the model and what am I missing ?
Thanks!
Code:
LPDIRECTDRAW7 lpDD;
LPDIRECTDRAWSURFACE7 lpDDSPrimary;
DirectDrawCreateEx(NULL, (LPVOID*)&lpDD, IID_IDirectDraw7, NULL);
lpDD->SetCooperativeLevel(NULL, DDSCL_NORMAL);
DDSURFACEDESC2 ddsd;
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL);
lpDDSPrimary->Lock(NULL, &ddsd, DDLOCK_READONLY, NULL);
// memcpy the data from 'ddsd.lpSurface'
lpDDSPrimary->Unlock(NULL);
.
- Follow-Ups:
- Re: Questions about PRIMARYSURFACE screen capture with DirectDraw
- From: Roman . Mikronika
- Re: Questions about PRIMARYSURFACE screen capture with DirectDraw
- Prev by Date: Re: D3DX and VS2005
- Next by Date: IDirect3DDevice9::Present speed
- Previous by thread: Re: D3DX and VS2005
- Next by thread: Re: Questions about PRIMARYSURFACE screen capture with DirectDraw
- Index(es):
Relevant Pages
|