Cygwin/X: Refactor framebuffer allocation/release in drawing engines

Refactor the drawing engines so we can explicitly allocate and release the framebuffer for a screen

Move the setting of dwPaddedWidth into the DDNL engine, so it is updated when the framebuffer changes size

Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
Reviewed-by: Colin Harrison <colin.harrison@virgin.net>
Tested-by: Colin Harrison <colin.harrison@virgin.net>
This commit is contained in:
Jon TURNEY 2009-10-13 14:47:33 +01:00
parent 708d0b9781
commit df51800127
7 changed files with 229 additions and 143 deletions

View File

@ -276,8 +276,12 @@ static Atom func (void) { \
typedef Bool (*winAllocateFBProcPtr)(ScreenPtr);
typedef void (*winFreeFBProcPtr)(ScreenPtr);
typedef void (*winShadowUpdateProcPtr)(ScreenPtr, shadowBufPtr);
typedef Bool (*winInitScreenProcPtr)(ScreenPtr);
typedef Bool (*winCloseScreenProcPtr)(int, ScreenPtr);
typedef Bool (*winInitVisualsProcPtr)(ScreenPtr);
@ -549,7 +553,9 @@ typedef struct _winPrivScreenRec
/* Engine specific functions */
winAllocateFBProcPtr pwinAllocateFB;
winFreeFBProcPtr pwinFreeFB;
winShadowUpdateProcPtr pwinShadowUpdate;
winInitScreenProcPtr pwinInitScreen;
winCloseScreenProcPtr pwinCloseScreen;
winInitVisualsProcPtr pwinInitVisuals;
winAdjustVideoModeProcPtr pwinAdjustVideoMode;

View File

@ -92,6 +92,18 @@ winAllocateFBNativeGDI (ScreenPtr pScreen)
return TRUE;
}
static void
winFreeFBNativeGDI (ScreenPtr pScreen)
{
FatalError ("winFreeFBNativeGDI\n");
}
static Bool
winInitScreenNativeGDI(ScreenPtr pScreen)
{
FatalError ("winInitScreenNativeGDI\n");
}
/*
* We wrap whatever CloseScreen procedure was specified by fb;
@ -506,7 +518,9 @@ winSetEngineFunctionsNativeGDI (ScreenPtr pScreen)
/* Set our pointers */
pScreenPriv->pwinAllocateFB = winAllocateFBNativeGDI;
pScreenPriv->pwinFreeFB = winFreeFBNativeGDI;
pScreenPriv->pwinShadowUpdate = winShadowUpdateNativeGDI;
pScreenPriv->pwinInitScreen = winInitScreenNativeGDI;
pScreenPriv->pwinCloseScreen = winCloseScreenNativeGDI;
pScreenPriv->pwinInitVisuals = winInitVisualsNativeGDI;
pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeNativeGDI;

View File

