diff --git a/dlls/ddraw/ddraw/dga.c b/dlls/ddraw/ddraw/dga.c index d8dcf41424d..d81254b5a8f 100644 --- a/dlls/ddraw/ddraw/dga.c +++ b/dlls/ddraw/ddraw/dga.c @@ -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); diff --git a/dlls/ddraw/ddraw/dga2.c b/dlls/ddraw/ddraw/dga2.c index a87bc006ee2..a661c595895 100644 --- a/dlls/ddraw/ddraw/dga2.c +++ b/dlls/ddraw/ddraw/dga2.c @@ -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); diff --git a/dlls/ddraw/ddraw/main.c b/dlls/ddraw/ddraw/main.c index e6a741cb754..45db5d76b5c 100644 --- a/dlls/ddraw/ddraw/main.c +++ b/dlls/ddraw/ddraw/main.c @@ -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; diff --git a/dlls/ddraw/ddraw/x11.c b/dlls/ddraw/ddraw/x11.c index 9375a1cc679..d5332167c3a 100644 --- a/dlls/ddraw/ddraw/x11.c +++ b/dlls/ddraw/ddraw/x11.c @@ -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) diff --git a/dlls/ddraw/dga.c b/dlls/ddraw/dga.c index c8ce82d3ebc..5fb7ffe8cb7 100644 --- a/dlls/ddraw/dga.c +++ b/dlls/ddraw/dga.c @@ -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; diff --git a/dlls/ddraw/dga2.c b/dlls/ddraw/dga2.c index 247cf0e1e38..e2eaa8e5638 100644 --- a/dlls/ddraw/dga2.c +++ b/dlls/ddraw/dga2.c @@ -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); diff --git a/dlls/ddraw/dga_private.h b/dlls/ddraw/dga_private.h index 5e606bcbb7b..b01b9c78fb6 100644 --- a/dlls/ddraw/dga_private.h +++ b/dlls/ddraw/dga_private.h @@ -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) ; diff --git a/dlls/ddraw/dsurface/dga.c b/dlls/ddraw/dsurface/dga.c index 3dc2aa592aa..d26d9d0b8bb 100644 --- a/dlls/ddraw/dsurface/dga.c +++ b/dlls/ddraw/dsurface/dga.c @@ -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, diff --git a/dlls/ddraw/dsurface/dga2.c b/dlls/ddraw/dsurface/dga2.c index f4f6d8dff5f..c5e9d3b5abf 100644 --- a/dlls/ddraw/dsurface/dga2.c +++ b/dlls/ddraw/dsurface/dga2.c @@ -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, diff --git a/dlls/ddraw/dsurface/main.c b/dlls/ddraw/dsurface/main.c index ad30436a6d7..5456115153f 100644 --- a/dlls/ddraw/dsurface/main.c +++ b/dlls/ddraw/dsurface/main.c @@ -15,6 +15,7 @@ #include #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); diff --git a/dlls/ddraw/dsurface/x11.c b/dlls/ddraw/dsurface/x11.c index f21e83f3d98..dd05e786d0f 100644 --- a/dlls/ddraw/dsurface/x11.c +++ b/dlls/ddraw/dsurface/x11.c @@ -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);