Source code of Windows XP (NT5)
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.

1344 lines
36 KiB

  1. #include <windows.h>
  2. #include <windowsx.h>
  3. #include <mmsystem.h> // for timeGetTime()
  4. #include "drawdibi.h"
  5. #include "profdisp.h"
  6. //#include "msvideo.h"
  7. //#include "lockbm.h"
  8. //#include "setdi.h"
  9. // Remove inline assembly warning
  10. #pragma warning(disable:4704)
  11. //
  12. // Set+Blt must be N% faster in order to say a driver isn't good
  13. //
  14. #define PROFDISP_FUDGE 110
  15. #ifndef WIN32
  16. #define GdiFlush()
  17. #endif
  18. DWORD VFWAPI DrawDibProfileDisplay(LPBITMAPINFOHEADER lpbi);
  19. static UINT NEAR PASCAL ProfDispCanDrawDib(LPBITMAPINFOHEADER lpbi);
  20. static HPALETTE CreateTestPalette(BOOL);
  21. #ifndef WIN32
  22. //C6 will die if we dont redefine this.
  23. #undef GlobalFreePtr
  24. #define GlobalFreePtr(p) GlobalFree(GlobalPtrHandle(p))
  25. #pragma alloc_text(DRAWDIB, DrawDibProfileDisplay)
  26. #pragma alloc_text(DRAWDIB, ProfDispCanDrawDib)
  27. #endif
  28. #ifndef QUERYDIBSUPPORT
  29. #define QUERYDIBSUPPORT 3073
  30. #endif
  31. #ifndef QDI_SETDIBITS
  32. #define QDI_SETDIBITS 0x0001
  33. #define QDI_GETDIBITS 0x0002
  34. #define QDI_DIBTOSCREEN 0x0004
  35. #define QDI_STRETCHDIB 0x0008
  36. #endif
  37. /*
  38. ** ProfDisp - profile the display driver
  39. */
  40. #define BITMAP_X 320
  41. #define BITMAP_Y 240
  42. #define N_FRAMES 10
  43. #define STRETCH_N 190 // 1.90 times
  44. #ifdef DEBUG
  45. #define FIRST_N 0 // do four bit
  46. #else
  47. #define FIRST_N 1
  48. #endif
  49. #define BITBLTINDEX 5
  50. #define BACKINDEX 6
  51. // Internal return codes from DrawDibTest
  52. #define CANT_DO_THESE_BITS 1
  53. #define CANT_DO_STRETCHDIBITS 2
  54. #define STRETCHDI_FASTER 3
  55. #define OTHER_FASTER 4
  56. static HWND ghwnd ;
  57. #ifndef WIN32
  58. #define CODE _based(_segname("_CODE"))
  59. #define STACK _based(_segname("_STACK"))
  60. #else
  61. #define CODE
  62. #define STACK
  63. #endif
  64. static UINT ProfileDisplay(HDC hdc, UINT wBitsToTest, int dx, int dy) ;
  65. static BOOL IsDisplay16Bit(HDC hdc ) ;
  66. static BOOL IsDisplay32Bit(HDC hdc ) ;
  67. static UINT DrawDibTest(HDC hdc, LPBITMAPINFOHEADER FAR *alpbi, UINT wFrames,UINT wStretch ) ;
  68. static void FreeFrames( LPBITMAPINFOHEADER FAR *alpbi) ;
  69. static void MakeFrames(LPBITMAPINFOHEADER FAR *alpbi, UINT bits, UINT wXSize,UINT wYSize ) ;
  70. static HANDLE MakeDib( HBITMAP hbitmap, UINT bits ) ;
  71. static TCHAR CODE szBoot[] = TEXT("boot" );
  72. static TCHAR CODE szDisplay[] = TEXT("display.drv" );
  73. static TCHAR CODE szNull[] = TEXT("") ;
  74. static TCHAR CODE szDrawdib[] = TEXT("drawdib" );
  75. static TCHAR CODE szSystemIni[] = TEXT("system.ini") ;
  76. static TCHAR CODE szNxNxNxType[] = TEXT(" %dx%dx%d(%s%u)");
  77. static TCHAR CODE szEntryFormat[] = TEXT("%d,%d,%d,%d");
  78. static TCHAR CODE szU[] = TEXT("%u");
  79. static TCHAR CODE sz02U[] = TEXT("%02u");
  80. static TCHAR CODE sz565[] = TEXT("565 ");
  81. static TCHAR CODE sz555[] = TEXT("555 ");
  82. static TCHAR CODE szRGB[] = TEXT("RGB ");
  83. static TCHAR CODE szBGR[] = TEXT("BGR ");
  84. // The following two strings are loaded from MSVIDEO.DLL - defined in
  85. // video\video.rc. If they cannot be found there, use these definitions
  86. static TCHAR CODE szProfilingDefault[] = TEXT("Profiling Display");
  87. static TCHAR CODE szListbox[] = TEXT("ListBox");
  88. #if 0 // dont warn any-more
  89. #ifndef WIN32
  90. static TCHAR CODE szWarning[] = TEXT("Warning!");
  91. static TCHAR CODE szDisplaySucks[]=
  92. TEXT("You may encounter display performance problems; ")
  93. TEXT("please contact the manufacturer of your video ")
  94. TEXT("board to see if an updated driver is available.");
  95. #endif
  96. #endif
  97. #define ARRAYLEN(array) (sizeof(array)/sizeof(array[0]))
  98. static int result[5] = {
  99. -1,
  100. -1,
  101. -1,
  102. -1,
  103. -1};
  104. //
  105. // UINT displayFPS[7][3][2] [test dib][stretch][method]
  106. //
  107. // this array contains fps numbers times 10, ie 10 == 1fps
  108. // zero means the test was not run.
  109. //
  110. // testdib:
  111. // 0 = 4bpp DIB (debug only)
  112. // 1 = 8bpp DIB
  113. // 2 = 16bpp DIB
  114. // 3 = 24bpp DIB
  115. // 4 = 32bpp DIB
  116. // 5 = BitBlt
  117. // 6 = 8bpp DIB (with non identity palette)
  118. //
  119. // stretch:
  120. // 0 = 1:1
  121. // 1 = 1:2
  122. // 2 = 1:N (realy 2:3)
  123. //
  124. // method (for stretch == 1:1)
  125. // 0 = StretchDIBits()
  126. // 1 = SetDIBits() + BitBlt *
  127. //
  128. // method (for stretch != 1:1)
  129. // 0 = StretchDIBits()
  130. // 1 = StretchDIB() + StretchDIBits() **
  131. //
  132. // method (for testdib == 5, bitblt)
  133. // 0 = BitBlt foreground palette
  134. // 1 = BitBlt background palette
  135. //
  136. // NOTE high color dibs (> 8) are not tested on devices with bitdepths <= 8
  137. //
  138. // NOTE stretching tests are not run unless the device does stretching.
  139. // (RasterCaps has RC_STRETCHBLT or RC_STRETCHDIBITS set)
  140. //
  141. // * NOTE if we can access bitmaps, we dont use SetDIBits() we use direct
  142. // code.
  143. //
  144. // ** NOTE (StretchDIB is not a GDI api...)
  145. //
  146. // EXAMPLE:
  147. // displayFPS[1][0][0] is the FPS of 1:1 StretchDIBits() on a 8bpp DIB
  148. // displayFPS[1][0][1] is the FPS of Set+BitBlt() on a 8bpp DIB
  149. // displayFPS[1][1][0] is the FPS of 1:2 StretchDIBits() on a 8bpp DIB
  150. //
  151. // how the ResultN flags get set:
  152. //
  153. // PD_CAN_DRAW_DIB (can draw this dib 1:1 using some method...)
  154. // displayFPS[N][0][0] != 0 or displayFPS[N][0][1] != 0
  155. //
  156. // PD_CAN_STRETCHDIB (can stretch this dib using StretchDIBits)
  157. // displayFPS[N][1][0] > displayFPS[N][1][1] or
  158. // displayFPS[N][2][0] > displayFPS[N][2][1]
  159. //
  160. // PD_STRETCHDIB_1_1_OK (StretchDIBits faster than Set+BitBlt)
  161. // displayFPS[N][0][0] > displayFPS[N][0][1]
  162. //
  163. // PD_STRETCHDIB_1_2_OK (StretchDIBits 1:2 is faster the doing it our self)
  164. // displayFPS[N][1][0] > displayFPS[N][1][1]
  165. //
  166. // PD_STRETCHDIB_1_N_OK (StretchDIBits 1:N is faster the doing it our self)
  167. // displayFPS[N][2][0] > displayFPS[N][2][1]
  168. //
  169. static UINT displayFPS[7] // 0=4bbp, 1=8bpp, 2=16bpp, 3=24bpp, 4=32bit, 5=BitBlt, 6=Dib ~1:1
  170. [3] // 0=1:1, 1=1:2, 2=1:N
  171. [2]; // 0=DrawDib, 1=Set+Blt (or ~1:1 for BitBlt)
  172. /***************************************************************************
  173. *
  174. * @doc INTERNAL
  175. *
  176. * @api LONG | atoi | local version of atoi
  177. *
  178. ***************************************************************************/
  179. static int NEAR PASCAL atoi(char FAR *sz)
  180. {
  181. int i = 0;
  182. while (*sz && *sz >= '0' && *sz <= '9')
  183. i = i*10 + *sz++ - '0';
  184. return i;
  185. }
  186. static void FAR InitProfDisp(BOOL fForceMe)
  187. {
  188. TCHAR ach[80];
  189. TCHAR achDisplay[80];
  190. HDC hdc;
  191. int i;
  192. int n;
  193. int BitDepth;
  194. GetPrivateProfileString(szBoot, szDisplay, szNull,
  195. achDisplay, ARRAYLEN(achDisplay), szSystemIni);
  196. hdc = GetDC(NULL);
  197. BitDepth = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
  198. n = GetBitmapType();
  199. switch(n & BM_TYPE)
  200. {
  201. default:
  202. case BM_8BIT: ach[0] = 0; break;
  203. case BM_16555: lstrcpy(ach, sz555); break;
  204. case BM_16565: lstrcpy(ach, sz565); break;
  205. case BM_24BGR:
  206. case BM_32BGR: lstrcpy(ach, szBGR); break;
  207. case BM_24RGB:
  208. case BM_32RGB: lstrcpy(ach, szRGB); break;
  209. }
  210. wsprintf(achDisplay + lstrlen(achDisplay), szNxNxNxType,
  211. GetSystemMetrics(SM_CXSCREEN),
  212. GetSystemMetrics(SM_CYSCREEN),
  213. BitDepth,(LPSTR)ach, n >> 4);
  214. ReleaseDC(NULL, hdc);
  215. GetProfileString(szDrawdib, achDisplay, szNull, ach, ARRAYLEN(ach));
  216. for (i=0,n=1; n<5; n++)
  217. {
  218. if (ach[i] == '\0')
  219. {
  220. result[n] = -1;
  221. }
  222. else
  223. {
  224. result[n] = atoi(ach+i);
  225. while (ach[i] != 0 && ach[i] != ',')
  226. i++;
  227. if (ach[i] != 0)
  228. i++;
  229. }
  230. }
  231. if (fForceMe ||
  232. result[1] == -1 ||
  233. result[2] == -1 ||
  234. result[3] == -1 ||
  235. result[4] == -1)
  236. {
  237. TestDibFormats(BITMAP_X,BITMAP_Y);
  238. wsprintf(ach, szEntryFormat,
  239. result[1], result[2], result[3], result[4]);
  240. WriteProfileString(szDrawdib, achDisplay, ach);
  241. #if 0
  242. //
  243. // if the DISPLAY driver isn't very good at drawing DIBs then warn the user.
  244. //
  245. // we will only warn if the device is at least 8bpp
  246. //
  247. if (BitDepth >= 8 && !(result[1] & PD_STRETCHDIB_1_1_OK))
  248. {
  249. #ifndef WIN32
  250. MessageBox(NULL, szDisplaySucks, szWarning,
  251. #ifdef BIDI
  252. MB_RTL_READING |
  253. #endif
  254. MB_OK | MB_SYSTEMMODAL | MB_ICONEXCLAMATION);
  255. #else
  256. RPF(("Display driver probably too slow for AVI"));
  257. #endif
  258. }
  259. #endif
  260. }
  261. }
  262. /****************************************************************
  263. *
  264. *****************************************************************/
  265. static UINT NEAR PASCAL ProfDispCanDrawDib(LPBITMAPINFOHEADER lpbi)
  266. {
  267. int n;
  268. LONG l;
  269. HDC hdc;
  270. UINT w;
  271. if (result[1] == -1 || lpbi==NULL)
  272. InitProfDisp(FALSE);
  273. if (lpbi == NULL)
  274. return 0;
  275. switch (lpbi->biCompression)
  276. {
  277. //
  278. // standard format use our pre-computed performance numbers.
  279. //
  280. case BI_RGB:
  281. n = (int)lpbi->biBitCount / 8;
  282. return result[n];
  283. case BI_RLE4:
  284. case BI_RLE8:
  285. //
  286. // return the un-rle results *but* RLE can't stretch
  287. //
  288. return result[1] & PD_CAN_DRAW_DIB|PD_STRETCHDIB_1_1_OK;
  289. //
  290. // custom format, ask the DISPLAY driver
  291. //
  292. default:
  293. l = 0;
  294. w = 0;
  295. hdc = GetDC(NULL);
  296. if (Escape(hdc, QUERYDIBSUPPORT, (int)lpbi->biSize, (LPVOID)lpbi, (LPVOID)&l) > 0)
  297. {
  298. // make sure the driver realy realy gave us back flags.
  299. if (l & ~(0x00FF))
  300. l = 0;
  301. if (l & QDI_DIBTOSCREEN)
  302. w |= PD_STRETCHDIB_1_1_OK | PD_CAN_DRAW_DIB;
  303. if (l & QDI_STRETCHDIB)
  304. w |= PD_CAN_STRETCHDIB;
  305. /* what about stretching? fast? */
  306. }
  307. ReleaseDC(NULL, hdc);
  308. return w;
  309. }
  310. }
  311. /****************************************************************
  312. * @doc EXTERNAL DrawDib
  313. *
  314. * @api void | DrawDibProfileDisplay | Profiles the display for DrawDib.
  315. *
  316. * @parm LPBITMAPINFOHEADER | parms | Specifies bitmap information.
  317. * Set to null if no information is available.
  318. *
  319. *****************************************************************/
  320. DWORD VFWAPI DrawDibProfileDisplay(LPBITMAPINFOHEADER lpbi)
  321. {
  322. if (lpbi == NULL)
  323. {
  324. InitProfDisp(TRUE) ;
  325. return (DWORD)(LPVOID)displayFPS;
  326. }
  327. else
  328. return ProfDispCanDrawDib(lpbi);
  329. }
  330. LPVOID FAR TestDibFormats(int dx, int dy)
  331. {
  332. int dxScreen,dyScreen;
  333. RECT rc;
  334. HWND hwnd;
  335. HDC hdc;
  336. int n;
  337. int i;
  338. HCURSOR hcur;
  339. HPALETTE hpal;
  340. #ifdef DEBUG
  341. HPALETTE hpalT;
  342. #endif
  343. HWND hwndActive;
  344. TCHAR szProfiling[80];
  345. // dont change this without changing MSVIDEO.RC
  346. #define IDS_PROFILING 4000
  347. extern HMODULE ghInst; // in MSVIDEO\init.c
  348. if (!LoadString(ghInst, IDS_PROFILING, szProfiling, sizeof(szProfiling)/sizeof(TCHAR)))
  349. lstrcpy(szProfiling, szProfilingDefault);
  350. #ifdef WIN32
  351. #define GetCurrentInstance() GetModuleHandle(NULL)
  352. #else
  353. #define GetCurrentInstance() NULL
  354. #endif
  355. dxScreen = GetSystemMetrics(SM_CXSCREEN);
  356. dyScreen = GetSystemMetrics(SM_CYSCREEN);
  357. // fill in displayFPS[7][3][2];
  358. for (n=0; n<7; n++)
  359. for (i=0; i<3; i++)
  360. displayFPS[n][i][0] =
  361. displayFPS[n][i][1] = 0;
  362. SetRect(&rc, 0, 0, dx, dy);
  363. AdjustWindowRect(&rc, (WS_OVERLAPPED | WS_CAPTION | WS_BORDER), FALSE);
  364. OffsetRect(&rc, -rc.left, -rc.top);
  365. hwnd =
  366. #ifdef BIDI
  367. CreateWindowEx(WS_EX_BIDI_SCROLL | WS_EX_BIDI_MENU |WS_EX_BIDI_NOICON,
  368. szListbox, // Class name
  369. szProfiling, // Caption
  370. LBS_NOINTEGRALHEIGHT|
  371. (WS_OVERLAPPED | WS_CAPTION | WS_BORDER),
  372. (dxScreen - rc.right) / 2,
  373. (dyScreen - rc.bottom) / 2,
  374. rc.right,
  375. rc.bottom,
  376. (HWND)NULL, // Parent window (no parent)
  377. (HMENU)NULL, // use class menu
  378. GetCurrentInstance(), // handle to window instance
  379. (LPTSTR)NULL // no params to pass on
  380. );
  381. #else
  382. CreateWindow (
  383. szListbox, // Class name
  384. szProfiling, // Caption
  385. LBS_NOINTEGRALHEIGHT|
  386. (WS_OVERLAPPED | WS_CAPTION | WS_BORDER),
  387. (dxScreen - rc.right) / 2,
  388. (dyScreen - rc.bottom) / 2,
  389. rc.right,
  390. rc.bottom,
  391. (HWND)NULL, // Parent window (no parent)
  392. (HMENU)NULL, // use class menu
  393. GetCurrentInstance(), // handle to window instance
  394. (LPTSTR)NULL // no params to pass on
  395. );
  396. #endif
  397. // make the window top most
  398. SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0,
  399. SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
  400. // and show it.
  401. SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
  402. SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_SHOWWINDOW);
  403. // and activate it.
  404. hwndActive = GetActiveWindow();
  405. SetActiveWindow(hwnd);
  406. hdc = GetDC(hwnd);
  407. hcur = SetCursor(NULL);
  408. if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)
  409. {
  410. hpal = CreateTestPalette(TRUE);
  411. SelectPalette(hdc, hpal, FALSE);
  412. RealizePalette(hdc);
  413. }
  414. Yield();
  415. Yield();
  416. Yield();
  417. #ifndef WIN32
  418. //
  419. // make sure no junk is around in the SmartDrv cache, this will
  420. // mess with the timings
  421. //
  422. _asm {
  423. mov ax,4A10h ; tell Bambi to flush the cache
  424. mov bx,0001h
  425. int 2fh
  426. mov ah,0Dh ; tell other people to commit...
  427. int 21h
  428. }
  429. #else
  430. GdiFlush();
  431. #endif
  432. for (n=FIRST_N; n<5; n++)
  433. result[n] = ProfileDisplay(hdc, n==0 ? 4 : n*8, dx, dy);
  434. #ifdef DEBUG
  435. if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)
  436. {
  437. //
  438. // re-run the 8bit tests with a background palette
  439. //
  440. SelectPalette(hdc, GetStockObject(DEFAULT_PALETTE), FALSE);
  441. RealizePalette(hdc);
  442. hpalT = CreateTestPalette(FALSE);
  443. SelectPalette(hdc, hpalT, TRUE);
  444. RealizePalette(hdc);
  445. Yield();
  446. Yield();
  447. Yield();
  448. ProfileDisplay(hdc, 8, dx, dy);
  449. SelectPalette(hdc, GetStockObject(DEFAULT_PALETTE), FALSE);
  450. RealizePalette(hdc);
  451. DeleteObject(hpalT);
  452. DeleteObject(hpal);
  453. }
  454. #endif
  455. SetCursor(hcur);
  456. ReleaseDC(hwnd, hdc);
  457. if (hwndActive)
  458. SetActiveWindow(hwndActive);
  459. DestroyWindow(hwnd) ;
  460. return (LPVOID)displayFPS;
  461. }
  462. static UINT ProfileDisplay(HDC hdc, UINT wBitsToTest, int dx, int dy)
  463. {
  464. LPBITMAPINFOHEADER alpbi[N_FRAMES];
  465. UINT wRetval;
  466. if (GetDeviceCaps(hdc, BITSPIXEL) *
  467. GetDeviceCaps(hdc, PLANES) <= 8 && wBitsToTest > 8)
  468. return 0;
  469. alpbi[0] = NULL;
  470. MakeFrames(alpbi,wBitsToTest,dx,dy);
  471. wRetval = 0 ;
  472. if (!alpbi[0])
  473. return (UINT)-1 ;
  474. switch(DrawDibTest(hdc,alpbi,N_FRAMES,100))
  475. {
  476. case CANT_DO_THESE_BITS:
  477. goto done ;
  478. case CANT_DO_STRETCHDIBITS:
  479. wRetval = PD_CAN_DRAW_DIB ;
  480. goto done ;
  481. case STRETCHDI_FASTER:
  482. wRetval = PD_STRETCHDIB_1_1_OK ;
  483. /* Falling through */
  484. case OTHER_FASTER:
  485. wRetval |= PD_CAN_DRAW_DIB;
  486. }
  487. if (DrawDibTest(hdc,alpbi,N_FRAMES,STRETCH_N) == STRETCHDI_FASTER)
  488. wRetval |= PD_STRETCHDIB_1_N_OK|PD_CAN_STRETCHDIB;
  489. if (DrawDibTest(hdc,alpbi,N_FRAMES,200) == STRETCHDI_FASTER)
  490. wRetval |= PD_STRETCHDIB_1_2_OK|PD_CAN_STRETCHDIB;
  491. done:
  492. FreeFrames(alpbi);
  493. return wRetval;
  494. }
  495. static UINT DrawDibTest(HDC hdc,LPBITMAPINFOHEADER FAR *alpbi,UINT wFrames,UINT wStretch)
  496. {
  497. HDC hdcMem ;
  498. HBITMAP hbitmap ;
  499. HBITMAP hbitmapOld ;
  500. UINT wBits ;
  501. DWORD dwSize;
  502. DWORD wSizeColors ;
  503. DWORD dwSizeImage;
  504. volatile LPBITMAPINFOHEADER lpbi ;
  505. LPBYTE bits ;
  506. LPBITMAPINFOHEADER lpbiStretch ;
  507. LPBYTE bitsStretch ;
  508. DWORD time0 = 0;
  509. DWORD time1 = 0;
  510. DWORD time2 = 0;
  511. RECT rc ;
  512. int XDest,YDest,cXDest,cYDest ;
  513. int cXSrc,cYSrc ;
  514. int i ;
  515. int n ;
  516. int q ;
  517. UINT DibUsage;
  518. HPALETTE hpal;
  519. BOOL fBack;
  520. BOOL f;
  521. lpbi = alpbi[0];
  522. /*
  523. ** Get stuff common to all frames
  524. */
  525. wBits = lpbi->biBitCount ;
  526. //cXSrc = (int)lpbi->biWidth ;
  527. //cYSrc = (int)lpbi->biHeight ;
  528. //cXDest = wStretch*(int)lpbi->biWidth/100 ;
  529. //cYDest = wStretch*(int)lpbi->biHeight/100 ;
  530. cXSrc = 100*(int)lpbi->biWidth/wStretch ;
  531. cYSrc = 100*(int)lpbi->biHeight/wStretch ;
  532. cXDest = (int)lpbi->biWidth ;
  533. cYDest = (int)lpbi->biHeight ;
  534. // are we background'ed
  535. n = wStretch == 100 ? 0 : wStretch == 200 ? 1 : 2;
  536. fBack = wBits==8 && displayFPS[1][n][0] != 0;
  537. if (lpbi->biBitCount <= 8)
  538. wSizeColors = sizeof(RGBQUAD) * (int)(lpbi->biClrUsed ? lpbi->biClrUsed : (1 << (int)lpbi->biBitCount));
  539. else
  540. wSizeColors = 0 ;
  541. bits = (LPBYTE)lpbi + (int)lpbi->biSize + wSizeColors ;
  542. if (GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES) <= 8 && wBits > 8)
  543. return CANT_DO_STRETCHDIBITS;
  544. ////if (wStretch != 100 && !(GetDeviceCaps(hdc,RASTERCAPS)&(RC_STRETCHDIB|RC_STRETCHBLT)))
  545. if (wStretch != 100 && !(GetDeviceCaps(hdc,RASTERCAPS)&(RC_STRETCHDIB)))
  546. return CANT_DO_STRETCHDIBITS ;
  547. if (wStretch != 100 && wBits == 4)
  548. return CANT_DO_STRETCHDIBITS ;
  549. if (wStretch != 100 && (GetWinFlags() & WF_CPU286))
  550. return STRETCHDI_FASTER;
  551. // if (wStretch != 100 && wBits > 8) //!!!
  552. // wFrames = 4;
  553. lpbi->biWidth = cXSrc;
  554. lpbi->biHeight = cYSrc;
  555. // get current palette
  556. hpal = SelectPalette(hdc, GetStockObject(DEFAULT_PALETTE), FALSE);
  557. SelectPalette(hdc, hpal, fBack);
  558. RealizePalette(hdc);
  559. if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)
  560. {
  561. DibUsage = DIB_PAL_COLORS;
  562. }
  563. else
  564. {
  565. DibUsage = DIB_RGB_COLORS;
  566. }
  567. ////GetClientRect(hwnd,&rc) ;
  568. GetClipBox(hdc,&rc) ;
  569. XDest = (rc.right - cXDest)/2 ;
  570. YDest = (rc.bottom - cYDest)/2 ;
  571. time0 = 0;
  572. if (wBits == 16 && !IsDisplay16Bit(hdc))
  573. goto test_bitmap;
  574. if (wBits == 32 && !IsDisplay32Bit(hdc))
  575. goto test_bitmap;
  576. time0 = timeGetTime() ;
  577. for (i=0; i<(int)wFrames; i++)
  578. {
  579. lpbi = alpbi[i%N_FRAMES];
  580. bits = ((LPBYTE)lpbi) + (int)lpbi->biSize + wSizeColors ;
  581. #ifdef WIN32
  582. /*
  583. * to correctly model the behaviour of DrawDibDraw, we
  584. * use SetDIBitsToDevice if 1:1 (source rect == dest rect).
  585. */
  586. if ( (cXSrc == cXDest) && (cYSrc == cYDest)) {
  587. f = SetDIBitsToDevice(hdc, XDest, YDest, cXDest, cYDest,
  588. 0, 0, 0, cYSrc,
  589. bits, (LPBITMAPINFO)lpbi, DibUsage);
  590. } else
  591. #endif
  592. {
  593. f = StretchDIBits(
  594. hdc,
  595. XDest,YDest,cXDest,cYDest,
  596. 0,0,cXSrc, cYSrc,
  597. bits,(LPBITMAPINFO)lpbi,DibUsage,SRCCOPY) ;
  598. }
  599. }
  600. GdiFlush();
  601. time0 = timeGetTime() - time0 ;
  602. if (f == 0)
  603. time0 = 0;
  604. test_bitmap:
  605. time1 = 0;
  606. if (wStretch == 100)
  607. {
  608. PSETDI psd;
  609. psd = (PSETDI)LocalAlloc(LPTR, sizeof(SETDI));
  610. if (psd == NULL)
  611. goto done;
  612. hbitmap = CreateCompatibleBitmap(hdc,cXDest,cYDest) ;
  613. hdcMem = CreateCompatibleDC(NULL) ;
  614. hbitmapOld = SelectObject(hdcMem,hbitmap) ;
  615. f = SetBitmapBegin(
  616. psd, // structure
  617. hdc, // device
  618. hbitmap, // bitmap to set into
  619. lpbi, // --> BITMAPINFO of source
  620. DibUsage);
  621. psd->hdc = hdc;
  622. if (f)
  623. f = SetBitmap(psd, 0, 0, cXDest, cYDest, bits, 0, 0, cXDest, cYDest);
  624. if (f)
  625. {
  626. // SelectPalette(hdc, GetStockObject(DEFAULT_PALETTE), FALSE);
  627. // RealizePalette(hdc);
  628. time1 = timeGetTime();
  629. for (i=0; i<(int)wFrames; i++)
  630. {
  631. SetBitmap(psd, 0, 0, cXDest, cYDest, bits, 0, 0, cXDest, cYDest);
  632. BitBlt(hdc,XDest,YDest,cXDest,cYDest,hdcMem,0,0,SRCCOPY);
  633. }
  634. GdiFlush();
  635. time1 = timeGetTime() - time1 ;
  636. SetBitmapEnd(psd);
  637. // SelectPalette(hdc, hpal, fBack);
  638. // RealizePalette(hdc);
  639. }
  640. #ifdef DEBUG
  641. if ((int)lpbi->biBitCount == GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES))
  642. {
  643. time2 = timeGetTime() ;
  644. for (i=0; i<(int)wFrames; i++)
  645. BitBlt(hdc,XDest,YDest,cXDest,cYDest,hdcMem,0,0,SRCCOPY) ;
  646. GdiFlush();
  647. time2 = timeGetTime() - time2 ;
  648. }
  649. #endif
  650. LocalFree((HLOCAL)psd);
  651. SelectObject(hdcMem,hbitmapOld) ;
  652. DeleteObject(hbitmap) ;
  653. DeleteDC(hdcMem) ;
  654. }
  655. else
  656. {
  657. if (wBits == 16 && !IsDisplay16Bit(hdc))
  658. goto done;
  659. if (wBits == 32 && !IsDisplay32Bit(hdc))
  660. goto done;
  661. #ifdef NOSTRETCH
  662. /*
  663. * StretchDIB not ported from ASM yet - so StretchDIBits must win.
  664. */
  665. time1 = time0 + 1;
  666. #else
  667. // Calc size we need to allocate for stretched bits
  668. dwSizeImage = (DWORD)(UINT)cYDest*(DWORD)(((UINT)cXDest*(UINT)lpbi->biBitCount+31)/32*4);
  669. dwSize = (int)lpbi->biSize + (int)lpbi->biClrUsed*sizeof(RGBQUAD);
  670. if ((lpbiStretch = (LPVOID)GlobalAllocPtr(GHND,dwSize + dwSizeImage)) != NULL)
  671. {
  672. hmemcpy(lpbiStretch, lpbi, dwSize);
  673. lpbiStretch->biWidth = cXDest;
  674. lpbiStretch->biHeight = cYDest;
  675. lpbiStretch->biSizeImage = dwSizeImage;
  676. bitsStretch = (LPBYTE)lpbiStretch + (UINT)dwSize;
  677. time1 = timeGetTime() ;
  678. for (i=0; i<(int)wFrames; i++)
  679. {
  680. lpbi = alpbi[i%N_FRAMES];
  681. bits = ((LPBYTE)lpbi) + (int)lpbi->biSize + wSizeColors;
  682. StretchDIB(
  683. lpbiStretch,bitsStretch,
  684. 0,0,cXDest,cYDest,
  685. lpbi,bits,
  686. 0,0,cXSrc,cYSrc);
  687. #ifdef WIN32
  688. /*
  689. * to correctly model the behaviour of DrawDibDraw, we
  690. * use SetDIBitsToDevice if 1:1 (source rect == dest rect).
  691. */
  692. f = SetDIBitsToDevice(hdc, XDest, YDest, cXDest, cYDest,
  693. 0, 0, 0, cYSrc,
  694. bits, (LPBITMAPINFO)lpbi, DibUsage);
  695. #else
  696. f = StretchDIBits(
  697. hdc,
  698. XDest,YDest,cXDest,cYDest,
  699. 0,0,cXDest,cYDest,
  700. bitsStretch,(LPBITMAPINFO)lpbiStretch,DibUsage,SRCCOPY);
  701. #endif
  702. }
  703. GdiFlush();
  704. time1 = timeGetTime() - time1 ;
  705. GlobalFreePtr(lpbiStretch);
  706. if (f == 0)
  707. time1 = 0;
  708. #endif
  709. }
  710. #ifdef DEBUG
  711. if ((int)lpbi->biBitCount == GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES))
  712. {
  713. hbitmap = CreateCompatibleBitmap(hdc,cXSrc,cYSrc) ;
  714. hdcMem = CreateCompatibleDC(NULL) ;
  715. hbitmapOld = SelectObject(hdcMem,hbitmap) ;
  716. lpbi = alpbi[0];
  717. bits = ((LPBYTE)lpbi) + (int)lpbi->biSize + wSizeColors;
  718. SetDIBits(hdc,hbitmap,0,cYSrc,bits,(LPBITMAPINFO)lpbi,DibUsage);
  719. SelectPalette(hdcMem, hpal, FALSE);
  720. // RealizePalette(hdcMem);
  721. time2 = timeGetTime() ;
  722. for (i=0; i<(int)wFrames; i++)
  723. StretchBlt(hdc,XDest,YDest,cXDest,cYDest,hdcMem,0,0,cXSrc,cYSrc,SRCCOPY) ;
  724. GdiFlush();
  725. time2 = timeGetTime() - time2 ;
  726. SelectObject(hdcMem,hbitmapOld) ;
  727. DeleteObject(hbitmap) ;
  728. DeleteDC(hdcMem) ;
  729. }
  730. #endif
  731. }
  732. done:
  733. /* time0 is the time required to do StretchDIBits */
  734. /* time1 is the time required to do Set + BitBlt */
  735. /* time2 is the time required to do a BitBlt */
  736. //
  737. // compute the FPS * 10 and store for later use.
  738. //
  739. n = wStretch == 100 ? 0 : wStretch == 200 ? 1 : 2;
  740. q = fBack ? BACKINDEX : wBits/8;
  741. time1 = (DWORD)MulDiv((int)time1,PROFDISP_FUDGE,100);
  742. displayFPS[q][n][0] = time0 ? (UINT)MulDiv(wFrames,10000,(int)time0) : 0;
  743. displayFPS[q][n][1] = time1 ? (UINT)MulDiv(wFrames,10000,(int)time1) : 0;
  744. if (time2)
  745. displayFPS[BITBLTINDEX][n][fBack] = (UINT)MulDiv(wFrames,10000,(int)time2);
  746. RPF(("DrawDibTest %dx%dx%d %d StretchDIBits=%04lu SetDI+BitBlt=%04lu BitBlt=%04lu %ls",cXDest,cYDest,wBits,wStretch,time0,time1,time2,(LPSTR)(time0 < time1 ? TEXT("") : TEXT("SUCKS!"))));
  747. lpbi->biWidth = cXDest;
  748. lpbi->biHeight = cYDest;
  749. if (time0 == 0)
  750. {
  751. return time1 ? OTHER_FASTER : CANT_DO_THESE_BITS;
  752. }
  753. else
  754. {
  755. if (time1)
  756. return (time0 < time1) ? STRETCHDI_FASTER : OTHER_FASTER;
  757. else
  758. return STRETCHDI_FASTER;
  759. }
  760. }
  761. static void MakeFrames(LPBITMAPINFOHEADER FAR *alpbi, UINT bits, UINT wXSize,UINT wYSize )
  762. {
  763. int i ;
  764. int x ;
  765. int y ;
  766. LPBITMAPINFOHEADER lpbi ;
  767. DWORD dwSizeImage;
  768. BYTE _huge *pb;
  769. WORD FAR *pw;
  770. DWORD FAR *pdw;
  771. UINT rc;
  772. HDC hdc;
  773. hdc = GetDC(NULL);
  774. rc = GetDeviceCaps(hdc, RASTERCAPS);
  775. ReleaseDC(NULL,hdc);
  776. FreeFrames(alpbi);
  777. dwSizeImage = wYSize*(DWORD)((wXSize*bits/8+3)&~3);
  778. lpbi = (LPVOID)GlobalAllocPtr(GHND,sizeof(BITMAPINFOHEADER)+dwSizeImage + 1024);
  779. lpbi->biSize = sizeof(BITMAPINFOHEADER) ;
  780. lpbi->biWidth = wXSize ;
  781. lpbi->biHeight = wYSize ;
  782. lpbi->biPlanes = 1 ;
  783. lpbi->biBitCount = bits ;
  784. lpbi->biCompression = BI_RGB ;
  785. lpbi->biSizeImage = dwSizeImage;
  786. lpbi->biXPelsPerMeter = 0 ;
  787. lpbi->biYPelsPerMeter = 0 ;
  788. lpbi->biClrUsed = 0 ;
  789. lpbi->biClrImportant = 0 ;
  790. // !!! These should be RGB DIBs if the device isn't a palette device!
  791. if (bits == 4)
  792. {
  793. lpbi->biClrUsed = 16;
  794. }
  795. else if (bits == 8)
  796. {
  797. lpbi->biClrUsed = 256;
  798. }
  799. pb = (BYTE _huge *)lpbi+lpbi->biSize+lpbi->biClrUsed * sizeof(RGBQUAD);
  800. if (bits == 4)
  801. {
  802. for (y=0; y<(int)wYSize; y++)
  803. for (x=0; x<(int)wXSize; x += 2)
  804. {
  805. i = ((x / (wXSize / 4)) + 4 * (y / (wYSize / 4)));
  806. i += i * 16;
  807. *pb++ = i;
  808. }
  809. if (rc & RC_PALETTE)
  810. {
  811. pw = (LPVOID)((LPBYTE)lpbi+(int)lpbi->biSize);
  812. for (i=0; i<8; i++)
  813. *pw++ = i;
  814. for (i=0; i<8; i++)
  815. *pw++ = 248+i;
  816. }
  817. else
  818. {
  819. pdw = (LPVOID)((LPBYTE)lpbi+(int)lpbi->biSize);
  820. *pdw++ = 0x00000000; // 0000 black
  821. *pdw++ = 0x00800000; // 0001 dark red
  822. *pdw++ = 0x00008000; // 0010 dark green
  823. *pdw++ = 0x00808000; // 0011 mustard
  824. *pdw++ = 0x00000080; // 0100 dark blue
  825. *pdw++ = 0x00800080; // 0101 purple
  826. *pdw++ = 0x00008080; // 0110 dark turquoise
  827. *pdw++ = 0x00C0C0C0; // 1000 gray
  828. *pdw++ = 0x00808080; // 0111 dark gray
  829. *pdw++ = 0x00FF0000; // 1001 red
  830. *pdw++ = 0x0000FF00; // 1010 green
  831. *pdw++ = 0x00FFFF00; // 1011 yellow
  832. *pdw++ = 0x000000FF; // 1100 blue
  833. *pdw++ = 0x00FF00FF; // 1101 pink (magenta)
  834. *pdw++ = 0x0000FFFF; // 1110 cyan
  835. *pdw++ = 0x00FFFFFF; // 1111 white
  836. }
  837. }
  838. else if (bits == 8)
  839. {
  840. for (y=0; y<(int)wYSize; y++)
  841. for (x=0; x<(int)wXSize; x++)
  842. {
  843. *pb++ = 10 + y * 236 / (int)wYSize;
  844. }
  845. if (rc & RC_PALETTE)
  846. {
  847. pw = (LPVOID)((LPBYTE)lpbi+(int)lpbi->biSize);
  848. for (i=0; i<256; i++)
  849. *pw++ = i;
  850. }
  851. else
  852. {
  853. pdw = (LPVOID)((LPBYTE)lpbi+(int)lpbi->biSize);
  854. for (i=0; i<256; i++)
  855. *pdw++ = RGB(i,0,0);
  856. }
  857. }
  858. else if (bits == 16)
  859. {
  860. for (y=0; y<(int)wYSize; y++)
  861. for (x=0; x<(int)wXSize; x++)
  862. {
  863. *pb++ = (BYTE) ((UINT)y * 32u / wYSize);
  864. *pb++ = (BYTE)(((UINT)x * 32u / wXSize) << 2);
  865. }
  866. }
  867. else if (bits == 24)
  868. {
  869. for (y=0; y<(int)wYSize; y++)
  870. for (x=0; x<(int)wXSize; x++)
  871. {
  872. *pb++ = (BYTE) (y * 256l / wYSize);
  873. *pb++ = (BYTE)~(x * 256l / wXSize);
  874. *pb++ = (BYTE) (x * 256l / wXSize);
  875. }
  876. }
  877. else if (bits == 32)
  878. {
  879. for (y=0; y<(int)wYSize; y++)
  880. for (x=0; x<(int)wXSize; x++)
  881. {
  882. *pb++ = (BYTE)~(x * 256l / wXSize);
  883. *pb++ = (BYTE) (y * 256l / wYSize);
  884. *pb++ = (BYTE) (x * 256l / wXSize);
  885. *pb++ = 0;
  886. }
  887. }
  888. for ( i=0; i<N_FRAMES; i++ )
  889. alpbi[i] = lpbi;
  890. }
  891. static void FreeFrames(LPBITMAPINFOHEADER FAR *alpbi)
  892. {
  893. UINT w ;
  894. if (!alpbi[0])
  895. return ;
  896. for (w=0; w<N_FRAMES; w++)
  897. if (alpbi[w] && (w == 0 || alpbi[w] != alpbi[w-1]))
  898. GlobalFreePtr(alpbi[w]);
  899. for (w=0; w<N_FRAMES; w++)
  900. alpbi[w] = NULL;
  901. }
  902. #if 0
  903. /*
  904. * CreateTestPalette()
  905. *
  906. */
  907. static HPALETTE CreateTestPalette(BOOL f)
  908. {
  909. HDC hdc;
  910. int i;
  911. struct {
  912. WORD palVersion;
  913. WORD palNumEntries;
  914. PALETTEENTRY palPalEntry[256];
  915. } pal;
  916. pal.palNumEntries = 256;
  917. pal.palVersion = 0x0300;
  918. hdc = GetDC(NULL);
  919. GetSystemPaletteEntries(hdc, 0, 256, &pal.palPalEntry[0]);
  920. ReleaseDC(NULL,hdc);
  921. for (i = 10; i < 246; i++)
  922. pal.palPalEntry[i].peFlags = PC_NOCOLLAPSE;
  923. if (!f)
  924. pal.palPalEntry[0].peRed = 255;
  925. return CreatePalette((LPLOGPALETTE)&pal);
  926. }
  927. #else
  928. /*
  929. * CreateTestPalette()
  930. *
  931. */
  932. static HPALETTE CreateTestPalette(BOOL fUp)
  933. {
  934. int i;
  935. HDC hdc;
  936. struct {
  937. WORD palVersion;
  938. WORD palNumEntries;
  939. PALETTEENTRY palPalEntry[256];
  940. } pal;
  941. pal.palNumEntries = 256;
  942. pal.palVersion = 0x0300;
  943. for (i = 0; i < 256; i++)
  944. {
  945. pal.palPalEntry[i].peRed = 0;
  946. pal.palPalEntry[i].peGreen = 0;
  947. pal.palPalEntry[i].peBlue = (BYTE)(fUp ? i : 255 - i);
  948. pal.palPalEntry[i].peFlags = PC_NOCOLLAPSE;
  949. }
  950. hdc = GetDC(NULL);
  951. GetSystemPaletteEntries(hdc, 0, 10, &pal.palPalEntry[0]);
  952. GetSystemPaletteEntries(hdc, 246, 10, &pal.palPalEntry[246]);
  953. ReleaseDC(NULL,hdc);
  954. return CreatePalette((LPLOGPALETTE)&pal);
  955. }
  956. #endif
  957. #define RGB555_RED 0x7C00
  958. #define RGB555_GREEN 0x03E0
  959. #define RGB555_BLUE 0x001F
  960. static BOOL IsDisplay16Bit( HDC hdc )
  961. {
  962. struct {
  963. BITMAPINFOHEADER bi;
  964. RGBQUAD rgbq[256];
  965. } dib;
  966. int w ;
  967. LONG l=0;
  968. WORD bits[2];
  969. COLORREF cref ;
  970. w = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES) ;
  971. if ( w < 15 )
  972. return FALSE;
  973. /*
  974. ** OK, the hardware is at least 16 bits - now test to see
  975. ** if they impelement 5-5-5 RGB
  976. */
  977. dib.bi.biSize = sizeof(BITMAPINFOHEADER);
  978. dib.bi.biWidth = 1;
  979. dib.bi.biHeight = 1;
  980. dib.bi.biPlanes = 1;
  981. dib.bi.biBitCount = 16;
  982. dib.bi.biCompression = BI_RGB;
  983. dib.bi.biSizeImage = 4;
  984. dib.bi.biXPelsPerMeter = 0;
  985. dib.bi.biYPelsPerMeter = 0;
  986. dib.bi.biClrUsed = 1;
  987. dib.bi.biClrImportant = 0;
  988. //
  989. // just in case they try to decode it as rle
  990. //
  991. bits[0] = 0x0000; // this is RLE EOL
  992. bits[1] = 0x0100; // this is RLE EOF
  993. //
  994. // send the Escape to see if they support 16bpp DIBs
  995. //
  996. if (Escape(hdc, QUERYDIBSUPPORT, (int)dib.bi.biSize, (LPVOID)&dib, (LPVOID)&l) > 0)
  997. {
  998. // make sure the driver realy realy gave us back flags.
  999. if (l & ~(0x00FF))
  1000. l = 0;
  1001. if (l & (QDI_DIBTOSCREEN|QDI_STRETCHDIB))
  1002. return TRUE;
  1003. }
  1004. //
  1005. // they dont support the QUERYDIBSUPPORT Escape, try to draw DIBs and see
  1006. // what they do!
  1007. //
  1008. if ( !StretchDIBits(hdc,0,0,1,1,0,0,1,1,bits,(LPBITMAPINFO)&dib,DIB_RGB_COLORS,SRCCOPY))
  1009. return FALSE;
  1010. cref = GetPixel(hdc,0,0) ;
  1011. if (cref != RGB(0,0,0))
  1012. return FALSE;
  1013. /*
  1014. ** Display a red pixel of the max value and get it back with
  1015. ** GetPixel(). Verify that red has the max value in the RGB
  1016. ** triplet and green and blue are nothing.
  1017. */
  1018. bits[0] = RGB555_RED ;
  1019. if ( !StretchDIBits(hdc,0,0,1,1,0,0,1,1,bits,(LPBITMAPINFO)&dib,DIB_RGB_COLORS,SRCCOPY))
  1020. return FALSE;
  1021. cref = GetPixel(hdc,0,0) & 0x00F8F8F8;
  1022. if (cref != RGB(0xF8,0,0))
  1023. return FALSE;
  1024. /*
  1025. ** Ditto green. Note that if the driver is implementing 5-6-5, then
  1026. ** green will read back as less than full scale and we will catch
  1027. ** it here.
  1028. */
  1029. bits[0] = RGB555_GREEN ;
  1030. if ( !StretchDIBits(hdc,0,0,1,1,0,0,1,1,bits,(LPBITMAPINFO)&dib,DIB_RGB_COLORS,SRCCOPY))
  1031. return FALSE;
  1032. cref = GetPixel(hdc,0,0) & 0x00F8F8F8;
  1033. if (cref != RGB(0,0xF8,0))
  1034. return FALSE;
  1035. /*
  1036. ** Ditto blue.
  1037. */
  1038. bits[0] = RGB555_BLUE ;
  1039. if ( !StretchDIBits(hdc,0,0,1,1,0,0,1,1,bits,(LPBITMAPINFO)&dib,DIB_RGB_COLORS,SRCCOPY))
  1040. return FALSE;
  1041. cref = GetPixel(hdc,0,0) & 0x00F8F8F8;
  1042. if (cref != RGB(0,0,0xF8))
  1043. return FALSE;
  1044. return TRUE;
  1045. }
  1046. static BOOL IsDisplay32Bit( HDC hdc )
  1047. {
  1048. struct {
  1049. BITMAPINFOHEADER bi;
  1050. RGBQUAD rgbq[256];
  1051. } dib;
  1052. int w ;
  1053. LONG l=0;
  1054. DWORD bits[2];
  1055. w = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES) ;
  1056. if ( w < 15 )
  1057. return FALSE;
  1058. /*
  1059. ** OK, the hardware is at least 16 bits - now test to see
  1060. ** if they impelement a 32 bit DIB
  1061. */
  1062. dib.bi.biSize = sizeof(BITMAPINFOHEADER);
  1063. dib.bi.biWidth = 2;
  1064. dib.bi.biHeight = 1;
  1065. dib.bi.biPlanes = 1;
  1066. dib.bi.biBitCount = 32;
  1067. dib.bi.biCompression = BI_RGB;
  1068. dib.bi.biSizeImage = 4;
  1069. dib.bi.biXPelsPerMeter = 0;
  1070. dib.bi.biYPelsPerMeter = 0;
  1071. dib.bi.biClrUsed = 1;
  1072. dib.bi.biClrImportant = 0;
  1073. //
  1074. // send the Escape to see if they support 32bpp DIBs
  1075. //
  1076. if (Escape(hdc, QUERYDIBSUPPORT, (int)dib.bi.biSize, (LPVOID)&dib, (LPVOID)&l) > 0)
  1077. {
  1078. // make sure the driver realy realy gave us back flags.
  1079. if (l & ~(0x00FF))
  1080. l = 0;
  1081. if (l & (QDI_DIBTOSCREEN|QDI_STRETCHDIB))
  1082. return TRUE;
  1083. }
  1084. bits[0] = 0x00000000;
  1085. bits[1] = 0x00FFFFFF;
  1086. //
  1087. // they dont support the QUERYDIBSUPPORT Escape, try to draw DIBs and see
  1088. // what they do!
  1089. //
  1090. if (!StretchDIBits(hdc,0,0,2,1,0,0,2,1,bits,(LPBITMAPINFO)&dib,DIB_RGB_COLORS,SRCCOPY))
  1091. return FALSE;
  1092. if (GetPixel(hdc,0,0) != 0)
  1093. return FALSE;
  1094. if ((GetPixel(hdc,1,0) & 0x00F8F8F8) != 0x00F8F8F8)
  1095. return FALSE;
  1096. return TRUE;
  1097. }