@ -233,6 +233,45 @@ winAllocateFBPrimaryDD (ScreenPtr pScreen)
return TRUE;
}
static void
winFreeFBPrimaryDD (ScreenPtr pScreen)
{
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
/* Free the offscreen surface, if there is one */
if (pScreenPriv->pddsOffscreen)
{
IDirectDrawSurface2_Unlock (pScreenPriv->pddsOffscreen, NULL);
IDirectDrawSurface2_Release (pScreenPriv->pddsOffscreen);
pScreenPriv->pddsOffscreen = NULL;
}
/* Release the primary surface, if there is one */
if (pScreenPriv->pddsPrimary)
{
IDirectDrawSurface2_Unlock (pScreenPriv->pddsPrimary, NULL);
IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
pScreenPriv->pddsPrimary = NULL;
}
/* Free the DirectDraw object, if there is one */
if (pScreenPriv->pdd)
{
IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd);
IDirectDraw2_Release (pScreenPriv->pdd);
pScreenPriv->pdd = NULL;
}
/* Invalidate the ScreenInfo's fb pointer */
pScreenInfo->pfb = NULL;
}
static Bool
winInitScreenPrimaryDD(ScreenPtr pScreen)
{
return winAllocateFBPrimaryDD(pScreen);
}
/*
* Call the wrapped CloseScreen function.
@ -260,29 +299,7 @@ winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen)
/* Delete the window property */
RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);
/* Free the offscreen surface, if there is one */
if (pScreenPriv->pddsOffscreen)
{
IDirectDrawSurface2_Unlock (pScreenPriv->pddsOffscreen, NULL);
IDirectDrawSurface2_Release (pScreenPriv->pddsOffscreen);
pScreenPriv->pddsOffscreen = NULL;
}
/* Release the primary surface, if there is one */
if (pScreenPriv->pddsPrimary)
{
IDirectDrawSurface2_Unlock (pScreenPriv->pddsPrimary, NULL);
IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
pScreenPriv->pddsPrimary = NULL;
}
/* Free the DirectDraw object, if there is one */
if (pScreenPriv->pdd)
{
IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd);
IDirectDraw2_Release (pScreenPriv->pdd);
pScreenPriv->pdd = NULL;
}
winFreeFBPrimaryDD(pScreen);
/* Delete tray icon, if we have one */
if (!pScreenInfo->fNoTrayIcon)
@ -305,9 +322,6 @@ winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen)
/* Kill our screeninfo's pointer to the screen */
pScreenInfo->pScreen = NULL;
/* Invalidate the ScreenInfo's fb pointer */
pScreenInfo->pfb = NULL;
/* Free the screen privates for this screen */
free ((pointer) pScreenPriv);
@ -653,8 +667,9 @@ winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen)
/* Set our pointers */
pScreenPriv->pwinAllocateFB = winAllocateFBPrimaryDD;
pScreenPriv->pwinShadowUpdate
= (winShadowUpdateProcPtr) (void (*)(void))NoopDDA;
pScreenPriv->pwinFreeFB = winFreeFBPrimaryDD;
pScreenPriv->pwinShadowUpdate = (winShadowUpdateProcPtr) (void (*)(void))NoopDDA;
pScreenPriv->pwinInitScreen = winInitScreenPrimaryDD;
pScreenPriv->pwinCloseScreen = winCloseScreenPrimaryDD;
pScreenPriv->pwinInitVisuals = winInitVisualsPrimaryDD;
pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModePrimaryDD;
@ -663,8 +678,7 @@ winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen)
else
pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
pScreenPriv->pwinBltExposedRegions
= (winBltExposedRegionsProcPtr) (void (*)(void))NoopDDA;
pScreenPriv->pwinBltExposedRegions = (winBltExposedRegionsProcPtr) (void (*)(void))NoopDDA;
pScreenPriv->pwinActivateApp = winActivateAppPrimaryDD;
pScreenPriv->pwinRedrawScreen = NULL;
pScreenPriv->pwinRealizeInstalledPalette = NULL;

View File

