wined3d: Implement overlay flipping.

This commit is contained in:
Stefan Dösinger 2008-07-24 11:38:51 -05:00 committed by Alexandre Julliard
parent fad3f9ba98
commit 851dd7339e
4 changed files with 91 additions and 74 deletions

View File

@ -710,7 +710,7 @@ IDirectDrawSurfaceImpl_Flip(IDirectDrawSurface7 *iface,
/* Flip has to be called from a front buffer
* What about overlay surfaces, AFAIK they can flip too?
*/
if( !(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) )
if( !(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_OVERLAY)) )
return DDERR_INVALIDOBJECT; /* Unchecked */
EnterCriticalSection(&ddraw_cs);

View File

@ -2622,14 +2622,99 @@ HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *Mem) {
return WINED3D_OK;
}
void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) {
/* Flip the surface contents */
/* Flip the DC */
{
HDC tmp;
tmp = front->hDC;
front->hDC = back->hDC;
back->hDC = tmp;
}
/* Flip the DIBsection */
{
HBITMAP tmp;
BOOL hasDib = front->Flags & SFLAG_DIBSECTION;
tmp = front->dib.DIBsection;
front->dib.DIBsection = back->dib.DIBsection;
back->dib.DIBsection = tmp;
if(back->Flags & SFLAG_DIBSECTION) front->Flags |= SFLAG_DIBSECTION;
else front->Flags &= ~SFLAG_DIBSECTION;
if(hasDib) back->Flags |= SFLAG_DIBSECTION;
else back->Flags &= ~SFLAG_DIBSECTION;
}
/* 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;
tmp = front->resource.heapMemory;
front->resource.heapMemory = back->resource.heapMemory;
back->resource.heapMemory = tmp;
}
/* Flip the PBO */
{
GLuint tmp_pbo = front->pbo;
front->pbo = back->pbo;
back->pbo = tmp_pbo;
}
/* 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;
}
/* Flip the opengl texture */
{
glDescriptor tmp_desc = back->glDescription;
back->glDescription = front->glDescription;
front->glDescription = tmp_desc;
}
{
DWORD tmp_flags = back->Flags;
back->Flags = front->Flags;
front->Flags = tmp_flags;
}
}
static HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DSurface *override, DWORD Flags) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
IWineD3DSwapChainImpl *swapchain = NULL;
HRESULT hr;
TRACE("(%p)->(%p,%x)\n", This, override, Flags);
/* Flipping is only supported on RenderTargets */
if( !(This->resource.usage & WINED3DUSAGE_RENDERTARGET) ) return WINEDDERR_NOTFLIPPABLE;
/* Flipping is only supported on RenderTargets and overlays*/
if( !(This->resource.usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_OVERLAY)) ) {
WARN("Tried to flip a non-render target, non-overlay surface\n");
return WINEDDERR_NOTFLIPPABLE;
}
if(This->resource.usage & WINED3DUSAGE_OVERLAY) {
flip_surface(This, (IWineD3DSurfaceImpl *) override);
/* Update the overlay if it is visible */
if(This->overlay_dest) {
return IWineD3DSurface_DrawOverlay((IWineD3DSurface *) This);
} else {
return WINED3D_OK;
}
}
if(override) {
/* DDraw sets this for the X11 surfaces, so don't confuse the user

View File

@ -307,79 +307,9 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
/* 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 frontuptodate = front->Flags & SFLAG_INSYSMEM;
BOOL backuptodate = back->Flags & SFLAG_INSYSMEM;
if(front->resource.size == back->resource.size) {
/* Flip the DC */
{
HDC tmp;
tmp = front->hDC;
front->hDC = back->hDC;
back->hDC = tmp;
}
/* Flip the DIBsection */
{
HBITMAP tmp;
BOOL hasDib = front->Flags & SFLAG_DIBSECTION;
tmp = front->dib.DIBsection;
front->dib.DIBsection = back->dib.DIBsection;
back->dib.DIBsection = tmp;
if(back->Flags & SFLAG_DIBSECTION) front->Flags |= SFLAG_DIBSECTION;
else front->Flags &= ~SFLAG_DIBSECTION;
if(hasDib) back->Flags |= SFLAG_DIBSECTION;
else back->Flags &= ~SFLAG_DIBSECTION;
}
/* 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;
tmp = front->resource.heapMemory;
front->resource.heapMemory = back->resource.heapMemory;
back->resource.heapMemory = tmp;
}
/* Flip the PBO */
{
DWORD tmp_flags = front->Flags;
GLuint tmp_pbo = front->pbo;
front->pbo = back->pbo;
back->pbo = tmp_pbo;
if(back->Flags & SFLAG_PBO)
front->Flags |= SFLAG_PBO;
else
front->Flags &= ~SFLAG_PBO;
if(tmp_flags & SFLAG_PBO)
back->Flags |= SFLAG_PBO;
else
back->Flags &= ~SFLAG_PBO;
}
/* 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(frontuptodate) back->Flags |= SFLAG_INSYSMEM;
else back->Flags &= ~SFLAG_INSYSMEM;
if(backuptodate) front->Flags |= SFLAG_INSYSMEM;
else front->Flags &= ~SFLAG_INSYSMEM;
flip_surface(front, back);
} else {
IWineD3DSurface_ModifyLocation((IWineD3DSurface *) front, SFLAG_INDRAWABLE, TRUE);
IWineD3DSurface_ModifyLocation((IWineD3DSurface *) back, SFLAG_INDRAWABLE, TRUE);

View File

@ -1379,6 +1379,8 @@ void get_drawable_size_backbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT *
void get_drawable_size_pbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT *height);
void get_drawable_size_fbo(IWineD3DSurfaceImpl *This, UINT *width, UINT *height);
void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back);
/* Surface flags: */
#define SFLAG_OVERSIZE 0x00000001 /* Surface is bigger than gl size, blts only */
#define SFLAG_CONVERTED 0x00000002 /* Converted for color keying or Palettized */