Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2081 lines
67 KiB

  1. /******************************************************************************
  2. * Module Name: BITBLT.c
  3. * Author: Noel VanHook
  4. * Purpose: Handle calls to DrvBitBlt
  5. *
  6. * Copyright (c) 1995,1996 Cirrus Logic, Inc.
  7. *
  8. * $Log: X:/log/laguna/nt35/displays/cl546x/BITBLT.C $
  9. *
  10. * Rev 1.45 Mar 04 1998 15:11:56 frido
  11. * Added new shadow macros.
  12. *
  13. * Rev 1.44 Feb 24 1998 13:24:40 frido
  14. * Removed some warning messages for NT 5.0 build.
  15. *
  16. * Rev 1.43 Jan 22 1998 18:15:58 frido
  17. * Revised the pattern blit filter for Access again.
  18. *
  19. * Rev 1.42 Jan 21 1998 17:33:56 frido
  20. * Revised the 24-bpp filter for Access & Excel.
  21. *
  22. * Rev 1.41 Jan 20 1998 11:43:56 frido
  23. * Added a filter for 24-bpp PatBlt.
  24. *
  25. * Rev 1.40 Nov 03 1997 11:35:48 frido
  26. * Added REQUIRE macros.
  27. *
  28. * Rev 1.39 18 Aug 1997 09:24:04 FRIDO
  29. *
  30. * Changed all SWAT5 labels into MEMMGR (I forgot that during the merge).
  31. * Added dynamic bitmap filter, borrowed from Windows 95.
  32. *
  33. * Rev 1.38 29 May 1997 10:59:24 noelv
  34. *
  35. * Frido's fix for 9773
  36. * SWAT:
  37. * SWAT: Rev 1.12 29 May 1997 12:12:20 frido
  38. * SWAT: Changed striping code from 16-bit to 32-bit.
  39. * SWAT:
  40. * SWAT: Rev 1.10 09 May 1997 12:57:30 frido
  41. * SWAT: Added support for new memory manager.
  42. *
  43. * Rev 1.37 29 Apr 1997 16:28:12 noelv
  44. *
  45. * Merged in new SWAT code.
  46. * SWAT:
  47. * SWAT: Rev 1.9 24 Apr 1997 11:45:54 frido
  48. * SWAT: NT140b09 merge.
  49. * SWAT: Revised comments.
  50. * SWAT:
  51. * SWAT: Rev 1.8 19 Apr 1997 16:42:30 frido
  52. * SWAT: Added SWAT.h include file.
  53. * SWAT:
  54. * SWAT: Rev 1.7 18 Apr 1997 00:14:58 frido
  55. * SWAT: NT140b07 merge.
  56. * SWAT:
  57. * SWAT: Rev 1.6 15 Apr 1997 19:13:34 frido
  58. * SWAT: Added SWAT6: striping in PatBlt.
  59. * SWAT:
  60. * SWAT: Rev 1.5 14 Apr 1997 15:30:12 frido
  61. * SWAT: Enabled SWAT5 (new bitmap allocation scheme).
  62. * SWAT:
  63. * SWAT: Rev 1.4 10 Apr 1997 17:37:12 frido
  64. * SWAT: Started work on SWAT5 optimizations.
  65. * SWAT:
  66. * SWAT: Rev 1.3 09 Apr 1997 20:24:18 frido
  67. * SWAT: Revised SWAT1 once again.
  68. * SWAT:
  69. * SWAT: Rev 1.2 09 Apr 1997 17:36:48 frido
  70. * SWAT: Changed SWAT1 pre-allocation scheme.
  71. * SWAT: Added SWAT1 and SWAT2 switches.
  72. * SWAT:
  73. * SWAT: Rev 1.1 07 Apr 1997 17:48:06 frido
  74. * SWAT: SWAT1: Added heap pre-allocation during WB97 pause.
  75. *
  76. * Rev 1.36 08 Apr 1997 11:52:46 einkauf
  77. *
  78. * add SYNC_W_3D to coordination MCD and 2D hw access
  79. *
  80. * Rev 1.35 21 Mar 1997 10:52:58 noelv
  81. * Combined do_flag and sw_test_flag together into 'pointer_switch'.
  82. *
  83. * Rev 1.34 04 Feb 1997 10:34:18 SueS
  84. * Added support for hardware clipping for the 5465.
  85. *
  86. * Rev 1.33 23 Jan 1997 11:03:18 noelv
  87. *
  88. * PuntBitBlt now handles device bitmaps stored on the host.
  89. * bCreateScreenFromDIB now checks the return code from host to screen operati
  90. *
  91. * Rev 1.32 17 Dec 1996 16:57:04 SueS
  92. * Reject bitmaps of 32x64 or smaller. This is based on WinBench97
  93. * optimization. Reject bitmaps that are larger than the visible screen
  94. * width. Added some things to log file writes.
  95. *
  96. * Rev 1.31 27 Nov 1996 11:32:46 noelv
  97. * Disabled Magic Bitmap. Yeah!!!
  98. *
  99. * Rev 1.30 26 Nov 1996 10:48:40 SueS
  100. * Changed WriteLogFile parameters for buffering.
  101. *
  102. * Rev 1.29 13 Nov 1996 17:05:12 SueS
  103. * Changed WriteFile calls to WriteLogFile.
  104. *
  105. * Rev 1.28 07 Nov 1996 16:07:08 bennyn
  106. *
  107. * Added no offscn mem allocation if DD enabled
  108. *
  109. * Rev 1.27 18 Sep 1996 13:49:04 noelv
  110. * Opps. Forgot to unhook STROKEANDFILLPATH.
  111. *
  112. * Rev 1.26 12 Sep 1996 09:18:42 noelv
  113. * Fixed bug in infinite offscreen memory.
  114. *
  115. * Rev 1.25 06 Sep 1996 09:03:54 noelv
  116. *
  117. * Cleaned up NULL driver code.
  118. *
  119. * Rev 1.24 20 Aug 1996 11:03:10 noelv
  120. * Bugfix release from Frido 8-19-96
  121. *
  122. * Rev 1.3 18 Aug 1996 22:48:42 frido
  123. * #lineto - Added DrvLineTo.
  124. *
  125. * Rev 1.2 17 Aug 1996 19:35:36 frido
  126. * Cleaned source.
  127. * Changed ScreenToMemory bitblt.
  128. *
  129. * Rev 1.1 15 Aug 1996 11:45:32 frido
  130. * Added precompiled header.
  131. *
  132. * Rev 1.0 14 Aug 1996 17:16:14 frido
  133. * Initial revision.
  134. *
  135. * Rev 1.23 07 Aug 1996 09:04:00 noelv
  136. * Sync before punting.
  137. *
  138. * Rev 1.22 11 Jul 1996 15:52:30 bennyn
  139. * Changed constant 400 and 90 to #define variables
  140. *
  141. * Rev 1.21 04 Jun 1996 15:56:32 noelv
  142. * Debug code.
  143. *
  144. * Rev 1.20 28 May 1996 15:11:02 noelv
  145. * Updated data logging.
  146. *
  147. * Rev 1.19 16 May 1996 15:05:54 bennyn
  148. * Added PIXEL_ALIGN to allocoffscnmem()
  149. *
  150. * Rev 1.18 16 May 1996 14:54:10 noelv
  151. * Added logging code.
  152. *
  153. * Rev 1.17 08 May 1996 17:02:46 noelv
  154. *
  155. * Preallocate device bitmap
  156. *
  157. * Rev 1.16 03 May 1996 14:41:42 noelv
  158. * Modified device bitmap allocation scheme.
  159. *
  160. * Rev 1.15 01 May 1996 10:57:28 bennyn
  161. *
  162. * Modified for NT4.0
  163. *
  164. * Rev 1.14 29 Apr 1996 14:16:20 noelv
  165. * Clean up.
  166. *
  167. * Rev 1.13 10 Apr 1996 14:13:52 NOELV
  168. * Frido release 27
  169. *
  170. * Rev 1.22 08 Apr 1996 16:47:44 frido
  171. * Added PuntBitBlt.
  172. *
  173. * Rev 1.21 27 Mar 1996 13:06:58 frido
  174. * Added check for destination in ROP.
  175. * Masked color expansions.
  176. * Added return value to clipping routine.
  177. *
  178. * Rev 1.20 25 Mar 1996 11:52:30 frido
  179. * Bellevue 102B03.
  180. *
  181. * Rev 1.9 20 Mar 1996 14:17:30 bennyn
  182. *
  183. * Rev 1.8 18 Mar 1996 11:42:30 noelv
  184. * Added data loggin stuff. Code cleanup.
  185. *
  186. * Rev 1.7 13 Mar 1996 13:21:04 noelv
  187. * Cleanup, documentation, and data logging.
  188. *
  189. * Rev 1.6 12 Mar 1996 15:43:36 noelv
  190. * Added data logging.
  191. * Cleanup.
  192. *
  193. * Rev 1.5 12 Mar 1996 11:17:48 noelv
  194. * Code cleanup
  195. *
  196. * Rev 1.4 08 Mar 1996 11:08:50 noelv
  197. * Code cleanup and comments
  198. *
  199. * Rev 1.3 05 Mar 1996 11:57:28 noelv
  200. * Frido version 19
  201. *
  202. * Rev 1.15 04 Mar 1996 20:21:44 frido
  203. * Removed check for monochrome source and brush.
  204. *
  205. * Rev 1.14 01 Mar 1996 17:47:58 frido
  206. * Added check for destination in BLTDEF.
  207. *
  208. * Rev 1.13 29 Feb 1996 20:17:32 frido
  209. * Added test for special size device bitmaps.
  210. * Check for bEnable in CreateScreenFromDib.
  211. *
  212. * Rev 1.12 28 Feb 1996 22:37:12 frido
  213. * Added Optimize.h.
  214. * Added check for brushes with monochrome source.
  215. *
  216. * Rev 1.11 27 Feb 1996 16:38:04 frido
  217. * Added device bitmap store/restore.
  218. *
  219. * Rev 1.10 26 Feb 1996 23:37:32 frido
  220. * Fixed several bugs.
  221. *
  222. * Rev 1.9 24 Feb 1996 01:25:12 frido
  223. * Added device bitmaps.
  224. * Removed old BitBlt code.
  225. *
  226. * Rev 1.8 10 Feb 1996 21:39:28 frido
  227. * Used SetBrush again for PatternBLT.
  228. *
  229. * Rev 1.7 08 Feb 1996 00:19:50 frido
  230. * Changed the interpretation of cache_slot.
  231. *
  232. * Rev 1.6 05 Feb 1996 17:35:58 frido
  233. * Added translation cache.
  234. *
  235. * Rev 1.5 03 Feb 1996 13:58:28 frido
  236. * Use the compile switch "-Dfrido=0" to disable my extensions.
  237. *
  238. * Rev 1.4 31 Jan 1996 12:57:50 frido
  239. * Called EngBitBlt in case of error.
  240. * Changed clipping algorithmns.
  241. *
  242. * Rev 1.3 25 Jan 1996 22:46:10 frido
  243. * Removed bug in complex clipping.
  244. *
  245. * Rev 1.2 25 Jan 1996 22:07:54 frido
  246. * Speeded up the pattern blit.
  247. *
  248. \**************************************************************************/
  249. #include "precomp.h"
  250. #include "SWAT.h" // SWAT optimizations.
  251. #define BITBLT_DBG_LEVEL 1
  252. #define CLIP_DBG_LEVEL 1
  253. #define BITMAP_DBG_LEVEL 1
  254. #define PUNT_DBG_LEVEL 1
  255. #define P 1
  256. #define S 2
  257. #define D 4
  258. #define PS (P|S)
  259. #define DP (P|D)
  260. #define DPS (P|D|S)
  261. #define DS (S|D)
  262. //
  263. // Table with ROP flags.
  264. //
  265. BYTE ropFlags[256] =
  266. {
  267. 0, DPS, DPS, PS, DPS, DP, DPS, DPS, DPS, DPS, DP, DPS, PS, DPS, DPS, P,
  268. DPS, DS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS,
  269. DPS, DPS, DS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS,
  270. PS, DPS, DPS, S, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, PS, DPS, DPS, PS,
  271. DPS, DPS, DPS, DPS, DS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS,
  272. DP, DPS, DPS, DPS, DPS, D, DPS, DPS, DPS, DPS, DP, DPS, DPS, DPS, DPS, DP,
  273. DPS, DPS, DPS, DPS, DPS, DPS, DS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS,
  274. DPS, DPS, DPS, DPS, DPS, DPS, DPS, DS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS,
  275. DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DS, DPS, DPS, DPS, DPS, DPS, DPS, DPS,
  276. DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DS, DPS, DPS, DPS, DPS, DPS, DPS,
  277. DP, DPS, DPS, DPS, DPS, DP, DPS, DPS, DPS, DPS, D, DPS, DPS, DPS, DPS, DP,
  278. DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DS, DPS, DPS, DPS, DPS,
  279. PS, DPS, DPS, PS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, S, DPS, DPS, PS,
  280. DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DS, DPS, DPS,
  281. DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DPS, DS, DPS,
  282. P, DPS, DPS, PS, DPS, DP, DPS, DPS, DPS, DPS, DP, DPS, PS, DPS, DPS, 0
  283. };
  284. extern void HostifyAllBitmaps(PPDEV ppdev);
  285. COPYFN DoDeviceToDevice;
  286. BOOL CopyDeviceBitmap(
  287. SURFOBJ *psoTrg,
  288. SURFOBJ *psoSrc,
  289. CLIPOBJ *pco,
  290. XLATEOBJ *pxlo,
  291. RECTL *prclTrg,
  292. POINTL *pptlSrc,
  293. ULONG ulDRAWBLTDEF,
  294. COPYFN *pfn);
  295. BOOL PuntBitBlt(
  296. SURFOBJ* psoDest,
  297. SURFOBJ* psoSrc,
  298. SURFOBJ* psoMask,
  299. CLIPOBJ* pco,
  300. XLATEOBJ* pxlo,
  301. RECTL* prclDest,
  302. POINTL* pptlSrc,
  303. POINTL* pptlMask,
  304. BRUSHOBJ* pbo,
  305. POINTL* pptlBrush,
  306. ROP4 rop4);
  307. #if SWAT6
  308. void StripePatBlt(
  309. PPDEV ppdev,
  310. ULONG x,
  311. ULONG y,
  312. ULONG cx,
  313. ULONG cy);
  314. #endif
  315. //
  316. // If data logging is enabled, Prototype the logging files.
  317. //
  318. #if LOG_CALLS
  319. void LogBitBlt(
  320. int acc,
  321. SURFOBJ* psoSrc,
  322. SURFOBJ* psoDest,
  323. ROP4 rop4,
  324. CLIPOBJ* pco,
  325. BRUSHOBJ* pbo,
  326. XLATEOBJ* pxlo);
  327. void LogDrvCreateDevBmp(
  328. int acc,
  329. PPDEV ppdev,
  330. SIZEL sizl,
  331. PDSURF pdsurf);
  332. void LogDrvDeleteDevBmp(
  333. PDSURF pdsurf);
  334. void LogCreateDibFromScreen(
  335. int acc,
  336. PPDEV ppdev,
  337. PDSURF pdsurf);
  338. void LogCreateScreenFromDib(
  339. int acc,
  340. PPDEV ppdev,
  341. PDSURF pdsurf);
  342. //
  343. // If data logging is not enabled, compile out the calls.
  344. //
  345. #else
  346. #define LogBitBlt(acc, psoSrc, psoDest, rop4, pco, pbo, pxlo)
  347. #define LogDrvCreateDevBmp(acc, ppdev, sizl, pdsurf)
  348. #define LogDrvDeleteDevBmp(pdsurf)
  349. #define LogCreateDibFromScreen(acc, ppdev, pdsurf)
  350. #define LogCreateScreenFromDib(acc, ppdev, pdsurf)
  351. #endif
  352. /****************************************************************************\
  353. * bIntersectTest *
  354. * Test for intersection between two rectangles. *
  355. \****************************************************************************/
  356. #define bIntersectTest(prcl1, prcl2) \
  357. (((prcl1)->left < (prcl2)->right) && \
  358. ((prcl1)->right > (prcl2)->left) && \
  359. ((prcl1)->top < (prcl2)->bottom) && \
  360. ((prcl1)->bottom > (prcl2)->top))
  361. /*****************************************************************************\
  362. * BOOL DrvBitBlt *
  363. \*****************************************************************************/
  364. #if (USE_ASM && defined(i386))
  365. BOOL i386BitBlt(
  366. #else
  367. BOOL DrvBitBlt(
  368. #endif
  369. SURFOBJ* psoDest,
  370. SURFOBJ* psoSrc,
  371. SURFOBJ* psoMask,
  372. CLIPOBJ* pco,
  373. XLATEOBJ* pxlo,
  374. RECTL* prclDest,
  375. POINTL* pptlSrc,
  376. POINTL* pptlMask,
  377. BRUSHOBJ* pbo,
  378. POINTL* pptlBrush,
  379. ROP4 rop4)
  380. {
  381. PPDEV ppdev;
  382. ULONG fg_rop, bg_rop;
  383. ULONG bltdef = 0;
  384. BOOL fSrc, fDest;
  385. #if NULL_BITBLT
  386. {
  387. if (pointer_switch) return(TRUE);
  388. }
  389. #endif
  390. DISPDBG((BITBLT_DBG_LEVEL, "DrvBitBlt: Entry.\n"));
  391. ASSERTMSG(psoDest != NULL, "DrvBitBlt: No destination.\n");
  392. //
  393. // Get the PDEV associated with the destination.
  394. //
  395. ppdev = (PPDEV) ((psoDest != NULL) ? psoDest->dhpdev :
  396. ((psoSrc != NULL) ? psoSrc->dhpdev : NULL));
  397. // Bad PDEV?
  398. if (ppdev == NULL) goto GoToEngine;
  399. SYNC_W_3D(ppdev);
  400. //
  401. // Set a flag to tell us if the source is the frame buffer.
  402. //
  403. fSrc = (psoSrc != NULL) && // Is there a source?
  404. ((psoSrc->iType == STYPE_DEVBITMAP) || // Is it a device bmp?
  405. (psoSrc->hsurf == ppdev->hsurfEng) ); // Is it the screen?
  406. //
  407. // Set a flag telling us if the destination is the frame buffer.
  408. //
  409. fDest = (psoDest != NULL) && // Is there a dest?
  410. ((psoDest->iType == STYPE_DEVBITMAP) || // Is it a device bmp?
  411. (psoDest->hsurf == ppdev->hsurfEng) ); // Is it the screen?
  412. //
  413. // If the destination is a DIB device bitmap, try copying it into
  414. // off-screen memory.
  415. //
  416. if ( fDest && // If dest is supposed to be
  417. // the frame buffer,
  418. (psoDest->iType == STYPE_DEVBITMAP) && // and it's a device bitmap,
  419. ((PDSURF)psoDest->dhsurf)->pso ) // but it's really on the host,
  420. {
  421. // try to copy it back into off screen memory.
  422. if ( !bCreateScreenFromDib(ppdev, (DSURF*) psoDest->dhsurf) )
  423. {
  424. // If that fails, then the destination is now on the host.
  425. psoDest = ((PDSURF)psoDest->dhsurf)->pso; // Host surface.
  426. fDest = FALSE; // Dest is not frame buffer.
  427. }
  428. }
  429. //
  430. // If the source is a DIB device bitmap, try copying it into off-screen
  431. // memory.
  432. //
  433. if ( fSrc && // If the source is supposed to
  434. // be the frame buffer,
  435. (psoSrc->iType == STYPE_DEVBITMAP) && // and it's a device bmp,
  436. ((PDSURF)psoSrc->dhsurf)->pso ) // but it's really on the host,
  437. {
  438. // try to copy it back into off-screen memory.
  439. if ( !bCreateScreenFromDib(ppdev, (DSURF*) psoSrc->dhsurf) )
  440. {
  441. // If that fails, then our source is really the host.
  442. psoSrc = ((PDSURF)psoSrc->dhsurf)->pso; // Host surface.
  443. fSrc = FALSE; // Src is not frame buffer.
  444. }
  445. }
  446. if ( fDest )
  447. {
  448. BYTE bROP;
  449. if (psoDest->iType == STYPE_DEVBITMAP)
  450. ppdev->ptlOffset = ((PDSURF)psoDest->dhsurf)->ptl;
  451. else
  452. ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0;
  453. //
  454. // Extract the foreground and background ROP from the ROP4
  455. //
  456. ASSERTMSG( (rop4>>16) == 0, "DrvBitBlt: Upper word in ROP4 non-zero. \n");
  457. fg_rop = rop4 & 0x000000FF;
  458. bg_rop = (rop4>>8) & 0x000000FF;
  459. // Punt all true 4 op rops.
  460. // If fg_rop != bg_rop, then this is a true 4 op rop, so punt it.
  461. // If fg_rop == bg_rop, then it's really a three op rop.
  462. if ((fg_rop != bg_rop)) // It's a three op rop,
  463. goto GoToEngine;
  464. bROP = ropFlags[fg_rop];
  465. #if !(USE_ASM && defined(i386))
  466. {
  467. if (!(bROP & S))
  468. {
  469. // It is a PatBLT. This is very important, so all calls to the
  470. // support routines are stretched into linear code, except for
  471. // the caching of the brushes, which should happen only once
  472. // for each brush.
  473. ULONG drawbltdef = 0x10000000 | fg_rop;
  474. if (bROP & D)
  475. drawbltdef |= 0x01000000;
  476. // Do we have a pttern to load?
  477. if (bROP & P)
  478. {
  479. ULONG color = pbo->iSolidColor;
  480. if (color != (ULONG) -1)
  481. {
  482. // We have a solid color.
  483. switch (ppdev->ulBitCount)
  484. {
  485. case 8:
  486. color = (color << 8) | (color & 0xFF);
  487. case 16:
  488. color = (color << 16) | (color & 0xFFFF);
  489. }
  490. drawbltdef |= 0x00070000;
  491. REQUIRE(2);
  492. LL_BGCOLOR(color, 2);
  493. }
  494. else
  495. {
  496. if (!SetBrush(ppdev, &bltdef, pbo, pptlBrush))
  497. goto GoToEngine;
  498. drawbltdef |= bltdef << 16;
  499. }
  500. }
  501. // Test for no clipping.
  502. if ( (pco == NULL) || (pco->iDComplexity == DC_TRIVIAL) )
  503. {
  504. #if SWAT6
  505. REQUIRE(2);
  506. LL_DRAWBLTDEF(drawbltdef, 2);
  507. StripePatBlt(ppdev, prclDest->left + ppdev->ptlOffset.x,
  508. prclDest->top + ppdev->ptlOffset.y,
  509. prclDest->right - prclDest->left,
  510. prclDest->bottom - prclDest->top);
  511. #else
  512. REQUIRE(7);
  513. LL_DRAWBLTDEF(drawbltdef, 0);
  514. LL_OP0(prclDest->left + ppdev->ptlOffset.x,
  515. prclDest->top + ppdev->ptlOffset.y);
  516. LL_BLTEXT(prclDest->right - prclDest->left,
  517. prclDest->bottom - prclDest->top);
  518. #endif
  519. }
  520. // Test for rectangle clipping.
  521. else if (pco->iDComplexity == DC_RECT)
  522. {
  523. LONG x, y, cx, cy;
  524. x = max(prclDest->left, pco->rclBounds.left);
  525. y = max(prclDest->top, pco->rclBounds.top);
  526. cx = min(prclDest->right, pco->rclBounds.right) - x;
  527. cy = min(prclDest->bottom, pco->rclBounds.bottom) - y;
  528. if ( (cx > 0) && (cy > 0) )
  529. {
  530. #if SWAT6
  531. REQUIRE(2);
  532. LL_DRAWBLTDEF(drawbltdef, 2);
  533. StripePatBlt(ppdev, x + ppdev->ptlOffset.x,
  534. y + ppdev->ptlOffset.y, cx, cy);
  535. #else
  536. REQUIRE(7);
  537. LL_DRAWBLTDEF(drawbltdef, 0);
  538. LL_OP0(x + ppdev->ptlOffset.x, y + ppdev->ptlOffset.y);
  539. LL_BLTEXT(cx, cy);
  540. #endif
  541. }
  542. }
  543. // Complex clipping.
  544. else
  545. {
  546. BOOL bMore;
  547. ENUMRECTS8 ce;
  548. RECTL* prcl;
  549. #if DRIVER_5465 && HW_CLIPPING
  550. // Get a chunk of rectangles.
  551. CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0);
  552. // Enable clipping
  553. REQUIRE(6);
  554. LL_DRAWBLTDEF(drawbltdef | DD_CLIPEN, 0);
  555. LL_CLIPULE(prclDest->left + ppdev->ptlOffset.x,
  556. prclDest->top + ppdev->ptlOffset.y);
  557. LL_CLIPLOR(prclDest->right + ppdev->ptlOffset.x,
  558. prclDest->bottom + ppdev->ptlOffset.y);
  559. do
  560. {
  561. bMore = CLIPOBJ_bEnum(pco, sizeof(ce), (ULONG *) &ce);
  562. for (prcl = ce.arcl; ce.c--; prcl++)
  563. {
  564. if ((prcl->right > prcl->left) &&
  565. (prcl->bottom > prcl->top))
  566. {
  567. #if SWAT6
  568. StripePatBlt(ppdev,
  569. prcl->left + ppdev->ptlOffset.x,
  570. prcl->top + ppdev->ptlOffset.y,
  571. prcl->right - prcl->left,
  572. prcl->bottom - prcl->top);
  573. #else
  574. REQUIRE(5);
  575. LL_OP0(prcl->left + ppdev->ptlOffset.x,
  576. prcl->top + ppdev->ptlOffset.y);
  577. LL_BLTEXT(prcl->right - prcl->left,
  578. prcl->bottom - prcl->top);
  579. #endif
  580. }
  581. }
  582. } while (bMore);
  583. #else
  584. REQUIRE(2);
  585. LL_DRAWBLTDEF(drawbltdef, 2);
  586. // Get a chunk of rectangles.
  587. CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0);
  588. do
  589. {
  590. bMore = CLIPOBJ_bEnum(pco, sizeof(ce), (ULONG *) &ce);
  591. for (prcl = ce.arcl; ce.c--; prcl++)
  592. {
  593. LONG x, y, cx, cy;
  594. x = max(prclDest->left, prcl->left);
  595. y = max(prclDest->top, prcl->top);
  596. cx = min(prclDest->right, prcl->right) - x;
  597. cy = min(prclDest->bottom, prcl->bottom) - y;
  598. if ( (cx > 0) && (cy > 0) )
  599. {
  600. #if SWAT6
  601. StripePatBlt(ppdev, x + ppdev->ptlOffset.x,
  602. y + ppdev->ptlOffset.y, cx, cy);
  603. #else
  604. REQUIRE(5);
  605. LL_OP0(x + ppdev->ptlOffset.x,
  606. y + ppdev->ptlOffset.y);
  607. LL_BLTEXT(cx, cy);
  608. #endif
  609. }
  610. }
  611. }
  612. while (bMore);
  613. #endif
  614. }
  615. LogBitBlt(0, psoSrc, psoDest, rop4, pco, pbo, pxlo);
  616. return(TRUE);
  617. }
  618. }
  619. #endif // !(USE_ASM && defined(i386))
  620. // We only support HostToScreen blits where the Host is either
  621. // 1-bpp, 4-bpp, 8-bpp, or the same format as the screen.
  622. if ( ((psoSrc->iBitmapFormat > BMF_8BPP) &&
  623. (psoSrc->iBitmapFormat != psoDest->iBitmapFormat)) )
  624. {
  625. goto GoToEngine;
  626. }
  627. if (bROP & P)
  628. {
  629. // Realize the brush.
  630. if (!SetBrush(ppdev, &bltdef, pbo, pptlBrush))
  631. {
  632. goto GoToEngine;
  633. }
  634. }
  635. // If the destination is part of the ROP, set the bit.
  636. if (bROP & D)
  637. {
  638. bltdef |= 0x0100;
  639. }
  640. // Do the blit.
  641. if (CopyDeviceBitmap(psoDest, psoSrc, pco, pxlo, prclDest,
  642. pptlSrc, (bltdef << 16) | fg_rop,
  643. fSrc ? DoDeviceToDevice : ppdev->pfnHostToScreen))
  644. {
  645. LogBitBlt(0, psoSrc, psoDest, rop4, pco, pbo, pxlo);
  646. return(TRUE);
  647. }
  648. } // fDest
  649. else if (fSrc) // Destination is bitmap, source is screen or device bitmap.
  650. {
  651. if (psoSrc->iType == STYPE_DEVBITMAP)
  652. {
  653. ppdev->ptlOffset = ((PDSURF) psoSrc->dhsurf)->ptl;
  654. }
  655. else
  656. {
  657. ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0;
  658. }
  659. #if S2H_USE_ENGINE
  660. {
  661. // ROP3?
  662. fg_rop = (BYTE) rop4;
  663. if (fg_rop == (rop4 >> 8))
  664. {
  665. BYTE bROP = ropFlags[fg_rop];
  666. // We dont's support ROPs where the destination is part of.
  667. if ( !(bROP & D) )
  668. {
  669. // If we need a brush, load it.
  670. if (bROP & P)
  671. {
  672. if (!SetBrush(ppdev, &bltdef, pbo, pptlBrush))
  673. {
  674. goto GoToEngine;
  675. }
  676. }
  677. // Now, call the routine through the clip manager.
  678. if (CopyDeviceBitmap(psoDest, psoSrc, pco, pxlo,
  679. prclDest, pptlSrc,
  680. (bltdef << 16) | fg_rop,
  681. ppdev->pfnScreenToHost))
  682. {
  683. LogBitBlt(0, psoSrc, psoDest, rop4, pco, pbo, pxlo);
  684. return(TRUE);
  685. }
  686. }
  687. }
  688. }
  689. #else
  690. {
  691. // We only support SRCCOPY.
  692. if (rop4 == 0x0000CCCC)
  693. {
  694. // Now, call the routine through the clip manager.
  695. if (CopyDeviceBitmap(psoDest, psoSrc, pco, pxlo, prclDest,
  696. pptlSrc, 0x000000CC,
  697. ppdev->pfnScreenToHost))
  698. {
  699. LogBitBlt(0, psoSrc, psoDest, rop4, pco, pbo, pxlo);
  700. return(TRUE);
  701. }
  702. }
  703. }
  704. #endif
  705. }
  706. GoToEngine:
  707. // BLT is too complex. Punt it to GDI.
  708. DISPDBG((BITBLT_DBG_LEVEL, "DrvBitBlt: Exit (punt). ROP4 = 0x%02X%02X.\n",
  709. bg_rop,fg_rop));
  710. LogBitBlt(1, psoSrc, psoDest, rop4, pco, pbo, pxlo);
  711. return PuntBitBlt(psoDest, psoSrc, psoMask, pco, pxlo, prclDest, pptlSrc,
  712. pptlMask, pbo, pptlBrush, rop4);
  713. }
  714. /*****************************************************************************\
  715. * DrvCreateDeviceBitmap
  716. *
  717. * This routine creates a device bitmap that is allocated off-screen.
  718. *
  719. * On entry: dhpdev Handle of PDEV structure.
  720. * sizl Size of the device bitmap to create.
  721. * iFormat Bitmap format of the device bitmap to create.
  722. *
  723. * Returns: We return the handle of a surface object that holds our device
  724. * bitmap or 0 if there is an error.
  725. \*****************************************************************************/
  726. HBITMAP DrvCreateDeviceBitmap(
  727. DHPDEV dhpdev,
  728. SIZEL sizl,
  729. ULONG iFormat
  730. )
  731. {
  732. PPDEV ppdev = (PPDEV) dhpdev;
  733. POFMHDL pofm;
  734. HBITMAP hbmDevice;
  735. PDSURF pdsurf;
  736. FLONG flHooks = HOOK_SYNCHRONIZEACCESS | HOOK_TEXTOUT
  737. | HOOK_BITBLT | HOOK_COPYBITS | HOOK_PAINT
  738. | HOOK_STROKEPATH | HOOK_FILLPATH
  739. #ifdef WINNT_VER40
  740. | HOOK_LINETO
  741. #endif
  742. ;
  743. SYNC_W_3D(ppdev);
  744. #if WINBENCH96
  745. //
  746. // We support only device bitmaps that WinBench is going to use. This
  747. // to circumvent the limitations of the heap management when there is
  748. // not so much video memory.
  749. //
  750. // Only support bitmaps with a width between 20 and 31, and bitmaps
  751. // wider than 100.
  752. if ( (sizl.cx < 20) || ((sizl.cx >= 32) && (sizl.cx < 100)) )
  753. {
  754. LogDrvCreateDevBmp(1, ppdev, sizl, NULL);
  755. return(0);
  756. }
  757. #else
  758. // We don't support anything under or equal to 8x8 (brushes) since
  759. // these will only slow us down.
  760. if ((sizl.cx <= 8) || (sizl.cy <= 8))
  761. {
  762. LogDrvCreateDevBmp(2, ppdev, sizl, NULL);
  763. return(0);
  764. }
  765. #if MEMMGR
  766. // New bitmap filter, borrowed from Windows 95.
  767. if (ppdev->fBitmapFilter)
  768. {
  769. if (( (sizl.cx <= ppdev->szlBitmapMin.cx)
  770. && (sizl.cy <= ppdev->szlBitmapMin.cy)
  771. )
  772. || (sizl.cx > ppdev->szlBitmapMax.cx)
  773. || (sizl.cy > ppdev->szlBitmapMax.cy)
  774. )
  775. {
  776. LogDrvCreateDevBmp(8, ppdev, sizl, NULL);
  777. DISPDBG((BITMAP_DBG_LEVEL, "DrvCreateDeviceBitmap - Rejected\n"));
  778. return(0);
  779. }
  780. }
  781. #else
  782. // Reject any x<=32, or y<=64, for 16 or 24 bpp.
  783. // Improves WinBench97 scores.
  784. if ((iFormat == BMF_16BPP) || (iFormat == BMF_24BPP))
  785. {
  786. if ((sizl.cx <= 32) || (sizl.cy <= 64))
  787. {
  788. LogDrvCreateDevBmp(8, ppdev, sizl, NULL);
  789. DISPDBG((BITMAP_DBG_LEVEL, "DrvCreateDeviceBitmap - Reject x<=32||y<=64\n"));
  790. return(0);
  791. }
  792. }
  793. #endif
  794. #endif
  795. // Reject if bigger than current screen size
  796. if ((ULONG)sizl.cx > ppdev->cxScreen)
  797. {
  798. LogDrvCreateDevBmp(9, ppdev, sizl, NULL);
  799. DISPDBG((BITMAP_DBG_LEVEL, "DrvCreateDeviceBitmap - Reject > cxScreen\n"));
  800. return(0);
  801. }
  802. // If the hardware is not in graphics mode, don't create a device bitmap!
  803. if (!ppdev->bEnable)
  804. {
  805. LogDrvCreateDevBmp(3, ppdev, sizl, NULL);
  806. return(0);
  807. }
  808. // We don't support device bitmaps in any other mode than the hardware.
  809. if (iFormat != ppdev->iBitmapFormat)
  810. {
  811. return(0);
  812. }
  813. #ifdef ALLOC_IN_CREATESURFACE
  814. if (ppdev->bDirectDrawInUse)
  815. return (0);
  816. #endif
  817. #if SWAT1
  818. // Is this the very first device bitmap?
  819. if (ppdev->fPreAllocate == FALSE)
  820. {
  821. // Setup step-down counter.
  822. ppdev->fPreAllocate = TRUE;
  823. ppdev->nPages = 10;
  824. }
  825. // Is this the WinBench 97 pause bitmap?
  826. else if (sizl.cx == 300 && sizl.cy == 150)
  827. {
  828. if (ppdev->nPages == 0)
  829. {
  830. PVOID p;
  831. // Allocate 8 full-screen pages from the heap.
  832. #ifdef WINNT_VER40
  833. p = MEM_ALLOC(FL_ZERO_MEMORY, 8 * ppdev->cxScreen *
  834. ppdev->iBytesPerPixel * ppdev->cyScreen, ALLOC_TAG);
  835. #else
  836. p = MEM_ALLOC(LPTR, 8 * ppdev->cxScreen * ppdev->iBytesPerPixel *
  837. ppdev->cyScreen);
  838. #endif
  839. // Free it again.
  840. MEMORY_FREE(p);
  841. }
  842. else
  843. {
  844. // Decrement step-down counter.
  845. ppdev->nPages--;
  846. }
  847. }
  848. // Is this a full-screen device bitmap?
  849. else if ( (ppdev->nPages == 0)
  850. && (sizl.cx == (LONG) ppdev->cxScreen)
  851. && (sizl.cy == (LONG) ppdev->cyScreen)
  852. )
  853. {
  854. PVOID p;
  855. // Allocate 8 full-screen pages from the heap.
  856. #ifdef WINNT_VER40
  857. p = MEM_ALLOC(FL_ZERO_MEMORY, 8 * ppdev->cxScreen *
  858. ppdev->iBytesPerPixel * ppdev->cyScreen, ALLOC_TAG);
  859. #else
  860. p = MEM_ALLOC(LPTR, 8 * ppdev->cxScreen * ppdev->iBytesPerPixel *
  861. ppdev->cyScreen);
  862. #endif
  863. // Free it again.
  864. MEMORY_FREE(p);
  865. }
  866. #endif // SWAT1
  867. #if SWAT2
  868. // Is this a full-screen device bitmap?
  869. if ( (sizl.cx == (LONG) ppdev->cxScreen)
  870. && (sizl.cy == (LONG) ppdev->cyScreen)
  871. )
  872. {
  873. #if MEMMGR
  874. // Hostify all device bitmaps.
  875. extern void HostifyAllBitmaps(PPDEV ppdev);
  876. HostifyAllBitmaps(ppdev);
  877. #else
  878. POFMHDL pofm, pofmNext;
  879. // Hostify all current off-screen device bitmaps.
  880. for (pofm = ppdev->OFM_UsedQ; pofm; pofm = pofmNext)
  881. {
  882. pofmNext = pofm->nexthdl;
  883. if (pofm->pdsurf && pofm->pdsurf->pofm)
  884. {
  885. bCreateDibFromScreen(ppdev, pofm->pdsurf);
  886. }
  887. else if (pofm->alignflag & SAVESCREEN_FLAG)
  888. {
  889. FreeOffScnMem(ppdev, pofm);
  890. }
  891. }
  892. #endif
  893. }
  894. #endif // SWAT2
  895. //
  896. // Allocate off-screen memory.
  897. //
  898. {
  899. #if INFINITE_OFFSCREEN_MEM
  900. //
  901. // This is our "infinite offscreen memory" test. Here we always
  902. // succeed in memory allocation. We do this by always allocating
  903. // bitmaps at screen 0,0.
  904. // It looks ugly, but we can use it to tell of our memory management
  905. // is hurting our benchmark scores.
  906. // This option is turned off for the retail version of the driver.
  907. // 'pointer_switch' is turned on and off in POINTER.C by moving the pointer
  908. // to a special place on the screen.
  909. //
  910. if (pointer_switch)
  911. {
  912. pofm = ppdev->ScrnHandle;
  913. }
  914. else
  915. #endif // INFINITE_OFFSCREEN_MEM
  916. {
  917. #if WINBENCH96
  918. //
  919. // This is our Magic Bitmap.
  920. // Winbench 96 allocates one special bitmap into which it does *lots*
  921. // of drawing. If the allocation for this bitmap fails, our WinBench
  922. // score will be poor. We ensure that this allocation succeeds
  923. // by pre-allocating it at boot time.
  924. //
  925. // If the size of the requested bitmap matches our magic bitmap, we
  926. // assume that Winbench is requesting it's special bitmap, and so we
  927. // use the magic bitmap.
  928. //
  929. if ( (sizl.cx == MAGIC_SIZEX) && (sizl.cy == MAGIC_SIZEY) &&
  930. ppdev->pofmMagic && !ppdev->bMagicUsed)
  931. {
  932. // If fits. Use pre-allocated bitmap.
  933. DISPDBG((BITMAP_DBG_LEVEL,
  934. "DrvCreateDeviceBitmap - Using the Magic Bitmap.\n"));
  935. ppdev->bMagicUsed = 1;
  936. pofm = ppdev->pofmMagic;
  937. }
  938. else
  939. #endif
  940. {
  941. DISPDBG((BITMAP_DBG_LEVEL,
  942. "DrvCreateDeviceBitmap - Allocating a %d x %d device bitmap.\n",
  943. sizl.cx, sizl.cy));
  944. #if MEMMGR
  945. if (ppdev->fBitmapFilter)
  946. {
  947. pofm = AllocOffScnMem(ppdev, &sizl, PIXEL_AlIGN, NULL);
  948. if (pofm == NULL)
  949. {
  950. HostifyAllBitmaps(ppdev);
  951. pofm = AllocOffScnMem(ppdev, &sizl, PIXEL_AlIGN, NULL);
  952. }
  953. }
  954. else if (sizl.cx <= ppdev->must_have_width)
  955. {
  956. pofm = AllocOffScnMem(ppdev, &sizl, PIXEL_AlIGN | MUST_HAVE,
  957. NULL);
  958. }
  959. else
  960. #endif
  961. pofm = AllocOffScnMem(ppdev, &sizl, PIXEL_AlIGN, NULL);
  962. }
  963. }
  964. }
  965. //
  966. // If we got the offscreen memory we need, then let's do some work.
  967. //
  968. if (pofm != NULL)
  969. {
  970. // Allocate device bitmap structure.
  971. #ifdef WINNT_VER40
  972. pdsurf = MEM_ALLOC(FL_ZERO_MEMORY, sizeof(DSURF), ALLOC_TAG);
  973. #else
  974. pdsurf = MEM_ALLOC(LPTR, sizeof(DSURF));
  975. #endif
  976. if (pdsurf != NULL)
  977. {
  978. // Create the device bitmap object.
  979. hbmDevice = EngCreateDeviceBitmap((DHSURF) pdsurf, sizl, iFormat);
  980. if (hbmDevice != NULL)
  981. {
  982. // Associate the device bitmap with the surface.
  983. if (EngAssociateSurface((HSURF) hbmDevice,
  984. ppdev->hdevEng,
  985. flHooks)
  986. )
  987. {
  988. // Store a pointer to the surface.
  989. {
  990. #if INFINITE_OFFSCREEN_MEM
  991. //
  992. // If we're using screen(0,0) as a device bitmap
  993. // then don't walk on ScrnHandle->pdsurf!
  994. //
  995. if (pofm != ppdev->ScrnHandle)
  996. #endif
  997. pofm->pdsurf = pdsurf;
  998. }
  999. // Initialize the device bitmap structure.
  1000. pdsurf->ppdev = ppdev;
  1001. pdsurf->pofm = pofm;
  1002. pdsurf->ptl.x = pofm->aligned_x / ppdev->iBytesPerPixel;
  1003. pdsurf->ptl.y = pofm->aligned_y;
  1004. pdsurf->packedXY = (pdsurf->ptl.y << 16) | pdsurf->ptl.x;
  1005. pdsurf->sizl = sizl;
  1006. LogDrvCreateDevBmp(0, ppdev, sizl, pdsurf);
  1007. return(hbmDevice);
  1008. }
  1009. else
  1010. {
  1011. LogDrvCreateDevBmp(4, ppdev, sizl, NULL);
  1012. }
  1013. // Delete the surface
  1014. EngDeleteSurface((HSURF) hbmDevice);
  1015. }
  1016. else
  1017. {
  1018. LogDrvCreateDevBmp(5, ppdev, sizl, NULL);
  1019. }
  1020. // Free the device bitmap structure.
  1021. MEMORY_FREE(pdsurf);
  1022. }
  1023. else
  1024. {
  1025. LogDrvCreateDevBmp(6, ppdev, sizl, NULL);
  1026. }
  1027. #if WINBENCH96
  1028. // Free the off-screen memory.
  1029. if (pofm == ppdev->pofmMagic)
  1030. {
  1031. // We were using the preallocated memory block. Don't free it,
  1032. // just mark it as unused.
  1033. ppdev->bMagicUsed = 0;
  1034. }
  1035. else
  1036. #endif
  1037. {
  1038. #if INFINITE_OFFSCREEN_MEM
  1039. // But don't free it if the device bitmap is at screen(0,0)...
  1040. if (pofm != ppdev->ScrnHandle)
  1041. #endif
  1042. FreeOffScnMem(ppdev, pofm);
  1043. }
  1044. }
  1045. else
  1046. {
  1047. LogDrvCreateDevBmp(7, ppdev, sizl, NULL);
  1048. }
  1049. return(0);
  1050. }
  1051. /*****************************************************************************\
  1052. * DrvDeleteDeviceBitmap
  1053. *
  1054. * This routine deletes a device bitmap and frees the off-screen memory.
  1055. *
  1056. * On entry: pdsurf Pointer to device bitmap to delete.
  1057. \*****************************************************************************/
  1058. void DrvDeleteDeviceBitmap(DHSURF dhsurf)
  1059. {
  1060. PDSURF pdsurf = (PDSURF) dhsurf;
  1061. //
  1062. // Log this call to a file.
  1063. //
  1064. LogDrvDeleteDevBmp(pdsurf);
  1065. // Is the device bitmap stored in a DIB?
  1066. if (pdsurf->pso)
  1067. {
  1068. // Delete the in-memory DIB.
  1069. HSURF hsurfDib = pdsurf->pso->hsurf;
  1070. EngUnlockSurface(pdsurf->pso);
  1071. EngDeleteSurface(hsurfDib);
  1072. }
  1073. else
  1074. {
  1075. PPDEV ppdev = pdsurf->ppdev;
  1076. #if INFINITE_OFFSCREEN_MEM
  1077. //
  1078. // If we're using screen(0,0) as a device bitmap
  1079. // then don't walk on ScrnHandle->pdsurf!
  1080. //
  1081. if (pdsurf->pofm != ppdev->ScrnHandle)
  1082. #endif
  1083. pdsurf->pofm->pdsurf = NULL;
  1084. #if WINBENCH96
  1085. if ( pdsurf->pofm == ppdev->pofmMagic)
  1086. {
  1087. // We were using the preallocated chunk of memory. Don't free
  1088. // it, just mark it as unused.
  1089. ppdev->bMagicUsed = 0;
  1090. }
  1091. else
  1092. #endif
  1093. {
  1094. // Free the off-screen memory.
  1095. #if INFINITE_OFFSCREEN_MEM
  1096. // unless our device bitmap is at screen(0,0)...
  1097. if (pdsurf->pofm != ppdev->ScrnHandle)
  1098. #endif
  1099. FreeOffScnMem(pdsurf->ppdev, pdsurf->pofm);
  1100. }
  1101. }
  1102. // Free the device bitmap structure.
  1103. MEMORY_FREE(pdsurf);
  1104. }
  1105. /*****************************************************************************\
  1106. * bCreateDibFromScreen
  1107. *
  1108. * This routine copy a device bitmap into a DIB and frees the off-screen
  1109. * memory.
  1110. *
  1111. * On entry: ppdev Pointer to physical device.
  1112. * pdsurf Pointer to device bitmap to copy.
  1113. *
  1114. * Returns: TRUE if the off-screen device bitmap was sucessfully copied
  1115. * into a memory DIB.
  1116. \*****************************************************************************/
  1117. BOOL bCreateDibFromScreen(
  1118. PPDEV ppdev,
  1119. PDSURF pdsurf
  1120. )
  1121. {
  1122. HBITMAP hbmDib;
  1123. // Create a DIB.
  1124. hbmDib = EngCreateBitmap(pdsurf->sizl, 0, ppdev->iBitmapFormat,
  1125. BMF_TOPDOWN, NULL);
  1126. if (hbmDib)
  1127. {
  1128. // Associate the surface with the driver.
  1129. if (EngAssociateSurface((HSURF) hbmDib, ppdev->hdevEng, 0))
  1130. {
  1131. // Lock the surface.
  1132. SURFOBJ* pso = EngLockSurface((HSURF) hbmDib);
  1133. if (pso != NULL)
  1134. {
  1135. SIZEL sizl;
  1136. PBYTE pjScreen, pjBits;
  1137. // Calculate the size of the blit.
  1138. sizl.cx = pdsurf->sizl.cx * ppdev->iBytesPerPixel;
  1139. sizl.cy = pdsurf->sizl.cy;
  1140. // Calculate the destination variables.
  1141. pjBits = (PBYTE) pso->pvScan0;
  1142. // Calculate the screen address.
  1143. pjScreen = ppdev->pjScreen
  1144. + (pdsurf->ptl.x * ppdev->iBytesPerPixel)
  1145. + (pdsurf->ptl.y * ppdev->lDeltaScreen);
  1146. // Wait for the hardware to become idle.
  1147. while (LLDR_SZ(grSTATUS) != 0) ;
  1148. while (sizl.cy--)
  1149. {
  1150. // Copy all pixels from screen to memory.
  1151. memcpy(pjBits, pjScreen, sizl.cx);
  1152. // Next line.
  1153. pjScreen += ppdev->lDeltaScreen;
  1154. pjBits += pso->lDelta;
  1155. }
  1156. #if WINBENCH96
  1157. //
  1158. // If the block we are freeing is our preallocated
  1159. // piece, then invalidate it's pointer.
  1160. //
  1161. if ( pdsurf->pofm == ppdev->pofmMagic)
  1162. ppdev->pofmMagic = 0;
  1163. #endif
  1164. #if !MEMMGR
  1165. // Free the off-screen memory handle.
  1166. #if INFINITE_OFFSCREEN_MEM
  1167. // unless our device bitmap is at screen(0,0)...
  1168. if (pdsurf->pofm != ppdev->ScrnHandle)
  1169. #endif
  1170. FreeOffScnMem(pdsurf->ppdev, pdsurf->pofm);
  1171. #endif
  1172. // Mark the device bitmap as DIB.
  1173. pdsurf->pofm = NULL;
  1174. pdsurf->pso = pso;
  1175. // Done.
  1176. LogCreateDibFromScreen(0, ppdev, pdsurf);
  1177. return(TRUE);
  1178. }
  1179. else
  1180. {
  1181. // Failed to lock host surface
  1182. LogCreateDibFromScreen(1, ppdev, pdsurf);
  1183. }
  1184. }
  1185. else
  1186. {
  1187. // Failed to associate host surface
  1188. LogCreateDibFromScreen(2, ppdev, pdsurf);
  1189. }
  1190. // Delete the DIB.
  1191. EngDeleteSurface((HSURF) hbmDib);
  1192. }
  1193. else
  1194. {
  1195. // Failed to create host surface.
  1196. LogCreateDibFromScreen(3, ppdev, pdsurf);
  1197. }
  1198. // Error.
  1199. return(FALSE);
  1200. }
  1201. /*****************************************************************************\
  1202. * bCreateScreenFromDib
  1203. *
  1204. * This routine copys a DIB into a device bitmap and frees the DIB from memory.
  1205. *
  1206. * On entry: ppdev Pointer to physical device.
  1207. * pdsurf Pointer to device bitmap to copy.
  1208. *
  1209. * Returns: TRUE if the DIB was sucessfully copied into an off-screen
  1210. * device bitmap.
  1211. \*****************************************************************************/
  1212. BOOL bCreateScreenFromDib(
  1213. PPDEV ppdev,
  1214. PDSURF pdsurf
  1215. )
  1216. {
  1217. POFMHDL pofm;
  1218. HSURF hsurf;
  1219. SURFOBJ* pso;
  1220. #if MEMMGR
  1221. // In low memory situations, bitmaps will be hostified very frequently, so
  1222. // don't copy them back to the off-screen...
  1223. if (ppdev->fBitmapFilter)
  1224. {
  1225. return FALSE;
  1226. }
  1227. #endif
  1228. // If the hardware is not in graphics mode, keep the device bitmap in
  1229. // memory.
  1230. if (!ppdev->bEnable)
  1231. {
  1232. LogCreateScreenFromDib (1, ppdev, pdsurf);
  1233. return(FALSE);
  1234. }
  1235. #ifdef ALLOC_IN_CREATESURFACE
  1236. if (ppdev->bDirectDrawInUse)
  1237. return (FALSE);
  1238. #endif
  1239. // Allocate off-screen memory.
  1240. pofm = AllocOffScnMem(ppdev, &pdsurf->sizl, PIXEL_AlIGN, NULL);
  1241. if (pofm != NULL)
  1242. {
  1243. SURFOBJ psoDest;
  1244. RECTL rclDest;
  1245. POINTL ptlSrc;
  1246. //
  1247. // Tell the device bitmap where it lives in offscreen memory.
  1248. //
  1249. pdsurf->ptl.x = pofm->aligned_x / ppdev->iBytesPerPixel;
  1250. pdsurf->ptl.y = pofm->aligned_y;
  1251. pdsurf->packedXY = (pdsurf->ptl.y << 16) | pdsurf->ptl.x;
  1252. //
  1253. // Create a two way link between the device bitmap and
  1254. // its offscreen memory block.
  1255. //
  1256. pdsurf->pofm = pofm; // Attach offscreen memory block to device bitmap
  1257. pofm->pdsurf = pdsurf; // Attach device bitmap to offscreen memory block
  1258. //
  1259. // Disattach the host bitmap from the device bitmap.
  1260. // Save the pointer, because if we fail to move the device bitmap
  1261. // into the frame buffer, it will remain in host memory, and we
  1262. // will have to restore this pointer.
  1263. //
  1264. pso = pdsurf->pso; // Save pointer to bitmap in host memory.
  1265. pdsurf->pso = NULL; // disattach host memory
  1266. //
  1267. // Wrap the offscreen memory in a destination surface object.
  1268. // This is so we can use a host to screen BLT to move the bitmap
  1269. // from the host to the offscreen memory.
  1270. //
  1271. psoDest.dhsurf = (DHSURF) pdsurf;
  1272. psoDest.iType = STYPE_DEVBITMAP;
  1273. //
  1274. // Build a destination rectangle that describes where to put the
  1275. // bitmap in offscreen memory. This rectangle is relative to
  1276. // upper left corner of the allocated block of offscreen memory.
  1277. //
  1278. rclDest.left = 0;
  1279. rclDest.top = 0;
  1280. rclDest.right = pdsurf->sizl.cx;
  1281. rclDest.bottom = pdsurf->sizl.cy;
  1282. //
  1283. // Build a source point.
  1284. // Since we're moving the entire bitmap, its (0,0).
  1285. //
  1286. ptlSrc.x = ptlSrc.y = 0;
  1287. //
  1288. // Use our host to screen code to copy the DIB into off-screen memory.
  1289. //
  1290. if (!ppdev->pfnHostToScreen(&psoDest, pso, NULL, &rclDest, &ptlSrc,
  1291. 0x000000CC))
  1292. {
  1293. //
  1294. // BLT engine couldn't put it back into off screen memory.
  1295. // Maybe the DIB engine can.
  1296. //
  1297. DISPDBG (( 0, "Couldn't BLT device bitmap back into framebuffer.\n"));
  1298. if (! PuntBitBlt(&psoDest, pso, NULL, NULL, NULL,
  1299. &rclDest, &ptlSrc, NULL, NULL, NULL, 0x0000CCCC))
  1300. {
  1301. // Nope! We can't move it back to the frame buffer.
  1302. DISPDBG (( 0, "Couldn't punt device bitmap back into framebuffer.\n"));
  1303. DISPDBG (( 0, "Device bitmap will remain in offscreen memory.\n"));
  1304. // Restore the surface object pointers.
  1305. pdsurf->pofm = NULL; // This device bitmap has no offscreen memory.
  1306. pdsurf->pso = pso; // This device bitmap lives here, on the host.
  1307. // Free the offscreen memory we allocated and fail.
  1308. FreeOffScnMem(ppdev, pofm);
  1309. return FALSE;
  1310. }
  1311. }
  1312. // Delete the DIB.
  1313. hsurf = pso->hsurf;
  1314. EngUnlockSurface(pso);
  1315. EngDeleteSurface(hsurf);
  1316. // Done.
  1317. LogCreateScreenFromDib (0, ppdev, pdsurf);
  1318. return(TRUE);
  1319. }
  1320. // Error.
  1321. LogCreateScreenFromDib (2, ppdev, pdsurf);
  1322. return(FALSE);
  1323. }
  1324. #if LOG_CALLS
  1325. // ============================================================================
  1326. //
  1327. // Everything from here down is for data logging and is not used in the
  1328. // production driver.
  1329. //
  1330. // ============================================================================
  1331. extern long lg_i;
  1332. extern char lg_buf[256];
  1333. // ****************************************************************************
  1334. //
  1335. // LogBitBlt()
  1336. // This routine is called only from DrvBitBlt()
  1337. // Dump information to a file about what is going on in BitBlt land.
  1338. //
  1339. // ****************************************************************************
  1340. void LogBitBlt(
  1341. int acc,
  1342. SURFOBJ* psoSrc,
  1343. SURFOBJ* psoDest,
  1344. ROP4 rop4,
  1345. CLIPOBJ* pco,
  1346. BRUSHOBJ* pbo,
  1347. XLATEOBJ* pxlo)
  1348. {
  1349. PPDEV dppdev,sppdev,ppdev;
  1350. BYTE fg_rop, bg_rop;
  1351. ULONG iDComplexity;
  1352. dppdev = (PPDEV) (psoDest ? psoDest->dhpdev : 0);
  1353. sppdev = (PPDEV) (psoSrc ? psoSrc->dhpdev : 0);
  1354. ppdev = dppdev ? dppdev : sppdev;
  1355. #if ENABLE_LOG_SWITCH
  1356. if (pointer_switch == 0) return;
  1357. #endif
  1358. lg_i = sprintf(lg_buf,"DBB: ");
  1359. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1360. if (acc)
  1361. {
  1362. lg_i = sprintf(lg_buf,"PNT ");
  1363. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1364. }
  1365. fg_rop = (BYTE) (rop4 & 0xff);
  1366. bg_rop = (BYTE) ((rop4>>8) & 0xff);
  1367. //
  1368. // Check the SRC
  1369. //
  1370. if ( (ropFlags[fg_rop] & S) &&
  1371. (psoSrc))
  1372. {
  1373. if (psoSrc->iType == STYPE_DEVBITMAP)
  1374. {
  1375. lg_i = sprintf(lg_buf, "Src Id=%p ", psoSrc->dhsurf);
  1376. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1377. if ( ((PDSURF)psoSrc->dhsurf)->pso )
  1378. lg_i = sprintf(lg_buf,"S=DH ");
  1379. else
  1380. lg_i = sprintf(lg_buf,"S=DF ");
  1381. }
  1382. else if (psoSrc->hsurf == ppdev->hsurfEng)
  1383. lg_i = sprintf(lg_buf,"S=S ");
  1384. else
  1385. lg_i = sprintf(lg_buf,"S=H ");
  1386. }
  1387. else
  1388. lg_i = sprintf(lg_buf,"S=N ");
  1389. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1390. //
  1391. // Check the DEST
  1392. //
  1393. if (psoDest)
  1394. {
  1395. if (psoDest->iType == STYPE_DEVBITMAP)
  1396. {
  1397. lg_i = sprintf(lg_buf, "Dst Id=%p ", psoDest->dhsurf);
  1398. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1399. if ( ((PDSURF)psoDest->dhsurf)->pso )
  1400. lg_i = sprintf(lg_buf,"D=DH ");
  1401. else
  1402. lg_i = sprintf(lg_buf,"D=DF ");
  1403. }
  1404. else if (psoDest->hsurf == ppdev->hsurfEng)
  1405. lg_i = sprintf(lg_buf,"D=S ");
  1406. else
  1407. lg_i = sprintf(lg_buf,"D=H ");
  1408. }
  1409. else
  1410. lg_i = sprintf(lg_buf,"D=N ");
  1411. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1412. //
  1413. // Check the ROP
  1414. //
  1415. if (fg_rop == bg_rop)
  1416. lg_i = sprintf(lg_buf,"R3=%02X ", fg_rop);
  1417. else
  1418. lg_i = sprintf(lg_buf,"R4=%04X ", rop4&0xFFFF);
  1419. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1420. //
  1421. // Check the type of clipping.
  1422. //
  1423. iDComplexity = (pco ? pco->iDComplexity : DC_TRIVIAL);
  1424. lg_i = sprintf(lg_buf,"C=%s ",
  1425. (iDComplexity==DC_TRIVIAL ? "T":
  1426. (iDComplexity == DC_RECT ? "R" : "C" )));
  1427. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1428. //
  1429. // Type of pattern.
  1430. //
  1431. if (ropFlags[fg_rop] & P)
  1432. {
  1433. if (pbo->iSolidColor == 0xFFFFFFFF )
  1434. {
  1435. lg_i = sprintf(lg_buf,"BR=P ");
  1436. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1437. }
  1438. else
  1439. {
  1440. lg_i = sprintf(lg_buf,"BR=0x%X ",(pbo->iSolidColor));
  1441. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1442. }
  1443. }
  1444. else
  1445. {
  1446. lg_i = sprintf(lg_buf,"BR=N ");
  1447. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1448. }
  1449. //
  1450. // Type of translation
  1451. //
  1452. if (!pxlo)
  1453. {
  1454. lg_i = sprintf(lg_buf,"TR=N ");
  1455. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1456. }
  1457. else if (pxlo->flXlate & XO_TRIVIAL)
  1458. {
  1459. lg_i = sprintf(lg_buf,"TR=T ");
  1460. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1461. }
  1462. else
  1463. {
  1464. lg_i = sprintf(lg_buf,"TR=NT ");
  1465. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1466. }
  1467. lg_i = sprintf(lg_buf,"\r\n");
  1468. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1469. return;
  1470. }
  1471. // ****************************************************************************
  1472. //
  1473. // LogDrvCreateDevBmp()
  1474. // This routine is called only from DrvCreateDeviceBitmap()
  1475. // Dump information to a file about what is going on in device bitmap land.
  1476. //
  1477. // ****************************************************************************
  1478. void LogDrvCreateDevBmp(
  1479. int acc,
  1480. PPDEV ppdev,
  1481. SIZEL sizl,
  1482. PDSURF pdsurf)
  1483. {
  1484. #if ENABLE_LOG_SWITCH
  1485. if (pointer_switch == 0) return;
  1486. #endif
  1487. switch(acc)
  1488. {
  1489. case 0: // Accelerated
  1490. lg_i = sprintf(lg_buf,
  1491. "DrvCreateDeviceBitmap: %4d x %4d Id: 0x%08X Loc: %d,%d \r\n",
  1492. sizl.cx, sizl.cy, pdsurf, pdsurf->pofm->x, pdsurf->pofm->y );
  1493. break;
  1494. case 1: // Punted
  1495. lg_i = sprintf(lg_buf,
  1496. "DrvCreateDeviceBitmap: %4d x %4d Punt size.\r\n",
  1497. sizl.cx, sizl.cy);
  1498. break;
  1499. case 2: // Punted
  1500. lg_i = sprintf(lg_buf,
  1501. "DrvCreateDeviceBitmap: %4d x %4d Punt 8x8.\r\n",
  1502. sizl.cx, sizl.cy);
  1503. break;
  1504. case 3: // Punted
  1505. lg_i = sprintf(lg_buf,
  1506. "DrvCreateDeviceBitmap: %4d x %4d Punt mode.\r\n",
  1507. sizl.cx, sizl.cy);
  1508. break;
  1509. case 4: // Punted
  1510. lg_i = sprintf(lg_buf,
  1511. "DrvCreateDeviceBitmap: %4d x %4d Punt assoc.\r\n",
  1512. sizl.cx, sizl.cy);
  1513. break;
  1514. case 5: // Punted
  1515. lg_i = sprintf(lg_buf,
  1516. "DrvCreateDeviceBitmap: %4d x %4d Punt bitmap.\r\n",
  1517. sizl.cx, sizl.cy);
  1518. break;
  1519. case 6: // Punted
  1520. lg_i = sprintf(lg_buf,
  1521. "DrvCreateDeviceBitmap: %4d x %4d Punt DSURF.\r\n",
  1522. sizl.cx, sizl.cy);
  1523. break;
  1524. case 7: // Punted
  1525. lg_i = sprintf(lg_buf,
  1526. "DrvCreateDeviceBitmap: %4d x %4d Punt FB alloc.\r\n",
  1527. sizl.cx, sizl.cy);
  1528. break;
  1529. case 8: // Punted
  1530. lg_i = sprintf(lg_buf,
  1531. "DrvCreateDeviceBitmap: %4d x %4d Punt 32x64.\r\n",
  1532. sizl.cx, sizl.cy);
  1533. break;
  1534. case 9: // Punted
  1535. lg_i = sprintf(lg_buf,
  1536. "DrvCreateDeviceBitmap: %4d x %4d Punt > cxScreen.\r\n",
  1537. sizl.cx, sizl.cy);
  1538. break;
  1539. default:
  1540. lg_i = sprintf(lg_buf,
  1541. "DrvCreateDeviceBitmap: %4d x %4d Punt unknown.\r\n",
  1542. sizl.cx, sizl.cy);
  1543. break;
  1544. }
  1545. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1546. }
  1547. // ****************************************************************************
  1548. //
  1549. // LogDrvDeleteDevBmp()
  1550. // This routine is called only from DrvDeleteDeviceBitmap()
  1551. // Dump information to a file about what is going on in device bitmap land.
  1552. //
  1553. // ****************************************************************************
  1554. void LogDrvDeleteDevBmp(
  1555. PDSURF pdsurf)
  1556. {
  1557. #if ENABLE_LOG_SWITCH
  1558. if (pointer_switch == 0) return;
  1559. #endif
  1560. lg_i = sprintf(lg_buf, "DrvDeleteDeviceBitmap: Id: 0x%08X. ", pdsurf);
  1561. WriteLogFile(pdsurf->ppdev->pmfile, lg_buf,
  1562. lg_i, pdsurf->ppdev->TxtBuff, &pdsurf->ppdev->TxtBuffIndex);
  1563. if (pdsurf->pso)
  1564. {
  1565. lg_i = sprintf(lg_buf, "Loc: HOST\r\n");
  1566. WriteLogFile(pdsurf->ppdev->pmfile, lg_buf, lg_i,
  1567. pdsurf->ppdev->TxtBuff, &pdsurf->ppdev->TxtBuffIndex);
  1568. }
  1569. else
  1570. {
  1571. lg_i = sprintf(lg_buf, "Loc: %d,%d\r\n", pdsurf->pofm->x, pdsurf->pofm->y);
  1572. WriteLogFile(pdsurf->ppdev->pmfile, lg_buf, lg_i,
  1573. pdsurf->ppdev->TxtBuff, &pdsurf->ppdev->TxtBuffIndex);
  1574. }
  1575. }
  1576. // ****************************************************************************
  1577. //
  1578. // LogCreateDibFromScreen()
  1579. // This routine is called only from bCreateDibFromScreen()
  1580. // Dump information to a file about what is going on in device bitmap land.
  1581. //
  1582. // ****************************************************************************
  1583. void LogCreateDibFromScreen(
  1584. int acc,
  1585. PPDEV ppdev,
  1586. PDSURF pdsurf
  1587. )
  1588. {
  1589. #if ENABLE_LOG_SWITCH
  1590. if (pointer_switch == 0) return;
  1591. #endif
  1592. lg_i = sprintf(lg_buf, "CreateDibFromScreen: Id: 0x%08X ", pdsurf);
  1593. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1594. switch(acc)
  1595. {
  1596. case 0: // Succeeded
  1597. lg_i = sprintf(lg_buf, " \r\n");
  1598. break;
  1599. case 1: // Failed
  1600. lg_i = sprintf(lg_buf, "Fail lock\r\n");
  1601. break;
  1602. case 2: // Failed
  1603. lg_i = sprintf(lg_buf, "Fail assoc\r\n");
  1604. break;
  1605. case 3: // Failed
  1606. lg_i = sprintf(lg_buf, " Fail create\r\n");
  1607. break;
  1608. default:
  1609. lg_i = sprintf(lg_buf, "Failed unknown\r\n");
  1610. break;
  1611. }
  1612. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1613. }
  1614. // ****************************************************************************
  1615. //
  1616. // LogCreateScreenFromDib()
  1617. // This routine is called only from bCreateScreenFromDib()
  1618. // Dump information to a file about what is going on in device bitmap land.
  1619. //
  1620. // ****************************************************************************
  1621. void LogCreateScreenFromDib(
  1622. int acc,
  1623. PPDEV ppdev,
  1624. PDSURF pdsurf
  1625. )
  1626. {
  1627. #if ENABLE_LOG_SWITCH
  1628. if (pointer_switch == 0) return;
  1629. #endif
  1630. lg_i = sprintf(lg_buf, "CreateScreenFromDib: ");
  1631. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1632. switch(acc)
  1633. {
  1634. case 0: // Succeeded
  1635. lg_i = sprintf(lg_buf, "Id: 0x%08X Dest: %d,%d\r\n",
  1636. pdsurf, pdsurf->pofm->x, pdsurf->pofm->y );
  1637. break;
  1638. case 1: // Failed
  1639. lg_i = sprintf(lg_buf, "Fail mode\r\n");
  1640. break;
  1641. case 2: // Failed
  1642. lg_i = sprintf(lg_buf, "Fail alloc\r\n");
  1643. break;
  1644. default: // Failed
  1645. lg_i = sprintf(lg_buf, "Fail unknown\r\n");
  1646. break;
  1647. }
  1648. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  1649. }
  1650. #endif // LOG_CALLS
  1651. // ============================================================================
  1652. //
  1653. // Punt a drawing operation back to GDI.
  1654. // Return TRUE if punt was successful.
  1655. // Return FALSE if punt failed.
  1656. //
  1657. BOOL PuntBitBlt(
  1658. SURFOBJ* psoDest,
  1659. SURFOBJ* psoSrc,
  1660. SURFOBJ* psoMask,
  1661. CLIPOBJ* pco,
  1662. XLATEOBJ* pxlo,
  1663. RECTL* prclDest,
  1664. POINTL* pptlSrc,
  1665. POINTL* pptlMask,
  1666. BRUSHOBJ* pbo,
  1667. POINTL* pptlBrush,
  1668. ROP4 rop4)
  1669. {
  1670. HBITMAP hbmDibSrc = 0;
  1671. HBITMAP hbmDibDest = 0;
  1672. PBYTE pjScreen;
  1673. BOOL bStatus;
  1674. PDSURF pdsurf;
  1675. PPDEV ppdev = 0;
  1676. DISPDBG((PUNT_DBG_LEVEL, "PuntBitBlt: Entry.\n"));
  1677. //
  1678. // If the source is a device bitmap, build a wrapper around it.
  1679. //
  1680. if ( psoSrc && (psoSrc->iType == STYPE_DEVBITMAP))
  1681. {
  1682. // Source is a device bitmap.
  1683. pdsurf = (PDSURF) psoSrc->dhsurf;
  1684. ppdev = pdsurf->ppdev;
  1685. if ( pdsurf->pofm ) // If it's in the frame buffer.
  1686. {
  1687. DISPDBG((PUNT_DBG_LEVEL,
  1688. " Source is device bitmap at (%d,%d).\n",
  1689. (pdsurf->ptl.x), (pdsurf->ptl.y)));
  1690. // Calculate the off-screen address.
  1691. // This is the upper left pixel in the device bitmap.
  1692. pjScreen = ppdev->pjScreen
  1693. + (pdsurf->ptl.x * ppdev->iBytesPerPixel)
  1694. + (pdsurf->ptl.y * ppdev->lDeltaScreen);
  1695. // Create a DIB. Point it's bits at the device bitmap.
  1696. hbmDibSrc = EngCreateBitmap(pdsurf->sizl, ppdev->lDeltaScreen,
  1697. ppdev->iBitmapFormat, BMF_TOPDOWN,
  1698. pjScreen);
  1699. // Associate the DIB surface with the driver.
  1700. EngAssociateSurface((HSURF) hbmDibSrc, ppdev->hdevEng, 0);
  1701. // Lock the DIB surface.
  1702. psoSrc = EngLockSurface((HSURF) hbmDibSrc);
  1703. }
  1704. else // The device bitmap is on the host.
  1705. {
  1706. DISPDBG((PUNT_DBG_LEVEL, " Source is device bitmap on host.\n"));
  1707. psoSrc = pdsurf->pso; // This is where it lives on the host.
  1708. }
  1709. }
  1710. //
  1711. // If the destination is a device bitmap, build a wrapper around it.
  1712. //
  1713. if ( psoDest && (psoDest->iType == STYPE_DEVBITMAP))
  1714. {
  1715. // Destination is a device bitmap.
  1716. pdsurf = (PDSURF) psoDest->dhsurf;
  1717. ppdev = pdsurf->ppdev;
  1718. if ( pdsurf->pofm ) // If it's in the frame buffer.
  1719. {
  1720. DISPDBG((PUNT_DBG_LEVEL,
  1721. " Dest is device bitmap at (%d,%d).\n",
  1722. (pdsurf->ptl.x), (pdsurf->ptl.y)));
  1723. // Calculate the off-screen address.
  1724. // This is the upper left pixel in the device bitmap.
  1725. pjScreen = ppdev->pjScreen
  1726. + (pdsurf->ptl.x * ppdev->iBytesPerPixel)
  1727. + (pdsurf->ptl.y * ppdev->lDeltaScreen);
  1728. // Create a DIB. Point it's bits at the device bitmap.
  1729. hbmDibDest = EngCreateBitmap(pdsurf->sizl, ppdev->lDeltaScreen,
  1730. ppdev->iBitmapFormat, BMF_TOPDOWN,
  1731. pjScreen);
  1732. // Associate the DIB surface with the driver.
  1733. EngAssociateSurface((HSURF) hbmDibDest, ppdev->hdevEng, 0);
  1734. // Lock the DIB surface.
  1735. psoDest = EngLockSurface((HSURF) hbmDibDest);
  1736. }
  1737. else // The device bitmap is on the host.
  1738. {
  1739. DISPDBG((PUNT_DBG_LEVEL, " Dest is device bitmap on host.\n"));
  1740. psoDest = pdsurf->pso;
  1741. }
  1742. }
  1743. //
  1744. // We're fooling GDI into thinking it's drawing to memory, when it's really
  1745. // drawing to the frame buffer. This means GDI won't call DrvSync() before
  1746. // drawing.
  1747. //
  1748. if (ppdev == 0)
  1749. {
  1750. ppdev = (PPDEV) psoDest->dhpdev;
  1751. if (ppdev == 0)
  1752. ppdev = (PPDEV) psoSrc->dhpdev;
  1753. }
  1754. ASSERTMSG(ppdev,"Panic. No ppdev in PuntBitBlt()!");
  1755. DrvSynchronize((DHPDEV) ppdev, NULL);
  1756. // Now, call the GDI.
  1757. bStatus = EngBitBlt(psoDest, psoSrc, psoMask, pco, pxlo, prclDest, pptlSrc,
  1758. pptlMask, pbo, pptlBrush, rop4);
  1759. // Delete the wrappers if they are created.
  1760. if (hbmDibSrc)
  1761. {
  1762. EngUnlockSurface(psoSrc);
  1763. EngDeleteSurface((HSURF) hbmDibSrc);
  1764. }
  1765. if (hbmDibDest)
  1766. {
  1767. EngUnlockSurface(psoDest);
  1768. EngDeleteSurface((HSURF) hbmDibDest);
  1769. }
  1770. DISPDBG((PUNT_DBG_LEVEL, "PuntBitBlt: Exit.\n"));
  1771. // Return the status.
  1772. return(bStatus);
  1773. }
  1774. #if SWAT6
  1775. /******************************************************************************\
  1776. * FUNCTION: StripePatBlt
  1777. *
  1778. * DESCRIPTION: Perform a PatBlt with striping.
  1779. *
  1780. * ON ENTRY: ppdev Pointer to physical device.
  1781. * x X coordinate of blit.
  1782. * y Y coordinate of blit.
  1783. * cx Width of blit.
  1784. * cy Height of blit.
  1785. *
  1786. * RETURNS: void Nothing.
  1787. \******************************************************************************/
  1788. void
  1789. StripePatBlt(
  1790. PPDEV ppdev,
  1791. ULONG x,
  1792. ULONG y,
  1793. ULONG cx,
  1794. ULONG cy
  1795. )
  1796. {
  1797. ULONG cxWidth;
  1798. ULONG TileWidth;
  1799. // Determine number of pixels per tile.
  1800. switch (ppdev->iBytesPerPixel)
  1801. {
  1802. case 1:
  1803. // 8-bpp.
  1804. TileWidth = (ULONG) ppdev->lTileSize;
  1805. break;
  1806. case 2:
  1807. // 16-bpp.
  1808. TileWidth = (ULONG) (ppdev->lTileSize) / 2;
  1809. break;
  1810. case 3:
  1811. // 24-bpp, perform the PatBlt at once since we don't have a nice
  1812. // number of pixels per tile.
  1813. REQUIRE(5);
  1814. LL_OP0(x, y);
  1815. LL_BLTEXT(cx, cy);
  1816. if (cx >= 0x391 && cy >= 0x24B)
  1817. {
  1818. ENDREQUIRE();
  1819. }
  1820. return;
  1821. case 4:
  1822. // 32-bpp.
  1823. TileWidth = (ULONG) (ppdev->lTileSize) / 4;
  1824. break;
  1825. }
  1826. // Determine number of pixels left in first tile.
  1827. cxWidth = TileWidth - (x & (TileWidth - 1));
  1828. if ( (cxWidth >= cx) || (cy == 1) )
  1829. {
  1830. // PatBlt width fits in a single tile.
  1831. REQUIRE(5);
  1832. LL_OP0(x, y);
  1833. LL_BLTEXT(cx, cy);
  1834. return;
  1835. }
  1836. // Perform the PatBlt in the first tile.
  1837. REQUIRE(5);
  1838. LL_OP0(x, y);
  1839. LL_BLTEXT(cxWidth, cy);
  1840. cx -= cxWidth;
  1841. x += cxWidth;
  1842. // Keep looping until we reach the last tile of the PatBlt.
  1843. while (cx > TileWidth)
  1844. {
  1845. // Perform the PatBlt on a complete tile (only x changes).
  1846. REQUIRE(5);
  1847. LL_OP0(x, y);
  1848. LL_BLTEXT(TileWidth, cy);
  1849. cx -= TileWidth;
  1850. x += TileWidth;
  1851. }
  1852. // Perform the PatBlt in the last tile (only x changes).
  1853. REQUIRE(5);
  1854. LL_OP0(x, y);
  1855. LL_BLTEXT(cx, cy);
  1856. } // StripePatBlt();
  1857. #endif // SWAT6