@ -210,10 +210,6 @@ winScreenInit (int index,
/* Clear the visuals list */
miClearVisualTypes ();
/* Set the padded screen width */
pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth,
pScreenInfo->dwBPP);
/* Call the engine dependent screen initialization procedure */
if (!((*pScreenPriv->pwinFinishScreenInit) (index, pScreen, argc, argv)))
@ -279,7 +275,7 @@ winFinishScreenInitFB (int index,
#endif
/* Create framebuffer */
if (!(*pScreenPriv->pwinAllocateFB) (pScreen))
if (!(*pScreenPriv->pwinInitScreen) (pScreen))
{
ErrorF ("winFinishScreenInitFB - Could not allocate framebuffer\n");
return FALSE;

View File

@ -239,9 +239,6 @@ winAllocateFBShadowDD (ScreenPtr pScreen)
winDebug ("winAllocateFBShadowDD - Created a clipper\n");
#endif
/* Get a device context for the screen */
pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
/* Attach the clipper to our display window */
ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary,
0,
@ -503,6 +500,57 @@ winAllocateFBShadowDD (ScreenPtr pScreen)
return TRUE;
}
static void
winFreeFBShadowDD (ScreenPtr pScreen)
{
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
/* Free the shadow surface, if there is one */
if (pScreenPriv->pddsShadow)
{
IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL);
IDirectDrawSurface2_Release (pScreenPriv->pddsShadow);
pScreenPriv->pddsShadow = NULL;
}
/* Detach the clipper from the primary surface and release the clipper. */
if (pScreenPriv->pddcPrimary)
{
/* Detach the clipper */
IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary,
NULL);
/* Release the clipper object */
IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
pScreenPriv->pddcPrimary = NULL;
}
/* Release the primary surface, if there is one */
if (pScreenPriv->pddsPrimary)
{
IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
pScreenPriv->pddsPrimary = NULL;
}
/* Free the DirectDraw2 object, if there is one */
if (pScreenPriv->pdd2)
{
IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd2);
IDirectDraw2_Release (pScreenPriv->pdd2);
pScreenPriv->pdd2 = NULL;
}
/* Free the DirectDraw object, if there is one */
if (pScreenPriv->pdd)
{
IDirectDraw_Release (pScreenPriv->pdd);
pScreenPriv->pdd = NULL;
}
/* Invalidate the ScreenInfo's fb pointer */
pScreenInfo->pfb = NULL;
}
/*
* Transfer the damaged regions of the shadow framebuffer to the display.
@ -666,6 +714,16 @@ winShadowUpdateDD (ScreenPtr pScreen,
}
}
static Bool
winInitScreenShadowDD (ScreenPtr pScreen)
{
winScreenPriv(pScreen);
/* Get a device context for the screen */
pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
return winAllocateFBShadowDD(pScreen);
}
/*
* Call the wrapped CloseScreen function.
@ -692,58 +750,18 @@ winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen)
WIN_UNWRAP(CloseScreen);
fReturn = (*pScreen->CloseScreen) (nIndex, pScreen);
winFreeFBShadowDD(pScreen);
/* Free the screen DC */
ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
/* Delete the window property */
RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);
/* Free the shadow surface, if there is one */
if (pScreenPriv->pddsShadow)
{
IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL);
IDirectDrawSurface2_Release (pScreenPriv->pddsShadow);
pScreenPriv->pddsShadow = NULL;
}
/* Detach the clipper from the primary surface and release the clipper. */
if (pScreenPriv->pddcPrimary)
{
/* Detach the clipper */
IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary,
NULL);
/* Release the clipper object */
IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
pScreenPriv->pddcPrimary = NULL;
}
/* Release the primary surface, if there is one */
if (pScreenPriv->pddsPrimary)
{
IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
pScreenPriv->pddsPrimary = NULL;
}
/* Free the DirectDraw2 object, if there is one */
if (pScreenPriv->pdd2)
{
IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd2);
IDirectDraw2_Release (pScreenPriv->pdd2);
pScreenPriv->pdd2 = NULL;
}
/* Free the DirectDraw object, if there is one */
if (pScreenPriv->pdd)
{
IDirectDraw_Release (pScreenPriv->pdd);
pScreenPriv->pdd = NULL;
}
/* Delete tray icon, if we have one */
if (!pScreenInfo->fNoTrayIcon)
winDeleteNotifyIcon (pScreenPriv);
/* Free the exit confirmation dialog box, if it exists */
if (g_hDlgExit != NULL)
{
@ -766,9 +784,6 @@ winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen)
/* Kill our screeninfo's pointer to the screen */
pScreenInfo->pScreen = NULL;
/* Invalidate the ScreenInfo's fb pointer */
pScreenInfo->pfb = NULL;
/* Free the screen privates for this screen */
free ((pointer) pScreenPriv);
@ -1370,7 +1385,9 @@ winSetEngineFunctionsShadowDD (ScreenPtr pScreen)
/* Set our pointers */
pScreenPriv->pwinAllocateFB = winAllocateFBShadowDD;
pScreenPriv->pwinFreeFB = winFreeFBShadowDD;
pScreenPriv->pwinShadowUpdate = winShadowUpdateDD;
pScreenPriv->pwinInitScreen = winInitScreenShadowDD;
pScreenPriv->pwinCloseScreen = winCloseScreenShadowDD;
pScreenPriv->pwinInitVisuals = winInitVisualsShadowDD;
pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDD;

