aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xwin/winshadddnl.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xwin/winshadddnl.c')
-rw-r--r--xorg-server/hw/xwin/winshadddnl.c305
1 files changed, 146 insertions, 159 deletions
diff --git a/xorg-server/hw/xwin/winshadddnl.c b/xorg-server/hw/xwin/winshadddnl.c
index cb326dc81..c7db77bac 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;
@@ -1007,15 +1004,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;
}
@@ -1143,10 +1132,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