示例#1
0
void
shadowUpdateIplan2p4(ScreenPtr pScreen, shadowBufPtr pBuf)
{
    RegionPtr damage = shadowDamage(pBuf);
    PixmapPtr pShadow = pBuf->pPixmap;
    int nbox = RegionNumRects(damage);
    BoxPtr pbox = RegionRects(damage);
    FbBits *shaBase;
    CARD16 *shaLine, *sha;
    FbStride shaStride;
    int scrLine;
    _X_UNUSED int shaBpp, shaXoff, shaYoff;
    int x, y, w, h;
    int i, n;
    CARD16 *win;
    _X_UNUSED CARD32 winSize;
    union {
        CARD8 bytes[8];
        CARD32 words[2];
    } d;

    fbGetDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff,
                  shaYoff);
    shaStride *= sizeof(FbBits) / sizeof(CARD16);

    while (nbox--) {
        x = pbox->x1;
        y = pbox->y1;
        w = pbox->x2 - pbox->x1;
        h = pbox->y2 - pbox->y1;

        scrLine = (x & -16) / 2;
        shaLine = (CARD16 *)shaBase + y * shaStride + scrLine / sizeof(CARD16);

        n = ((x & 15) + w + 15) / 16;   /* number of c2p units in scanline */

        while (h--) {
            sha = shaLine;
            win = (CARD16 *) (*pBuf->window) (pScreen,
                                              y,
                                              scrLine,
                                              SHADOW_WINDOW_WRITE,
                                              &winSize,
                                              pBuf->closure);
            if (!win)
                return;
            for (i = 0; i < n; i++) {
                memcpy(d.bytes, sha, sizeof(d.bytes));
                c2p_16x4(d.words);
                store_iplan2p4(win, d.words);
                sha += sizeof(d.bytes) / sizeof(*sha);
                win += sizeof(d.bytes) / sizeof(*win);
            }
            shaLine += shaStride;
            y++;
        }
        pbox++;
    }
}
示例#2
0
文件: winshaddd.c 项目: L3oV1nc3/VMGL
static void
winShadowUpdateDD (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 = REGION_NUM_RECTS (damage);
  BoxPtr		pBox = REGION_RECTS (damage);
  HRGN			hrgnTemp = NULL, hrgnCombined = NULL;

  /*
   * Return immediately if the app is not active
   * and we are fullscreen, or if we have a bad display depth
   */
  if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
      || pScreenPriv->fBadDepth) return;

  /* Get the origin of the window in the screen coords */
  ptOrigin.x = pScreenInfo->dwXOffset;
  ptOrigin.y = pScreenInfo->dwYOffset;
  MapWindowPoints (pScreenPriv->hwndScreen,
		   HWND_DESKTOP,
		   (LPPOINT)&ptOrigin, 1);

  /* Unlock the shadow surface, so we can blit */
  ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL);
  if (FAILED (ddrval))
    {
      ErrorF ("winShadowUpdateDD - Unlock failed\n");
      return;
    }

  /*
   * Handle small regions with multiple blits,
   * handle large regions by creating a clipping region and 
   * doing a single blit constrained to that clipping region.
   */
  if (pScreenInfo->dwClipUpdatesNBoxes == 0
      || dwBox < pScreenInfo->dwClipUpdatesNBoxes)
    {
      /* Loop through all boxes in the damaged region */
      while (dwBox--)
	{
	  /* Assign damage box to source rectangle */
	  rcSrc.left = pBox->x1;
	  rcSrc.top = pBox->y1;
	  rcSrc.right = pBox->x2;
	  rcSrc.bottom = pBox->y2;
	  
	  /* Calculate destination rectange */
	  rcDest.left = ptOrigin.x + rcSrc.left;
	  rcDest.top = ptOrigin.y + rcSrc.top;
	  rcDest.right = ptOrigin.x + rcSrc.right;
	  rcDest.bottom = ptOrigin.y + rcSrc.bottom;
	  
	  /* Blit the damaged areas */
	  ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary,
					    &rcDest,
					    pScreenPriv->pddsShadow,
					    &rcSrc,
					    DDBLT_WAIT,
					    NULL);
	  
	  /* Get a pointer to the next box */
	  ++pBox;
	}
    }
  else
    {
      BoxPtr		pBoxExtents = REGION_EXTENTS (pScreen, damage);

      /* Compute a GDI region from the damaged region */
      hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
      dwBox--;
      pBox++;
      while (dwBox--)
	{
	  hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
	  CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
	  DeleteObject (hrgnTemp);
	  pBox++;
	}  

      /* Install the GDI region as a clipping region */
      SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined);
      DeleteObject (hrgnCombined);
      hrgnCombined = NULL;

      /* Calculating a bounding box for the source is easy */
      rcSrc.left = pBoxExtents->x1;
      rcSrc.top = pBoxExtents->y1;
      rcSrc.right = pBoxExtents->x2;
      rcSrc.bottom = pBoxExtents->y2;

      /* Calculating a bounding box for the destination is trickier */
      rcDest.left = ptOrigin.x + rcSrc.left;
      rcDest.top = ptOrigin.y + rcSrc.top;
      rcDest.right = ptOrigin.x + rcSrc.right;
      rcDest.bottom = ptOrigin.y + rcSrc.bottom;
      
      /* Our Blt should be clipped to the invalidated region */
      ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary,
					&rcDest,
					pScreenPriv->pddsShadow,
					&rcSrc,
					DDBLT_WAIT,
					NULL);

      /* Reset the clip region */
      SelectClipRgn (pScreenPriv->hdcScreen, NULL);
    }

  /* Relock the shadow surface */
  ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow,
				     NULL,
				     pScreenPriv->pddsdShadow,
				     DDLOCK_WAIT,
				     NULL);
  if (FAILED (ddrval))
    {
      ErrorF ("winShadowUpdateDD - Lock failed\n");
      return;
    }

  /* Has our memory pointer changed? */
  if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface)
    {
      ErrorF ("winShadowUpdateDD - Memory location of the shadow "
	      "surface has changed, trying to update the root window "
	      "pixmap header to point to the new address.  If you get "
	      "this message and "PROJECT_NAME" freezes or crashes "
	      "after this message then send a problem report and your "
	      "%s file to " BUILDERADDR, g_pszLogFile);

      /* Location of shadow framebuffer has changed */
      pScreenInfo->pfb = pScreenPriv->pddsdShadow->lpSurface;
      
      /* Update the screen pixmap */
      if (!(*pScreen->ModifyPixmapHeader)(pScreen->devPrivate,
					  pScreen->width,
					  pScreen->height,
					  pScreen->rootDepth,
					  BitsPerPixel (pScreen->rootDepth),
					  PixmapBytePad (pScreenInfo->dwStride,
							 pScreenInfo->dwBPP),
					  pScreenInfo->pfb))
	{
	  ErrorF ("winShadowUpdateDD - Bits changed, could not "
		  "notify fb.\n");
	  return;
	}
    }
}
static void
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);
  BoxPtr		pBox = RegionRects (damage);
  HRGN			hrgnTemp = NULL, hrgnCombined = NULL;

  /*
   * Return immediately if the app is not active
   * and we are fullscreen, or if we have a bad display depth
   */
  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;
  MapWindowPoints (pScreenPriv->hwndScreen,
		   HWND_DESKTOP,
		   (LPPOINT)&ptOrigin, 1);

  /*
   * Handle small regions with multiple blits,
   * handle large regions by creating a clipping region and 
   * doing a single blit constrained to that clipping region.
   */
  if (pScreenInfo->dwClipUpdatesNBoxes == 0
      || dwBox < pScreenInfo->dwClipUpdatesNBoxes)
    {
      /* Loop through all boxes in the damaged region */
      while (dwBox--)
	{
	  /* Assign damage box to source rectangle */
	  rcSrc.left = pBox->x1;
	  rcSrc.top = pBox->y1;
	  rcSrc.right = pBox->x2;
	  rcSrc.bottom = pBox->y2;
	  
	  /* Calculate destination rectangle */
	  rcDest.left = ptOrigin.x + rcSrc.left;
	  rcDest.top = ptOrigin.y + rcSrc.top;
	  rcDest.right = ptOrigin.x + rcSrc.right;
	  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);
		    }
		}
	    }
	  
	  /* Get a pointer to the next box */
	  ++pBox;
	}
    }
  else
    {
      BoxPtr		pBoxExtents = RegionExtents(damage);

      /* Compute a GDI region from the damaged region */
      hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
      dwBox--;
      pBox++;
      while (dwBox--)
	{
	  hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
	  CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
	  DeleteObject (hrgnTemp);
	  pBox++;
	}

      /* Install the GDI region as a clipping region */
      SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined);
      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;
      rcSrc.top = pBoxExtents->y1;
      rcSrc.right = pBoxExtents->x2;
      rcSrc.bottom = pBoxExtents->y2;

      /* Calculating a bounding box for the destination is trickier */
      rcDest.left = ptOrigin.x + rcSrc.left;
      rcDest.top = ptOrigin.y + rcSrc.top;
      rcDest.right = ptOrigin.x + rcSrc.right;
      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);

      /* Reset the clip region */
      SelectClipRgn (pScreenPriv->hdcScreen, NULL);
    }
}
示例#4
0
static void
winShadowUpdateGDI (ScreenPtr pScreen, 
		    shadowBufPtr pBuf)
{
  winScreenPriv(pScreen);
  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
  RegionPtr		damage = shadowDamage(pBuf);
  DWORD			dwBox = RegionNumRects (damage);
  BoxPtr		pBox = RegionRects (damage);
  int			x, y, w, h;
  HRGN			hrgnTemp = NULL, hrgnCombined = NULL;
#ifdef XWIN_UPDATESTATS
  static DWORD		s_dwNonUnitRegions = 0;
  static DWORD		s_dwTotalUpdates = 0;
  static DWORD		s_dwTotalBoxes = 0;
#endif
  BoxPtr		pBoxExtents = RegionExtents(damage);

  /*
   * Return immediately if the app is not active
   * and we are fullscreen, or if we have a bad display depth
   */
  if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
      || pScreenPriv->fBadDepth) return;

