diff options
Diffstat (limited to 'xorg-server/hw/xwin/winshadddnl.c')
| -rw-r--r-- | xorg-server/hw/xwin/winshadddnl.c | 309 | 
1 files changed, 136 insertions, 173 deletions
| diff --git a/xorg-server/hw/xwin/winshadddnl.c b/xorg-server/hw/xwin/winshadddnl.c index 63d48adb6..b7ba8ef94 100644 --- a/xorg-server/hw/xwin/winshadddnl.c +++ b/xorg-server/hw/xwin/winshadddnl.c @@ -41,10 +41,12 @@   * FIXME: Headers are broken, DEFINE_GUID doesn't work correctly,   * so we have to redefine it here.   */ +#ifndef _MSC_VER  #ifdef DEFINE_GUID  #undef DEFINE_GUID  #define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}  #endif /* DEFINE_GUID */ +#endif  /*   * FIXME: Headers are broken, IID_IDirectDraw4 has to be defined @@ -109,6 +111,61 @@ winCreatePrimarySurfaceShadowDDNL (ScreenPtr pScreen);  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) +  { +    ddrval = IDirectDrawSurface4_Blt(pScreenPriv->pddsPrimary4, pRect, pScreenPriv->pddsShadow4, prcSrc, DDBLT_WAIT, NULL); +     /* 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. @@ -154,9 +211,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, @@ -169,28 +224,16 @@ 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)      { @@ -198,8 +241,7 @@ winReleasePrimarySurfaceShadowDDNL (ScreenPtr pScreen)         * 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"); @@ -208,6 +250,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; @@ -232,29 +315,42 @@ 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) +  if ( pScreenInfo->pfb) +  { +    ErrorF("winAllocateFBShadowDDNL calling for the second time, reallocating\n"); +    lpSurface=pScreenInfo->pfb; + +    if (pScreenPriv->pddsShadow4)      { -      ErrorF ("winAllocateFBShadowDDNL - Could not allocate bits\n"); -      return FALSE; +      IDirectDrawSurface4_Release (pScreenPriv->pddsShadow4); +      pScreenPriv->pddsShadow4 = NULL;      } - -  /* -   * Initialize the framebuffer memory so we don't get a  -   * strange display at startup -   */ -  ZeroMemory (lpSurface, pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); +    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, @@ -266,9 +362,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, @@ -282,9 +376,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, @@ -298,9 +390,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, @@ -458,14 +548,12 @@ 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 */    /* @@ -502,19 +590,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; @@ -524,9 +608,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;  } @@ -549,27 +631,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; @@ -635,7 +697,6 @@ winShadowUpdateDDNL (ScreenPtr pScreen,    winScreenPriv(pScreen);    winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;    RegionPtr		damage = shadowDamage(pBuf); -  HRESULT		ddrval = DD_OK;    RECT			rcDest, rcSrc;    POINT			ptOrigin;    DWORD			dwBox = RegionNumRects (damage); @@ -684,33 +745,10 @@ winShadowUpdateDDNL (ScreenPtr pScreen,  	  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; @@ -737,11 +775,9 @@ winShadowUpdateDDNL (ScreenPtr pScreen,        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; @@ -756,12 +792,7 @@ winShadowUpdateDDNL (ScreenPtr pScreen,        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); @@ -792,9 +823,7 @@ winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen)    winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;    Bool			fReturn; -#if CYGDEBUG    winDebug ("winCloseScreenShadowDDNL - Freeing screen resources\n"); -#endif    /* Flag that the screen is closed */    pScreenPriv->fClosed = TRUE; @@ -947,9 +976,7 @@ winInitVisualsShadowDDNL (ScreenPtr pScreen)        return FALSE;      } -#if CYGDEBUG    winDebug ("winInitVisualsShadowDDNL - Returning\n"); -#endif    return TRUE;  } @@ -1049,63 +1076,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)) +  ddrval = myIDirectDrawSurface4_Blt (pScreen, &rcDest, &rcSrc); +  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;  	} -    } - winBltExposedRegionsShadowDDNL_Exit: +winBltExposedRegionsShadowDDNL_Exit:    /* EndPaint frees the DC */    if (hdcUpdate != NULL)      EndPaint (pScreenPriv->hwndScreen, &ps); @@ -1148,7 +1126,6 @@ winRedrawScreenShadowDDNL (ScreenPtr pScreen)  {    winScreenPriv(pScreen);    winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo; -  HRESULT		ddrval = DD_OK;    RECT			rcSrc, rcDest;    POINT			ptOrigin; @@ -1170,19 +1147,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;  } @@ -1320,9 +1285,7 @@ winDestroyColormapShadowDDNL (ColormapPtr pColormap)     */    if (pColormap->flags & IsDefault)      { -#if CYGDEBUG        winDebug ("winDestroyColormapShadowDDNL - Destroying default colormap\n"); -#endif        /*         * FIXME: Walk the list of all screens, popping the default | 