View File

@ -237,6 +237,10 @@ winAllocateFBShadowDDNL (ScreenPtr pScreen)
pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwDepth);
#endif
/* Set the padded screen width */
pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth,
pScreenInfo->dwBPP);
/* Allocate memory for our shadow surface */
lpSurface = malloc (pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight);
if (lpSurface == NULL)
@ -266,9 +270,6 @@ winAllocateFBShadowDDNL (ScreenPtr pScreen)
winDebug ("winAllocateFBShadowDDNL - Created a clipper\n");
#endif
/* Get a device context for the screen */
pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
/* Attach the clipper to our display window */
ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary,
0,
@ -530,6 +531,58 @@ winAllocateFBShadowDDNL (ScreenPtr pScreen)
return TRUE;
}
static void
winFreeFBShadowDDNL(ScreenPtr pScreen)
{
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
/* Free the shadow surface, if there is one */
if (pScreenPriv->pddsShadow4)
{
IDirectDrawSurface4_Release (pScreenPriv->pddsShadow4);
free (pScreenInfo->pfb);
pScreenInfo->pfb = NULL;
pScreenPriv->pddsShadow4 = NULL;
}
/* Detach the clipper from the primary surface and release the clipper. */
if (pScreenPriv->pddcPrimary)
{
/* Detach the clipper */
IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4,
NULL);
/* Release the clipper object */
IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
pScreenPriv->pddcPrimary = NULL;
}
/* Release the primary surface, if there is one */
if (pScreenPriv->pddsPrimary4)
{
IDirectDrawSurface4_Release (pScreenPriv->pddsPrimary4);
pScreenPriv->pddsPrimary4 = NULL;
}
/* Free the DirectDraw4 object, if there is one */
if (pScreenPriv->pdd4)
{
IDirectDraw4_RestoreDisplayMode (pScreenPriv->pdd4);
IDirectDraw4_Release (pScreenPriv->pdd4);
pScreenPriv->pdd4 = NULL;
}
/* Free the DirectDraw object, if there is one */
if (pScreenPriv->pdd)
{
IDirectDraw_Release (pScreenPriv->pdd);
pScreenPriv->pdd = NULL;
}
/* Invalidate the ScreenInfo's fb pointer */
pScreenInfo->pfb = NULL;
}
#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
/*
@ -720,6 +773,16 @@ winShadowUpdateDDNL (ScreenPtr pScreen,
}
}
static Bool
winInitScreenShadowDDNL(ScreenPtr pScreen)
{
winScreenPriv(pScreen);
/* Get a device context for the screen */
pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
return winAllocateFBShadowDDNL(pScreen);
}
/*
* Call the wrapped CloseScreen function.
@ -746,55 +809,14 @@ winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen)
WIN_UNWRAP(CloseScreen);
fReturn = (*pScreen->CloseScreen) (nIndex, pScreen);
winFreeFBShadowDDNL(pScreen);
/* Free the screen DC */
ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
/* Delete the window property */
RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);
/* Free the shadow surface, if there is one */
if (pScreenPriv->pddsShadow4)
{
IDirectDrawSurface4_Release (pScreenPriv->pddsShadow4);
free (pScreenInfo->pfb);
pScreenInfo->pfb = NULL;
pScreenPriv->pddsShadow4 = NULL;
}
/* Detach the clipper from the primary surface and release the clipper. */
if (pScreenPriv->pddcPrimary)
{
/* Detach the clipper */
IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4,
NULL);
/* Release the clipper object */
IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
pScreenPriv->pddcPrimary = NULL;
}
/* Release the primary surface, if there is one */
if (pScreenPriv->pddsPrimary4)
{
IDirectDrawSurface4_Release (pScreenPriv->pddsPrimary4);
pScreenPriv->pddsPrimary4 = NULL;
}
/* Free the DirectDraw4 object, if there is one */
if (pScreenPriv->pdd4)
{
IDirectDraw4_RestoreDisplayMode (pScreenPriv->pdd4);
IDirectDraw4_Release (pScreenPriv->pdd4);
pScreenPriv->pdd4 = NULL;
}
/* Free the DirectDraw object, if there is one */
if (pScreenPriv->pdd)
{
IDirectDraw_Release (pScreenPriv->pdd);
pScreenPriv->pdd = NULL;
}
/* Delete tray icon, if we have one */
if (!pScreenInfo->fNoTrayIcon)
winDeleteNotifyIcon (pScreenPriv);
@ -821,9 +843,6 @@ winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen)
/* Kill our screeninfo's pointer to the screen */
pScreenInfo->pScreen = NULL;
/* Invalidate the ScreenInfo's fb pointer */
pScreenInfo->pfb = NULL;
/* Free the screen privates for this screen */
free ((pointer) pScreenPriv);
@ -1382,7 +1401,9 @@ winSetEngineFunctionsShadowDDNL (ScreenPtr pScreen)
/* Set our pointers */
pScreenPriv->pwinAllocateFB = winAllocateFBShadowDDNL;
pScreenPriv->pwinFreeFB = winFreeFBShadowDDNL;
pScreenPriv->pwinShadowUpdate = winShadowUpdateDDNL;
pScreenPriv->pwinInitScreen = winInitScreenShadowDDNL;
pScreenPriv->pwinCloseScreen = winCloseScreenShadowDDNL;
pScreenPriv->pwinInitVisuals = winInitVisualsShadowDDNL;
pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDDNL;