#ifdef XWIN_UPDATESTATS
  ++s_dwTotalUpdates;
  s_dwTotalBoxes += dwBox;

  if (dwBox != 1)
    {
      ++s_dwNonUnitRegions;
      ErrorF ("winShadowUpdatGDI - dwBox: %d\n", dwBox);
    }
  
  if ((s_dwTotalUpdates % 100) == 0)
    ErrorF ("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d "
	    "nu: %d tu: %d\n",
	    (s_dwNonUnitRegions * 100) / s_dwTotalUpdates,
	    s_dwTotalBoxes / s_dwTotalUpdates,
	    s_dwNonUnitRegions, s_dwTotalUpdates);
#endif /* XWIN_UPDATESTATS */

  /*
   * Handle small regions with multiple blits,
   * handle large regions by creating a clipping region and 
   * doing a single blit constrained to that clipping region.
   */
  if (!pScreenInfo->fMultiWindow &&
      (pScreenInfo->dwClipUpdatesNBoxes == 0 ||
      dwBox < pScreenInfo->dwClipUpdatesNBoxes))
    {
      /* Loop through all boxes in the damaged region */
      while (dwBox--)
	{
	  /*
	   * Calculate x offset, y offset, width, and height for
	   * current damage box
	   */
	  x = pBox->x1;
	  y = pBox->y1;
	  w = pBox->x2 - pBox->x1;
	  h = pBox->y2 - pBox->y1;
	  
	  BitBlt (pScreenPriv->hdcScreen,
		  x, y,
		  w, h,
		  pScreenPriv->hdcShadow,
		  x, y,
		  SRCCOPY);
	  
	  /* Get a pointer to the next box */
	  ++pBox;
	}
    }
  else if (!pScreenInfo->fMultiWindow)
    {
      /* Compute a GDI region from the damaged region */
      hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
      dwBox--;
      pBox++;
      while (dwBox--)
	{
	  hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
	  CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
	  DeleteObject (hrgnTemp);
	  pBox++;
	}
      
      /* Install the GDI region as a clipping region */
      SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined);
      DeleteObject (hrgnCombined);
      hrgnCombined = NULL;
      
      /*
       * Blit the shadow buffer to the screen,
       * constrained to the clipping region.
       */
      BitBlt (pScreenPriv->hdcScreen,
	      pBoxExtents->x1, pBoxExtents->y1,
	      pBoxExtents->x2 - pBoxExtents->x1,
	      pBoxExtents->y2 - pBoxExtents->y1,
	      pScreenPriv->hdcShadow,
	      pBoxExtents->x1, pBoxExtents->y1,
	      SRCCOPY);

      /* Reset the clip region */
      SelectClipRgn (pScreenPriv->hdcScreen, NULL);
    }

#ifdef XWIN_MULTIWINDOW
  /* Redraw all multiwindow windows */
  if (pScreenInfo->fMultiWindow)
    EnumThreadWindows (g_dwCurrentThreadID,
		       winRedrawDamagedWindowShadowGDI,
		       (LPARAM)pBoxExtents);
#endif
}