Cygwin/X: Deal with RANDR depth changes correctly in ShadowGDI drawing engine

Make ShadowGDI drawing engine only change the size of the screen
pixmap/shadow framebuffer on an RANDR change, not the bpp/depth
as well.

The server requires the screen pixmap's depth to be invariant.

Other drawing engines aren't quite as affected by this issue as
they won't draw to the display, if it has changed colour depth,
but probably still need some attention.

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 2010-08-31 10:13:01 +01:00
parent 8b22f83113
commit 3f7339a7c5
4 changed files with 60 additions and 70 deletions

View File

@ -504,7 +504,8 @@ typedef struct _winPrivScreenRec
HDC hdcScreen;
HDC hdcShadow;
HWND hwndScreen;
BITMAPINFOHEADER *pbmih;
/* Privates used by shadow fb and primary fb DirectDraw servers */
LPDIRECTDRAW pdd;
LPDIRECTDRAWSURFACE2 pddsPrimary;

View File

@ -126,7 +126,7 @@ winScreenInit (int index,
return FALSE;
}
/* Adjust the video mode for our engine type */
/* Horribly misnamed function: Allow engine to adjust BPP for screen */
if (!(*pScreenPriv->pwinAdjustVideoMode) (pScreen))
{
ErrorF ("winScreenInit - winAdjustVideoMode () failed\n");
@ -269,7 +269,8 @@ winFinishScreenInitFB (int index,
}
/*
* Grab the number of bits that are used to represent color in each pixel.
* Calculate the number of bits that are used to represent color in each pixel,
* the color depth for the screen
*/
if (pScreenInfo->dwBPP == 8)
pScreenInfo->dwDepth = 8;
@ -277,7 +278,7 @@ winFinishScreenInitFB (int index,
pScreenInfo->dwDepth = winCountBits (pScreenPriv->dwRedMask)
+ winCountBits (pScreenPriv->dwGreenMask)
+ winCountBits (pScreenPriv->dwBlueMask);
winErrorFVerb (2, "winFinishScreenInitFB - Masks: %08x %08x %08x\n",
(unsigned int) pScreenPriv->dwRedMask,
(unsigned int) pScreenPriv->dwGreenMask,

View File

@ -338,33 +338,20 @@ winAllocateFBShadowGDI (ScreenPtr pScreen)
{
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
BITMAPINFOHEADER *pbmih = NULL;
DIBSECTION dibsection;
Bool fReturn = TRUE;
/* Allocate bitmap info header */
pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
+ 256 * sizeof (RGBQUAD));
if (pbmih == NULL)
{
ErrorF ("winAllocateFBShadowGDI - malloc () failed\n");
return FALSE;
}
/* Query the screen format */
fReturn = winQueryScreenDIBFormat (pScreen, pbmih);
/* Describe shadow bitmap to be created */
pbmih->biWidth = pScreenInfo->dwWidth;
pbmih->biHeight = -pScreenInfo->dwHeight;
pScreenPriv->pbmih->biWidth = pScreenInfo->dwWidth;
pScreenPriv->pbmih->biHeight = -pScreenInfo->dwHeight;
ErrorF ("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d "
"depth: %d\n",
(int) pbmih->biWidth, (int) -pbmih->biHeight, pbmih->biBitCount);
(int) pScreenPriv->pbmih->biWidth, (int) -pScreenPriv->pbmih->biHeight, pScreenPriv->pbmih->biBitCount);
/* Create a DI shadow bitmap with a bit pointer */
pScreenPriv->hbmpShadow = CreateDIBSection (pScreenPriv->hdcScreen,
(BITMAPINFO *) pbmih,
(BITMAPINFO *) pScreenPriv->pbmih,
DIB_RGB_COLORS,
(VOID**) &pScreenInfo->pfb,
NULL,
@ -445,13 +432,6 @@ winAllocateFBShadowGDI (ScreenPtr pScreen)
(int) pScreenInfo->dwStride);
#endif
/* Determine our color masks */
if (!winQueryRGBBitsAndMasks (pScreen))
{
ErrorF ("winAllocateFBShadowGDI - winQueryRGBBitsAndMasks failed\n");
return FALSE;
}
#ifdef XWIN_MULTIWINDOW
/* Redraw all windows */
if (pScreenInfo->fMultiWindow)
@ -607,6 +587,29 @@ winInitScreenShadowGDI (ScreenPtr pScreen)
pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
pScreenPriv->hdcShadow = CreateCompatibleDC (pScreenPriv->hdcScreen);
/* Allocate bitmap info header */
pScreenPriv->pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
+ 256 * sizeof (RGBQUAD));
if (pScreenPriv->pbmih == NULL)
{
ErrorF ("winInitScreenShadowGDI - malloc () failed\n");
return FALSE;
}
/* Query the screen format */
if (!winQueryScreenDIBFormat (pScreen, pScreenPriv->pbmih))
{
ErrorF ("winInitScreenShadowGDI - winQueryScreenDIBFormat failed\n");
return FALSE;
}
/* Determine our color masks */
if (!winQueryRGBBitsAndMasks (pScreen))
{
ErrorF ("winInitScreenShadowGDI - winQueryRGBBitsAndMasks failed\n");
return FALSE;
}
return winAllocateFBShadowGDI(pScreen);
}