View File

@ -342,10 +342,6 @@ winAllocateFBShadowGDI (ScreenPtr pScreen)
DIBSECTION dibsection;
Bool fReturn = TRUE;
/* Get device contexts for the screen and shadow bitmap */
pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
pScreenPriv->hdcShadow = CreateCompatibleDC (pScreenPriv->hdcScreen);
/* Allocate bitmap info header */
pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
+ 256 * sizeof (RGBQUAD));
@ -477,6 +473,18 @@ winAllocateFBShadowGDI (ScreenPtr pScreen)
return fReturn;
}
static void
winFreeFBShadowGDI (ScreenPtr pScreen)
{
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
/* Free the shadow bitmap */
DeleteObject (pScreenPriv->hbmpShadow);
/* Invalidate the ScreenInfo's fb pointer */
pScreenInfo->pfb = NULL;
}
/*
* Blit the damaged regions of the shadow fb to the screen
@ -602,6 +610,18 @@ winShadowUpdateGDI (ScreenPtr pScreen,
}
static Bool
winInitScreenShadowGDI (ScreenPtr pScreen)
{
winScreenPriv(pScreen);
/* Get device contexts for the screen and shadow bitmap */
pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
pScreenPriv->hdcShadow = CreateCompatibleDC (pScreenPriv->hdcScreen);
return winAllocateFBShadowGDI(pScreen);
}
/* See Porting Layer Definition - p. 33 */
/*
* We wrap whatever CloseScreen procedure was specified by fb;
@ -632,9 +652,8 @@ winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen)
/* Free the shadow DC; which allows the bitmap to be freed */
DeleteDC (pScreenPriv->hdcShadow);
/* Free the shadow bitmap */
DeleteObject (pScreenPriv->hbmpShadow);
winFreeFBShadowGDI(pScreen);
/* Free the screen DC */
ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
@ -665,9 +684,6 @@ winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen)
/* Invalidate our screeninfo's pointer to the screen */
pScreenInfo->pScreen = NULL;
/* Invalidate the ScreenInfo's fb pointer */
pScreenInfo->pfb = NULL;
/* Free the screen privates for this screen */
free ((pointer) pScreenPriv);
@ -1235,7 +1251,9 @@ winSetEngineFunctionsShadowGDI (ScreenPtr pScreen)
/* Set our pointers */
pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI;
pScreenPriv->pwinFreeFB = winFreeFBShadowGDI;
pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI;
pScreenPriv->pwinInitScreen = winInitScreenShadowGDI;
pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI;
pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI;
pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI;