Improved DIBSection support for IDirectDrawSurface::GetDC.

This commit is contained in:
Ove Kaaven 2000-05-14 22:53:51 +00:00 committed by Alexandre Julliard
parent 61e4283585
commit 270c9fb109
11 changed files with 118 additions and 42 deletions

View File

@ -409,9 +409,11 @@ static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 ifac
static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
ICOM_THIS(IDirectDraw2Impl,iface);
DDPRIVATE(This);
TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
if (!--(This->ref)) {
VirtualFree(ddpriv->fb_addr, 0, MEM_RELEASE);
TSXF86DGADirectVideo(display,DefaultScreen(display),0);
if (This->d.window && GetPropA(This->d.window,ddProp))
DestroyWindow(This->d.window);

View File

@ -146,6 +146,7 @@ static HRESULT WINAPI DGA2_IDirectDrawImpl_SetDisplayMode(
} else {
TRACE("Using mode number %d\n", mode_to_use);
VirtualFree(ddpriv->DGA.fb_addr, 0, MEM_RELEASE);
TSXDGACloseFramebuffer(display, DefaultScreen(display));
if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
@ -155,6 +156,7 @@ static HRESULT WINAPI DGA2_IDirectDrawImpl_SetDisplayMode(
/* Initialize the frame buffer */
_DGA2_Initialize_FrameBuffer(This, mode_to_use);
VirtualAlloc(ddpriv->DGA.fb_addr, ddpriv->DGA.fb_memsize, MEM_RESERVE|MEM_SYSTEM, PAGE_READWRITE);
/* Re-get (if necessary) the DGA events */
TSXDGASelectInput(display, DefaultScreen(display),
@ -226,6 +228,7 @@ static ULONG WINAPI DGA2_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
if (!--(This->ref)) {
TRACE("Closing access to the FrameBuffer\n");
VirtualFree(ddpriv->DGA.fb_addr, 0, MEM_RELEASE);
TSXDGACloseFramebuffer(display, DefaultScreen(display));
TRACE("Going back to normal X mode of operation\n");
TSXDGASetMode(display, DefaultScreen(display), 0);

View File

@ -547,10 +547,11 @@ HRESULT common_off_screen_CreateSurface(
ERR("Creates a surface that is already allocated : assuming this is an application bug !\n");
lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
lpdsf->s.surface_desc.u1.lpSurface =(LPBYTE)HeapAlloc(
GetProcessHeap(),
0,
lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp
lpdsf->s.surface_desc.u1.lpSurface =(LPBYTE)VirtualAlloc(
NULL,
lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE
);
lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
return DD_OK;

View File

@ -245,15 +245,18 @@ static XImage *create_xshmimage(
if (This->d.pixel_convert != NULL) {
int bpp = PFGET_BPP(This->d.directdraw_pixelformat);
lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
lpdsf->s.surface_desc.u1.lpSurface = VirtualAlloc(
NULL,
lpdsf->s.surface_desc.dwWidth *
lpdsf->s.surface_desc.dwHeight *
bpp
bpp,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE
);
} else
} else {
lpdsf->s.surface_desc.u1.lpSurface = img->data;
VirtualAlloc(img->data, img->bytes_per_line * img->height, MEM_RESERVE|MEM_SYSTEM, PAGE_READWRITE);
}
return img;
}
#endif /* HAVE_LIBXXSHM */
@ -271,12 +274,13 @@ static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lp
if (img == NULL) {
#endif
/* Allocate surface memory */
lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
lpdsf->s.surface_desc.u1.lpSurface = VirtualAlloc(
NULL,
lpdsf->s.surface_desc.dwWidth *
lpdsf->s.surface_desc.dwHeight *
bpp
bpp,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE
);
if (This->d.pixel_convert != NULL)

View File

@ -155,6 +155,9 @@ DGA_Create( LPDIRECTDRAW *lplpDD ) {
dgpriv->fb_memsize = memsize;
dgpriv->vpmask = 0;
/* Register frame buffer with the kernel, it is a potential DIB section */
VirtualAlloc(dgpriv->fb_addr, dgpriv->fb_memsize, MEM_RESERVE|MEM_SYSTEM, PAGE_READWRITE);
/* The cast is because DGA2's install colormap does not return a value whereas
DGA1 version does */
dgpriv->InstallColormap = (void (*)(Display *, int, Colormap)) TSXF86DGAInstallColormap;

View File

@ -156,6 +156,9 @@ DGA2_Create( LPDIRECTDRAW *lplpDD ) {
/* Initialize the frame buffer */
_DGA2_Initialize_FrameBuffer(ddraw, mode_to_use);
/* Register frame buffer with the kernel, it is as a potential DIB section */
VirtualAlloc(dgpriv->DGA.fb_addr, dgpriv->DGA.fb_memsize, MEM_RESERVE|MEM_SYSTEM, PAGE_READWRITE);
/* Set the input handling for relative mouse movements */
X11DRV_EVENT_SetInputMethod(X11DRV_INPUT_RELATIVE);

View File

@ -33,6 +33,8 @@ typedef struct dga_ds_private {
/* For usage in DGA2 */
extern ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) ;
extern HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal) ;
extern HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(LPDIRECTDRAWSURFACE4 iface,LPVOID surface) ;
extern HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface_no_VT(LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,
LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk) ;

View File

@ -22,6 +22,14 @@ DEFAULT_DEBUG_CHANNEL(ddraw);
#define DPPRIVATE(x) dga_dp_private *dppriv = ((dga_dp_private*)(x)->private)
#define DSPRIVATE(x) dga_ds_private *dspriv = ((dga_ds_private*)(x)->private)
static BYTE DGA_TouchSurface(LPDIRECTDRAWSURFACE4 iface)
{
ICOM_THIS(IDirectDrawSurface4Impl,iface);
/* if the DIB section is in GdiMod state, we must
* touch the surface to get any updates from the DIB */
return *(BYTE*)(This->s.surface_desc.u1.lpSurface);
}
/******************************************************************************
* IDirectDrawSurface methods
*
@ -41,6 +49,8 @@ HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
LPBYTE surf;
TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
DGA_TouchSurface(iface);
iflipto = _common_find_flipto(This,iflipto);
/* and flip! */
@ -107,7 +117,7 @@ ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
/* clear out of surface list */
if (ddpriv->fb_height == -1)
HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
VirtualFree(This->s.surface_desc.u1.lpSurface, 0, MEM_RELEASE);
else
ddpriv->vpmask &= ~(1<<(dspriv->fb_height/ddpriv->fb_height));
@ -124,6 +134,18 @@ ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
return S_OK;
}
HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
LPDIRECTDRAWSURFACE4 iface,LPVOID surface
) {
ICOM_THIS(IDirectDrawSurface4Impl,iface);
TRACE("(%p)->Unlock(%p)\n",This,surface);
/* in case this was called from ReleaseDC */
DGA_TouchSurface(iface);
return DD_OK;
}
ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
@ -159,7 +181,7 @@ ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
IDirectDrawSurface4Impl_SetColorKey,
IDirectDrawSurface4Impl_SetOverlayPosition,
DGA_IDirectDrawSurface4Impl_SetPalette,
IDirectDrawSurface4Impl_Unlock,
DGA_IDirectDrawSurface4Impl_Unlock,
IDirectDrawSurface4Impl_UpdateOverlay,
IDirectDrawSurface4Impl_UpdateOverlayDisplay,
IDirectDrawSurface4Impl_UpdateOverlayZOrder,

View File

@ -21,6 +21,14 @@ DEFAULT_DEBUG_CHANNEL(ddraw);
#define DPPRIVATE(x) dga2_dp_private *dppriv = ((dga2_dp_private*)(x)->private)
#define DSPRIVATE(x) dga2_ds_private *dspriv = ((dga2_ds_private*)(x)->private)
static BYTE DGA2_TouchSurface(LPDIRECTDRAWSURFACE4 iface)
{
ICOM_THIS(IDirectDrawSurface4Impl,iface);
/* if the DIB section is in GdiMod state, we must
* touch the surface to get any updates from the DIB */
return *(BYTE*)(This->s.surface_desc.u1.lpSurface);
}
HRESULT WINAPI DGA2_IDirectDrawSurface4Impl_Flip(
LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
) {
@ -32,6 +40,8 @@ HRESULT WINAPI DGA2_IDirectDrawSurface4Impl_Flip(
LPBYTE surf;
TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
DGA2_TouchSurface(iface);
iflipto = _common_find_flipto(This,iflipto);
/* and flip! */
@ -94,7 +104,7 @@ ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt =
IDirectDrawSurface4Impl_SetColorKey,
IDirectDrawSurface4Impl_SetOverlayPosition,
DGA_IDirectDrawSurface4Impl_SetPalette,
IDirectDrawSurface4Impl_Unlock,
DGA_IDirectDrawSurface4Impl_Unlock,
IDirectDrawSurface4Impl_UpdateOverlay,
IDirectDrawSurface4Impl_UpdateOverlayDisplay,
IDirectDrawSurface4Impl_UpdateOverlayZOrder,

View File

@ -15,6 +15,7 @@
#include <stdio.h>
#include "debugtools.h"
#include "bitmap.h"
#include "ddraw_private.h"
DEFAULT_DEBUG_CHANNEL(ddraw);
@ -675,8 +676,9 @@ HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lph
DDSURFACEDESC desc;
BITMAPINFO *b_info;
UINT usage;
HDC ddc;
FIXME("(%p)->GetDC(%p)\n",This,lphdc);
TRACE("(%p)->GetDC(%p)\n",This,lphdc);
/* Creates a DIB Section of the same size / format as the surface */
IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
@ -702,7 +704,7 @@ HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lph
b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
b_info->bmiHeader.biWidth = desc.dwWidth;
b_info->bmiHeader.biHeight = desc.dwHeight;
b_info->bmiHeader.biHeight = -desc.dwHeight;
b_info->bmiHeader.biPlanes = 1;
b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
#if 0
@ -760,16 +762,19 @@ HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lph
}
break;
}
This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
ddc = CreateDCA("DISPLAY",NULL,NULL,NULL);
This->s.DIBsection = ddc ? DIB_CreateDIBSection(ddc,
b_info,
usage,
&(This->s.bitmap_data),
0,
0
);
EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
(DWORD)desc.u1.lpSurface,
desc.lPitch
) : 0;
if (!This->s.DIBsection) {
ERR("CreateDIBSection failed!\n");
if (ddc) DeleteDC(ddc);
HeapFree(GetProcessHeap(), 0, b_info);
return E_FAIL;
}
TRACE("DIBSection at : %p\n", This->s.bitmap_data);
@ -778,19 +783,26 @@ HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lph
HeapFree(GetProcessHeap(), 0, b_info);
/* Create the DC */
This->s.hdc = CreateCompatibleDC(0);
This->s.hdc = CreateCompatibleDC(ddc);
This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
if (ddc) DeleteDC(ddc);
}
/* Copy our surface in the DIB section */
if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
else
/* TODO */
FIXME("This case has to be done :/\n");
if (This->s.bitmap_data != desc.u1.lpSurface) {
FIXME("DIBSection not created for frame buffer, reverting to old code\n");
/* Copy our surface in the DIB section */
if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
else
/* TODO */
FIXME("This case has to be done :/\n");
}
TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
*lphdc = This->s.hdc;
if (lphdc) {
TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
*lphdc = This->s.hdc;
}
return DD_OK;
}
@ -798,14 +810,17 @@ HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lph
HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
ICOM_THIS(IDirectDrawSurface4Impl,iface);
FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
/* Copy the DIB section to our surface */
if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
} else {
/* TODO */
FIXME("This case has to be done :/\n");
TRACE("(%p)->(0x%08lx)\n",This,(long)hdc);
if (This->s.bitmap_data != This->s.surface_desc.u1.lpSurface) {
TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
/* Copy the DIB section to our surface */
if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
} else {
/* TODO */
FIXME("This case has to be done :/\n");
}
}
/* Unlock the surface */
IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);

View File

@ -30,6 +30,12 @@ DEFAULT_DEBUG_CHANNEL(ddraw);
#define DPPRIVATE(x) x11_dp_private *dppriv = ((x11_dp_private*)(x)->private)
#define DSPRIVATE(x) x11_ds_private *dspriv = ((x11_ds_private*)(x)->private)
static BYTE Xlib_TouchData(LPVOID data)
{
/* this is a function so it doesn't get optimized out */
return *(BYTE*)data;
}
/******************************************************************************
* IDirectDrawSurface methods
*
@ -126,6 +132,7 @@ HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Lock(
X11DRV_EVENT_WaitShmCompletions( ddpriv->drawable );
}
#endif
return DD_OK;
}
@ -140,6 +147,9 @@ static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
This->s.surface_desc.lPitch,
This->s.palette);
/* if the DIB section is in GdiMod state, we must
* touch the surface to get any updates from the DIB */
Xlib_TouchData(dspriv->image->data);
#ifdef HAVE_LIBXXSHM
if (ddpriv->xshm_active) {
/*
@ -321,7 +331,7 @@ ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
if (dspriv->image != NULL) {
if (This->s.ddraw->d.pixel_convert != NULL) {
/* In pixel conversion mode, there are 2 buffers to release. */
HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
VirtualFree(This->s.surface_desc.u1.lpSurface, 0, MEM_RELEASE);
#ifdef HAVE_LIBXXSHM
if (ddpriv->xshm_active) {
@ -340,19 +350,20 @@ ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
#ifdef HAVE_LIBXXSHM
if (ddpriv->xshm_active) {
VirtualFree(dspriv->image->data, 0, MEM_RELEASE);
TSXShmDetach(display, &(dspriv->shminfo));
TSXDestroyImage(dspriv->image);
shmdt(dspriv->shminfo.shmaddr);
} else
#endif
{
HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
VirtualFree(This->s.surface_desc.u1.lpSurface, 0, MEM_RELEASE);
TSXDestroyImage(dspriv->image);
}
}
dspriv->image = 0;
} else
HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
VirtualFree(This->s.surface_desc.u1.lpSurface, 0, MEM_RELEASE);
if (This->s.palette)
IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);