View File

@ -182,28 +182,6 @@ winWindowProc (HWND hwnd, UINT message,
"new height: %d new bpp: %d\n",
LOWORD (lParam), HIWORD (lParam), wParam);
/*
* TrueColor --> TrueColor depth changes are disruptive for:
* Windowed:
* Shadow DirectDraw
* Shadow DirectDraw Non-Locking
* Primary DirectDraw
*
* TrueColor --> TrueColor depth changes are non-optimal for:
* Windowed:
* Shadow GDI
*
* FullScreen:
* Shadow GDI
*
* TrueColor --> PseudoColor or vice versa are disruptive for:
* Windowed:
* Shadow DirectDraw
* Shadow DirectDraw Non-Locking
* Primary DirectDraw
* Shadow GDI
*/
/*
* Check for a disruptive change in depth.
* We can only display a message for a disruptive depth change,
@ -213,31 +191,38 @@ winWindowProc (HWND hwnd, UINT message,
XXX: maybe we need to check if GetSystemMetrics(SM_SAMEDISPLAYFORMAT)
has changed as well...
*/
if ((s_pScreenInfo->dwBPP != GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL))
&& (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
|| s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
if (s_pScreenInfo->dwBPP != GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL))
{
if ((s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
|| s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
#ifdef XWIN_PRIMARYFB
|| s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD
|| s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD
#endif
))
{
/* Cannot display the visual until the depth is restored */
ErrorF ("winWindowProc - Disruptive change in depth\n");
))
{
/* Cannot display the visual until the depth is restored */
ErrorF ("winWindowProc - Disruptive change in depth\n");
/* Display depth change dialog */
winDisplayDepthChangeDialog (s_pScreenPriv);
/* Display depth change dialog */
winDisplayDepthChangeDialog (s_pScreenPriv);
/* Flag that we have an invalid screen depth */
s_pScreenPriv->fBadDepth = TRUE;
/* Flag that we have an invalid screen depth */
s_pScreenPriv->fBadDepth = TRUE;
/* Minimize the display window */
ShowWindow (hwnd, SW_MINIMIZE);
}
/* Minimize the display window */
ShowWindow (hwnd, SW_MINIMIZE);
}
else
{
/* For GDI, performance may suffer until original depth is restored */
ErrorF ("winWindowProc - Performance may be non-optimal after change in depth\n");
}
}
else
{
/* Flag that we have a valid screen depth */
s_pScreenPriv->fBadDepth = FALSE;
}
{
/* Flag that we have a valid screen depth */
s_pScreenPriv->fBadDepth = FALSE;
}
/*
If we could cheaply check if this WM_DISPLAYCHANGE change