diff options
Diffstat (limited to 'xorg-server/hw/xwin/winshadddnl.c')
-rw-r--r-- | xorg-server/hw/xwin/winshadddnl.c | 305 |
1 files changed, 146 insertions, 159 deletions
diff --git a/xorg-server/hw/xwin/winshadddnl.c b/xorg-server/hw/xwin/winshadddnl.c index 55af5c383..047482e09 100644 --- a/xorg-server/hw/xwin/winshadddnl.c +++ b/xorg-server/hw/xwin/winshadddnl.c @@ -35,6 +35,7 @@ #include <xwin-config.h> #endif #include "win.h" +#include "winprefs.h" #define FAIL_MSG_MAX_BLT 10 @@ -87,6 +88,65 @@ static Bool static Bool winReleasePrimarySurfaceShadowDDNL(ScreenPtr pScreen); +static HRESULT myIDirectDrawSurface4_Blt( ScreenPtr pScreen, RECT *pRect, RECT *prcSrc) +{ + HRESULT ddrval = DD_OK; + unsigned i; + winScreenPriv(pScreen); + + + for (i = 0; i < 3; ++i) + { + if (pScreenPriv->pddsPrimary4) + ddrval = IDirectDrawSurface4_Blt(pScreenPriv->pddsPrimary4, pRect, pScreenPriv->pddsShadow4, prcSrc, DDBLT_WAIT, NULL); + else + ddrval = DDERR_SURFACELOST; // Surface has been closed + /* Try to regain the primary surface and blit again if we've lost it */ + if (ddrval == DDERR_SURFACELOST) + { + /* Surface was lost */ + ErrorF ("IDirectDrawSurface4_Blt reported that the primary " + "surface was lost, trying to restore, retry: %d\n", i + 1); + + /* Try to restore the surface, once */ + + if (i==1) + { + ErrorF("Recreating DDraw surface because restoring of surface didn't work.\n"); + winAllocateFBShadowDDNL(pScreen); + } + else + { + ddrval = IDirectDraw4_RestoreAllSurfaces (pScreenPriv->pdd4); + ErrorF ("IDirectDraw4_RestoreAllSurfaces returned: "); + if (ddrval == DD_OK) + ErrorF ("DD_OK\n"); + else if (ddrval == DDERR_WRONGMODE) + ErrorF ("DDERR_WRONGMODE\n"); + else if (ddrval == DDERR_INCOMPATIBLEPRIMARY) + ErrorF ("DDERR_INCOMPATIBLEPRIMARY\n"); + else if (ddrval == DDERR_UNSUPPORTED) + ErrorF ("DDERR_UNSUPPORTED\n"); + else if (ddrval == DDERR_INVALIDPARAMS) + ErrorF ("DDERR_INVALIDPARAMS\n"); + else if (ddrval == DDERR_INVALIDOBJECT) + ErrorF ("DDERR_INVALIDOBJECT\n"); + else + ErrorF ("unknown error: %08x\n", ddrval); + } + /* Loop around to try the blit one more time */ + continue; + } + else if (FAILED (ddrval)) + { + ErrorF ("IDirectDrawSurface4_Blt failed, but surface not " + "lost: %08x %d\n", ddrval, ddrval); + } + break; + } + return ddrval; +} + /* * Create the primary surface and attach the clipper. * Used for both the initial surface creation and during @@ -127,9 +187,7 @@ winCreatePrimarySurfaceShadowDDNL(ScreenPtr pScreen) return FALSE; } -#if 1 winDebug("winCreatePrimarySurfaceShadowDDNL - Created primary surface\n"); -#endif /* Attach our clipper to our primary surface handle */ ddrval = IDirectDrawSurface4_SetClipper(pScreenPriv->pddsPrimary4, @@ -140,34 +198,22 @@ winCreatePrimarySurfaceShadowDDNL(ScreenPtr pScreen) return FALSE; } -#if 1 winDebug("winCreatePrimarySurfaceShadowDDNL - Attached clipper to primary " "surface\n"); -#endif /* Everything was correct */ return TRUE; } -/* - * Detach the clipper and release the primary surface. - * Called from WM_DISPLAYCHANGE. - */ - -static Bool -winReleasePrimarySurfaceShadowDDNL(ScreenPtr pScreen) +static void ClosePrimarySurfaceShadowDDNL (winPrivScreenPtr pScreenPriv) { - winScreenPriv(pScreen); - - winDebug("winReleasePrimarySurfaceShadowDDNL - Hello\n"); - /* Release the primary surface and clipper, if they exist */ if (pScreenPriv->pddsPrimary4) { /* * Detach the clipper from the primary surface. * NOTE: We do this explicity for clarity. The Clipper is not released. */ - IDirectDrawSurface4_SetClipper(pScreenPriv->pddsPrimary4, NULL); + IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4, NULL); winDebug("winReleasePrimarySurfaceShadowDDNL - Detached clipper\n"); @@ -176,6 +222,47 @@ winReleasePrimarySurfaceShadowDDNL(ScreenPtr pScreen) pScreenPriv->pddsPrimary4 = NULL; } +} + +static void ReleaseDDNL(winPrivScreenPtr pScreenPriv) +{ + /* Release the clipper object */ + if (pScreenPriv->pddcPrimary) + { + IDirectDrawClipper_Release (pScreenPriv->pddcPrimary); + pScreenPriv->pddcPrimary = 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; + } +} + +/* + * Detach the clipper and release the primary surface. + * Called from WM_DISPLAYCHANGE. + */ + +static Bool +winReleasePrimarySurfaceShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + + winDebug ("winReleasePrimarySurfaceShadowDDNL - Hello\n"); + + ClosePrimarySurfaceShadowDDNL(pScreenPriv); + winDebug("winReleasePrimarySurfaceShadowDDNL - Released primary surface\n"); return TRUE; @@ -199,28 +286,41 @@ winAllocateFBShadowDDNL(ScreenPtr pScreen) char *lpSurface = NULL; DDPIXELFORMAT ddpfPrimary; -#if CYGDEBUG winDebug("winAllocateFBShadowDDNL - w %d h %d d %d\n", 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) { - ErrorF("winAllocateFBShadowDDNL - Could not allocate bits\n"); - return FALSE; - } - - /* - * Initialize the framebuffer memory so we don't get a - * strange display at startup - */ - ZeroMemory(lpSurface, pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); + if ( pScreenInfo->pfb) + { + ErrorF("winAllocateFBShadowDDNL calling for the second time, reallocating\n"); + lpSurface=pScreenInfo->pfb; + if (pScreenPriv->pddsShadow4) + { + IDirectDrawSurface4_Release (pScreenPriv->pddsShadow4); + pScreenPriv->pddsShadow4 = NULL; + } + ClosePrimarySurfaceShadowDDNL(pScreenPriv); + ReleaseDDNL(pScreenPriv); + } + else + { + /* Allocate memory for our shadow surface */ + lpSurface = malloc (pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); + if (lpSurface == NULL) { + ErrorF ("winAllocateFBShadowDDNL - Could not allocate bits\n"); + return FALSE; + } + + /* + * Initialize the framebuffer memory so we don't get a + * strange display at startup + */ + ZeroMemory (lpSurface, pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); + } /* Create a clipper */ ddrval = (*g_fpDirectDrawCreateClipper) (0, &pScreenPriv->pddcPrimary, NULL); @@ -230,9 +330,7 @@ winAllocateFBShadowDDNL(ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug("winAllocateFBShadowDDNL - Created a clipper\n"); -#endif /* Attach the clipper to our display window */ ddrval = IDirectDrawClipper_SetHWnd(pScreenPriv->pddcPrimary, @@ -243,9 +341,7 @@ winAllocateFBShadowDDNL(ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug("winAllocateFBShadowDDNL - Attached clipper to window\n"); -#endif /* Create a DirectDraw object, store the address at lpdd */ ddrval = (*g_fpDirectDrawCreate) (NULL, @@ -257,9 +353,7 @@ winAllocateFBShadowDDNL(ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug("winAllocateFBShadowDDNL - Created and initialized DD\n"); -#endif /* Get a DirectDraw4 interface pointer */ ddrval = IDirectDraw_QueryInterface(pScreenPriv->pdd, @@ -398,13 +492,11 @@ winAllocateFBShadowDDNL(ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug("winAllocateFBShadowDDNL - Primary masks: %08x %08x %08x " "dwRGBBitCount: %d\n", ddpfPrimary.u2.dwRBitMask, ddpfPrimary.u3.dwGBitMask, ddpfPrimary.u4.dwBBitMask, ddpfPrimary.u1.dwRGBBitCount); -#endif /* Describe the shadow surface to be created */ /* @@ -439,19 +531,15 @@ winAllocateFBShadowDDNL(ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG || YES winDebug("winAllocateFBShadowDDNL - Created shadow pitch: %d\n", (int) ddsdShadow.u1.lPitch); -#endif /* Grab the pitch from the surface desc */ pScreenInfo->dwStride = (ddsdShadow.u1.lPitch * 8) / pScreenInfo->dwBPP; -#if CYGDEBUG || YES winDebug("winAllocateFBShadowDDNL - Created shadow stride: %d\n", (int) pScreenInfo->dwStride); -#endif /* Save the pointer to our surface memory */ pScreenInfo->pfb = lpSurface; @@ -461,9 +549,7 @@ winAllocateFBShadowDDNL(ScreenPtr pScreen) pScreenPriv->dwGreenMask = ddsdShadow.u4.ddpfPixelFormat.u3.dwGBitMask; pScreenPriv->dwBlueMask = ddsdShadow.u4.ddpfPixelFormat.u4.dwBBitMask; -#if CYGDEBUG winDebug("winAllocateFBShadowDDNL - Returning\n"); -#endif return TRUE; } @@ -485,24 +571,7 @@ winFreeFBShadowDDNL(ScreenPtr pScreen) /* 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) { - IDirectDrawClipper_Release(pScreenPriv->pddcPrimary); - pScreenPriv->pddcPrimary = 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; - } + ReleaseDDNL(pScreenPriv); /* Invalidate the ScreenInfo's fb pointer */ pScreenInfo->pfb = NULL; @@ -518,7 +587,6 @@ winShadowUpdateDDNL(ScreenPtr pScreen, shadowBufPtr pBuf) winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; RegionPtr damage = shadowDamage(pBuf); - HRESULT ddrval = DD_OK; RECT rcDest, rcSrc; POINT ptOrigin; DWORD dwBox = RegionNumRects(damage); @@ -565,27 +633,10 @@ winShadowUpdateDDNL(ScreenPtr pScreen, shadowBufPtr pBuf) rcDest.bottom = ptOrigin.y + rcSrc.bottom; /* Blit the damaged areas */ - ddrval = IDirectDrawSurface4_Blt(pScreenPriv->pddsPrimary4, - &rcDest, - pScreenPriv->pddsShadow4, - &rcSrc, DDBLT_WAIT, NULL); - if (FAILED(ddrval)) { - static int s_iFailCount = 0; - - if (s_iFailCount < FAIL_MSG_MAX_BLT) { - ErrorF("winShadowUpdateDDNL - IDirectDrawSurface4_Blt () " - "failed: %08x\n", (unsigned int) ddrval); - - ++s_iFailCount; - - if (s_iFailCount == FAIL_MSG_MAX_BLT) { - ErrorF("winShadowUpdateDDNL - IDirectDrawSurface4_Blt " - "failure message maximum (%d) reached. No " - "more failure messages will be printed.\n", - FAIL_MSG_MAX_BLT); - } - } - } + if (pScreenPriv->pddsPrimary4) + myIDirectDrawSurface4_Blt (pScreen, + &rcDest, + &rcSrc); /* Get a pointer to the next box */ ++pBox; @@ -604,11 +655,9 @@ winShadowUpdateDDNL(ScreenPtr pScreen, shadowBufPtr pBuf) DeleteObject(hrgnCombined); hrgnCombined = NULL; -#if CYGDEBUG winDebug("winShadowUpdateDDNL - be x1 %d y1 %d x2 %d y2 %d\n", pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2, pBoxExtents->y2); -#endif /* Calculating a bounding box for the source is easy */ rcSrc.left = pBoxExtents->x1; @@ -623,10 +672,7 @@ winShadowUpdateDDNL(ScreenPtr pScreen, shadowBufPtr pBuf) rcDest.bottom = ptOrigin.y + rcSrc.bottom; /* Our Blt should be clipped to the invalidated region */ - ddrval = IDirectDrawSurface4_Blt(pScreenPriv->pddsPrimary4, - &rcDest, - pScreenPriv->pddsShadow4, - &rcSrc, DDBLT_WAIT, NULL); + myIDirectDrawSurface4_Blt (pScreen, &rcDest, &rcSrc); /* Reset the clip region */ SelectClipRgn(pScreenPriv->hdcScreen, NULL); @@ -655,11 +701,9 @@ winCloseScreenShadowDDNL(ScreenPtr pScreen) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - Bool fReturn; + Bool fReturn=FALSE; -#if CYGDEBUG winDebug("winCloseScreenShadowDDNL - Freeing screen resources\n"); -#endif /* Flag that the screen is closed */ pScreenPriv->fClosed = TRUE; @@ -679,7 +723,7 @@ winCloseScreenShadowDDNL(ScreenPtr pScreen) RemoveProp(pScreenPriv->hwndScreen, WIN_SCR_PROP); /* Delete tray icon, if we have one */ - if (!pScreenInfo->fNoTrayIcon) + if (!pScreenInfo->fNoTrayIcon && !pref.fNoTrayIcon) winDeleteNotifyIcon(pScreenPriv); /* Free the exit confirmation dialog box, if it exists */ @@ -696,7 +740,7 @@ winCloseScreenShadowDDNL(ScreenPtr pScreen) #if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) /* Destroy the thread startup mutex */ - pthread_mutex_destroy(&pScreenPriv->pmServerStarted); + if (pScreenPriv->pmServerStarted) pthread_mutex_destroy (&pScreenPriv->pmServerStarted); #endif /* Kill our screeninfo's pointer to the screen */ @@ -798,9 +842,7 @@ winInitVisualsShadowDDNL(ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug("winInitVisualsShadowDDNL - Returning\n"); -#endif return TRUE; } @@ -892,58 +934,14 @@ winBltExposedRegionsShadowDDNL(ScreenPtr pScreen) rcSrc.right = pScreenInfo->dwWidth; rcSrc.bottom = pScreenInfo->dwHeight; - /* Try to regain the primary surface and blit again if we've lost it */ - for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i) { - /* Our Blt should be clipped to the invalidated region */ - ddrval = IDirectDrawSurface4_Blt(pScreenPriv->pddsPrimary4, - &rcDest, - pScreenPriv->pddsShadow4, - &rcSrc, DDBLT_WAIT, NULL); - if (ddrval == DDERR_SURFACELOST) { - /* Surface was lost */ - winErrorFVerb(1, "winBltExposedRegionsShadowDDNL - " - "IDirectDrawSurface4_Blt reported that the primary " - "surface was lost, trying to restore, retry: %d\n", - i + 1); - - /* Try to restore the surface, once */ - - ddrval = IDirectDrawSurface4_Restore(pScreenPriv->pddsPrimary4); - winDebug("winBltExposedRegionsShadowDDNL - " - "IDirectDrawSurface4_Restore returned: "); - if (ddrval == DD_OK) - winDebug("DD_OK\n"); - else if (ddrval == DDERR_WRONGMODE) - winDebug("DDERR_WRONGMODE\n"); - else if (ddrval == DDERR_INCOMPATIBLEPRIMARY) - winDebug("DDERR_INCOMPATIBLEPRIMARY\n"); - else if (ddrval == DDERR_UNSUPPORTED) - winDebug("DDERR_UNSUPPORTED\n"); - else if (ddrval == DDERR_INVALIDPARAMS) - winDebug("DDERR_INVALIDPARAMS\n"); - else if (ddrval == DDERR_INVALIDOBJECT) - winDebug("DDERR_INVALIDOBJECT\n"); - else - winDebug("unknown error: %08x\n", (unsigned int) ddrval); - - /* Loop around to try the blit one more time */ - continue; - } - else if (FAILED(ddrval)) { - fReturn = FALSE; - winErrorFVerb(1, "winBltExposedRegionsShadowDDNL - " - "IDirectDrawSurface4_Blt failed, but surface not " - "lost: %08x %d\n", - (unsigned int) ddrval, (int) ddrval); - goto winBltExposedRegionsShadowDDNL_Exit; - } - else { - /* Success, stop looping */ - break; - } + /* Our Blt should be clipped to the invalidated region */ + ddrval = myIDirectDrawSurface4_Blt (pScreen, &rcDest, &rcSrc); + if (FAILED (ddrval)) + { + fReturn = FALSE; } - winBltExposedRegionsShadowDDNL_Exit: +winBltExposedRegionsShadowDDNL_Exit: /* EndPaint frees the DC */ if (hdcUpdate != NULL) EndPaint(pScreenPriv->hwndScreen, &ps); @@ -982,7 +980,6 @@ winRedrawScreenShadowDDNL(ScreenPtr pScreen) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - HRESULT ddrval = DD_OK; RECT rcSrc, rcDest; POINT ptOrigin; @@ -1003,15 +1000,7 @@ winRedrawScreenShadowDDNL(ScreenPtr pScreen) rcSrc.bottom = pScreenInfo->dwHeight; /* Redraw the whole window, to take account for the new colors */ - ddrval = IDirectDrawSurface4_Blt(pScreenPriv->pddsPrimary4, - &rcDest, - pScreenPriv->pddsShadow4, - &rcSrc, DDBLT_WAIT, NULL); - if (FAILED(ddrval)) { - ErrorF("winRedrawScreenShadowDDNL - IDirectDrawSurface4_Blt () " - "failed: %08x\n", (unsigned int) ddrval); - } - + myIDirectDrawSurface4_Blt (pScreen, &rcDest, &rcSrc); return TRUE; } @@ -1139,10 +1128,8 @@ winDestroyColormapShadowDDNL(ColormapPtr pColormap) * we need to handle the default colormap in a special way. */ if (pColormap->flags & IsDefault) { -#if CYGDEBUG winDebug ("winDestroyColormapShadowDDNL - Destroying default colormap\n"); -#endif /* * FIXME: Walk the list of all screens, popping the default |