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.

1122 lines
40 KiB

  1. #include "precomp.h"
  2. // this will be compiled only for NT40 and greater
  3. #if TARGET_BUILD > 351
  4. void ModifyOverlayPosition (PDEV* , LPRECTL , LPDWORD );
  5. /* This procedure writes the Overlay pitch*/
  6. __inline void WriteVTOverlayPitch (PDEV* ppdev, DWORD Pitch)
  7. {
  8. DD_WriteVTReg ( DD_BUF0_PITCH, Pitch );
  9. DD_WriteVTReg ( DD_BUF1_PITCH, Pitch );
  10. }
  11. void DeskScanCallback (PDEV* ppdev )
  12. {
  13. RECTL rPhysOverlay;
  14. DWORD dwBuf0Offset, dwBuf1Offset;
  15. DWORD dwVInc = ppdev->OverlayInfo16.dwVInc;
  16. DWORD dwHInc = ppdev->OverlayInfo16.dwHInc;
  17. static DWORD dwOldVInc = 0, dwOldHInc = 0;
  18. static WORD wOldX = 0xFFFF, wOldY = 0xFFFF;
  19. static RECTL rOldPhysOverlay = { 0, 0, 0, 0 };
  20. /*
  21. * If we have not allocated the overlay then we better not do
  22. * anything or we might collide with the video capture stuff
  23. */
  24. if ( ! ( ppdev->OverlayInfo16.dwFlags & OVERLAY_ALLOCATED ) )
  25. {
  26. return;
  27. }
  28. dwBuf0Offset = ppdev->OverlayInfo16.dwBuf0Start;
  29. dwBuf1Offset = ppdev->OverlayInfo16.dwBuf1Start;
  30. rPhysOverlay.top = ppdev->OverlayInfo16.rDst.top;
  31. rPhysOverlay.bottom = ppdev->OverlayInfo16.rDst.bottom ;
  32. rPhysOverlay.left = ppdev->OverlayInfo16.rDst.left ;
  33. rPhysOverlay.right = ppdev->OverlayInfo16.rDst.right ;
  34. /*
  35. * Turn off keyer if overlay has moved off the screen.
  36. */
  37. if ( rPhysOverlay.right < 0 ||
  38. rPhysOverlay.bottom < 0 ||
  39. rPhysOverlay.left > ppdev->cxScreen - 1 ||
  40. rPhysOverlay.top > ppdev->cyScreen - 1 )
  41. {
  42. DD_WriteVTReg ( DD_OVERLAY_KEY_CNTL, 0x00000110L );
  43. return;
  44. }
  45. /*
  46. * Adjust Offsets if overlay source rectangle is clipped
  47. */
  48. if ( ppdev->OverlayInfo16.dwFlags & UPDATEOVERLAY )
  49. {
  50. if ( ppdev->OverlayInfo16.rSrc.left > 0 )
  51. {
  52. dwBuf0Offset += ppdev->OverlayInfo16.rSrc.left * 2;
  53. dwBuf1Offset += ppdev->OverlayInfo16.rSrc.left * 2;
  54. }
  55. if ( ppdev->OverlayInfo16.rSrc.top > 0 )
  56. {
  57. if ( ppdev->OverlayInfo16.dwFlags & DOUBLE_PITCH )
  58. {
  59. dwBuf0Offset +=
  60. ppdev->OverlayInfo16.rSrc.top * ppdev->OverlayInfo16.lBuf0Pitch * 2;
  61. dwBuf1Offset +=
  62. ppdev->OverlayInfo16.rSrc.top * ppdev->OverlayInfo16.lBuf1Pitch * 2;
  63. }
  64. else
  65. {
  66. dwBuf0Offset +=
  67. ppdev->OverlayInfo16.rSrc.top * ppdev->OverlayInfo16.lBuf0Pitch;
  68. dwBuf1Offset +=
  69. ppdev->OverlayInfo16.rSrc.top * ppdev->OverlayInfo16.lBuf1Pitch;
  70. }
  71. }
  72. }
  73. if ( M64_ID_DIRECT(ppdev->pjMmBase, CRTC_GEN_CNTL ) & CRTC_INTERLACE_EN )
  74. ModifyOverlayPosition (ppdev, &rPhysOverlay, &dwVInc );
  75. if ( dwVInc != dwOldVInc || dwHInc != dwOldHInc )
  76. DD_WriteVTReg ( DD_OVERLAY_SCALE_INC, ( dwHInc << 16 ) | dwVInc );
  77. /*
  78. * Try not to write new position at a bad time!
  79. */
  80. // if ((ppdev->iAsic ==CI_M64_VTA)||(ppdev->iAsic ==CI_M64_GTA))
  81. // {
  82. if ( rPhysOverlay.top != rOldPhysOverlay.top ||
  83. rPhysOverlay.bottom != rOldPhysOverlay.bottom ||
  84. rPhysOverlay.left != rOldPhysOverlay.left ||
  85. rPhysOverlay.right != rOldPhysOverlay.right )
  86. //((M64_ID(ppdev->pjMmBase, CRTC_VLINE_CRNT_VLINE)&0x07FF0000L)>>16L)
  87. if ( (LONG)((M64_ID_DIRECT(ppdev->pjMmBase, CRTC_VLINE_CRNT_VLINE)&0x07FF0000L)>>16L)>= rOldPhysOverlay.top )
  88. while ( (LONG)((M64_ID_DIRECT(ppdev->pjMmBase, CRTC_VLINE_CRNT_VLINE)&0x07FF0000L)>>16L) <= rOldPhysOverlay.bottom );
  89. // }
  90. /*
  91. * Hit the registers with the new overlay information.
  92. */
  93. DD_WriteVTReg ( DD_BUF0_OFFSET, dwBuf0Offset );
  94. DD_WriteVTReg ( DD_BUF1_OFFSET, dwBuf1Offset );
  95. DD_WriteVTReg ( DD_OVERLAY_Y_X, (DWORD)(
  96. ( (DWORD)rPhysOverlay.left << 16L ) |
  97. ( (DWORD)rPhysOverlay.top ) | (0x80000000) ) );
  98. DD_WriteVTReg ( DD_OVERLAY_Y_X_END, (DWORD)(
  99. ( (DWORD)rPhysOverlay.right << 16L ) |
  100. ( (DWORD)rPhysOverlay.bottom ) ) );
  101. if ( ppdev->OverlayInfo16.dwFlags & UPDATEOVERLAY )
  102. {
  103. DD_WriteVTReg ( DD_OVERLAY_KEY_CNTL, ppdev->OverlayInfo16.dwOverlayKeyCntl );
  104. }
  105. dwOldVInc = dwVInc;
  106. dwOldHInc = dwHInc;
  107. rOldPhysOverlay.top = max ( rPhysOverlay.top, 0 );
  108. rOldPhysOverlay.bottom = min ( rPhysOverlay.bottom, (LONG)ppdev->cyScreen - 1 );
  109. rOldPhysOverlay.left = rPhysOverlay.left;
  110. rOldPhysOverlay.right = rPhysOverlay.right;
  111. }
  112. void ModifyOverlayPosition (PDEV* ppdev, LPRECTL lprOverlay, LPDWORD lpdwVInc )
  113. {
  114. DWORD dwVInc;
  115. DWORD dwScaleChange;
  116. DWORD dwHeight;
  117. DWORD dwTop, dwBottom;
  118. lprOverlay->top -= 3;
  119. if ( lprOverlay->top < 0 )
  120. {
  121. lprOverlay->top += M64_ID(ppdev->pjMmBase, CRTC_V_TOTAL_DISP )& 0x07FFL;
  122. }
  123. if ( lprOverlay->top != 0 )
  124. {
  125. if ( lprOverlay->top % 2 == 0 )
  126. lprOverlay->top++;
  127. if ( lprOverlay->top == 1 )
  128. lprOverlay->top = 0;
  129. }
  130. if ( lprOverlay->bottom%2 == 1 )
  131. lprOverlay->bottom++;
  132. lprOverlay->bottom = min ( lprOverlay->bottom,
  133. (LONG) ppdev->cyScreen - 2 );
  134. /*
  135. * Adjust scaling factor so we don't get the "green line" at the
  136. * bottom of the overlay if we are moving the overlay off the top
  137. * of the screen
  138. */
  139. dwVInc = ppdev->OverlayInfo16.dwVInc;
  140. dwBottom = lprOverlay->bottom;
  141. dwTop = lprOverlay->top;
  142. if ( (LONG)dwTop > ppdev->cyScreen - 1 )
  143. dwTop = 0L;
  144. dwHeight = dwBottom - dwTop;
  145. if ( dwHeight != 0 )
  146. dwScaleChange = ( ( dwHeight - 1 ) << 12 ) / ( dwHeight );
  147. else
  148. dwScaleChange = 0;
  149. if ( dwScaleChange != 0 )
  150. dwVInc = ( dwVInc * dwScaleChange ) >> 12;
  151. *lpdwVInc = dwVInc;
  152. }
  153. void TurnOnVTRegisters ( PDEV* ppdev )
  154. {
  155. DWORD dwBusCntl;
  156. dwBusCntl = M64_ID_DIRECT(ppdev->pjMmBase, BUS_CNTL );
  157. dwBusCntl |= 0x08000000U;
  158. M64_OD_DIRECT(ppdev->pjMmBase, BUS_CNTL, dwBusCntl );
  159. }
  160. void TurnOffVTRegisters ( PDEV* ppdev )
  161. {
  162. DWORD dwBusCntl;
  163. dwBusCntl = M64_ID(ppdev->pjMmBase, BUS_CNTL );
  164. dwBusCntl &= ~0x08000000U;
  165. M64_CHECK_FIFO_SPACE(ppdev,ppdev-> pjMmBase, 2);
  166. M64_OD(ppdev->pjMmBase, BUS_CNTL, dwBusCntl );
  167. }
  168. DWORD DdSetColorKey(PDD_SETCOLORKEYDATA lpSetColorKey)
  169. {
  170. PDEV* ppdev;
  171. BYTE* pjIoBase;
  172. BYTE* pjMmBase;
  173. DD_SURFACE_GLOBAL* lpSurface;
  174. DWORD dwKeyLow;
  175. DWORD dwKeyHigh;
  176. ppdev = (PDEV*) lpSetColorKey->lpDD->dhpdev;
  177. pjMmBase = ppdev->pjMmBase;
  178. lpSurface = lpSetColorKey->lpDDSurface->lpGbl;
  179. // We don't have to do anything for normal blt source colour keys:
  180. if (lpSetColorKey->dwFlags & DDCKEY_SRCBLT)
  181. {
  182. lpSetColorKey->ddRVal = DD_OK;
  183. return(DDHAL_DRIVER_HANDLED);
  184. }
  185. else if (lpSetColorKey->dwFlags & DDCKEY_DESTOVERLAY)
  186. {
  187. dwKeyLow = lpSetColorKey->ckNew.dwColorSpaceLowValue;
  188. /*
  189. if (lpSurface->ddpfSurface.dwFlags & DDPF_PALETTEINDEXED8)
  190. {
  191. dwKeyLow = dwGetPaletteEntry(ppdev, dwKeyLow);
  192. }
  193. else
  194. {
  195. ASSERTDD(lpSurface->ddpfSurface.dwFlags & DDPF_RGB,
  196. "Expected only RGB cases here");
  197. // We have to transform the colour key from its native format
  198. // to 8-8-8:
  199. if (lpSurface->ddpfSurface.dwRGBBitCount == 16)
  200. {
  201. if (IS_RGB15_R(lpSurface->ddpfSurface.dwRBitMask))
  202. dwKeyLow = RGB15to32(dwKeyLow);
  203. else
  204. dwKeyLow = RGB16to32(dwKeyLow);
  205. }
  206. else
  207. {
  208. ASSERTDD((lpSurface->ddpfSurface.dwRGBBitCount == 32),
  209. "Expected the primary surface to be either 8, 16, or 32bpp");
  210. }
  211. }
  212. */
  213. DD_WriteVTReg ( DD_OVERLAY_GRAPHICS_KEY_CLR, dwKeyLow );
  214. ppdev->OverlayInfo16.dwOverlayKeyCntl &= 0xFFFFFF8FL;
  215. ppdev->OverlayInfo16.dwOverlayKeyCntl |= 0x00000050L;
  216. DD_WriteVTReg ( DD_OVERLAY_KEY_CNTL, ppdev->OverlayInfo16.dwOverlayKeyCntl );
  217. lpSetColorKey->ddRVal = DD_OK;
  218. return(DDHAL_DRIVER_HANDLED);
  219. }
  220. DISPDBG((0, "DdSetColorKey: Invalid command"));
  221. return(DDHAL_DRIVER_NOTHANDLED);
  222. }
  223. /******************************Public*Routine******************************\
  224. * DWORD DdCanCreateSurface
  225. *
  226. \**************************************************************************/
  227. DWORD DdCanCreateSurface( PDD_CANCREATESURFACEDATA lpCanCreateSurface)
  228. {
  229. PDEV* ppdev;
  230. DWORD dwRet;
  231. LPDDSURFACEDESC lpSurfaceDesc;
  232. ppdev = (PDEV*) lpCanCreateSurface->lpDD->dhpdev;
  233. lpSurfaceDesc = lpCanCreateSurface->lpDDSurfaceDesc;
  234. dwRet = DDHAL_DRIVER_NOTHANDLED;
  235. if (!lpCanCreateSurface->bIsDifferentPixelFormat)
  236. {
  237. // It's trivially easy to create plain surfaces that are the same
  238. // type as the primary surface:
  239. dwRet = DDHAL_DRIVER_HANDLED;
  240. }
  241. else if (ppdev->iAsic >=CI_M64_VTA)
  242. {
  243. // When using the Streams processor, we handle only overlays of
  244. // different pixel formats -- not any off-screen memory:
  245. if (lpSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_OVERLAY)
  246. {
  247. // We handle two types of YUV overlay surfaces:
  248. if (lpSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_FOURCC)
  249. {
  250. // Check first for a supported YUV type:
  251. if ( (lpSurfaceDesc->ddpfPixelFormat.dwFourCC == FOURCC_UYVY) || (lpSurfaceDesc->ddpfPixelFormat.dwFourCC == FOURCC_YUY2) )
  252. {
  253. lpSurfaceDesc->ddpfPixelFormat.dwYUVBitCount = 16;
  254. dwRet = DDHAL_DRIVER_HANDLED;
  255. }
  256. }
  257. // We handle 16bpp and 32bpp RGB overlay surfaces:
  258. else if ((lpSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB) &&
  259. !(lpSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8))
  260. {
  261. if (lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount == 16)
  262. {
  263. if (IS_RGB15(&lpSurfaceDesc->ddpfPixelFormat) ||
  264. IS_RGB16(&lpSurfaceDesc->ddpfPixelFormat))
  265. {
  266. dwRet = DDHAL_DRIVER_HANDLED;
  267. }
  268. }
  269. else if (lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount == 32)
  270. {
  271. if (IS_RGB32(&lpSurfaceDesc->ddpfPixelFormat))
  272. {
  273. dwRet = DDHAL_DRIVER_HANDLED;
  274. }
  275. }
  276. }
  277. }
  278. }
  279. // Print some spew if this was a surface we refused to create:
  280. if (dwRet == DDHAL_DRIVER_NOTHANDLED)
  281. {
  282. if (lpSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB)
  283. {
  284. DISPDBG((10, "Failed creation of %libpp RGB surface %lx %lx %lx",
  285. lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount,
  286. lpSurfaceDesc->ddpfPixelFormat.dwRBitMask,
  287. lpSurfaceDesc->ddpfPixelFormat.dwGBitMask,
  288. lpSurfaceDesc->ddpfPixelFormat.dwBBitMask));
  289. }
  290. else
  291. {
  292. DISPDBG((10, "Failed creation of type 0x%lx YUV 0x%lx surface",
  293. lpSurfaceDesc->ddpfPixelFormat.dwFlags,
  294. lpSurfaceDesc->ddpfPixelFormat.dwFourCC));
  295. }
  296. }
  297. lpCanCreateSurface->ddRVal = DD_OK;
  298. return(dwRet);
  299. }
  300. /******************************Public*Routine******************************\
  301. * DWORD DdCreateSurface
  302. *
  303. \**************************************************************************/
  304. DWORD DdCreateSurface(
  305. PDD_CREATESURFACEDATA lpCreateSurface)
  306. {
  307. PDEV* ppdev;
  308. DD_SURFACE_LOCAL* lpSurfaceLocal;
  309. DD_SURFACE_GLOBAL* lpSurfaceGlobal;
  310. LPDDSURFACEDESC lpSurfaceDesc;
  311. DWORD dwByteCount;
  312. LONG lLinearPitch;
  313. DWORD dwHeight;
  314. OH* poh;
  315. FLATPTR fpVidMem;
  316. DISPDBG((10, " Enter Create Surface"));
  317. ppdev = (PDEV*) lpCreateSurface->lpDD->dhpdev;
  318. // On Windows NT, dwSCnt will always be 1, so there will only ever
  319. // be one entry in the 'lplpSList' array:
  320. lpSurfaceLocal = lpCreateSurface->lplpSList[0];
  321. lpSurfaceGlobal = lpSurfaceLocal->lpGbl;
  322. lpSurfaceDesc = lpCreateSurface->lpDDSurfaceDesc;
  323. // We repeat the same checks we did in 'DdCanCreateSurface' because
  324. // it's possible that an application doesn't call 'DdCanCreateSurface'
  325. // before calling 'DdCreateSurface'.
  326. ASSERTDD(lpSurfaceGlobal->ddpfSurface.dwSize == sizeof(DDPIXELFORMAT), "NT is supposed to guarantee that ddpfSurface.dwSize is valid");
  327. // DdCanCreateSurface already validated whether the hardware supports
  328. // the surface, so we don't need to do any validation here. We'll
  329. // just go ahead and allocate it.
  330. //
  331. //
  332. // Note that on NT, an overlay can be created only if the driver
  333. // okay's it here in this routine. Under Win95, the overlay will be
  334. // created automatically if it's the same pixel format as the primary
  335. // display.
  336. if ((lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_OVERLAY) ||
  337. (lpSurfaceGlobal->ddpfSurface.dwFlags & DDPF_FOURCC) ||
  338. (lpSurfaceGlobal->ddpfSurface.dwYUVBitCount != (DWORD) 8 * ppdev->cjPelSize) ||
  339. (lpSurfaceGlobal->ddpfSurface.dwRBitMask != ppdev->flRed))
  340. {
  341. if (lpSurfaceGlobal->wWidth <= (DWORD) ppdev->cxMemory)
  342. {
  343. if (lpSurfaceGlobal->ddpfSurface.dwFlags & DDPF_FOURCC)
  344. {
  345. //dwByteCount = (lpSurfaceGlobal->ddpfSurface.dwFourCC == FOURCC_UYVY)? 2 : 1;
  346. dwByteCount =2;
  347. // We have to fill in the bit-count for FourCC surfaces:
  348. lpSurfaceGlobal->ddpfSurface.dwYUVBitCount = 8 * dwByteCount;
  349. DISPDBG((10, "Created YUV: %li x %li",
  350. lpSurfaceGlobal->wWidth, lpSurfaceGlobal->wHeight));
  351. }
  352. else
  353. {
  354. dwByteCount = lpSurfaceGlobal->ddpfSurface.dwRGBBitCount >> 3;
  355. DISPDBG((10, "Created RGB %libpp: %li x %li Red: %lx",
  356. 8 * dwByteCount, lpSurfaceGlobal->wWidth, lpSurfaceGlobal->wHeight,
  357. lpSurfaceGlobal->ddpfSurface.dwRBitMask));
  358. // we support 15,16 and 32 bits
  359. if (((dwByteCount < 2)||(dwByteCount ==3)) &&
  360. (lpSurfaceLocal->ddsCaps.dwCaps & DDSCAPS_OVERLAY))
  361. {
  362. lpCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT;
  363. return(DDHAL_DRIVER_HANDLED);
  364. }
  365. }
  366. // We want to allocate a linear surface to store the FourCC
  367. // surface, but our driver is using a 2-D heap-manager because
  368. // the rest of our surfaces have to be 2-D. So here we have to
  369. // convert the linear size to a 2-D size.
  370. //
  371. lLinearPitch = (lpSurfaceGlobal->wWidth * dwByteCount ) ; // + 7) & ~7; // The stride has to be a qword multiple.
  372. dwHeight = ( (lpSurfaceGlobal->wHeight * lLinearPitch + ppdev->lDelta - 1) / ppdev->lDelta) ; /// ppdev->cjPelSize; // in pixels
  373. // Free up as much off-screen memory as possible:
  374. bMoveAllDfbsFromOffscreenToDibs(ppdev);
  375. poh = pohAllocate(ppdev, NULL, ppdev->cxMemory, dwHeight, FLOH_MAKE_PERMANENT);
  376. if (poh != NULL)
  377. {
  378. fpVidMem = (poh->y * ppdev->lDelta) + (poh->x ) * ppdev->cjPelSize; // poh->x must be 0 in this case
  379. lpSurfaceGlobal->dwReserved1 = (ULONG_PTR)poh;
  380. lpSurfaceGlobal->xHint = poh->x;
  381. lpSurfaceGlobal->yHint = poh->y;
  382. lpSurfaceGlobal->fpVidMem = fpVidMem;
  383. lpSurfaceGlobal->lPitch = lLinearPitch;
  384. lpSurfaceDesc->lPitch = lLinearPitch;
  385. lpSurfaceDesc->dwFlags |= DDSD_PITCH;
  386. // We handled the creation entirely ourselves, so we have to
  387. // set the return code and return DDHAL_DRIVER_HANDLED:
  388. lpCreateSurface->ddRVal = DD_OK;
  389. DISPDBG((10, " Exit Create Surface 1: Created YUV surface at poh X=%d, Y=%d", poh->x, poh->y));
  390. return(DDHAL_DRIVER_HANDLED);
  391. }
  392. /*
  393. // Now fill in enough stuff to have the DirectDraw heap-manager
  394. // do the allocation for us:
  395. lpSurfaceGlobal->fpVidMem = DDHAL_PLEASEALLOC_BLOCKSIZE;
  396. lpSurfaceGlobal->dwBlockSizeX = ppdev->lDelta; // Specified in bytes
  397. lpSurfaceGlobal->dwBlockSizeY = dwHeight;
  398. lpSurfaceGlobal->lPitch = lLinearPitch;
  399. lpSurfaceGlobal->dwReserved1 = DD_RESERVED_DIFFERENTPIXELFORMAT;
  400. lpSurfaceDesc->lPitch = lLinearPitch;
  401. lpSurfaceDesc->dwFlags |= DDSD_PITCH;
  402. */
  403. }
  404. else
  405. {
  406. DISPDBG((10, "Refused to create surface with large width"));
  407. }
  408. }
  409. else
  410. {
  411. if (lpSurfaceGlobal->wWidth <= (DWORD) ppdev->cxMemory)
  412. {
  413. if(lpSurfaceGlobal->ddpfSurface.dwRBitMask == ppdev->flRed)
  414. {
  415. DISPDBG((10, "Surface with the same pixel format as primary"));
  416. dwByteCount = lpSurfaceGlobal->ddpfSurface.dwRGBBitCount >> 3;
  417. lLinearPitch = ppdev->lDelta ;
  418. dwHeight = lpSurfaceGlobal->wHeight ;
  419. // Free up as much off-screen memory as possible:
  420. bMoveAllDfbsFromOffscreenToDibs(ppdev);
  421. DISPDBG((10, "Try to allocate Cx=%d, Cy=%d", ppdev->cxMemory, dwHeight));
  422. if((ULONG)lpSurfaceGlobal->wWidth*dwByteCount < (ULONG)ppdev->lDelta)
  423. poh = pohAllocate(ppdev, NULL, ( (lpSurfaceGlobal->wWidth*dwByteCount + 8) / (ppdev->cjPelSize) ) +1, dwHeight, FLOH_MAKE_PERMANENT);
  424. else
  425. poh = pohAllocate(ppdev, NULL, (lpSurfaceGlobal->wWidth*dwByteCount )/ppdev->cjPelSize , dwHeight, FLOH_MAKE_PERMANENT);
  426. if (poh != NULL)
  427. {
  428. if((ULONG)lpSurfaceGlobal->wWidth*dwByteCount < (ULONG)ppdev->lDelta)
  429. fpVidMem =( ( (poh->y * ppdev->lDelta) + ((poh->x ) * ppdev->cjPelSize) + 7 )&~7 ); // poh->x must be 0 in this case
  430. else
  431. fpVidMem = (poh->y * ppdev->lDelta) + ((poh->x ) * ppdev->cjPelSize) ;
  432. // no allocation for flip surfaces beyond 4MB
  433. if (( (LONG)lpSurfaceGlobal->wWidth < ppdev->cxScreen) ||
  434. ( (LONG)lpSurfaceGlobal->wHeight < ppdev->cyScreen) ||
  435. (fpVidMem < 0x400000))
  436. {
  437. lpSurfaceGlobal->dwReserved1=(ULONG_PTR)poh;
  438. lpSurfaceGlobal->xHint = poh->x;
  439. lpSurfaceGlobal->yHint = poh->y;
  440. lpSurfaceGlobal->fpVidMem = fpVidMem;
  441. lpSurfaceGlobal->lPitch = ppdev->lDelta;
  442. lpSurfaceDesc->lPitch = ppdev->lDelta;
  443. lpSurfaceDesc->dwFlags |= DDSD_PITCH;
  444. // We handled the creation entirely ourselves, so we have to
  445. // set the return code and return DDHAL_DRIVER_HANDLED:
  446. DISPDBG((10, " Exit Create Surface 2: Created RGB surface at poh X=%d, Y=%d", poh->x, poh->y));
  447. lpCreateSurface->ddRVal = DD_OK;
  448. return(DDHAL_DRIVER_HANDLED);
  449. }
  450. // dealocate the poh because The allocation is beyond 4MB for a flip surface: cx = cxScreen ; cy = cyScreen
  451. // bMoveAllDfbsFromOffscreenToDibs(ppdev); // avoid fragmentation
  452. pohFree(ppdev, poh);
  453. DISPDBG((10, " The allocation is beyond 4MB, so we deallocate; for a flip surface: cx = cxScreen ; cy = cyScreen"));
  454. }
  455. DISPDBG((10, " Cannot allocate poh"));
  456. }
  457. }
  458. }
  459. DISPDBG((10, " Exit Create Surface NOTOK"));
  460. return(DDHAL_DRIVER_NOTHANDLED);
  461. }
  462. /******************************Public*Routine******************************\
  463. * DWORD DdUpdateOverlay
  464. *
  465. \**************************************************************************/
  466. DWORD DdUpdateOverlay(PDD_UPDATEOVERLAYDATA lpUpdateOverlay)
  467. {
  468. PDEV* ppdev;
  469. BYTE* pjIoBase;
  470. BYTE* pjMmBase;
  471. DD_SURFACE_GLOBAL* lpSource;
  472. DD_SURFACE_GLOBAL* lpDestination;
  473. DWORD dwStride;
  474. LONG srcWidth;
  475. LONG srcHeight;
  476. LONG dstWidth;
  477. LONG dstHeight;
  478. DWORD dwBitCount;
  479. DWORD dwStart;
  480. DWORD dwTmp;
  481. BOOL bColorKey;
  482. DWORD dwKeyLow;
  483. DWORD dwKeyHigh;
  484. DWORD dwBytesPerPixel;
  485. DWORD dwSecCtrl;
  486. DWORD dwBlendCtrl;
  487. LONG dwVInc;
  488. LONG dwHInc;
  489. DWORD SrcBufOffset,Temp;
  490. BYTE bPLLAddr,bFatPixel;
  491. RECTL rSrc,rDst,rOverlay;
  492. DWORD myval;
  493. DWORD g_dwGamma=0; // Used to set the gamma correction for the overlay.
  494. DWORD value;
  495. ppdev = (PDEV*) lpUpdateOverlay->lpDD->dhpdev;
  496. pjMmBase = ppdev->pjMmBase;
  497. // 'Source' is the overlay surface, 'destination' is the surface to
  498. // be overlayed:
  499. lpSource = lpUpdateOverlay->lpDDSrcSurface->lpGbl;
  500. if (lpUpdateOverlay->dwFlags & DDOVER_HIDE)
  501. {
  502. if (lpSource->fpVidMem == ppdev->fpVisibleOverlay)
  503. {
  504. ppdev->semph_overlay=0; // = 0 ; resource free
  505. //WAIT_FOR_VBLANK(pjIoBase);
  506. ppdev->OverlayInfo16.dwFlags |= UPDATEOVERLAY;
  507. ppdev->OverlayInfo16.dwFlags &= ~OVERLAY_VISIBLE;
  508. ppdev->OverlayInfo16.dwOverlayKeyCntl = 0x00000110L;
  509. DeskScanCallback (ppdev );
  510. ppdev->OverlayInfo16.dwFlags &= ~UPDATEOVERLAY;
  511. ppdev->fpVisibleOverlay = 0;
  512. }
  513. lpUpdateOverlay->ddRVal = DD_OK;
  514. return(DDHAL_DRIVER_HANDLED);
  515. }
  516. // Dereference 'lpDDDestSurface' only after checking for the DDOVER_HIDE
  517. // case:
  518. lpDestination = lpUpdateOverlay->lpDDDestSurface->lpGbl;
  519. if (lpSource->fpVidMem != ppdev->fpVisibleOverlay)
  520. {
  521. if (lpUpdateOverlay->dwFlags & DDOVER_SHOW)
  522. {
  523. if (ppdev->fpVisibleOverlay != 0)
  524. {
  525. // Some other overlay is already visible:
  526. DISPDBG((10, "DdUpdateOverlay: An overlay is already visible"));
  527. lpUpdateOverlay->ddRVal = DDERR_OUTOFCAPS;
  528. return(DDHAL_DRIVER_HANDLED);
  529. }
  530. else
  531. {
  532. // first we have to verify if the overlay resource is in use
  533. if(ppdev->semph_overlay==0) // = 0 ; resource free
  534. // = 1 ; in use by DDraw
  535. // = 2 ; in use by Palindrome
  536. {
  537. // We're going to make the overlay visible, so mark it as
  538. // such:
  539. ppdev->semph_overlay = 1;
  540. ppdev->fpVisibleOverlay = lpSource->fpVidMem;
  541. }
  542. else
  543. {
  544. // Palindrome is using the overlay :
  545. DISPDBG((10, "DdUpdateOverlay: An overlay is already visible (used byPalindrome) "));
  546. lpUpdateOverlay->ddRVal = DDERR_OUTOFCAPS;
  547. return(DDHAL_DRIVER_HANDLED);
  548. }
  549. }
  550. }
  551. else
  552. {
  553. // The overlay isn't visible, and we haven't been asked to make
  554. // it visible, so this call is trivially easy:
  555. lpUpdateOverlay->ddRVal = DD_OK;
  556. return(DDHAL_DRIVER_HANDLED);
  557. }
  558. }
  559. dwStride = lpSource->lPitch;
  560. srcWidth = lpUpdateOverlay->rSrc.right - lpUpdateOverlay->rSrc.left;
  561. srcHeight = lpUpdateOverlay->rSrc.bottom - lpUpdateOverlay->rSrc.top;
  562. dstWidth = lpUpdateOverlay->rDest.right - lpUpdateOverlay->rDest.left;
  563. dstHeight = lpUpdateOverlay->rDest.bottom - lpUpdateOverlay->rDest.top;
  564. if ( dstHeight < srcHeight || lpUpdateOverlay->rSrc.top > 0 )
  565. ppdev->OverlayScalingDown = 1;
  566. else
  567. ppdev->OverlayScalingDown = 0;
  568. /*
  569. * Determine scaling factors for the hardware. These factors will
  570. * be modified based on either "fat pixel" mode or interlace mode.
  571. */
  572. dwHInc = ( srcWidth << 12L ) / ( dstWidth );
  573. /*
  574. * Determine if VT/GT is in FAT PIXEL MODE
  575. */
  576. /* Get current PLL reg so we can restore. */
  577. value=M64_ID_DIRECT(ppdev->pjMmBase, CLOCK_CNTL );
  578. /* Set PLL reg 5 for reading. This is where the "fat pixel" bit is */
  579. M64_OD_DIRECT(ppdev->pjMmBase, CLOCK_CNTL, (value&0xFFFF00FF)|0x1400);
  580. /* Get the "fat pixel" bit from PLL reg */
  581. bFatPixel =(BYTE)( (M64_ID_DIRECT(ppdev->pjMmBase, CLOCK_CNTL )&0x00FF0000)>>16 ) & 0x30;
  582. /* Restore original register pointer in PLL reg */
  583. M64_OD_DIRECT( ppdev->pjMmBase, CLOCK_CNTL, value);
  584. /* adjust horizontal scaling if necessary */
  585. if ( bFatPixel )
  586. dwHInc *= 2;
  587. /*
  588. * We can't clip overlays, so we must make sure the co-ord, are within
  589. * the bounds of the screen.
  590. */
  591. rOverlay.top = max ( 0,lpUpdateOverlay->rDest.top );
  592. rOverlay.left = max ( 0, lpUpdateOverlay->rDest.left );
  593. rOverlay.bottom = min ( (DWORD)ppdev->cyScreen - 1,
  594. (DWORD)lpUpdateOverlay->rDest.bottom );
  595. rOverlay.right = min ( (DWORD)ppdev->cxScreen - 1,
  596. (DWORD)lpUpdateOverlay->rDest.right );
  597. /*
  598. * Modify overlay destination based on wether we are in inerlace mode.
  599. * If we are in interlace dwVInc must be multiplied by 2.
  600. */
  601. dwVInc = ( srcHeight << 12L ) / ( dstHeight );
  602. if ( M64_ID_DIRECT(ppdev->pjMmBase, CRTC_GEN_CNTL ) & CRTC_INTERLACE_EN )
  603. {
  604. ppdev->OverlayScalingDown = 1; /* Always replicate UVs in this case */
  605. dwVInc *= 2;
  606. }
  607. /*
  608. * Overlay destination must be primary, so we will check current
  609. * pixel depth of the screen.
  610. */
  611. // here we have to turn on the second block of regs
  612. switch ( ppdev->cBitsPerPel) //Screen BPP
  613. {
  614. case 8:
  615. DD_WriteVTReg ( DD_OVERLAY_GRAPHICS_KEY_MSK, 0x000000FFL );
  616. break;
  617. case 16:
  618. DD_WriteVTReg ( DD_OVERLAY_GRAPHICS_KEY_MSK, 0x0000FFFFL );
  619. break;
  620. case 24:
  621. case 32:
  622. DD_WriteVTReg ( DD_OVERLAY_GRAPHICS_KEY_MSK, 0x00FFFFFFL );
  623. break;
  624. default:
  625. DD_WriteVTReg ( DD_OVERLAY_GRAPHICS_KEY_MSK, 0x0000FFFFL );
  626. break;
  627. }
  628. /* Scaler */
  629. DD_WriteVTReg ( DD_SCALER_HEIGHT_WIDTH, ( srcWidth << 16L ) |
  630. ( srcHeight ) );
  631. // Overlay input data format:
  632. if (lpSource->ddpfSurface.dwFlags & DDPF_FOURCC)
  633. {
  634. dwBitCount = lpSource->ddpfSurface.dwYUVBitCount;
  635. switch (lpSource->ddpfSurface.dwFourCC)
  636. {
  637. case FOURCC_UYVY: /* YVYU in VT Specs */
  638. WriteVTOverlayPitch (ppdev, lpUpdateOverlay->lpDDSrcSurface->lpGbl->lPitch /2); //Check's to see if it's VTB or not.
  639. DD_WriteVTReg ( DD_VIDEO_FORMAT, 0x000C000CL );
  640. DD_WriteVTReg ( DD_OVERLAY_VIDEO_KEY_MSK, 0x0000FFFF );
  641. ppdev->OverlayInfo16.dwFlags &= ~DOUBLE_PITCH;
  642. break;
  643. case FOURCC_YUY2: /* VYUY in VT Specs */
  644. WriteVTOverlayPitch (ppdev, lpUpdateOverlay->lpDDSrcSurface->lpGbl->lPitch /2 ); //Check's to see if it's VTB or not.
  645. DD_WriteVTReg ( DD_VIDEO_FORMAT, 0x000B000BL );
  646. DD_WriteVTReg ( DD_OVERLAY_VIDEO_KEY_MSK, 0x0000FFFF );
  647. ppdev->OverlayInfo16.dwFlags &= ~DOUBLE_PITCH;
  648. break;
  649. default:
  650. WriteVTOverlayPitch (ppdev, lpUpdateOverlay->lpDDSrcSurface->lpGbl->lPitch); //Check's to see if it's VTB or not.
  651. DD_WriteVTReg ( DD_VIDEO_FORMAT, 0x000B000BL );
  652. DD_WriteVTReg ( DD_OVERLAY_VIDEO_KEY_MSK, 0x0000FFFF );
  653. ppdev->OverlayInfo16.dwFlags &= ~DOUBLE_PITCH;
  654. break;
  655. }
  656. }
  657. else
  658. {
  659. ASSERTDD(lpSource->ddpfSurface.dwFlags & DDPF_RGB,
  660. "Expected us to have created only RGB or YUV overlays");
  661. // The overlay surface is in RGB format:
  662. dwBitCount = lpSource->ddpfSurface.dwRGBBitCount;
  663. switch ( lpSource->ddpfSurface.dwRGBBitCount )
  664. {
  665. case 16:
  666. /***********
  667. *
  668. * Are we 5:5:5 or 5:6:5?
  669. *
  670. ************/
  671. if ( lpUpdateOverlay->lpDDSrcSurface->lpGbl->ddpfSurface.dwRBitMask & 0x00008000L )
  672. {
  673. DD_WriteVTReg ( DD_VIDEO_FORMAT, 0x00040004L );
  674. }
  675. else
  676. {
  677. DD_WriteVTReg ( DD_VIDEO_FORMAT, 0x00030003L );
  678. }
  679. WriteVTOverlayPitch (ppdev, lpUpdateOverlay->lpDDSrcSurface->lpGbl->lPitch /2);
  680. DD_WriteVTReg ( DD_OVERLAY_VIDEO_KEY_MSK, 0x0000FFFF );
  681. ppdev->OverlayInfo16.dwFlags &= ~DOUBLE_PITCH;
  682. break;
  683. case 32:
  684. WriteVTOverlayPitch (ppdev, lpUpdateOverlay->lpDDSrcSurface->lpGbl->lPitch /4);
  685. DD_WriteVTReg ( DD_VIDEO_FORMAT, 0x00060006L );
  686. DD_WriteVTReg ( DD_OVERLAY_VIDEO_KEY_MSK, 0xFFFFFFFF );
  687. ppdev->OverlayInfo16.dwFlags &= ~DOUBLE_PITCH;
  688. break;
  689. default:
  690. WriteVTOverlayPitch (ppdev, lpUpdateOverlay->lpDDSrcSurface->lpGbl->lPitch /2); //Check's to see if it's VTB or not.
  691. DD_WriteVTReg ( DD_VIDEO_FORMAT, 0x00030003L );
  692. DD_WriteVTReg ( DD_OVERLAY_VIDEO_KEY_MSK, 0x0000FFFF );
  693. ppdev->OverlayInfo16.dwFlags &= ~DOUBLE_PITCH;
  694. break;
  695. }
  696. }
  697. // Calculate start of video memory in QWORD boundary
  698. dwBytesPerPixel = dwBitCount >> 3;
  699. dwStart = (lpUpdateOverlay->rSrc.top * dwStride)
  700. + (lpUpdateOverlay->rSrc.left * dwBytesPerPixel);
  701. dwStart = dwStart - (dwStart & 0x7);
  702. ppdev->dwOverlayFlipOffset = dwStart; // Save for flip
  703. dwStart += (DWORD)lpSource->fpVidMem;
  704. // Set overlay filter characteristics:
  705. /*
  706. * This register write enables the overlay and scaler registers
  707. */
  708. //gwRedTemp =0 ; //gamma control
  709. if(0) //if ( gwRedTemp )
  710. {
  711. DD_WriteVTReg ( DD_OVERLAY_SCALE_CNTL, 0xC0000001L | g_dwGamma );
  712. }
  713. else
  714. {
  715. DD_WriteVTReg ( DD_OVERLAY_SCALE_CNTL, 0xC0000003L | g_dwGamma );
  716. }
  717. /*
  718. * Get offset of buffer, if we are using a YUV Planar Overlay we
  719. * must extract the address from another field (dwReserved1).
  720. */
  721. SrcBufOffset = (DWORD)(lpUpdateOverlay->lpDDSrcSurface->lpGbl->fpVidMem); //- (FLATPTR)ppdev->pjScreen;
  722. ppdev->OverlayInfo16.dwBuf0Start = SrcBufOffset;
  723. ppdev->OverlayInfo16.dwBuf1Start = SrcBufOffset;
  724. /*
  725. * Set up the colour keying, if any?
  726. */
  727. if ( lpUpdateOverlay->dwFlags & DDOVER_KEYSRC ||
  728. lpUpdateOverlay->dwFlags & DDOVER_KEYSRCOVERRIDE ||
  729. lpUpdateOverlay->dwFlags & DDOVER_KEYDEST ||
  730. lpUpdateOverlay->dwFlags & DDOVER_KEYDESTOVERRIDE )
  731. {
  732. ppdev->OverlayInfo16.dwOverlayKeyCntl = 0;
  733. if ( lpUpdateOverlay->dwFlags & DDOVER_KEYSRC ||
  734. lpUpdateOverlay->dwFlags & DDOVER_KEYSRCOVERRIDE )
  735. {
  736. //Set source colour key
  737. if ( lpUpdateOverlay->dwFlags & DDOVER_KEYSRC )
  738. {
  739. Temp=lpUpdateOverlay->lpDDDestSurface->ddckCKSrcOverlay.dwColorSpaceLowValue;
  740. }
  741. else
  742. {
  743. Temp=lpUpdateOverlay->overlayFX.dckSrcColorkey.dwColorSpaceLowValue;
  744. }
  745. DD_WriteVTReg ( DD_OVERLAY_VIDEO_KEY_CLR, Temp );
  746. //ppdev->OverlayInfo16.dwOverlayKeyCntl &= 0xFFFFFEE8;
  747. if(ppdev->iAsic ==CI_M64_VTA)
  748. {
  749. ppdev->OverlayInfo16.dwOverlayKeyCntl &= 0xFFFFF0E8;
  750. ppdev->OverlayInfo16.dwOverlayKeyCntl |= 0x00000c14;
  751. }
  752. else
  753. {
  754. ppdev->OverlayInfo16.dwOverlayKeyCntl &= 0xFFFFFEE8;
  755. ppdev->OverlayInfo16.dwOverlayKeyCntl |= 0x00000114;
  756. }
  757. }
  758. if ( lpUpdateOverlay->dwFlags & DDOVER_KEYDEST ||
  759. lpUpdateOverlay->dwFlags & DDOVER_KEYDESTOVERRIDE )
  760. {
  761. //Set destination colour key
  762. if ( lpUpdateOverlay->dwFlags & DDOVER_KEYDEST )
  763. {
  764. Temp=lpUpdateOverlay->lpDDDestSurface->ddckCKDestOverlay.dwColorSpaceLowValue;
  765. }
  766. else
  767. {
  768. Temp=lpUpdateOverlay->overlayFX.dckDestColorkey.dwColorSpaceLowValue;
  769. if ( Temp == 0 && ppdev->cBitsPerPel == 32 )
  770. Temp = 0x00FF00FF;
  771. }
  772. DD_WriteVTReg ( DD_OVERLAY_GRAPHICS_KEY_CLR, Temp );
  773. ppdev->OverlayInfo16.dwOverlayKeyCntl &= 0xFFFFFF8FL;
  774. ppdev->OverlayInfo16.dwOverlayKeyCntl |= 0x00000050L;
  775. }
  776. }
  777. else
  778. {
  779. //No source or destination colour keying
  780. DD_WriteVTReg ( DD_OVERLAY_GRAPHICS_KEY_CLR, 0x00000000 );
  781. ppdev->OverlayInfo16.dwOverlayKeyCntl = 0x8000211L;
  782. }
  783. /*
  784. * Now set the stretch factor and overlay position.
  785. */
  786. ppdev->OverlayWidth = rOverlay.right - rOverlay.left;
  787. ppdev->OverlayHeight = rOverlay.bottom - rOverlay.top;
  788. //LastOverlayPos=OverlayRect;
  789. ppdev->OverlayInfo16.dwFlags |= OVERLAY_ALLOCATED;
  790. ppdev->OverlayInfo16.dwFlags |= UPDATEOVERLAY;
  791. ppdev->OverlayInfo16.dwFlags |= OVERLAY_VISIBLE;
  792. ppdev->OverlayInfo16.rOverlay = rOverlay;
  793. ppdev->OverlayInfo16.dwVInc = dwVInc;
  794. ppdev->OverlayInfo16.dwHInc = dwHInc;
  795. // new for DeskScanCallback
  796. ppdev->OverlayInfo16.rDst = rOverlay;
  797. ppdev->OverlayInfo16.rSrc = lpUpdateOverlay->rSrc;
  798. DeskScanCallback (ppdev );
  799. ppdev->OverlayInfo16.dwFlags &= ~UPDATEOVERLAY;
  800. /*
  801. * return to DirectDraw.
  802. */
  803. lpUpdateOverlay->ddRVal = DD_OK;
  804. return(DDHAL_DRIVER_HANDLED);
  805. }
  806. /*
  807. * structure for passing information to DDHAL SetOverlayPosition
  808. */
  809. DWORD DdSetOverlayPosition (PDD_SETOVERLAYPOSITIONDATA lpSetOverlayPosition )
  810. {
  811. RECTL rOverlay;
  812. PDEV* ppdev;
  813. ppdev = (PDEV*) lpSetOverlayPosition->lpDD->dhpdev;
  814. rOverlay.left = lpSetOverlayPosition->lXPos;
  815. rOverlay.top = lpSetOverlayPosition->lYPos;
  816. rOverlay.right = ppdev->OverlayWidth + lpSetOverlayPosition->lXPos;
  817. rOverlay.bottom = ppdev->OverlayHeight + lpSetOverlayPosition->lYPos;
  818. /*
  819. * We can't clip overlays, so we must make sure the co-ord, are within the
  820. * boundaries of the screen.
  821. */
  822. rOverlay.top = max ( 0, rOverlay.top );
  823. rOverlay.left = max ( 0, rOverlay.left );
  824. rOverlay.bottom = min ( (DWORD)ppdev->cyScreen -1 ,
  825. (DWORD) rOverlay.bottom );
  826. rOverlay.right = min ( (DWORD)ppdev->cxScreen -1 ,
  827. (DWORD) rOverlay.right );
  828. /*
  829. *Set overlay position
  830. */
  831. M64_CHECK_FIFO_SPACE(ppdev,ppdev-> pjMmBase, 1);
  832. ppdev->OverlayWidth =rOverlay.right - rOverlay.left;
  833. ppdev->OverlayHeight = rOverlay.bottom - rOverlay.top;
  834. ppdev->OverlayInfo16.dwFlags |= SETOVERLAYPOSITION;
  835. ppdev->OverlayInfo16.rOverlay = rOverlay;
  836. ppdev->OverlayInfo16.rDst = rOverlay;
  837. DeskScanCallback (ppdev );
  838. ppdev->OverlayInfo16.dwFlags &= ~SETOVERLAYPOSITION;
  839. /*
  840. * return to DirectDraw
  841. */
  842. lpSetOverlayPosition->ddRVal = DD_OK;
  843. return DDHAL_DRIVER_HANDLED;
  844. }
  845. /******************************Public*Routine******************************\
  846. * DWORD DdDestroySurface
  847. *
  848. * Note that if DirectDraw did the allocation, DDHAL_DRIVER_NOTHANDLED
  849. * should be returned.
  850. *
  851. \**************************************************************************/
  852. DWORD DdDestroySurface(
  853. PDD_DESTROYSURFACEDATA lpDestroySurface)
  854. {
  855. PDEV* ppdev;
  856. DD_SURFACE_GLOBAL* lpSurface;
  857. LONG lPitch;
  858. OH* poh;
  859. DISPDBG((10, " Enter Destroy Surface"));
  860. ppdev = (PDEV*) lpDestroySurface->lpDD->dhpdev;
  861. lpSurface = lpDestroySurface->lpDDSurface->lpGbl;
  862. poh= (OH*)( lpSurface->dwReserved1);
  863. if( (ULONG)lpSurface->dwReserved1 != (ULONG_PTR) NULL )
  864. {
  865. // let's see first if the value in reserved field is indeed an poh and not a cookie
  866. // because I don't know if ddraw is using also this value for system memory surfaces
  867. if(poh->ohState==OH_PERMANENT)
  868. {
  869. // bMoveAllDfbsFromOffscreenToDibs(ppdev); // avoid fragmentation
  870. pohFree(ppdev, poh);
  871. // Since we did the original allocation ourselves, we have to
  872. // return DDHAL_DRIVER_HANDLED here:
  873. lpDestroySurface->ddRVal = DD_OK;
  874. DISPDBG((10, " Exit Destroy Surface OK; deallocate poh X=%d, Y=%d ", poh->x, poh->y));
  875. return(DDHAL_DRIVER_HANDLED);
  876. }
  877. DISPDBG((10, " Exit Destroy Surface Not OK : The Reserved1 is not a poh"));
  878. }
  879. DISPDBG((10, " Exit Destroy Surface Not OK : The Reserved1 is NULL"));
  880. return(DDHAL_DRIVER_NOTHANDLED);
  881. }
  882. #endif