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++; } }
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); } }
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 }