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.

1151 lines
32 KiB

  1. /****************************************************************************
  2. *****************************************************************************
  3. *
  4. * ******************************************
  5. * * Copyright (c) 1995, Cirrus Logic, Inc. *
  6. * * All Rights Reserved *
  7. * ******************************************
  8. *
  9. * PROJECT: Laguna I (CL-GD5462) -
  10. *
  11. * FILE: stretch.c
  12. *
  13. * AUTHOR: Benny Ng
  14. *
  15. * DESCRIPTION:
  16. * This module implements the DrvStretchBlt() function for the
  17. * Laguna NT driver.
  18. *
  19. * MODULES:
  20. * AdjustSrcSize()
  21. * bRectIntersect()
  22. * cRectIntersect()
  23. * Shrink()
  24. * Stretch()
  25. * CopySrcToOffMem()
  26. * bStretchDIB()
  27. * HandleCase_1()
  28. * DrvStretchBlt()
  29. *
  30. * REVISION HISTORY:
  31. * 7/11/95 Benny Ng Initial version
  32. *
  33. * $Log: X:/log/laguna/nt35/displays/cl546x/STRETCH.C $
  34. *
  35. * Rev 1.14 Nov 03 1997 11:10:48 frido
  36. * Added REQUIRE and WRITE_STRING macros.
  37. *
  38. * Rev 1.13 08 Apr 1997 12:29:06 einkauf
  39. *
  40. * add SYNC_W_3D to coordinate MCD/2D access
  41. *
  42. * Rev 1.12 21 Mar 1997 12:22:16 noelv
  43. * Combined "do_flag" and "sw_test_flag" together into "pointer_switch"
  44. *
  45. * Rev 1.11 07 Mar 1997 10:15:58 SueS
  46. * Handle NULL pointer in DrvStretchBlt.
  47. *
  48. * Rev 1.10 06 Sep 1996 15:16:40 noelv
  49. * Updated NULL driver for 4.0
  50. *
  51. * Rev 1.9 20 Aug 1996 11:04:26 noelv
  52. * Bugfix release from Frido 8-19-96
  53. *
  54. * Rev 1.1 15 Aug 1996 11:39:42 frido
  55. * Added precompiled header.
  56. *
  57. * Rev 1.0 14 Aug 1996 17:16:30 frido
  58. * Initial revision.
  59. *
  60. * Rev 1.8 16 May 1996 15:01:40 bennyn
  61. *
  62. * Add PIXEL_ALIGN to allocoffscnmem()
  63. *
  64. * Rev 1.7 04 Apr 1996 13:20:28 noelv
  65. * No change.
  66. *
  67. * Rev 1.6 15 Mar 1996 09:40:00 andys
  68. *
  69. * Removed BITMASK setting from code
  70. *
  71. * Rev 1.5 13 Mar 1996 11:11:20 bennyn
  72. * Added device bitmap support
  73. *
  74. * Rev 1.4 07 Mar 1996 18:23:50 bennyn
  75. *
  76. * Removed read/modify/write on CONTROL reg
  77. *
  78. * Rev 1.3 05 Mar 1996 11:59:10 noelv
  79. * Frido version 19
  80. *
  81. * Rev 1.1 20 Jan 1996 01:16:50 frido
  82. *
  83. *
  84. * Rev 1.5 10 Jan 1996 16:11:12 NOELV
  85. * Added NULL driver ability.
  86. *
  87. * Rev 1.4 18 Oct 1995 14:09:06 NOELV
  88. *
  89. * Fixed the mess I made of STRETCH.C I was writing to the BLT extents instea
  90. *
  91. * Rev 1.3 18 Oct 1995 12:10:26 NOELV
  92. *
  93. * Reworked register writes.
  94. * punted 16,24, and 32 bpp
  95. *
  96. * Rev 1.2 06 Oct 1995 13:50:26 bennyn
  97. *
  98. * Rev 1.1 22 Aug 1995 16:40:38 bennyn
  99. *
  100. * Rev 1.3 15 Aug 1995 11:27:28 bennyn
  101. *
  102. * Rev 1.2 07 Aug 1995 08:02:34 bennyn
  103. *
  104. * Rev 1.1 02 Aug 1995 12:13:04 bennyn
  105. *
  106. * Rev 1.0 11 Jul 1995 15:14:16 BENNYN
  107. * Initial revision.
  108. *
  109. ****************************************************************************
  110. ****************************************************************************/
  111. /*----------------------------- INCLUDES ----------------------------------*/
  112. #include "precomp.h"
  113. /*----------------------------- DEFINES -----------------------------------*/
  114. //#define PUNTBRK
  115. //#define DBGBRK
  116. #define DBGDISP
  117. #define OPTION_1
  118. //#define OPTION_2
  119. //#define OPTION_3
  120. #define X_INTERP_ENABLE 0x1
  121. #define Y_INTERP_ENABLE 0x2
  122. #define X_SHRINK_ENABLE 0x4
  123. #define Y_SHRINK_ENABLE 0x8
  124. #define _32K 32768
  125. #define SF 0x10000L
  126. /*--------------------- STATIC FUNCTION PROTOTYPES ------------------------*/
  127. /*--------------------------- ENUMERATIONS --------------------------------*/
  128. /*----------------------------- TYPEDEFS ----------------------------------*/
  129. typedef union _HOST_DATA {
  130. BYTE bData[4];
  131. DWORD dwData;
  132. } HOST_DATA;
  133. /*-------------------------- STATIC VARIABLES -----------------------------*/
  134. /*-------------------------- GLOBAL FUNCTIONS -----------------------------*/
  135. /****************************************************************************
  136. * FUNCTION NAME: AdjustSrcSize()
  137. *
  138. * DESCRIPTION: If the destination rectange is changed due to the clipping,
  139. * the source rectange size need to proportional change.
  140. * This routine handles the source size change calcualtion.
  141. *
  142. * RETURN: TRUE: Punt it.
  143. *
  144. * REVISION HISTORY:
  145. * 7/27/95 Benny Ng Initial version
  146. ****************************************************************************/
  147. BOOL AdjustSrcSize(LONG dx,
  148. LONG dy,
  149. LONG origdx,
  150. LONG origdy,
  151. LONG dszX,
  152. LONG dszY,
  153. LONG origdszX,
  154. LONG origdszY,
  155. LONG *sszX,
  156. LONG *sszY,
  157. LONG *XsrcOff,
  158. LONG *YsrcOff)
  159. {
  160. LONG ratioX, ratioY;
  161. LONG ltemp;
  162. UINT orig_sszX, orig_sszY;
  163. BOOL bpuntit = FALSE;
  164. BOOL bStretchX = FALSE;
  165. BOOL bStretchY = FALSE;
  166. orig_sszX = *sszX;
  167. orig_sszY = *sszY;
  168. // -------------------------------------------------------
  169. // Calculate the source to destination size ratio
  170. if (*sszX < origdszX)
  171. {
  172. ratioX = (origdszX * SF) / *sszX;
  173. bStretchX = TRUE;
  174. }
  175. else
  176. {
  177. ratioX = (*sszX * SF) / origdszX;
  178. };
  179. if (*sszY < origdszY)
  180. {
  181. ratioY = (origdszY * SF) / *sszY;
  182. bStretchY = TRUE;
  183. }
  184. else
  185. {
  186. ratioY = (*sszY * SF) / origdszY;
  187. };
  188. // -------------------------------------------------------
  189. // Calculate the source X offset
  190. if (origdx != dx)
  191. {
  192. if (bStretchX)
  193. ltemp = ((dx - origdx) * SF) / ratioX;
  194. else
  195. ltemp = ((dx - origdx) * ratioX) / SF;
  196. *XsrcOff = ltemp;
  197. };
  198. // Calculate the source X size change
  199. if (origdszX != dszX)
  200. {
  201. if (bStretchX)
  202. ltemp = ((origdszX - dszX) * SF) / ratioX;
  203. else
  204. ltemp = ((origdszX - dszX) * ratioX) / SF;
  205. *sszX = *sszX - ltemp;
  206. };
  207. // -------------------------------------------------------
  208. // Calculate the source Y offset
  209. if (origdy != dy)
  210. {
  211. if (bStretchY)
  212. ltemp = ((dy - origdy) * SF) / ratioY;
  213. else
  214. ltemp = ((dy - origdy) * ratioY) / SF;
  215. *YsrcOff = ltemp;
  216. };
  217. // Calculate the source Y size change
  218. if (origdszY != dszY)
  219. {
  220. if (bStretchY)
  221. ltemp = ((origdszY - dszY) * SF) / ratioY;
  222. else
  223. ltemp = ((origdszY - dszY) * ratioY) / SF;
  224. *sszY = *sszY - ltemp;
  225. };
  226. #ifdef DBGDISP
  227. DISPDBG((1, "AdjustSrcSize - bpuntit= %x, ratioX=%d, ratioY=%d\n",
  228. bpuntit, ratioX, ratioY));
  229. DISPDBG((1, "dx=%d, dy=%d, origdx=%d, origdy=%d,\n",
  230. dx, dy, origdx, origdy));
  231. DISPDBG((1, "dszX=%d, dszY=%d, origdszX=%d, origdszY=%d,\n",
  232. dszX, dszY, origdszX, origdszY));
  233. DISPDBG((1, "*sszX=%d, *sszY=%d, orig_sszX=%d, orig_sszY=%d,\n",
  234. *sszX, *sszY, orig_sszX, orig_sszY));
  235. DISPDBG((1, "*XsrcOff=%d, *YsrcOff=%d\n", *XsrcOff, *YsrcOff));
  236. #endif
  237. #ifdef DBGBRK
  238. DbgBreakPoint();
  239. #endif
  240. return(bpuntit);
  241. }
  242. /****************************************************************************
  243. * FUNCTION NAME: bRectIntersect()
  244. *
  245. * DESCRIPTION: If 'prcl1' and 'prcl2' intersect, has a return value of
  246. * TRUE and returns the intersection in 'prclResult'.
  247. * If they don't intersect, has a return value of FALSE,
  248. * and 'prclResult' is undefined.
  249. *
  250. * RETURN: TRUE: Rectange intersect.
  251. *
  252. * REVISION HISTORY:
  253. * 8/01/95 Benny Ng Initial version
  254. \**************************************************************************/
  255. BOOL bRectIntersect(RECTL* prcl1,
  256. RECTL* prcl2,
  257. RECTL* prclResult)
  258. {
  259. prclResult->left = max(prcl1->left, prcl2->left);
  260. prclResult->right = min(prcl1->right, prcl2->right);
  261. if (prclResult->left < prclResult->right)
  262. {
  263. prclResult->top = max(prcl1->top, prcl2->top);
  264. prclResult->bottom = min(prcl1->bottom, prcl2->bottom);
  265. if (prclResult->top < prclResult->bottom)
  266. return(TRUE);
  267. };
  268. return(FALSE);
  269. }
  270. /****************************************************************************
  271. * FUNCTION NAME: cRectIntersect()
  272. *
  273. * DESCRIPTION: This routine takes a list of rectangles from 'prclIn'
  274. * and clips them in-place to the rectangle 'prclClip'.
  275. * The input rectangles don't have to intersect 'prclClip';
  276. * the return value will reflect the number of input rectangles
  277. * that did intersect, and the intersecting rectangles will
  278. * be densely packed.
  279. *
  280. * RETURN: TRUE: Rectange intersect.
  281. *
  282. * REVISION HISTORY:
  283. * 8/01/95 Benny Ng Initial version
  284. \**************************************************************************/
  285. LONG cRectIntersect(RECTL* prclClip,
  286. RECTL* prclIn, // List of rectangles
  287. LONG c) // Can be zero
  288. {
  289. LONG cIntersections;
  290. RECTL* prclOut;
  291. cIntersections = 0;
  292. prclOut = prclIn;
  293. for (; c != 0; prclIn++, c--)
  294. {
  295. prclOut->left = max(prclIn->left, prclClip->left);
  296. prclOut->right = min(prclIn->right, prclClip->right);
  297. if (prclOut->left < prclOut->right)
  298. {
  299. prclOut->top = max(prclIn->top, prclClip->top);
  300. prclOut->bottom = min(prclIn->bottom, prclClip->bottom);
  301. if (prclOut->top < prclOut->bottom)
  302. {
  303. prclOut++;
  304. cIntersections++;
  305. };
  306. };
  307. }
  308. return(cIntersections);
  309. }
  310. /****************************************************************************
  311. * FUNCTION NAME: Shrink()
  312. *
  313. * DESCRIPTION: This function calculates the parameters for shrink BLT
  314. * operation.
  315. *
  316. * REVISION HISTORY:
  317. * 7/18/95 Benny Ng Initial version
  318. ****************************************************************************/
  319. VOID Shrink(PPDEV ppdev,
  320. LONG lSrc,
  321. LONG lDst,
  322. char chCoord,
  323. ULONG LnCntl,
  324. LONG *sShrinkInc)
  325. {
  326. LONG maj = 0;
  327. LONG min = 0;
  328. LONG accum = 0;
  329. // Set SHRINKINC value,
  330. // for y, SHRINKINC = ratio of src/dst
  331. // for x, SHRINKINC = ratio of src/dst if not interpolating
  332. // SHRINKINC = (ratio of src/dst minus one) if interpolating
  333. // low byte for x coordinate
  334. // high byte for y coordinate
  335. if (chCoord == 'X')
  336. {
  337. *sShrinkInc |= (lSrc / lDst);
  338. if (LnCntl & X_INTERP_ENABLE)
  339. sShrinkInc--;
  340. }
  341. else
  342. {
  343. *sShrinkInc |= ((lSrc / lDst) << 8);
  344. };
  345. // Compute ACCUM_?, MAJ_? and MIN_? values
  346. // MAJ_? = width (for x) or height (for y) of destination
  347. // MIN_? = negative of the remainder of src/dst
  348. // ACCUM_? = MAJ_? - 1 - ( Src%Dst / (shrink factor + 1))
  349. maj = lDst;
  350. min = -(lSrc % lDst);
  351. accum = maj - 1 - ((lSrc % lDst) / ((lSrc / lDst) + 1)) ;
  352. if (chCoord == 'X')
  353. {
  354. REQUIRE(3);
  355. LL16 (grMAJ_X, maj);
  356. LL16 (grMIN_X, min);
  357. LL16 (grACCUM_X, accum);
  358. }
  359. else
  360. {
  361. REQUIRE(3);
  362. LL16 (grMAJ_Y, maj);
  363. LL16 (grMIN_Y, min);
  364. LL16 (grACCUM_Y, accum);
  365. };
  366. #ifdef DBGBRK
  367. DISPDBG((1, "DrvStretchBlt - shrink\n"));
  368. DbgBreakPoint();
  369. #endif
  370. }
  371. /****************************************************************************
  372. * FUNCTION NAME: Stretch()
  373. *
  374. * DESCRIPTION: This function calculates the parameters for stretch BLT
  375. * operation.
  376. *
  377. * REVISION HISTORY:
  378. * 7/18/95 Benny Ng Initial version
  379. ****************************************************************************/
  380. VOID Stretch(PPDEV ppdev,
  381. LONG lSrc,
  382. LONG lDst,
  383. char chCoord,
  384. ULONG LnCntl)
  385. {
  386. LONG min = 0;
  387. LONG maj = 0;
  388. LONG accum = 0;
  389. // For interpolated stretches registers values differ from values for
  390. // replicated stretches
  391. if (((chCoord == 'X') && ((LnCntl & X_INTERP_ENABLE) == 0)) ||
  392. ((chCoord == 'Y') && ((LnCntl & Y_INTERP_ENABLE) == 0)))
  393. {
  394. // Compute ACCUM_?, MAJ_? and MIN_? for replicated stretch
  395. // MAJ_? = width (for x) or height (for y) of destination
  396. // MIN_? = negative of width (for x) or height (for y) of source
  397. // ACCUM_? = MAJ_? - 1 - ( Dst%Src / (stretch factor + 1))
  398. maj = lDst;
  399. min = -lSrc;
  400. accum = maj - 1 - ((lDst % lSrc) / ((lDst / lSrc) + 1));
  401. }
  402. else
  403. {
  404. // Compute ACCUM_?, MAJ_? and MIN_? for interpolated stretch
  405. // Interpolated strecthes use bits 13 & 14 of ACCUM_? to determine
  406. // whether to use pixel A, 3/4 A + 1/4 B, 1/2 A + 1/2 B or
  407. // 1/4 A + 3/4 B.
  408. // To set DDA values appropriately there are three choices.
  409. // 1) Set MAJ_? to 32k and scale MIN_? to keep ratio approximately
  410. // correct
  411. // MAJ_? = 32k
  412. // MIN_? = (negative of ratio of src/dst) scaled up to 32k
  413. // ACCUM_? = MAJ_? - 1 - (1/2 * Absolute difference of MAJ and MIN)
  414. //
  415. // 2) Scale both src and dst appropriately such that the ratio of
  416. // src/dst is preserved exactly.
  417. // Note: In the following, the division is performed first thus
  418. // there is a possiblity of a rounding error which shows the
  419. // difference between options 1 & 2.
  420. // MAJ_? = (32k / dst) * dst
  421. // MIN_? = (32k / dst) * src
  422. // ACCUM_? = MAJ_? - 1 - (1/2 * Absolute difference of MAJ and MIN)
  423. //
  424. // 3) Scale both SRC and Dest in such a manner as to force the last
  425. // pixels output on a line to match the last source pixels rather
  426. // than the last source interpolated with the pixel past the end
  427. // of the line. Option 3 is used here.
  428. // NOTE: Options 1 and both oversample Src data and so will replicate
  429. // last pixel in X and interpolate past end of data in Y
  430. #ifdef OPTION_1 // Option 1
  431. maj = _32K;
  432. min = -((_32K * lSrc) / lDst);
  433. #endif
  434. #ifdef OPTION_2 // Option 2
  435. maj = ((_32K / lDst) * lDst);
  436. min = -((_32K / lDst) * lSrc);
  437. #else // Option 3
  438. lDst *= 4;
  439. lSrc = lSrc * 4 - 3;
  440. maj = ((_32K / lDst) * lDst);
  441. min = -((_32K / lDst) * lSrc);
  442. #endif
  443. accum = maj - 1 - ((maj % -min) / (lDst/lSrc + 1));
  444. };
  445. if (chCoord == 'X')
  446. {
  447. REQUIRE(3);
  448. LL16 (grMAJ_X, maj);
  449. LL16 (grMIN_X, min);
  450. LL16 (grACCUM_X, accum);
  451. }
  452. else
  453. {
  454. REQUIRE(3);
  455. LL16 (grMAJ_Y, maj);
  456. LL16 (grMIN_Y, min);
  457. LL16 (grACCUM_Y, accum);
  458. };
  459. #ifdef DBGBRK
  460. DISPDBG((1, "DrvStretchBlt - stretch\n"));
  461. DbgBreakPoint();
  462. #endif
  463. }
  464. /****************************************************************************
  465. * FUNCTION NAME: CopySrcToOffMem()
  466. *
  467. * DESCRIPTION: This function copies source data from host memory to
  468. * offscreen memory
  469. *
  470. * REVISION HISTORY:
  471. * 7/18/95 Benny Ng Initial version
  472. ****************************************************************************/
  473. VOID CopySrcToOffMem(PPDEV ppdev,
  474. BYTE *pSrcScan0,
  475. LONG sDelta,
  476. LONG sszY,
  477. POFMHDL SrcHandle)
  478. {
  479. LONG DWcnt;
  480. LONG i, j, k;
  481. LONG cnt;
  482. BYTE *pSrcScan;
  483. PDWORD pSrcData;
  484. ULONG ultmp;
  485. LONG Ycord;
  486. HOST_DATA SrcData;
  487. pSrcScan = pSrcScan0;
  488. Ycord = SrcHandle->aligned_y;
  489. // Clear Laguna Command Control Register SWIZ_CNTL bit
  490. ppdev->grCONTROL = ppdev->grCONTROL & ~SWIZ_CNTL;
  491. LL16(grCONTROL, ppdev->grCONTROL);
  492. pSrcData = &SrcData.dwData;
  493. DWcnt = sDelta / sizeof(DWORD);
  494. // Setup the laguna registers for byte to byte BLT extents
  495. REQUIRE(8);
  496. LL16 (grBLTDEF, 0x1020);
  497. LL16 (grDRAWDEF, 0x00CC);
  498. LL16 (grOP1_opRDRAM.pt.X, 0);
  499. // LL (grOP0_opMRDRAM.pt.X, SrcHandle->aligned_x);
  500. // LL (grOP0_opMRDRAM.pt.Y, Ycord);
  501. LL_OP0_MONO (SrcHandle->aligned_x + ppdev->ptlOffset.x, Ycord + ppdev->ptlOffset.y);
  502. // LL (grMBLTEXT_EX.pt.X, sDelta);
  503. // LL (grMBLTEXT_EX.pt.Y, sszY);
  504. LL_MBLTEXT (sDelta, sszY);
  505. cnt = DWcnt;
  506. k = 0;
  507. for (i=0; i < sszY; i++)
  508. {
  509. // Pre-fill the 32-bits pattern with default values
  510. for (j=0; j < 4; j++)
  511. SrcData.bData[j] = 0;
  512. // Copy one screen line mask data from source to destination
  513. for (j=0; j < sDelta; j++)
  514. {
  515. SrcData.bData[k++] = *pSrcScan;
  516. pSrcScan++;
  517. if (k > 3)
  518. {
  519. REQUIRE(1);
  520. LL32 (grHOSTDATA[0], *pSrcData);
  521. k = 0;
  522. cnt--;
  523. }; // endif (k > 3)
  524. }; // endfor j
  525. // Check whether one screen line of data are written to the
  526. // HOSTDATA register.
  527. if (cnt == 0)
  528. {
  529. // Reset the row data count
  530. cnt = DWcnt;
  531. }; // endif (cnt == 0)
  532. }; // end for i
  533. #ifdef DBGBRK
  534. DISPDBG((0, "DrvStretchBlt-CopySrcToOffMem\n"));
  535. DbgBreakPoint();
  536. #endif
  537. }
  538. /****************************************************************************
  539. * FUNCTION NAME: bStretchDIB()
  540. *
  541. * DESCRIPTION: StretchBlt using integer math. Must be from one surface
  542. * to another surface of the same format.
  543. *
  544. * RETURN: TRUE: Punt it.
  545. *
  546. * REVISION HISTORY:
  547. * 7/27/95 Benny Ng Initial version
  548. ****************************************************************************/
  549. BOOL bStretchDIB(SURFOBJ* psoSrc,
  550. SURFOBJ* psoMsk,
  551. PDEV* ppdev,
  552. VOID* pvDst,
  553. LONG lDeltaDst,
  554. RECTL* prclDst,
  555. VOID* pvSrc,
  556. LONG lDeltaSrc,
  557. RECTL* prclSrc,
  558. RECTL* prclClip)
  559. {
  560. LONG ltmp;
  561. ULONG ultmp;
  562. SIZEL reqsz;
  563. LONG bpp;
  564. BYTE *pSrcScan;
  565. RECTL rclRes;
  566. BOOL bNoBlt = FALSE;
  567. BOOL bpuntit = TRUE;
  568. POFMHDL SrcHandle = NULL;
  569. long drawdef = 0;
  570. long srcx = 0;
  571. ULONG LnCntl = 0;
  572. LONG sShrinkInc = 0;
  573. LONG XsrcOff = 0;
  574. LONG YsrcOff = 0;
  575. // Calculate the rectange start points and sizes:
  576. //
  577. LONG WidthDst = prclDst->right - prclDst->left;
  578. LONG HeightDst = prclDst->bottom - prclDst->top;
  579. LONG WidthSrc = prclSrc->right - prclSrc->left;
  580. LONG HeightSrc = prclSrc->bottom - prclSrc->top;
  581. LONG XDstStart = prclDst->left;
  582. LONG YDstStart = prclDst->top;
  583. LONG XSrcStart = prclSrc->left;
  584. LONG YSrcStart = prclSrc->top;
  585. // -------------------------------------------------------
  586. // Calculate bytes per pixel
  587. bpp = ppdev->ulBitCount/8;
  588. // Get the informations from source and destination surface
  589. pSrcScan = pvSrc;
  590. if (psoMsk != NULL)
  591. {
  592. #ifdef DBGDISP
  593. DISPDBG((1, "DrvStretchBlt - HandleCase_1 mask pointer != NULL (punt it)\n"));
  594. #endif
  595. goto Punt_It;
  596. };
  597. // -------------------------------------------------------
  598. // Check whether source is from host or video memory
  599. if ((pSrcScan < ppdev->pjScreen) ||
  600. (pSrcScan > (ppdev->pjScreen + ppdev->lTotalMem)))
  601. {
  602. #ifdef DBGDISP
  603. DISPDBG((1, "DrvStretchBlt - HandleCase_1 - src host\n"));
  604. #endif
  605. // Allocate the offscreen memory for the source if not enough offscreen
  606. // memory available punt it.
  607. reqsz.cx = psoSrc->sizlBitmap.cx;
  608. reqsz.cy = psoSrc->sizlBitmap.cy;
  609. if ((SrcHandle = AllocOffScnMem(ppdev, &reqsz, PIXEL_AlIGN, NULL)) == NULL)
  610. { goto Punt_It; };
  611. //?? bbbbbbbbbb
  612. // Note: The following lines of code takes care the host data HW problem,
  613. // it punt back to GDI when host data size is 29 to 30 to DWORD.
  614. //
  615. if ((lDeltaSrc >= 116) && (lDeltaSrc <= 120))
  616. {
  617. DISPDBG((1, "DrvStretchBlt - src host (punt it)\n"));
  618. goto Punt_It;
  619. };
  620. //?? eeeeeeeeee
  621. // Copy the source data into allocated offscreen memory
  622. CopySrcToOffMem(ppdev,
  623. pSrcScan,
  624. lDeltaSrc,
  625. HeightSrc,
  626. SrcHandle);
  627. XSrcStart = SrcHandle->aligned_x / bpp;
  628. YSrcStart = SrcHandle->aligned_y;
  629. }
  630. else
  631. {
  632. #ifdef DBGDISP
  633. DISPDBG((1, "DrvStretchBlt - HandleCase_1 - src videow\n"));
  634. #endif
  635. if ((WidthSrc * bpp) > ppdev->lDeltaScreen)
  636. WidthSrc = ppdev->lDeltaScreen / bpp;
  637. ltmp = ppdev->lTotalMem / ppdev->lDeltaScreen;
  638. if (HeightSrc > ltmp)
  639. HeightSrc = ltmp;
  640. };
  641. // -------------------------------------------------------
  642. if (prclClip != NULL)
  643. {
  644. // Test for intersection of clipping rectangle and destination
  645. // rectangle. If they don't intersect, go on for stretch BLT.
  646. // For DC_RECT clipping we have a single clipping rectangle.
  647. // We create a new destination rectangle which is the intersection
  648. // between the old destination rectangle and the clipping rectangle.
  649. // Then we adjust our source rectangle accordingly.
  650. //
  651. if (!bRectIntersect(prclDst, prclClip, &rclRes))
  652. {
  653. #ifdef DBGDISP
  654. DISPDBG((1, "DrvStretchBlt - HandleCase_1 - DC_RECT no intersect\n"));
  655. #endif
  656. goto Punt_It;
  657. };
  658. // Adjust the source size
  659. bNoBlt = AdjustSrcSize(rclRes.left, rclRes.top,
  660. XDstStart, YDstStart,
  661. (rclRes.right - rclRes.left),
  662. (rclRes.bottom - rclRes.top),
  663. WidthDst, HeightDst,
  664. &WidthSrc, &HeightSrc,
  665. &XsrcOff, &YsrcOff);
  666. // Adjust the destination rectange size
  667. XDstStart = rclRes.left;
  668. YDstStart = rclRes.top;
  669. WidthDst = rclRes.right - rclRes.left;
  670. HeightDst = rclRes.bottom - rclRes.top;
  671. }; // endif (prclClip != NULL)
  672. if (!bNoBlt)
  673. {
  674. // -------------------------------------------------------
  675. // Perform the shrink or stretch operation
  676. // Set the shrink or interpolate bit in LNCNTL
  677. if (WidthSrc >= WidthDst)
  678. {
  679. LnCntl |= X_SHRINK_ENABLE;
  680. Shrink(ppdev, WidthSrc, WidthDst, 'X', LnCntl, &sShrinkInc);
  681. }
  682. else
  683. {
  684. Stretch(ppdev, WidthSrc, WidthDst, 'X', LnCntl);
  685. };
  686. if (HeightSrc >= HeightDst)
  687. {
  688. LnCntl |= Y_SHRINK_ENABLE;
  689. Shrink(ppdev, HeightSrc, HeightDst, 'Y', LnCntl, &sShrinkInc);
  690. }
  691. else
  692. {
  693. Stretch(ppdev, HeightSrc, HeightDst, 'Y', LnCntl);
  694. };
  695. #ifdef DBGBRK
  696. DISPDBG((1, "DrvStretchBlt - bStretchDIB - before exec\n"));
  697. DbgBreakPoint();
  698. #endif
  699. // -------------------------------------------------------
  700. XSrcStart += XsrcOff;
  701. YSrcStart += YsrcOff;
  702. // LL (grOP1_opRDRAM.pt.X, XSrcStart);
  703. // LL (grOP1_opRDRAM.pt.Y, YSrcStart);
  704. REQUIRE(12);
  705. LL_OP1 (XSrcStart, YSrcStart);
  706. LL16 (grSHRINKINC, sShrinkInc);
  707. LL16 (grBLTDEF, 0x1010);
  708. LL16 (grDRAWDEF, 0x00CC);
  709. // Setup the shrink and interpolate bits in LNCNTL
  710. ultmp = LLDR_SZ (grLNCNTL.w);
  711. ultmp |= LnCntl;
  712. LL16 (grLNCNTL, ultmp);
  713. srcx = WidthSrc * bpp;
  714. LL16 (grSRCX, srcx);
  715. // LL (grOP0_opRDRAM.pt.X, XDstStart);
  716. // LL (grOP0_opRDRAM.pt.Y, YDstStart);
  717. LL_OP0 (XDstStart + ppdev->ptlOffset.x, YDstStart + ppdev->ptlOffset.y);
  718. // LL (grBLTEXTR_EX.pt.X, WidthDst);
  719. // LL (grBLTEXTR_EX.pt.Y, HeightDst);
  720. LL_BLTEXTR (WidthDst, HeightDst);
  721. #ifdef DBGBRK
  722. DISPDBG((1, "DrvStretchBlt - bStretchDIB - after exec\n"));
  723. DbgBreakPoint();
  724. #endif
  725. bpuntit = FALSE;
  726. }; //endif (!bNoBlt)
  727. Punt_It:
  728. // -------------------------------------------------------
  729. // Release the offscreen buffer if allocated
  730. if (SrcHandle != NULL)
  731. FreeOffScnMem(ppdev, SrcHandle);
  732. return(bpuntit);
  733. }
  734. /****************************************************************************
  735. * FUNCTION NAME: HandleCase_1()
  736. *
  737. * DESCRIPTION: This function handle the case when
  738. * Both src and dst surface types are equal to STYPE_BITMAP,
  739. * both src and dst surface have same iBitmapFormat,
  740. * no color translation.
  741. *
  742. * RETURN: TRUE: Punt it.
  743. *
  744. * REVISION HISTORY:
  745. * 7/18/95 Benny Ng Initial version
  746. ****************************************************************************/
  747. BOOL HandleCase_1(SURFOBJ* psoDst,
  748. SURFOBJ* psoSrc,
  749. SURFOBJ* psoMsk,
  750. CLIPOBJ* pco,
  751. RECTL* prclDst,
  752. RECTL* prclSrc,
  753. POINTL* pptlMsk,
  754. BOOL* bRet)
  755. {
  756. BOOL bpuntit = TRUE;
  757. PDEV* ppdev = (PDEV*) psoDst->dhpdev;
  758. BYTE iDComplexity;
  759. PRECTL prclClip;
  760. ENUMRECTS ce;
  761. BOOL bMore;
  762. LONG c;
  763. LONG i;
  764. *bRet = FALSE;
  765. // -------------------------------------------------------
  766. // CHeck what kind of clipping is it?
  767. iDComplexity = (pco ? pco->iDComplexity : DC_TRIVIAL);
  768. switch (iDComplexity)
  769. {
  770. case DC_TRIVIAL:
  771. #ifdef DBGDISP
  772. DISPDBG((1, "DrvStretchBlt - HandleCase_1 - DC_TRIVIAL\n"));
  773. #endif
  774. bpuntit = bStretchDIB(psoSrc,
  775. psoMsk,
  776. ppdev,
  777. NULL,
  778. psoDst->lDelta,
  779. prclDst,
  780. psoSrc->pvScan0,
  781. psoSrc->lDelta,
  782. prclSrc,
  783. NULL);
  784. break;
  785. case DC_RECT:
  786. #ifdef DBGDISP
  787. DISPDBG((1, "DrvStretchBlt - HandleCase_1 - DC_RECT\n"));
  788. #endif
  789. // Get the clipping rectangle.
  790. prclClip = &pco->rclBounds;
  791. bpuntit = bStretchDIB(psoSrc,
  792. psoMsk,
  793. ppdev,
  794. NULL,
  795. psoDst->lDelta,
  796. prclDst,
  797. psoSrc->pvScan0,
  798. psoSrc->lDelta,
  799. prclSrc,
  800. prclClip);
  801. break;
  802. case DC_COMPLEX:
  803. #ifdef DBGDISP
  804. DISPDBG((1, "DrvStretchBlt - HandleCase_1 - DC_COMPLEX\n"));
  805. #endif
  806. bpuntit = FALSE;
  807. CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0);
  808. do
  809. {
  810. bMore = CLIPOBJ_bEnum(pco, sizeof(ce), (ULONG*) &ce);
  811. c = cRectIntersect(prclDst, ce.arcl, ce.c);
  812. if (c != 0)
  813. {
  814. for (i = 0; i < c; i++)
  815. {
  816. bpuntit = bStretchDIB(psoSrc,
  817. psoMsk,
  818. ppdev,
  819. NULL,
  820. psoDst->lDelta,
  821. prclDst,
  822. psoSrc->pvScan0,
  823. psoSrc->lDelta,
  824. prclSrc,
  825. &ce.arcl[i]);
  826. if (bpuntit)
  827. break;
  828. }; // enddo
  829. }; // endif
  830. } while ((bMore) && (!bpuntit));
  831. break;
  832. default:
  833. break;
  834. }; // end switch (iDComplexity)
  835. // -------------------------------------------------------
  836. // Check whether the operation was handled successfully
  837. if (!bpuntit)
  838. *bRet = TRUE;
  839. return (bpuntit);
  840. }
  841. /****************************************************************************
  842. * FUNCTION NAME: DrvStretchBlt()
  843. *
  844. * DESCRIPTION: This function provides stretching bit-block transfer
  845. * capabilities for Laguna NT
  846. *
  847. * REVISION HISTORY:
  848. * 7/11/95 Benny Ng Initial version
  849. ****************************************************************************/
  850. #define TSTFRIDO 1
  851. BOOL DrvStretchBlt(SURFOBJ* psoDst,
  852. SURFOBJ* psoSrc,
  853. SURFOBJ* psoMsk,
  854. CLIPOBJ* pco,
  855. XLATEOBJ* pxlo,
  856. COLORADJUSTMENT* pca,
  857. POINTL* pptlHTOrg,
  858. RECTL* prclDst,
  859. RECTL* prclSrc,
  860. POINTL* pptlMsk,
  861. ULONG iMode)
  862. {
  863. BOOL bRet = TRUE;
  864. BOOL bPuntIt = TRUE;
  865. LONG HandleIt = 0;
  866. #if NULL_STRETCH
  867. {
  868. if (pointer_switch) return TRUE;
  869. }
  870. #endif
  871. #ifdef TSTFRIDO
  872. {
  873. PPDEV ppdev = (PPDEV) psoDst->dhpdev;
  874. SYNC_W_3D(ppdev);
  875. if (psoDst->iType == STYPE_DEVBITMAP)
  876. {
  877. PDSURF pdsurf = (PDSURF)psoDst->dhsurf;
  878. if ( pdsurf->pso )
  879. {
  880. if ( !bCreateScreenFromDib(ppdev, pdsurf) )
  881. {
  882. return EngStretchBlt(psoDst, psoSrc, psoMsk, pco,
  883. pxlo, pca, pptlHTOrg,
  884. prclDst, prclSrc, pptlMsk, iMode);
  885. };
  886. };
  887. ppdev->ptlOffset.x = pdsurf->ptl.x;
  888. ppdev->ptlOffset.y = pdsurf->ptl.y;
  889. }
  890. else
  891. {
  892. if (ppdev != NULL)
  893. ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0;
  894. else
  895. return(EngStretchBlt(psoDst, psoSrc, psoMsk, pco, pxlo, pca, pptlHTOrg,
  896. prclDst, prclSrc, pptlMsk, iMode));
  897. };
  898. ppdev = (PPDEV) psoSrc->dhpdev;
  899. if (psoSrc->iType == STYPE_DEVBITMAP)
  900. {
  901. PDSURF pdsurf = (PDSURF)psoSrc->dhsurf;
  902. if ( pdsurf->pso )
  903. {
  904. if ( !bCreateScreenFromDib(ppdev, pdsurf) )
  905. {
  906. return EngStretchBlt(psoDst, psoSrc, psoMsk, pco,
  907. pxlo, pca, pptlHTOrg,
  908. prclDst, prclSrc, pptlMsk, iMode);
  909. };
  910. };
  911. ppdev->ptlOffset.x = pdsurf->ptl.x;
  912. ppdev->ptlOffset.y = pdsurf->ptl.y;
  913. }
  914. else
  915. {
  916. if (ppdev != NULL)
  917. ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0;
  918. else
  919. return(EngStretchBlt(psoDst, psoSrc, psoMsk, pco, pxlo, pca, pptlHTOrg,
  920. prclDst, prclSrc, pptlMsk, iMode));
  921. };
  922. }
  923. #else
  924. {
  925. PPDEV ppdev = (PPDEV) psoDst->dhpdev;
  926. SYNC_W_3D(ppdev);
  927. }
  928. bRet = EngStretchBlt(psoDst, psoSrc, psoMsk, pco, pxlo, pca, pptlHTOrg,
  929. prclDst, prclSrc, pptlMsk, iMode);
  930. return(bRet);
  931. #endif
  932. #ifdef DBGDISP
  933. DISPDBG((1, "DrvStretchBlt - %d\n", iMode));
  934. #endif
  935. if ((psoDst->iType == psoSrc->iType) &&
  936. (psoDst->fjBitmap == psoSrc->fjBitmap) &&
  937. (psoDst->fjBitmap == BMF_TOPDOWN))
  938. {
  939. // If src and dst surface have same iBitmapFormat
  940. if (psoDst->iBitmapFormat == psoSrc->iBitmapFormat)
  941. {
  942. // Check for color translation
  943. if (pxlo == NULL)
  944. {
  945. HandleIt = 1;
  946. }
  947. else if ((pxlo != NULL) && (pxlo->iSrcType == pxlo->iDstType))
  948. {
  949. switch (pxlo->flXlate)
  950. {
  951. case XO_TRIVIAL:
  952. case 0:
  953. HandleIt = 1;
  954. break;
  955. default:
  956. #ifdef DBGDISP
  957. DISPDBG((1, "DrvStretchBlt - pxlo->flXlate (punt it)\n"));
  958. #endif
  959. break;
  960. };
  961. }; // endif (pxlo == NULL)
  962. }; // endif (src and dst surface have same iBitmapFormat)
  963. }; // endif (Both src and dst surface types are equal to STYPE_BITMAP)
  964. // Check whether we can handle this case, if yes call the case
  965. // handle routine to try to handle it. Otherwise punt it back to GDI
  966. if (HandleIt != 0)
  967. {
  968. if (HandleIt == 1)
  969. {
  970. bPuntIt = HandleCase_1(psoDst,
  971. psoSrc,
  972. psoMsk,
  973. pco,
  974. prclDst,
  975. prclSrc,
  976. pptlMsk,
  977. &bRet);
  978. }
  979. else if (HandleIt == 2)
  980. {
  981. };
  982. }; // endif (HandleIt)
  983. // -------------------------------------------------------
  984. // Punt It back to GDI to handle it
  985. if (bPuntIt)
  986. {
  987. DISPDBG((1, "DrvStretchBlt - punt it\n"));
  988. #ifdef PUNTBRK
  989. DbgBreakPoint();
  990. #endif
  991. bRet = EngStretchBlt(psoDst, psoSrc, psoMsk, pco, pxlo, pca, pptlHTOrg,
  992. prclDst, prclSrc, pptlMsk, iMode);
  993. };
  994. return(bRet);
  995. }
  996.