From 1b4887abedce1f5653fbcdcdef442357ef0de38c Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Wed, 29 Sep 2010 22:54:22 +0100 Subject: Cygwin/X: DirectDraw engines shouldn't try to blit if the surface wasn't allocated Fix winShadowUpdateDD(|NL) so we don't try to blit to primary surface if it didn't get allocated (Intel drivers, in particular, seem to like to issue a WM_DISPLAYCHANGE during a suspend/resume cycle, but not allow surface to be allocated right then) Also: Use winReleasePrimarySurfaceShadowDD(|NL) in winFreeFBShadowDD(|NL) rather than open coding it Don't mess about recreating surface if we're going to resize it anyhow Signed-off-by: Jon TURNEY --- hw/xwin/winshaddd.c | 21 +++++++----------- hw/xwin/winshadddnl.c | 21 +++++++----------- hw/xwin/winwndproc.c | 60 +++++++++++++++++++++++---------------------------- 3 files changed, 43 insertions(+), 59 deletions(-) diff --git a/hw/xwin/winshaddd.c b/hw/xwin/winshaddd.c index f6dfc82bf..864a8cec7 100644 --- a/hw/xwin/winshaddd.c +++ b/hw/xwin/winshaddd.c @@ -521,25 +521,16 @@ winFreeFBShadowDD (ScreenPtr pScreen) pScreenPriv->pddsShadow = NULL; } - /* Detach the clipper from the primary surface and release the clipper. */ + /* Detach the clipper from the primary surface and release the primary surface, if there is one */ + winReleasePrimarySurfaceShadowDD(pScreen); + + /* Release the clipper object */ 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) { @@ -584,6 +575,10 @@ winShadowUpdateDD (ScreenPtr pScreen, if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) || pScreenPriv->fBadDepth) return; + /* Return immediately if we didn't get needed surfaces */ + if (!pScreenPriv->pddsPrimary || !pScreenPriv->pddsShadow) + return; + /* Get the origin of the window in the screen coords */ ptOrigin.x = pScreenInfo->dwXOffset; ptOrigin.y = pScreenInfo->dwYOffset; diff --git a/hw/xwin/winshadddnl.c b/hw/xwin/winshadddnl.c index 72f0f4696..3d8c42e56 100644 --- a/hw/xwin/winshadddnl.c +++ b/hw/xwin/winshadddnl.c @@ -553,25 +553,16 @@ winFreeFBShadowDDNL(ScreenPtr pScreen) pScreenPriv->pddsShadow4 = NULL; } - /* Detach the clipper from the primary surface and release the clipper. */ + /* Detach the clipper from the primary surface and release the primary surface, if there is one */ + winReleasePrimarySurfaceShadowDDNL(pScreen); + + /* Release the clipper object */ 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) { @@ -665,6 +656,10 @@ winShadowUpdateDDNL (ScreenPtr pScreen, if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) || pScreenPriv->fBadDepth) return; + /* Return immediately if we didn't get needed surfaces */ + if (!pScreenPriv->pddsPrimary4 || !pScreenPriv->pddsShadow4) + return; + /* Get the origin of the window in the screen coords */ ptOrigin.x = pScreenInfo->dwXOffset; ptOrigin.y = pScreenInfo->dwYOffset; diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c index d78491d57..1f9e749ad 100644 --- a/hw/xwin/winwndproc.c +++ b/hw/xwin/winwndproc.c @@ -246,40 +246,7 @@ winWindowProc (HWND hwnd, UINT message, (this is probably usually the case so that might be an overoptimization) */ - - /* - * We can simply recreate the same-sized primary surface when - * the display dimensions change. - */ { - /* - * NOTE: The non-DirectDraw engines set the ReleasePrimarySurface - * and CreatePrimarySurface function pointers to point - * to the no operation function, NoopDDA. This allows us - * to blindly call these functions, even if they are not - * relevant to the current engine (e.g., Shadow GDI). - */ - -#if CYGDEBUG - winDebug ("winWindowProc - WM_DISPLAYCHANGE - Dimensions changed\n"); -#endif - - /* Release the old primary surface */ - (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen); - -#if CYGDEBUG - winDebug ("winWindowProc - WM_DISPLAYCHANGE - Released " - "primary surface\n"); -#endif - - /* Create the new primary surface */ - (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen); - -#if CYGDEBUG - winDebug ("winWindowProc - WM_DISPLAYCHANGE - Recreated " - "primary surface\n"); -#endif - /* In rootless modes which are monitor or virtual desktop size use RandR to resize the X screen @@ -333,6 +300,33 @@ winWindowProc (HWND hwnd, UINT message, (dwWidth / monitorResolution) * 25.4, (dwHeight / monitorResolution) * 25.4); } + else + { + /* + * We can simply recreate the same-sized primary surface when + * the display dimensions change. + */ + + /* + * NOTE: The non-DirectDraw engines set the ReleasePrimarySurface + * and CreatePrimarySurface function pointers to point + * to the no operation function, NoopDDA. This allows us + * to blindly call these functions, even if they are not + * relevant to the current engine (e.g., Shadow GDI). + */ + + winDebug ("winWindowProc - WM_DISPLAYCHANGE - Dimensions changed\n"); + + /* Release the old primary surface */ + (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen); + + winDebug ("winWindowProc - WM_DISPLAYCHANGE - Released primary surface\n"); + + /* Create the new primary surface */ + (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen); + + winDebug ("winWindowProc - WM_DISPLAYCHANGE - Recreated primary surface\n"); + } } break; -- cgit v1.2.3