/****************************************************************************** * Module Name: BITBLT.c * Author: Noel VanHook * Purpose: Handle calls to DrvBitBlt * * Copyright (c) 1995,1996 Cirrus Logic, Inc. * * $Log: X:/log/laguna/nt35/displays/cl546x/BITBLT.C $ * * Rev 1.45 Mar 04 1998 15:11:56 frido * Added new shadow macros. * * Rev 1.44 Feb 24 1998 13:24:40 frido * Removed some warning messages for NT 5.0 build. * * Rev 1.43 Jan 22 1998 18:15:58 frido * Revised the pattern blit filter for Access again. * * Rev 1.42 Jan 21 1998 17:33:56 frido * Revised the 24-bpp filter for Access & Excel. * * Rev 1.41 Jan 20 1998 11:43:56 frido * Added a filter for 24-bpp PatBlt. * * Rev 1.40 Nov 03 1997 11:35:48 frido * Added REQUIRE macros. * * Rev 1.39 18 Aug 1997 09:24:04 FRIDO * * Changed all SWAT5 labels into MEMMGR (I forgot that during the merge). * Added dynamic bitmap filter, borrowed from Windows 95. * * Rev 1.38 29 May 1997 10:59:24 noelv * * Frido's fix for 9773 * SWAT: * SWAT: Rev 1.12 29 May 1997 12:12:20 frido * SWAT: Changed striping code from 16-bit to 32-bit. * SWAT: * SWAT: Rev 1.10 09 May 1997 12:57:30 frido * SWAT: Added support for new memory manager. * * Rev 1.37 29 Apr 1997 16:28:12 noelv * * Merged in new SWAT code. * SWAT: * SWAT: Rev 1.9 24 Apr 1997 11:45:54 frido * SWAT: NT140b09 merge. * SWAT: Revised comments. * SWAT: * SWAT: Rev 1.8 19 Apr 1997 16:42:30 frido * SWAT: Added SWAT.h include file. * SWAT: * SWAT: Rev 1.7 18 Apr 1997 00:14:58 frido * SWAT: NT140b07 merge. * SWAT: * SWAT: Rev 1.6 15 Apr 1997 19:13:34 frido * SWAT: Added SWAT6: striping in PatBlt. * SWAT: * SWAT: Rev 1.5 14 Apr 1997 15:30:12 frido * SWAT: Enabled SWAT5 (new bitmap allocation scheme). * SWAT: * SWAT: Rev 1.4 10 Apr 1997 17:37:12 frido * SWAT: Started work on SWAT5 optimizations. * SWAT: * SWAT: Rev 1.3 09 Apr 1997 20:24:18 frido * SWAT: Revised SWAT1 once again. * SWAT: * SWAT: Rev 1.2 09 Apr 1997 17:36:48 frido * SWAT: Changed SWAT1 pre-allocation scheme. * SWAT: Added SWAT1 and SWAT2 switches. * SWAT: * SWAT: Rev 1.1 07 Apr 1997 17:48:06 frido * SWAT: SWAT1: Added heap pre-allocation during WB97 pause. * * Rev 1.36 08 Apr 1997 11:52:46 einkauf * * add SYNC_W_3D to coordination MCD and 2D hw access * * Rev 1.35 21 Mar 1997 10:52:58 noelv * Combined do_flag and sw_test_flag together into 'pointer_switch'. * * Rev 1.34 04 Feb 1997 10:34:18 SueS * Added support for hardware clipping for the 5465. * * Rev 1.33 23 Jan 1997 11:03:18 noelv * * PuntBitBlt now handles device bitmaps stored on the host. * bCreateScreenFromDIB now checks the return code from host to screen operati * * Rev 1.32 17 Dec 1996 16:57:04 SueS * Reject bitmaps of 32x64 or smaller. This is based on WinBench97 * optimization. Reject bitmaps that are larger than the visible screen * width. Added some things to log file writes. * * Rev 1.31 27 Nov 1996 11:32:46 noelv * Disabled Magic Bitmap. Yeah!!! * * Rev 1.30 26 Nov 1996 10:48:40 SueS * Changed WriteLogFile parameters for buffering. * * Rev 1.29 13 Nov 1996 17:05:12 SueS * Changed WriteFile calls to WriteLogFile. * * Rev 1.28 07 Nov 1996 16:07:08 bennyn * * Added no offscn mem allocation if DD enabled * * Rev 1.27 18 Sep 1996 13:49:04 noelv * Opps. Forgot to unhook STROKEANDFILLPATH. * * Rev 1.26 12 Sep 1996 09:18:42 noelv * Fixed bug in infinite offscreen memory. * * Rev 1.25 06 Sep 1996 09:03:54 noelv * * Cleaned up NULL driver code. * * Rev 1.24 20 Aug 1996 11:03:10 noelv * Bugfix release from Frido 8-19-96 * * Rev 1.3 18 Aug 1996 22:48:42 frido * #lineto - Added DrvLineTo. * * Rev 1.2 17 Aug 1996 19:35:36 frido * Cleaned source. * Changed ScreenToMemory bitblt. * * Rev 1.1 15 Aug 1996 11:45:32 frido * Added precompiled header. * * Rev 1.0 14 Aug 1996 17:16:14 frido * Initial revision. * * Rev 1.23 07 Aug 1996 09:04:00 noelv * Sync before punting. * * Rev 1.22 11 Jul 1996 15:52:30 bennyn * Changed constant 400 and 90 to #define variables * * Rev 1.21 04 Jun 1996 15:56:32 noelv * Debug code. * * Rev 1.20 28 May 1996 15:11:02 noelv * Updated data logging. * * Rev 1.19 16 May 1996 15:05:54 bennyn * Added PIXEL_ALIGN to allocoffscnmem() * * Rev 1.18 16 May 1996 14:54:10 noelv * Added logging code. * * Rev 1.17 08 May 1996 17:02:46 noelv * * Preallocate device bitmap * * Rev 1.16 03 May 1996 14:41:42 noelv * Modified device bitmap allocation scheme. * * Rev 1.15 01 May 1996 10:57:28 bennyn * * Modified for NT4.0 * * Rev 1.14 29 Apr 1996 14:16:20 noelv * Clean up. * * Rev 1.13 10 Apr 1996 14:13:52 NOELV * Frido release 27 * * Rev 1.22 08 Apr 1996 16:47:44 frido * Added PuntBitBlt. * * Rev 1.21 27 Mar 1996 13:06:58 frido * Added check for destination in ROP. * Masked color expansions. * Added return value to clipping routine. * * Rev 1.20 25 Mar 1996 11:52:30 frido * Bellevue 102B03. * * Rev 1.9 20 Mar 1996 14:17:30 bennyn * * Rev 1.8 18 Mar 1996 11:42:30 noelv * Added data loggin stuff. Code cleanup. * * Rev 1.7 13 Mar 1996 13:21:04 noelv * Cleanup, documentation, and data logging. * * Rev 1.6 12 Mar 1996 15:43:36 noelv * Added data logging. * Cleanup. * * Rev 1.5 12 Mar 1996 11:17:48 noelv * Code cleanup * * Rev 1.4 08 Mar 1996 11:08:50 noelv * Code cleanup and comments * * Rev 1.3 05 Mar 1996 11:57:28 noelv * Frido version 19 * * Rev 1.15 04 Mar 1996 20:21:44 frido * Removed check for monochrome source and brush. * * Rev 1.14 01 Mar 1996 17:47:58 frido * Added check for destination in BLTDEF. * * Rev 1.13 29 Feb 1996 20:17:32 frido * Added test for special size device bitmaps. * Check for bEnable in CreateScreenFromDib. * * Rev 1.12 28 Feb 1996 22:37:12 frido * Added Optimize.h. * Added check for brushes with monochrome source. * * Rev 1.11 27 Feb 1996 16:38:04 frido * Added device bitmap store/restore. * * Rev 1.10 26 Feb 1996 23:37:32 frido * Fixed several bugs. * * Rev 1.9 24 Feb 1996 01:25:12 frido * Added device bitmaps. * Removed old BitBlt code. * * Rev 1.8 10 Feb 1996 21:39:28 frido * Used SetBrush again for PatternBLT. * * Rev 1.7 08 Feb 1996 00:19:50 frido * Changed the interpretation of cache_slot. * * Rev 1.6 05 Feb 1996 17:35:58 frido * Added translation cache. * * Rev 1.5 03 Feb 1996 13:58:28 frido * Use the compile switch "-Dfrido=0" to disable my extensions. * * Rev 1.4 31 Jan 1996 12:57:50 frido * Called EngBitBlt in case of error. * Changed clipping algorithmns. * * Rev 1.3 25 Jan 1996 22:46:10 frido * Removed bug in complex clipping. * * Rev 1.2 25 Jan 1996 22:07:54 frido * Speeded up the pattern blit. * \**************************************************************************/ #include "precomp.h" #include "SWAT.h" // SWAT optimizations. #define BITBLT_DBG_LEVEL 1 #define CLIP_DBG_LEVEL 1 #define BITMAP_DBG_LEVEL 1 #define PUNT_DBG_LEVEL 1 #define P 1 #define S 2 #define D 4 #define PS (P|S) #define DP (P|D) #define DPS (P|D|S) #define DS (S|D) // // Table with ROP flags. // BYTE ropFlags[256] = { 0, DPS, DPS, PS, DPS, DP, DPS, DPS, DPS, DPS, DP, DPS, PS, DPS, DPS, P, DPS, DS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, PS, DPS, DPS, S, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, PS, DPS, DPS, PS, DPS, DPS, DPS, DPS, DS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DP, DPS, DPS, DPS, DPS, D, DPS, DPS, DPS, DPS, DP, DPS, DPS, DPS, DPS, DP, DPS, DPS, DPS, DPS, DPS, DPS, DS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DS, DPS, DPS, DPS, DPS, DPS, DPS, DP, DPS, DPS, DPS, DPS, DP, DPS, DPS, DPS, DPS, D, DPS, DPS, DPS, DPS, DP, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DS, DPS, DPS, DPS, DPS, PS, DPS, DPS, PS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, S, DPS, DPS, PS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DS, DPS, P, DPS, DPS, PS, DPS, DP, DPS, DPS, DPS, DPS, DP, DPS, PS, DPS, DPS, 0 }; extern void HostifyAllBitmaps(PPDEV ppdev); COPYFN DoDeviceToDevice; BOOL CopyDeviceBitmap( SURFOBJ *psoTrg, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclTrg, POINTL *pptlSrc, ULONG ulDRAWBLTDEF, COPYFN *pfn); BOOL PuntBitBlt( SURFOBJ* psoDest, SURFOBJ* psoSrc, SURFOBJ* psoMask, CLIPOBJ* pco, XLATEOBJ* pxlo, RECTL* prclDest, POINTL* pptlSrc, POINTL* pptlMask, BRUSHOBJ* pbo, POINTL* pptlBrush, ROP4 rop4); #if SWAT6 void StripePatBlt( PPDEV ppdev, ULONG x, ULONG y, ULONG cx, ULONG cy); #endif // // If data logging is enabled, Prototype the logging files. // #if LOG_CALLS void LogBitBlt( int acc, SURFOBJ* psoSrc, SURFOBJ* psoDest, ROP4 rop4, CLIPOBJ* pco, BRUSHOBJ* pbo, XLATEOBJ* pxlo); void LogDrvCreateDevBmp( int acc, PPDEV ppdev, SIZEL sizl, PDSURF pdsurf); void LogDrvDeleteDevBmp( PDSURF pdsurf); void LogCreateDibFromScreen( int acc, PPDEV ppdev, PDSURF pdsurf); void LogCreateScreenFromDib( int acc, PPDEV ppdev, PDSURF pdsurf); // // If data logging is not enabled, compile out the calls. // #else #define LogBitBlt(acc, psoSrc, psoDest, rop4, pco, pbo, pxlo) #define LogDrvCreateDevBmp(acc, ppdev, sizl, pdsurf) #define LogDrvDeleteDevBmp(pdsurf) #define LogCreateDibFromScreen(acc, ppdev, pdsurf) #define LogCreateScreenFromDib(acc, ppdev, pdsurf) #endif /****************************************************************************\ * bIntersectTest * * Test for intersection between two rectangles. * \****************************************************************************/ #define bIntersectTest(prcl1, prcl2) \ (((prcl1)->left < (prcl2)->right) && \ ((prcl1)->right > (prcl2)->left) && \ ((prcl1)->top < (prcl2)->bottom) && \ ((prcl1)->bottom > (prcl2)->top)) /*****************************************************************************\ * BOOL DrvBitBlt * \*****************************************************************************/ #if (USE_ASM && defined(i386)) BOOL i386BitBlt( #else BOOL DrvBitBlt( #endif SURFOBJ* psoDest, SURFOBJ* psoSrc, SURFOBJ* psoMask, CLIPOBJ* pco, XLATEOBJ* pxlo, RECTL* prclDest, POINTL* pptlSrc, POINTL* pptlMask, BRUSHOBJ* pbo, POINTL* pptlBrush, ROP4 rop4) { PPDEV ppdev; ULONG fg_rop, bg_rop; ULONG bltdef = 0; BOOL fSrc, fDest; #if NULL_BITBLT { if (pointer_switch) return(TRUE); } #endif DISPDBG((BITBLT_DBG_LEVEL, "DrvBitBlt: Entry.\n")); ASSERTMSG(psoDest != NULL, "DrvBitBlt: No destination.\n"); // // Get the PDEV associated with the destination. // ppdev = (PPDEV) ((psoDest != NULL) ? psoDest->dhpdev : ((psoSrc != NULL) ? psoSrc->dhpdev : NULL)); // Bad PDEV? if (ppdev == NULL) goto GoToEngine; SYNC_W_3D(ppdev); // // Set a flag to tell us if the source is the frame buffer. // fSrc = (psoSrc != NULL) && // Is there a source? ((psoSrc->iType == STYPE_DEVBITMAP) || // Is it a device bmp? (psoSrc->hsurf == ppdev->hsurfEng) ); // Is it the screen? // // Set a flag telling us if the destination is the frame buffer. // fDest = (psoDest != NULL) && // Is there a dest? ((psoDest->iType == STYPE_DEVBITMAP) || // Is it a device bmp? (psoDest->hsurf == ppdev->hsurfEng) ); // Is it the screen? // // If the destination is a DIB device bitmap, try copying it into // off-screen memory. // if ( fDest && // If dest is supposed to be // the frame buffer, (psoDest->iType == STYPE_DEVBITMAP) && // and it's a device bitmap, ((PDSURF)psoDest->dhsurf)->pso ) // but it's really on the host, { // try to copy it back into off screen memory. if ( !bCreateScreenFromDib(ppdev, (DSURF*) psoDest->dhsurf) ) { // If that fails, then the destination is now on the host. psoDest = ((PDSURF)psoDest->dhsurf)->pso; // Host surface. fDest = FALSE; // Dest is not frame buffer. } } // // If the source is a DIB device bitmap, try copying it into off-screen // memory. // if ( fSrc && // If the source is supposed to // be the frame buffer, (psoSrc->iType == STYPE_DEVBITMAP) && // and it's a device bmp, ((PDSURF)psoSrc->dhsurf)->pso ) // but it's really on the host, { // try to copy it back into off-screen memory. if ( !bCreateScreenFromDib(ppdev, (DSURF*) psoSrc->dhsurf) ) { // If that fails, then our source is really the host. psoSrc = ((PDSURF)psoSrc->dhsurf)->pso; // Host surface. fSrc = FALSE; // Src is not frame buffer. } } if ( fDest ) { BYTE bROP; if (psoDest->iType == STYPE_DEVBITMAP) ppdev->ptlOffset = ((PDSURF)psoDest->dhsurf)->ptl; else ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0; // // Extract the foreground and background ROP from the ROP4 // ASSERTMSG( (rop4>>16) == 0, "DrvBitBlt: Upper word in ROP4 non-zero. \n"); fg_rop = rop4 & 0x000000FF; bg_rop = (rop4>>8) & 0x000000FF; // Punt all true 4 op rops. // If fg_rop != bg_rop, then this is a true 4 op rop, so punt it. // If fg_rop == bg_rop, then it's really a three op rop. if ((fg_rop != bg_rop)) // It's a three op rop, goto GoToEngine; bROP = ropFlags[fg_rop]; #if !(USE_ASM && defined(i386)) { if (!(bROP & S)) { // It is a PatBLT. This is very important, so all calls to the // support routines are stretched into linear code, except for // the caching of the brushes, which should happen only once // for each brush. ULONG drawbltdef = 0x10000000 | fg_rop; if (bROP & D) drawbltdef |= 0x01000000; // Do we have a pttern to load? if (bROP & P) { ULONG color = pbo->iSolidColor; if (color != (ULONG) -1) { // We have a solid color. switch (ppdev->ulBitCount) { case 8: color = (color << 8) | (color & 0xFF); case 16: color = (color << 16) | (color & 0xFFFF); } drawbltdef |= 0x00070000; REQUIRE(2); LL_BGCOLOR(color, 2); } else { if (!SetBrush(ppdev, &bltdef, pbo, pptlBrush)) goto GoToEngine; drawbltdef |= bltdef << 16; } } // Test for no clipping. if ( (pco == NULL) || (pco->iDComplexity == DC_TRIVIAL) ) { #if SWAT6 REQUIRE(2); LL_DRAWBLTDEF(drawbltdef, 2); StripePatBlt(ppdev, prclDest->left + ppdev->ptlOffset.x, prclDest->top + ppdev->ptlOffset.y, prclDest->right - prclDest->left, prclDest->bottom - prclDest->top); #else REQUIRE(7); LL_DRAWBLTDEF(drawbltdef, 0); LL_OP0(prclDest->left + ppdev->ptlOffset.x, prclDest->top + ppdev->ptlOffset.y); LL_BLTEXT(prclDest->right - prclDest->left, prclDest->bottom - prclDest->top); #endif } // Test for rectangle clipping. else if (pco->iDComplexity == DC_RECT) { LONG x, y, cx, cy; x = max(prclDest->left, pco->rclBounds.left); y = max(prclDest->top, pco->rclBounds.top); cx = min(prclDest->right, pco->rclBounds.right) - x; cy = min(prclDest->bottom, pco->rclBounds.bottom) - y; if ( (cx > 0) && (cy > 0) ) { #if SWAT6 REQUIRE(2); LL_DRAWBLTDEF(drawbltdef, 2); StripePatBlt(ppdev, x + ppdev->ptlOffset.x, y + ppdev->ptlOffset.y, cx, cy); #else REQUIRE(7); LL_DRAWBLTDEF(drawbltdef, 0); LL_OP0(x + ppdev->ptlOffset.x, y + ppdev->ptlOffset.y); LL_BLTEXT(cx, cy); #endif } } // Complex clipping. else { BOOL bMore; ENUMRECTS8 ce; RECTL* prcl; #if DRIVER_5465 && HW_CLIPPING // Get a chunk of rectangles. CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0); // Enable clipping REQUIRE(6); LL_DRAWBLTDEF(drawbltdef | DD_CLIPEN, 0); LL_CLIPULE(prclDest->left + ppdev->ptlOffset.x, prclDest->top + ppdev->ptlOffset.y); LL_CLIPLOR(prclDest->right + ppdev->ptlOffset.x, prclDest->bottom + ppdev->ptlOffset.y); do { bMore = CLIPOBJ_bEnum(pco, sizeof(ce), (ULONG *) &ce); for (prcl = ce.arcl; ce.c--; prcl++) { if ((prcl->right > prcl->left) && (prcl->bottom > prcl->top)) { #if SWAT6 StripePatBlt(ppdev, prcl->left + ppdev->ptlOffset.x, prcl->top + ppdev->ptlOffset.y, prcl->right - prcl->left, prcl->bottom - prcl->top); #else REQUIRE(5); LL_OP0(prcl->left + ppdev->ptlOffset.x, prcl->top + ppdev->ptlOffset.y); LL_BLTEXT(prcl->right - prcl->left, prcl->bottom - prcl->top); #endif } } } while (bMore); #else REQUIRE(2); LL_DRAWBLTDEF(drawbltdef, 2); // Get a chunk of rectangles. CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0); do { bMore = CLIPOBJ_bEnum(pco, sizeof(ce), (ULONG *) &ce); for (prcl = ce.arcl; ce.c--; prcl++) { LONG x, y, cx, cy; x = max(prclDest->left, prcl->left); y = max(prclDest->top, prcl->top); cx = min(prclDest->right, prcl->right) - x; cy = min(prclDest->bottom, prcl->bottom) - y; if ( (cx > 0) && (cy > 0) ) { #if SWAT6 StripePatBlt(ppdev, x + ppdev->ptlOffset.x, y + ppdev->ptlOffset.y, cx, cy); #else REQUIRE(5); LL_OP0(x + ppdev->ptlOffset.x, y + ppdev->ptlOffset.y); LL_BLTEXT(cx, cy); #endif } } } while (bMore); #endif } LogBitBlt(0, psoSrc, psoDest, rop4, pco, pbo, pxlo); return(TRUE); } } #endif // !(USE_ASM && defined(i386)) // We only support HostToScreen blits where the Host is either // 1-bpp, 4-bpp, 8-bpp, or the same format as the screen. if ( ((psoSrc->iBitmapFormat > BMF_8BPP) && (psoSrc->iBitmapFormat != psoDest->iBitmapFormat)) ) { goto GoToEngine; } if (bROP & P) { // Realize the brush. if (!SetBrush(ppdev, &bltdef, pbo, pptlBrush)) { goto GoToEngine; } } // If the destination is part of the ROP, set the bit. if (bROP & D) { bltdef |= 0x0100; } // Do the blit. if (CopyDeviceBitmap(psoDest, psoSrc, pco, pxlo, prclDest, pptlSrc, (bltdef << 16) | fg_rop, fSrc ? DoDeviceToDevice : ppdev->pfnHostToScreen)) { LogBitBlt(0, psoSrc, psoDest, rop4, pco, pbo, pxlo); return(TRUE); } } // fDest else if (fSrc) // Destination is bitmap, source is screen or device bitmap. { if (psoSrc->iType == STYPE_DEVBITMAP) { ppdev->ptlOffset = ((PDSURF) psoSrc->dhsurf)->ptl; } else { ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0; } #if S2H_USE_ENGINE { // ROP3? fg_rop = (BYTE) rop4; if (fg_rop == (rop4 >> 8)) { BYTE bROP = ropFlags[fg_rop]; // We dont's support ROPs where the destination is part of. if ( !(bROP & D) ) { // If we need a brush, load it. if (bROP & P) { if (!SetBrush(ppdev, &bltdef, pbo, pptlBrush)) { goto GoToEngine; } } // Now, call the routine through the clip manager. if (CopyDeviceBitmap(psoDest, psoSrc, pco, pxlo, prclDest, pptlSrc, (bltdef << 16) | fg_rop, ppdev->pfnScreenToHost)) { LogBitBlt(0, psoSrc, psoDest, rop4, pco, pbo, pxlo); return(TRUE); } } } } #else { // We only support SRCCOPY. if (rop4 == 0x0000CCCC) { // Now, call the routine through the clip manager. if (CopyDeviceBitmap(psoDest, psoSrc, pco, pxlo, prclDest, pptlSrc, 0x000000CC, ppdev->pfnScreenToHost)) { LogBitBlt(0, psoSrc, psoDest, rop4, pco, pbo, pxlo); return(TRUE); } } } #endif } GoToEngine: // BLT is too complex. Punt it to GDI. DISPDBG((BITBLT_DBG_LEVEL, "DrvBitBlt: Exit (punt). ROP4 = 0x%02X%02X.\n", bg_rop,fg_rop)); LogBitBlt(1, psoSrc, psoDest, rop4, pco, pbo, pxlo); return PuntBitBlt(psoDest, psoSrc, psoMask, pco, pxlo, prclDest, pptlSrc, pptlMask, pbo, pptlBrush, rop4); } /*****************************************************************************\ * DrvCreateDeviceBitmap * * This routine creates a device bitmap that is allocated off-screen. * * On entry: dhpdev Handle of PDEV structure. * sizl Size of the device bitmap to create. * iFormat Bitmap format of the device bitmap to create. * * Returns: We return the handle of a surface object that holds our device * bitmap or 0 if there is an error. \*****************************************************************************/ HBITMAP DrvCreateDeviceBitmap( DHPDEV dhpdev, SIZEL sizl, ULONG iFormat ) { PPDEV ppdev = (PPDEV) dhpdev; POFMHDL pofm; HBITMAP hbmDevice; PDSURF pdsurf; FLONG flHooks = HOOK_SYNCHRONIZEACCESS | HOOK_TEXTOUT | HOOK_BITBLT | HOOK_COPYBITS | HOOK_PAINT | HOOK_STROKEPATH | HOOK_FILLPATH #ifdef WINNT_VER40 | HOOK_LINETO #endif ; SYNC_W_3D(ppdev); #if WINBENCH96 // // We support only device bitmaps that WinBench is going to use. This // to circumvent the limitations of the heap management when there is // not so much video memory. // // Only support bitmaps with a width between 20 and 31, and bitmaps // wider than 100. if ( (sizl.cx < 20) || ((sizl.cx >= 32) && (sizl.cx < 100)) ) { LogDrvCreateDevBmp(1, ppdev, sizl, NULL); return(0); } #else // We don't support anything under or equal to 8x8 (brushes) since // these will only slow us down. if ((sizl.cx <= 8) || (sizl.cy <= 8)) { LogDrvCreateDevBmp(2, ppdev, sizl, NULL); return(0); } #if MEMMGR // New bitmap filter, borrowed from Windows 95. if (ppdev->fBitmapFilter) { if (( (sizl.cx <= ppdev->szlBitmapMin.cx) && (sizl.cy <= ppdev->szlBitmapMin.cy) ) || (sizl.cx > ppdev->szlBitmapMax.cx) || (sizl.cy > ppdev->szlBitmapMax.cy) ) { LogDrvCreateDevBmp(8, ppdev, sizl, NULL); DISPDBG((BITMAP_DBG_LEVEL, "DrvCreateDeviceBitmap - Rejected\n")); return(0); } } #else // Reject any x<=32, or y<=64, for 16 or 24 bpp. // Improves WinBench97 scores. if ((iFormat == BMF_16BPP) || (iFormat == BMF_24BPP)) { if ((sizl.cx <= 32) || (sizl.cy <= 64)) { LogDrvCreateDevBmp(8, ppdev, sizl, NULL); DISPDBG((BITMAP_DBG_LEVEL, "DrvCreateDeviceBitmap - Reject x<=32||y<=64\n")); return(0); } } #endif #endif // Reject if bigger than current screen size if ((ULONG)sizl.cx > ppdev->cxScreen) { LogDrvCreateDevBmp(9, ppdev, sizl, NULL); DISPDBG((BITMAP_DBG_LEVEL, "DrvCreateDeviceBitmap - Reject > cxScreen\n")); return(0); } // If the hardware is not in graphics mode, don't create a device bitmap! if (!ppdev->bEnable) { LogDrvCreateDevBmp(3, ppdev, sizl, NULL); return(0); } // We don't support device bitmaps in any other mode than the hardware. if (iFormat != ppdev->iBitmapFormat) { return(0); } #ifdef ALLOC_IN_CREATESURFACE if (ppdev->bDirectDrawInUse) return (0); #endif #if SWAT1 // Is this the very first device bitmap? if (ppdev->fPreAllocate == FALSE) { // Setup step-down counter. ppdev->fPreAllocate = TRUE; ppdev->nPages = 10; } // Is this the WinBench 97 pause bitmap? else if (sizl.cx == 300 && sizl.cy == 150) { if (ppdev->nPages == 0) { PVOID p; // Allocate 8 full-screen pages from the heap. #ifdef WINNT_VER40 p = MEM_ALLOC(FL_ZERO_MEMORY, 8 * ppdev->cxScreen * ppdev->iBytesPerPixel * ppdev->cyScreen, ALLOC_TAG); #else p = MEM_ALLOC(LPTR, 8 * ppdev->cxScreen * ppdev->iBytesPerPixel * ppdev->cyScreen); #endif // Free it again. MEMORY_FREE(p); } else { // Decrement step-down counter. ppdev->nPages--; } } // Is this a full-screen device bitmap? else if ( (ppdev->nPages == 0) && (sizl.cx == (LONG) ppdev->cxScreen) && (sizl.cy == (LONG) ppdev->cyScreen) ) { PVOID p; // Allocate 8 full-screen pages from the heap. #ifdef WINNT_VER40 p = MEM_ALLOC(FL_ZERO_MEMORY, 8 * ppdev->cxScreen * ppdev->iBytesPerPixel * ppdev->cyScreen, ALLOC_TAG); #else p = MEM_ALLOC(LPTR, 8 * ppdev->cxScreen * ppdev->iBytesPerPixel * ppdev->cyScreen); #endif // Free it again. MEMORY_FREE(p); } #endif // SWAT1 #if SWAT2 // Is this a full-screen device bitmap? if ( (sizl.cx == (LONG) ppdev->cxScreen) && (sizl.cy == (LONG) ppdev->cyScreen) ) { #if MEMMGR // Hostify all device bitmaps. extern void HostifyAllBitmaps(PPDEV ppdev); HostifyAllBitmaps(ppdev); #else POFMHDL pofm, pofmNext; // Hostify all current off-screen device bitmaps. for (pofm = ppdev->OFM_UsedQ; pofm; pofm = pofmNext) { pofmNext = pofm->nexthdl; if (pofm->pdsurf && pofm->pdsurf->pofm) { bCreateDibFromScreen(ppdev, pofm->pdsurf); } else if (pofm->alignflag & SAVESCREEN_FLAG) { FreeOffScnMem(ppdev, pofm); } } #endif } #endif // SWAT2 // // Allocate off-screen memory. // { #if INFINITE_OFFSCREEN_MEM // // This is our "infinite offscreen memory" test. Here we always // succeed in memory allocation. We do this by always allocating // bitmaps at screen 0,0. // It looks ugly, but we can use it to tell of our memory management // is hurting our benchmark scores. // This option is turned off for the retail version of the driver. // 'pointer_switch' is turned on and off in POINTER.C by moving the pointer // to a special place on the screen. // if (pointer_switch) { pofm = ppdev->ScrnHandle; } else #endif // INFINITE_OFFSCREEN_MEM { #if WINBENCH96 // // This is our Magic Bitmap. // Winbench 96 allocates one special bitmap into which it does *lots* // of drawing. If the allocation for this bitmap fails, our WinBench // score will be poor. We ensure that this allocation succeeds // by pre-allocating it at boot time. // // If the size of the requested bitmap matches our magic bitmap, we // assume that Winbench is requesting it's special bitmap, and so we // use the magic bitmap. // if ( (sizl.cx == MAGIC_SIZEX) && (sizl.cy == MAGIC_SIZEY) && ppdev->pofmMagic && !ppdev->bMagicUsed) { // If fits. Use pre-allocated bitmap. DISPDBG((BITMAP_DBG_LEVEL, "DrvCreateDeviceBitmap - Using the Magic Bitmap.\n")); ppdev->bMagicUsed = 1; pofm = ppdev->pofmMagic; } else #endif { DISPDBG((BITMAP_DBG_LEVEL, "DrvCreateDeviceBitmap - Allocating a %d x %d device bitmap.\n", sizl.cx, sizl.cy)); #if MEMMGR if (ppdev->fBitmapFilter) { pofm = AllocOffScnMem(ppdev, &sizl, PIXEL_AlIGN, NULL); if (pofm == NULL) { HostifyAllBitmaps(ppdev); pofm = AllocOffScnMem(ppdev, &sizl, PIXEL_AlIGN, NULL); } } else if (sizl.cx <= ppdev->must_have_width) { pofm = AllocOffScnMem(ppdev, &sizl, PIXEL_AlIGN | MUST_HAVE, NULL); } else #endif pofm = AllocOffScnMem(ppdev, &sizl, PIXEL_AlIGN, NULL); } } } // // If we got the offscreen memory we need, then let's do some work. // if (pofm != NULL) { // Allocate device bitmap structure. #ifdef WINNT_VER40 pdsurf = MEM_ALLOC(FL_ZERO_MEMORY, sizeof(DSURF), ALLOC_TAG); #else pdsurf = MEM_ALLOC(LPTR, sizeof(DSURF)); #endif if (pdsurf != NULL) { // Create the device bitmap object. hbmDevice = EngCreateDeviceBitmap((DHSURF) pdsurf, sizl, iFormat); if (hbmDevice != NULL) { // Associate the device bitmap with the surface. if (EngAssociateSurface((HSURF) hbmDevice, ppdev->hdevEng, flHooks) ) { // Store a pointer to the surface. { #if INFINITE_OFFSCREEN_MEM // // If we're using screen(0,0) as a device bitmap // then don't walk on ScrnHandle->pdsurf! // if (pofm != ppdev->ScrnHandle) #endif pofm->pdsurf = pdsurf; } // Initialize the device bitmap structure. pdsurf->ppdev = ppdev; pdsurf->pofm = pofm; pdsurf->ptl.x = pofm->aligned_x / ppdev->iBytesPerPixel; pdsurf->ptl.y = pofm->aligned_y; pdsurf->packedXY = (pdsurf->ptl.y << 16) | pdsurf->ptl.x; pdsurf->sizl = sizl; LogDrvCreateDevBmp(0, ppdev, sizl, pdsurf); return(hbmDevice); } else { LogDrvCreateDevBmp(4, ppdev, sizl, NULL); } // Delete the surface EngDeleteSurface((HSURF) hbmDevice); } else { LogDrvCreateDevBmp(5, ppdev, sizl, NULL); } // Free the device bitmap structure. MEMORY_FREE(pdsurf); } else { LogDrvCreateDevBmp(6, ppdev, sizl, NULL); } #if WINBENCH96 // Free the off-screen memory. if (pofm == ppdev->pofmMagic) { // We were using the preallocated memory block. Don't free it, // just mark it as unused. ppdev->bMagicUsed = 0; } else #endif { #if INFINITE_OFFSCREEN_MEM // But don't free it if the device bitmap is at screen(0,0)... if (pofm != ppdev->ScrnHandle) #endif FreeOffScnMem(ppdev, pofm); } } else { LogDrvCreateDevBmp(7, ppdev, sizl, NULL); } return(0); } /*****************************************************************************\ * DrvDeleteDeviceBitmap * * This routine deletes a device bitmap and frees the off-screen memory. * * On entry: pdsurf Pointer to device bitmap to delete. \*****************************************************************************/ void DrvDeleteDeviceBitmap(DHSURF dhsurf) { PDSURF pdsurf = (PDSURF) dhsurf; // // Log this call to a file. // LogDrvDeleteDevBmp(pdsurf); // Is the device bitmap stored in a DIB? if (pdsurf->pso) { // Delete the in-memory DIB. HSURF hsurfDib = pdsurf->pso->hsurf; EngUnlockSurface(pdsurf->pso); EngDeleteSurface(hsurfDib); } else { PPDEV ppdev = pdsurf->ppdev; #if INFINITE_OFFSCREEN_MEM // // If we're using screen(0,0) as a device bitmap // then don't walk on ScrnHandle->pdsurf! // if (pdsurf->pofm != ppdev->ScrnHandle) #endif pdsurf->pofm->pdsurf = NULL; #if WINBENCH96 if ( pdsurf->pofm == ppdev->pofmMagic) { // We were using the preallocated chunk of memory. Don't free // it, just mark it as unused. ppdev->bMagicUsed = 0; } else #endif { // Free the off-screen memory. #if INFINITE_OFFSCREEN_MEM // unless our device bitmap is at screen(0,0)... if (pdsurf->pofm != ppdev->ScrnHandle) #endif FreeOffScnMem(pdsurf->ppdev, pdsurf->pofm); } } // Free the device bitmap structure. MEMORY_FREE(pdsurf); } /*****************************************************************************\ * bCreateDibFromScreen * * This routine copy a device bitmap into a DIB and frees the off-screen * memory. * * On entry: ppdev Pointer to physical device. * pdsurf Pointer to device bitmap to copy. * * Returns: TRUE if the off-screen device bitmap was sucessfully copied * into a memory DIB. \*****************************************************************************/ BOOL bCreateDibFromScreen( PPDEV ppdev, PDSURF pdsurf ) { HBITMAP hbmDib; // Create a DIB. hbmDib = EngCreateBitmap(pdsurf->sizl, 0, ppdev->iBitmapFormat, BMF_TOPDOWN, NULL); if (hbmDib) { // Associate the surface with the driver. if (EngAssociateSurface((HSURF) hbmDib, ppdev->hdevEng, 0)) { // Lock the surface. SURFOBJ* pso = EngLockSurface((HSURF) hbmDib); if (pso != NULL) { SIZEL sizl; PBYTE pjScreen, pjBits; // Calculate the size of the blit. sizl.cx = pdsurf->sizl.cx * ppdev->iBytesPerPixel; sizl.cy = pdsurf->sizl.cy; // Calculate the destination variables. pjBits = (PBYTE) pso->pvScan0; // Calculate the screen address. pjScreen = ppdev->pjScreen + (pdsurf->ptl.x * ppdev->iBytesPerPixel) + (pdsurf->ptl.y * ppdev->lDeltaScreen); // Wait for the hardware to become idle. while (LLDR_SZ(grSTATUS) != 0) ; while (sizl.cy--) { // Copy all pixels from screen to memory. memcpy(pjBits, pjScreen, sizl.cx); // Next line. pjScreen += ppdev->lDeltaScreen; pjBits += pso->lDelta; } #if WINBENCH96 // // If the block we are freeing is our preallocated // piece, then invalidate it's pointer. // if ( pdsurf->pofm == ppdev->pofmMagic) ppdev->pofmMagic = 0; #endif #if !MEMMGR // Free the off-screen memory handle. #if INFINITE_OFFSCREEN_MEM // unless our device bitmap is at screen(0,0)... if (pdsurf->pofm != ppdev->ScrnHandle) #endif FreeOffScnMem(pdsurf->ppdev, pdsurf->pofm); #endif // Mark the device bitmap as DIB. pdsurf->pofm = NULL; pdsurf->pso = pso; // Done. LogCreateDibFromScreen(0, ppdev, pdsurf); return(TRUE); } else { // Failed to lock host surface LogCreateDibFromScreen(1, ppdev, pdsurf); } } else { // Failed to associate host surface LogCreateDibFromScreen(2, ppdev, pdsurf); } // Delete the DIB. EngDeleteSurface((HSURF) hbmDib); } else { // Failed to create host surface. LogCreateDibFromScreen(3, ppdev, pdsurf); } // Error. return(FALSE); } /*****************************************************************************\ * bCreateScreenFromDib * * This routine copys a DIB into a device bitmap and frees the DIB from memory. * * On entry: ppdev Pointer to physical device. * pdsurf Pointer to device bitmap to copy. * * Returns: TRUE if the DIB was sucessfully copied into an off-screen * device bitmap. \*****************************************************************************/ BOOL bCreateScreenFromDib( PPDEV ppdev, PDSURF pdsurf ) { POFMHDL pofm; HSURF hsurf; SURFOBJ* pso; #if MEMMGR // In low memory situations, bitmaps will be hostified very frequently, so // don't copy them back to the off-screen... if (ppdev->fBitmapFilter) { return FALSE; } #endif // If the hardware is not in graphics mode, keep the device bitmap in // memory. if (!ppdev->bEnable) { LogCreateScreenFromDib (1, ppdev, pdsurf); return(FALSE); } #ifdef ALLOC_IN_CREATESURFACE if (ppdev->bDirectDrawInUse) return (FALSE); #endif // Allocate off-screen memory. pofm = AllocOffScnMem(ppdev, &pdsurf->sizl, PIXEL_AlIGN, NULL); if (pofm != NULL) { SURFOBJ psoDest; RECTL rclDest; POINTL ptlSrc; // // Tell the device bitmap where it lives in offscreen memory. // pdsurf->ptl.x = pofm->aligned_x / ppdev->iBytesPerPixel; pdsurf->ptl.y = pofm->aligned_y; pdsurf->packedXY = (pdsurf->ptl.y << 16) | pdsurf->ptl.x; // // Create a two way link between the device bitmap and // its offscreen memory block. // pdsurf->pofm = pofm; // Attach offscreen memory block to device bitmap pofm->pdsurf = pdsurf; // Attach device bitmap to offscreen memory block // // Disattach the host bitmap from the device bitmap. // Save the pointer, because if we fail to move the device bitmap // into the frame buffer, it will remain in host memory, and we // will have to restore this pointer. // pso = pdsurf->pso; // Save pointer to bitmap in host memory. pdsurf->pso = NULL; // disattach host memory // // Wrap the offscreen memory in a destination surface object. // This is so we can use a host to screen BLT to move the bitmap // from the host to the offscreen memory. // psoDest.dhsurf = (DHSURF) pdsurf; psoDest.iType = STYPE_DEVBITMAP; // // Build a destination rectangle that describes where to put the // bitmap in offscreen memory. This rectangle is relative to // upper left corner of the allocated block of offscreen memory. // rclDest.left = 0; rclDest.top = 0; rclDest.right = pdsurf->sizl.cx; rclDest.bottom = pdsurf->sizl.cy; // // Build a source point. // Since we're moving the entire bitmap, its (0,0). // ptlSrc.x = ptlSrc.y = 0; // // Use our host to screen code to copy the DIB into off-screen memory. // if (!ppdev->pfnHostToScreen(&psoDest, pso, NULL, &rclDest, &ptlSrc, 0x000000CC)) { // // BLT engine couldn't put it back into off screen memory. // Maybe the DIB engine can. // DISPDBG (( 0, "Couldn't BLT device bitmap back into framebuffer.\n")); if (! PuntBitBlt(&psoDest, pso, NULL, NULL, NULL, &rclDest, &ptlSrc, NULL, NULL, NULL, 0x0000CCCC)) { // Nope! We can't move it back to the frame buffer. DISPDBG (( 0, "Couldn't punt device bitmap back into framebuffer.\n")); DISPDBG (( 0, "Device bitmap will remain in offscreen memory.\n")); // Restore the surface object pointers. pdsurf->pofm = NULL; // This device bitmap has no offscreen memory. pdsurf->pso = pso; // This device bitmap lives here, on the host. // Free the offscreen memory we allocated and fail. FreeOffScnMem(ppdev, pofm); return FALSE; } } // Delete the DIB. hsurf = pso->hsurf; EngUnlockSurface(pso); EngDeleteSurface(hsurf); // Done. LogCreateScreenFromDib (0, ppdev, pdsurf); return(TRUE); } // Error. LogCreateScreenFromDib (2, ppdev, pdsurf); return(FALSE); } #if LOG_CALLS // ============================================================================ // // Everything from here down is for data logging and is not used in the // production driver. // // ============================================================================ extern long lg_i; extern char lg_buf[256]; // **************************************************************************** // // LogBitBlt() // This routine is called only from DrvBitBlt() // Dump information to a file about what is going on in BitBlt land. // // **************************************************************************** void LogBitBlt( int acc, SURFOBJ* psoSrc, SURFOBJ* psoDest, ROP4 rop4, CLIPOBJ* pco, BRUSHOBJ* pbo, XLATEOBJ* pxlo) { PPDEV dppdev,sppdev,ppdev; BYTE fg_rop, bg_rop; ULONG iDComplexity; dppdev = (PPDEV) (psoDest ? psoDest->dhpdev : 0); sppdev = (PPDEV) (psoSrc ? psoSrc->dhpdev : 0); ppdev = dppdev ? dppdev : sppdev; #if ENABLE_LOG_SWITCH if (pointer_switch == 0) return; #endif lg_i = sprintf(lg_buf,"DBB: "); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); if (acc) { lg_i = sprintf(lg_buf,"PNT "); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); } fg_rop = (BYTE) (rop4 & 0xff); bg_rop = (BYTE) ((rop4>>8) & 0xff); // // Check the SRC // if ( (ropFlags[fg_rop] & S) && (psoSrc)) { if (psoSrc->iType == STYPE_DEVBITMAP) { lg_i = sprintf(lg_buf, "Src Id=%p ", psoSrc->dhsurf); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); if ( ((PDSURF)psoSrc->dhsurf)->pso ) lg_i = sprintf(lg_buf,"S=DH "); else lg_i = sprintf(lg_buf,"S=DF "); } else if (psoSrc->hsurf == ppdev->hsurfEng) lg_i = sprintf(lg_buf,"S=S "); else lg_i = sprintf(lg_buf,"S=H "); } else lg_i = sprintf(lg_buf,"S=N "); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); // // Check the DEST // if (psoDest) { if (psoDest->iType == STYPE_DEVBITMAP) { lg_i = sprintf(lg_buf, "Dst Id=%p ", psoDest->dhsurf); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); if ( ((PDSURF)psoDest->dhsurf)->pso ) lg_i = sprintf(lg_buf,"D=DH "); else lg_i = sprintf(lg_buf,"D=DF "); } else if (psoDest->hsurf == ppdev->hsurfEng) lg_i = sprintf(lg_buf,"D=S "); else lg_i = sprintf(lg_buf,"D=H "); } else lg_i = sprintf(lg_buf,"D=N "); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); // // Check the ROP // if (fg_rop == bg_rop) lg_i = sprintf(lg_buf,"R3=%02X ", fg_rop); else lg_i = sprintf(lg_buf,"R4=%04X ", rop4&0xFFFF); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); // // Check the type of clipping. // iDComplexity = (pco ? pco->iDComplexity : DC_TRIVIAL); lg_i = sprintf(lg_buf,"C=%s ", (iDComplexity==DC_TRIVIAL ? "T": (iDComplexity == DC_RECT ? "R" : "C" ))); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); // // Type of pattern. // if (ropFlags[fg_rop] & P) { if (pbo->iSolidColor == 0xFFFFFFFF ) { lg_i = sprintf(lg_buf,"BR=P "); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); } else { lg_i = sprintf(lg_buf,"BR=0x%X ",(pbo->iSolidColor)); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); } } else { lg_i = sprintf(lg_buf,"BR=N "); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); } // // Type of translation // if (!pxlo) { lg_i = sprintf(lg_buf,"TR=N "); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); } else if (pxlo->flXlate & XO_TRIVIAL) { lg_i = sprintf(lg_buf,"TR=T "); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); } else { lg_i = sprintf(lg_buf,"TR=NT "); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); } lg_i = sprintf(lg_buf,"\r\n"); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); return; } // **************************************************************************** // // LogDrvCreateDevBmp() // This routine is called only from DrvCreateDeviceBitmap() // Dump information to a file about what is going on in device bitmap land. // // **************************************************************************** void LogDrvCreateDevBmp( int acc, PPDEV ppdev, SIZEL sizl, PDSURF pdsurf) { #if ENABLE_LOG_SWITCH if (pointer_switch == 0) return; #endif switch(acc) { case 0: // Accelerated lg_i = sprintf(lg_buf, "DrvCreateDeviceBitmap: %4d x %4d Id: 0x%08X Loc: %d,%d \r\n", sizl.cx, sizl.cy, pdsurf, pdsurf->pofm->x, pdsurf->pofm->y ); break; case 1: // Punted lg_i = sprintf(lg_buf, "DrvCreateDeviceBitmap: %4d x %4d Punt size.\r\n", sizl.cx, sizl.cy); break; case 2: // Punted lg_i = sprintf(lg_buf, "DrvCreateDeviceBitmap: %4d x %4d Punt 8x8.\r\n", sizl.cx, sizl.cy); break; case 3: // Punted lg_i = sprintf(lg_buf, "DrvCreateDeviceBitmap: %4d x %4d Punt mode.\r\n", sizl.cx, sizl.cy); break; case 4: // Punted lg_i = sprintf(lg_buf, "DrvCreateDeviceBitmap: %4d x %4d Punt assoc.\r\n", sizl.cx, sizl.cy); break; case 5: // Punted lg_i = sprintf(lg_buf, "DrvCreateDeviceBitmap: %4d x %4d Punt bitmap.\r\n", sizl.cx, sizl.cy); break; case 6: // Punted lg_i = sprintf(lg_buf, "DrvCreateDeviceBitmap: %4d x %4d Punt DSURF.\r\n", sizl.cx, sizl.cy); break; case 7: // Punted lg_i = sprintf(lg_buf, "DrvCreateDeviceBitmap: %4d x %4d Punt FB alloc.\r\n", sizl.cx, sizl.cy); break; case 8: // Punted lg_i = sprintf(lg_buf, "DrvCreateDeviceBitmap: %4d x %4d Punt 32x64.\r\n", sizl.cx, sizl.cy); break; case 9: // Punted lg_i = sprintf(lg_buf, "DrvCreateDeviceBitmap: %4d x %4d Punt > cxScreen.\r\n", sizl.cx, sizl.cy); break; default: lg_i = sprintf(lg_buf, "DrvCreateDeviceBitmap: %4d x %4d Punt unknown.\r\n", sizl.cx, sizl.cy); break; } WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); } // **************************************************************************** // // LogDrvDeleteDevBmp() // This routine is called only from DrvDeleteDeviceBitmap() // Dump information to a file about what is going on in device bitmap land. // // **************************************************************************** void LogDrvDeleteDevBmp( PDSURF pdsurf) { #if ENABLE_LOG_SWITCH if (pointer_switch == 0) return; #endif lg_i = sprintf(lg_buf, "DrvDeleteDeviceBitmap: Id: 0x%08X. ", pdsurf); WriteLogFile(pdsurf->ppdev->pmfile, lg_buf, lg_i, pdsurf->ppdev->TxtBuff, &pdsurf->ppdev->TxtBuffIndex); if (pdsurf->pso) { lg_i = sprintf(lg_buf, "Loc: HOST\r\n"); WriteLogFile(pdsurf->ppdev->pmfile, lg_buf, lg_i, pdsurf->ppdev->TxtBuff, &pdsurf->ppdev->TxtBuffIndex); } else { lg_i = sprintf(lg_buf, "Loc: %d,%d\r\n", pdsurf->pofm->x, pdsurf->pofm->y); WriteLogFile(pdsurf->ppdev->pmfile, lg_buf, lg_i, pdsurf->ppdev->TxtBuff, &pdsurf->ppdev->TxtBuffIndex); } } // **************************************************************************** // // LogCreateDibFromScreen() // This routine is called only from bCreateDibFromScreen() // Dump information to a file about what is going on in device bitmap land. // // **************************************************************************** void LogCreateDibFromScreen( int acc, PPDEV ppdev, PDSURF pdsurf ) { #if ENABLE_LOG_SWITCH if (pointer_switch == 0) return; #endif lg_i = sprintf(lg_buf, "CreateDibFromScreen: Id: 0x%08X ", pdsurf); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); switch(acc) { case 0: // Succeeded lg_i = sprintf(lg_buf, " \r\n"); break; case 1: // Failed lg_i = sprintf(lg_buf, "Fail lock\r\n"); break; case 2: // Failed lg_i = sprintf(lg_buf, "Fail assoc\r\n"); break; case 3: // Failed lg_i = sprintf(lg_buf, " Fail create\r\n"); break; default: lg_i = sprintf(lg_buf, "Failed unknown\r\n"); break; } WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); } // **************************************************************************** // // LogCreateScreenFromDib() // This routine is called only from bCreateScreenFromDib() // Dump information to a file about what is going on in device bitmap land. // // **************************************************************************** void LogCreateScreenFromDib( int acc, PPDEV ppdev, PDSURF pdsurf ) { #if ENABLE_LOG_SWITCH if (pointer_switch == 0) return; #endif lg_i = sprintf(lg_buf, "CreateScreenFromDib: "); WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); switch(acc) { case 0: // Succeeded lg_i = sprintf(lg_buf, "Id: 0x%08X Dest: %d,%d\r\n", pdsurf, pdsurf->pofm->x, pdsurf->pofm->y ); break; case 1: // Failed lg_i = sprintf(lg_buf, "Fail mode\r\n"); break; case 2: // Failed lg_i = sprintf(lg_buf, "Fail alloc\r\n"); break; default: // Failed lg_i = sprintf(lg_buf, "Fail unknown\r\n"); break; } WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); } #endif // LOG_CALLS // ============================================================================ // // Punt a drawing operation back to GDI. // Return TRUE if punt was successful. // Return FALSE if punt failed. // BOOL PuntBitBlt( SURFOBJ* psoDest, SURFOBJ* psoSrc, SURFOBJ* psoMask, CLIPOBJ* pco, XLATEOBJ* pxlo, RECTL* prclDest, POINTL* pptlSrc, POINTL* pptlMask, BRUSHOBJ* pbo, POINTL* pptlBrush, ROP4 rop4) { HBITMAP hbmDibSrc = 0; HBITMAP hbmDibDest = 0; PBYTE pjScreen; BOOL bStatus; PDSURF pdsurf; PPDEV ppdev = 0; DISPDBG((PUNT_DBG_LEVEL, "PuntBitBlt: Entry.\n")); // // If the source is a device bitmap, build a wrapper around it. // if ( psoSrc && (psoSrc->iType == STYPE_DEVBITMAP)) { // Source is a device bitmap. pdsurf = (PDSURF) psoSrc->dhsurf; ppdev = pdsurf->ppdev; if ( pdsurf->pofm ) // If it's in the frame buffer. { DISPDBG((PUNT_DBG_LEVEL, " Source is device bitmap at (%d,%d).\n", (pdsurf->ptl.x), (pdsurf->ptl.y))); // Calculate the off-screen address. // This is the upper left pixel in the device bitmap. pjScreen = ppdev->pjScreen + (pdsurf->ptl.x * ppdev->iBytesPerPixel) + (pdsurf->ptl.y * ppdev->lDeltaScreen); // Create a DIB. Point it's bits at the device bitmap. hbmDibSrc = EngCreateBitmap(pdsurf->sizl, ppdev->lDeltaScreen, ppdev->iBitmapFormat, BMF_TOPDOWN, pjScreen); // Associate the DIB surface with the driver. EngAssociateSurface((HSURF) hbmDibSrc, ppdev->hdevEng, 0); // Lock the DIB surface. psoSrc = EngLockSurface((HSURF) hbmDibSrc); } else // The device bitmap is on the host. { DISPDBG((PUNT_DBG_LEVEL, " Source is device bitmap on host.\n")); psoSrc = pdsurf->pso; // This is where it lives on the host. } } // // If the destination is a device bitmap, build a wrapper around it. // if ( psoDest && (psoDest->iType == STYPE_DEVBITMAP)) { // Destination is a device bitmap. pdsurf = (PDSURF) psoDest->dhsurf; ppdev = pdsurf->ppdev; if ( pdsurf->pofm ) // If it's in the frame buffer. { DISPDBG((PUNT_DBG_LEVEL, " Dest is device bitmap at (%d,%d).\n", (pdsurf->ptl.x), (pdsurf->ptl.y))); // Calculate the off-screen address. // This is the upper left pixel in the device bitmap. pjScreen = ppdev->pjScreen + (pdsurf->ptl.x * ppdev->iBytesPerPixel) + (pdsurf->ptl.y * ppdev->lDeltaScreen); // Create a DIB. Point it's bits at the device bitmap. hbmDibDest = EngCreateBitmap(pdsurf->sizl, ppdev->lDeltaScreen, ppdev->iBitmapFormat, BMF_TOPDOWN, pjScreen); // Associate the DIB surface with the driver. EngAssociateSurface((HSURF) hbmDibDest, ppdev->hdevEng, 0); // Lock the DIB surface. psoDest = EngLockSurface((HSURF) hbmDibDest); } else // The device bitmap is on the host. { DISPDBG((PUNT_DBG_LEVEL, " Dest is device bitmap on host.\n")); psoDest = pdsurf->pso; } } // // We're fooling GDI into thinking it's drawing to memory, when it's really // drawing to the frame buffer. This means GDI won't call DrvSync() before // drawing. // if (ppdev == 0) { ppdev = (PPDEV) psoDest->dhpdev; if (ppdev == 0) ppdev = (PPDEV) psoSrc->dhpdev; } ASSERTMSG(ppdev,"Panic. No ppdev in PuntBitBlt()!"); DrvSynchronize((DHPDEV) ppdev, NULL); // Now, call the GDI. bStatus = EngBitBlt(psoDest, psoSrc, psoMask, pco, pxlo, prclDest, pptlSrc, pptlMask, pbo, pptlBrush, rop4); // Delete the wrappers if they are created. if (hbmDibSrc) { EngUnlockSurface(psoSrc); EngDeleteSurface((HSURF) hbmDibSrc); } if (hbmDibDest) { EngUnlockSurface(psoDest); EngDeleteSurface((HSURF) hbmDibDest); } DISPDBG((PUNT_DBG_LEVEL, "PuntBitBlt: Exit.\n")); // Return the status. return(bStatus); } #if SWAT6 /******************************************************************************\ * FUNCTION: StripePatBlt * * DESCRIPTION: Perform a PatBlt with striping. * * ON ENTRY: ppdev Pointer to physical device. * x X coordinate of blit. * y Y coordinate of blit. * cx Width of blit. * cy Height of blit. * * RETURNS: void Nothing. \******************************************************************************/ void StripePatBlt( PPDEV ppdev, ULONG x, ULONG y, ULONG cx, ULONG cy ) { ULONG cxWidth; ULONG TileWidth; // Determine number of pixels per tile. switch (ppdev->iBytesPerPixel) { case 1: // 8-bpp. TileWidth = (ULONG) ppdev->lTileSize; break; case 2: // 16-bpp. TileWidth = (ULONG) (ppdev->lTileSize) / 2; break; case 3: // 24-bpp, perform the PatBlt at once since we don't have a nice // number of pixels per tile. REQUIRE(5); LL_OP0(x, y); LL_BLTEXT(cx, cy); if (cx >= 0x391 && cy >= 0x24B) { ENDREQUIRE(); } return; case 4: // 32-bpp. TileWidth = (ULONG) (ppdev->lTileSize) / 4; break; } // Determine number of pixels left in first tile. cxWidth = TileWidth - (x & (TileWidth - 1)); if ( (cxWidth >= cx) || (cy == 1) ) { // PatBlt width fits in a single tile. REQUIRE(5); LL_OP0(x, y); LL_BLTEXT(cx, cy); return; } // Perform the PatBlt in the first tile. REQUIRE(5); LL_OP0(x, y); LL_BLTEXT(cxWidth, cy); cx -= cxWidth; x += cxWidth; // Keep looping until we reach the last tile of the PatBlt. while (cx > TileWidth) { // Perform the PatBlt on a complete tile (only x changes). REQUIRE(5); LL_OP0(x, y); LL_BLTEXT(TileWidth, cy); cx -= TileWidth; x += TileWidth; } // Perform the PatBlt in the last tile (only x changes). REQUIRE(5); LL_OP0(x, y); LL_BLTEXT(cx, cy); } // StripePatBlt(); #endif // SWAT6