home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1997 February / PCO2_97.ISO / filesbbs / os2 / sysb091c.arj / SYSBENCH / SRC / PMB_GFX.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-23  |  28.0 KB  |  966 lines

  1.  
  2. // SysBench graphics test module
  3.  
  4. #define INCL_WIN
  5. #define INCL_GPI
  6. #define INCL_DOS
  7. #include <os2.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "pmb.h"
  11. #include "types.h"
  12.  
  13. #define ID_WINDOW1 8000
  14. #define PMB_GFX_CLASS "SysBench gfx winclass"
  15. #define WIN_WIDTH 640
  16. #define WIN_HEIGHT 460
  17. #define MIN_GFX_TIME 10.0
  18. #define MIN_MEASURE 0.1
  19. #define MARGINAL 1.1
  20. #define RUN_NUM 500
  21.  
  22. //static HAB  hab;
  23.  
  24. extern void err(char* s);
  25. extern void warn(char* s);
  26. extern void logit(char* s);
  27. extern HAB anchorblock(void);
  28. extern double rtime(void);    // real time in milliseconds
  29. extern double test_time;
  30.  
  31. VOID APIENTRY paint_vlines(ULONG unused);
  32. VOID APIENTRY paint_dlines(ULONG unused);
  33. VOID APIENTRY paint_hlines(ULONG unused);
  34. VOID APIENTRY paint_bitblitss(ULONG unused);
  35. VOID APIENTRY paint_bitblitms(ULONG unused);
  36. VOID APIENTRY paint_text(ULONG unused);
  37. VOID APIENTRY paint_fillrect(ULONG unused);
  38. VOID APIENTRY paint_patrect(ULONG unused);
  39. static MRESULT EXPENTRY GfxWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
  40. static void Open(void *paintfun);
  41. static void Close(void);
  42. static HWND hwndClient = NULLHANDLE;         /* Client area window handle    */
  43. static HWND hwndFrame = NULLHANDLE;          /* Frame window handle          */
  44. static HMQ  hmq;
  45. static ULONG flCreate;                       /* Window creation control flags*/
  46. static HAB bkHab;
  47. static TID paint_tid;
  48. static double result;
  49.  
  50. static void Open(void *paintfun) {
  51.   s32 w,h, x,y;
  52.   RECTL rctl, rctlScreen;
  53.   QMSG qmsg;                            /* Message from message queue   */
  54.   hwndClient = NULLHANDLE;         /* Client area window handle    */
  55.   hwndFrame = NULLHANDLE;          /* Frame window handle          */
  56. //  hab = anchorblock();
  57.  
  58.   if ((bkHab = WinInitialize(0)) == 0L) /* Initialize PM     */
  59.     err("Can't get anchor block handle for background thread");
  60.  
  61.   if ((hmq = WinCreateMsgQueue( bkHab, 0 )) == 0L)/* Create a msg queue */
  62.     err("Can't create message queue for graphics test window");
  63.  
  64.   if (!WinRegisterClass(bkHab, (PSZ)PMB_GFX_CLASS, (PFNWP)GfxWindowProc, 0, 0)) {
  65.     err("GFX test error: can't register class for child test window");
  66.   }
  67.  
  68.   flCreate = FCF_TITLEBAR | FCF_BORDER | FCF_SYSMENU;
  69.  
  70.   if ((hwndFrame = WinCreateStdWindow(
  71.                HWND_DESKTOP,            /* Desktop window is parent     */
  72.                0,                       /* window styles           */
  73.                &flCreate,               /* Frame control flag           */
  74.                PMB_GFX_CLASS,    /* Client window class name     */
  75.                "SysBench graphics test window",    /* window text               */
  76.                0,                       /* No special class style       */
  77.                (HMODULE)0L,             /* Resource is in .EXE file     */
  78.                ID_WINDOW1,               /* Frame window identifier      */
  79.                &hwndClient              /* Client window handle         */
  80.                )) == 0L)
  81.     err("Can't create graphics test window");
  82.  
  83.   WinQueryWindowRect(HWND_DESKTOP, &rctlScreen);
  84.  
  85.   rctl.xLeft = 0;
  86.   rctl.yBottom = 0;
  87.   rctl.xRight = WIN_WIDTH-1;
  88.   rctl.yTop = WIN_HEIGHT-1;
  89.   if (!WinCalcFrameRect(hwndFrame, &rctl, false))
  90.     err("Gfx test: WinCalcFrameRect() error");
  91.  
  92.   // now adjust position to make it centered on the screen
  93.   x = ((rctlScreen.xRight-rctlScreen.xLeft+1) - (rctl.xRight-rctl.xLeft+1))/2;
  94.   y = ((rctlScreen.yTop-rctlScreen.yBottom+1) - (rctl.yTop-rctl.yBottom+1))/2;
  95.  
  96.   w = rctl.xRight-rctl.xLeft+1;
  97.   h = rctl.yTop-rctl.yBottom+1;
  98.  
  99.   WinSetWindowPos( hwndFrame,      /* Shows and activates frame    */
  100.                    HWND_TOP,            /* window at position x,y  */
  101.                    x, y, w, h,         /* and size w,h     */
  102.                    SWP_SIZE | SWP_MOVE | SWP_SHOW
  103.                  );
  104.  
  105.   DosCreateThread(&paint_tid, (PFNTHREAD)paintfun, 0, 0, 64000);
  106.   while( WinGetMsg( bkHab, &qmsg, 0L, 0, 0 ) )
  107.     WinDispatchMsg( bkHab, &qmsg );
  108. }
  109.  
  110. static void Close(void) {
  111.   WinDestroyWindow(hwndFrame);           /* Tidy up...                   */
  112.   WinDestroyMsgQueue( hmq );             /* Tidy up...                   */
  113.   WinTerminate(bkHab);
  114. }
  115.  
  116. double pmb_gfx_vlines(void) {
  117.   Open((void*)paint_vlines);
  118.   Close();
  119.   return result;
  120. }
  121.  
  122. double pmb_gfx_dlines(void) {
  123.   Open((void*)paint_dlines);
  124.   Close();
  125.   return result;
  126. }
  127.  
  128. double pmb_gfx_hlines(void) {
  129.   Open((void*)paint_hlines);
  130.   Close();
  131.   return result;
  132. }
  133.  
  134. double pmb_gfx_bitblitss(void) {
  135.   Open((void*)paint_bitblitss);
  136.   Close();
  137.   return result;
  138. }
  139.  
  140. double pmb_gfx_bitblitms(void) {
  141.   Open((void*)paint_bitblitms);
  142.   Close();
  143.   return result;
  144. }
  145.  
  146. double pmb_gfx_textrender(void) {
  147.   Open((void*)paint_text);
  148.   Close();
  149.   return result;
  150. }
  151.  
  152. double pmb_gfx_fillrect(void) {
  153.   Open((void*)paint_fillrect);
  154.   Close();
  155.   return result;
  156. }
  157.  
  158. double pmb_gfx_patrect(void) {
  159.   Open((void*)paint_patrect);
  160.   Close();
  161.   return result;
  162. }
  163.  
  164. static MRESULT EXPENTRY
  165. GfxWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  166. {
  167.   switch( msg )
  168.   {
  169.     case WM_CREATE:
  170.       break;
  171.  
  172.     case WM_COMMAND:
  173.       break;
  174.  
  175.     case WM_ERASEBACKGROUND:
  176.       return (MRESULT)( FALSE ); // TRUE -> yes, erase the background
  177.  
  178.     case WM_PAINT:
  179.       {
  180.         HPS    hps;
  181.         RECTL  rc;
  182.         POINTL pt;
  183.  
  184.         hps = WinBeginPaint( hwnd, 0L, &rc );
  185.         GpiSetColor( hps, CLR_BLACK );      // colour of the text,
  186.         GpiSetBackColor( hps, CLR_BLACK );   // its background and
  187.         GpiSetBackMix( hps, BM_OVERPAINT );  // how it mixes,
  188.         GpiSetMix( hps, FM_OVERPAINT );  // how it mixes,
  189. //        WinFillRect(hps, &rc, CLR_BLACK);
  190.         WinEndPaint( hps );                  // Drawing is complete
  191.         break;
  192.       }
  193.     case WM_CLOSE:
  194.       exit(1); //WinPostMsg( hwnd, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  195.       break;
  196.     default:
  197.       return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  198.   }
  199.   return (MRESULT)FALSE;
  200. }
  201.  
  202. VOID APIENTRY paint_vlines(ULONG unused) {
  203.   HPS hps;
  204.   POINTL p1, p2;
  205.   double t1, t2;
  206.   RECTL rc;
  207.   s32 i, j, c, runs, runs_10;
  208.   int notstop = 1;
  209.  
  210.   hps = WinGetPS(hwndClient);
  211.   GpiSetBackMix( hps, BM_OVERPAINT );  // how it mixes,
  212.   GpiSetMix( hps, FM_OVERPAINT );  // how it mixes,
  213.   GpiSetColor(hps, CLR_WHITE);
  214.   GpiSetBackColor( hps, CLR_BLACK);
  215.   rc.xLeft = 0;
  216.   rc.xRight = WIN_WIDTH;
  217.   rc.yBottom = 0;
  218.   rc.yTop = WIN_HEIGHT;
  219.   WinFillRect(hps, &rc, CLR_BLACK);
  220.  
  221.   DosSleep(200);
  222.  
  223.   p1.x = WIN_WIDTH/2;
  224.   p1.y = 1;
  225.   p2.x = WIN_WIDTH/2;
  226.   p2.y = WIN_HEIGHT-2;
  227.   GpiMove(hps, &p1);
  228.   runs = RUN_NUM;
  229.   runs_10 = runs/10;
  230.   while(notstop) {
  231.     j = 0;
  232.     c = 0;
  233.     t1 = rtime();
  234.     for(i = 0; i < runs; i++) {
  235.       GpiLine(hps, &p2);
  236.       GpiLine(hps, &p1);
  237.       if (j++ == runs_10) {
  238.         GpiSetColor(hps, (c++)%6+1);
  239.         j = 0;
  240.       }
  241.     }
  242.     t2 = rtime();
  243.     test_time = (t2-t1);
  244.  
  245.     if (test_time < MIN_GFX_TIME)   /* if total time in test < min time */
  246.        {
  247.         if ((test_time) < MIN_MEASURE)  /* if total time in test < 0.1 */
  248.            {
  249.             runs = MIN_GFX_TIME/MIN_MEASURE*runs; /* increase number of runs by factor 100 */
  250.             runs_10 = runs/10;
  251.             }
  252.         else                         /* if 10 > total time in test > 0.1 */
  253.            {
  254.             runs = MIN_GFX_TIME*MARGINAL/(test_time)*runs; /* increase runs by enough to make tottime > 10 */
  255.             runs_10 = runs/10;
  256.             }
  257.         }
  258.     else                              /* if total time in test > 10 */
  259.      {
  260.       break;                          /* stop test */
  261.       }                               /* otherwise repeat with new run # */
  262.   }
  263.  
  264.   result = runs*2.0/(test_time)*(WIN_HEIGHT-2);
  265.   WinReleasePS(hps);
  266.   WinPostMsg( hwndClient, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  267. }
  268.  
  269. VOID APIENTRY paint_hlines(ULONG unused) {
  270.   HPS hps;
  271.   POINTL p1, p2;
  272.   RECTL rc;
  273.   double t1, t2;
  274.   s32 i, j, c, runs, runs_10;
  275.   int notstop = 1;
  276.  
  277.   hps = WinGetPS(hwndClient);
  278.   GpiSetBackMix( hps, BM_OVERPAINT );  // how it mixes,
  279.   GpiSetMix( hps, FM_OVERPAINT );  // how it mixes,
  280.   GpiSetColor(hps, CLR_WHITE);
  281.   GpiSetBackColor( hps, CLR_BLACK);
  282.   rc.xLeft = 0;
  283.   rc.xRight = WIN_WIDTH;
  284.   rc.yBottom = 0;
  285.   rc.yTop = WIN_HEIGHT;
  286.   WinFillRect(hps, &rc, CLR_BLACK);
  287.  
  288.   DosSleep(200);
  289.  
  290.   p1.x = (WIN_WIDTH - (WIN_HEIGHT-2))/2;
  291.   p1.y = WIN_HEIGHT/2;
  292.   p2.x = p1.x + WIN_HEIGHT - 3;
  293.   p2.y = WIN_HEIGHT/2;
  294.   GpiMove(hps, &p1);
  295.   runs = RUN_NUM;
  296.   runs_10 = runs/10;
  297.   while(notstop) {
  298.     j = 0;
  299.     c = 0;
  300.     t1 = rtime();
  301.     for(i = 0; i < runs; i++) {
  302.       GpiLine(hps, &p2);
  303.       GpiLine(hps, &p1);
  304.       if (j++ == runs_10) {
  305.         GpiSetColor(hps, (c++)%6+1);
  306.         j = 0;
  307.       }
  308.     }
  309.     t2 = rtime();
  310.  
  311.     test_time = (t2-t1);
  312.     if (test_time < MIN_GFX_TIME)   /* if total time in test < min time */
  313.        {
  314.         if ((test_time) < MIN_MEASURE)  /* if total time in test < 0.1 */
  315.            {
  316.             runs = MIN_GFX_TIME/MIN_MEASURE*runs; /* increase number of runs by factor 100 */
  317.             runs_10 = runs/10;
  318.             }
  319.         else                         /* if 10 > total time in test > 0.1 */
  320.            {
  321.             runs = MIN_GFX_TIME*MARGINAL/(test_time)*runs; /* increase runs by enough to make tottime > 10 */
  322.             runs_10 = runs/10;
  323.             }
  324.         }
  325.     else                              /* if total time in test > 10 */
  326.      {
  327.       break;                          /* stop test */
  328.       }                               /* otherwise repeat with new run # */
  329.   }
  330.  
  331.   result = runs*2.0/(test_time)*(p2.x-p1.x);
  332.   WinReleasePS(hps);
  333.   WinPostMsg( hwndClient, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  334. }
  335.  
  336. VOID APIENTRY paint_dlines(ULONG unused) {
  337.   HPS hps;
  338.   POINTL p1, p2;
  339.   RECTL rc;
  340.   double t1, t2;
  341.   s32 i, j, c, runs, runs_10;
  342.   int notstop = 1;
  343.  
  344.   hps = WinGetPS(hwndClient);
  345.   GpiSetBackMix( hps, BM_OVERPAINT );  // how it mixes,
  346.   GpiSetMix( hps, FM_OVERPAINT );  // how it mixes,
  347.   GpiSetColor(hps, CLR_WHITE);
  348.   GpiSetBackColor( hps, CLR_BLACK);
  349.  
  350.   rc.xLeft = 0;
  351.   rc.xRight = WIN_WIDTH;
  352.   rc.yBottom = 0;
  353.   rc.yTop = WIN_HEIGHT;
  354.   WinFillRect(hps, &rc, CLR_BLACK);
  355.   DosSleep(200);
  356.  
  357. /*
  358.   p1.x = (WIN_WIDTH - (WIN_HEIGHT-2))/2;
  359.   p1.y = WIN_HEIGHT/2;
  360.   p2.x = p1.x + WIN_HEIGHT - 3;
  361.   p2.y = WIN_HEIGHT/2;
  362. */
  363.  
  364.   p1.x = (WIN_WIDTH - (WIN_HEIGHT-2))/2;
  365.   p1.y = 1 + (WIN_HEIGHT/4);
  366.   p2.x = p1.x + WIN_HEIGHT - 3;
  367.   p2.y = WIN_HEIGHT-2 - WIN_HEIGHT/4;
  368.   GpiMove(hps, &p1);
  369.   runs = RUN_NUM;
  370.   runs_10 = runs/10;
  371.   while(notstop) {
  372.     j = 0;
  373.     c = 0;
  374.     t1 = rtime();
  375.     for(i = 0; i < runs; i++) {
  376.       GpiLine(hps, &p2);
  377.       GpiLine(hps, &p1);
  378.       if (j++ == runs_10) {
  379.         GpiSetColor(hps, (c++)%6+1);
  380.         j = 0;
  381.       }
  382.     }
  383.     t2 = rtime();
  384.     test_time = (t2-t1);
  385.     if (test_time < MIN_GFX_TIME)   /* if total time in test < min time */
  386.         {
  387.         if ((test_time) < MIN_MEASURE)  /* if total time in test < 0.1 */
  388.            {
  389.             runs = MIN_GFX_TIME/MIN_MEASURE*runs; /* increase number of runs by factor 100 */
  390.             runs_10 = runs/10;
  391.             }
  392.         else                         /* if 10 > total time in test > 0.1 */
  393.            {
  394.             runs = MIN_GFX_TIME*MARGINAL/(test_time)*runs; /* increase runs by enough to make tottime > 10 */
  395.             runs_10 = runs/10;
  396.             }
  397.         }
  398.     else                              /* if total time in test > 10 */
  399.      {
  400.       break;                          /* stop test */
  401.       }                               /* otherwise repeat with new run # */
  402.   }
  403.  
  404.  
  405.   result = runs*2.0/(test_time)*(WIN_HEIGHT-2);
  406.   WinReleasePS(hps);
  407.   WinPostMsg( hwndClient, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  408. }
  409.  
  410. // define size of blit rectangle
  411. #define BLIT_X 303 // not giving any special treatment to even numbered bitblits...
  412. #define BLIT_Y 303
  413.  
  414.  
  415. VOID APIENTRY paint_bitblitss(ULONG unused) {
  416.   HPS hps;
  417.   POINTL p1, p2;
  418.   RECTL rc;
  419.   double t1, t2;
  420.   s32 i, x, y, j, c, runs, runs_10;
  421.   POINTL tran[3];
  422.   int notstop = 1;
  423.  
  424.   hps = WinGetPS(hwndClient);
  425.   GpiSetBackMix( hps, BM_OVERPAINT );  // how it mixes,
  426.   GpiSetMix( hps, FM_OVERPAINT );  // how it mixes,
  427.   GpiSetColor(hps, CLR_WHITE);
  428.   GpiSetBackColor( hps, CLR_BLACK);
  429.  
  430.   DosSleep(200);
  431.  
  432.   runs = RUN_NUM;
  433.   while(notstop) {
  434.     // paint background pattern
  435.     rc.xLeft = 0;
  436.     rc.xRight = WIN_WIDTH;
  437.     rc.yBottom = 0;
  438.     rc.yTop = WIN_HEIGHT;
  439.     WinFillRect(hps, &rc, CLR_BLACK);
  440.     GpiSetColor(hps, CLR_PINK);
  441.     for (x = -WIN_HEIGHT; x < WIN_WIDTH; x += 20) {
  442.       p1.x = x;
  443.       p1.y = 0;
  444.       p2.x = x+WIN_HEIGHT-1;
  445.       p2.y = WIN_HEIGHT-1;
  446.       GpiMove(hps, &p1);
  447.       GpiLine(hps, &p2);
  448.     }
  449.     GpiSetColor(hps, CLR_YELLOW);
  450.     for (x = 0; x < (WIN_WIDTH+WIN_HEIGHT); x += 20) {
  451.       p1.x = x;
  452.       p1.y = 0;
  453.       p2.x = x-(WIN_HEIGHT-1);
  454.       p2.y = WIN_HEIGHT-1;
  455.       GpiMove(hps, &p1);
  456.       GpiLine(hps, &p2);
  457.     }
  458.     i = 0;
  459.     t1 = rtime();
  460.     while(notstop) {
  461.       tran[0].y = WIN_HEIGHT-BLIT_Y;
  462.       tran[1].y = WIN_HEIGHT;
  463.       tran[2].y = WIN_HEIGHT-BLIT_Y;
  464.       for (x = 1; x <= WIN_WIDTH-BLIT_X; x++) {
  465.         tran[0].x = x;
  466.         tran[1].x = x + BLIT_X;
  467.         tran[2].x = x-1;
  468.         GpiBitBlt(hps, hps, 3, tran, ROP_SRCCOPY, 0);
  469.         i++;
  470.         if (i == runs) {
  471.           goto done;
  472.         }
  473.       }
  474.       tran[0].x = WIN_WIDTH-BLIT_X;
  475.       tran[1].x = WIN_WIDTH;
  476.       tran[2].x = WIN_WIDTH-BLIT_X;
  477.       for (y = WIN_HEIGHT-BLIT_Y-1; y >= 0; y--) {
  478.         tran[0].y = y;
  479.         tran[1].y = y + BLIT_Y;
  480.         tran[2].y = y+1;
  481.         GpiBitBlt(hps, hps, 3, tran, ROP_SRCCOPY, 0);
  482.         i++;
  483.         if (i == runs) {
  484.           goto done;
  485.         }
  486.       }
  487.       tran[0].y = 0;
  488.       tran[1].y = BLIT_Y;
  489.       tran[2].y = 0;
  490.       for (x = WIN_WIDTH-BLIT_X-1; x >= 0; x--) {
  491.         tran[0].x = x;
  492.         tran[1].x = x + BLIT_X;
  493.         tran[2].x = x+1;
  494.         GpiBitBlt(hps, hps, 3, tran, ROP_SRCCOPY, 0);
  495.         i++;
  496.         if (i == runs) {
  497.           goto done;
  498.         }
  499.       }
  500.       tran[0].x = 0;
  501.       tran[1].x = BLIT_X;
  502.       tran[2].x = 0;
  503.       for (y = 1; y <= WIN_HEIGHT-BLIT_Y; y++) {
  504.         tran[0].y = y;
  505.         tran[1].y = y + BLIT_Y;
  506.         tran[2].y = y-1;
  507.         GpiBitBlt(hps, hps, 3, tran, ROP_SRCCOPY, 0);
  508.         i++;
  509.         if (i == runs) {
  510.           goto done;
  511.         }
  512.       }
  513.     }
  514. done:
  515.     t2 = rtime();
  516.     test_time = (t2-t1);
  517.     if (test_time < MIN_GFX_TIME)   /* if total time in test < min time */
  518.        {
  519.         if ((test_time) < MIN_MEASURE)  /* if total time in test < 0.1 */
  520.            {
  521.             runs = MIN_GFX_TIME/MIN_MEASURE*runs; /* increase number of runs by factor 100 */
  522.             runs_10 = runs/10;
  523.             }
  524.         else                         /* if 10 > total time in test > 0.1 */
  525.            {
  526.             runs = MIN_GFX_TIME*MARGINAL/(test_time)*runs; /* increase runs by enough to make tottime > 10 */
  527.             runs_10 = runs/10;
  528.             }
  529.         }
  530.     else                              /* if total time in test > 10 */
  531.      {
  532.       break;                          /* stop test */
  533.       }                               /* otherwise repeat with new run # */
  534.   }
  535.  
  536.   result = runs/(test_time)*(BLIT_X*BLIT_Y);
  537.   WinReleasePS(hps);
  538.   WinPostMsg( hwndClient, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  539. }
  540.  
  541.  
  542. // Memory -> screen bitblit
  543. VOID APIENTRY paint_bitblitms(ULONG unused) {
  544.   POINTL p1, p2;
  545.   RECTL rc;
  546.   double t1, t2;
  547.   s32 i, x, y, j, c, runs, runs_10;
  548.   POINTL tran[3];
  549.   SIZEL sizl;
  550.   HDC hdc, hdcMemory;
  551.   HPS hps, hpsMemory;
  552.   BITMAPINFOHEADER2 bmih;
  553.   HBITMAP hbm;
  554.   int notstop = 1;
  555.  
  556.   hps = WinGetPS(hwndClient);
  557.  
  558. /*  hdc = WinOpenWindowDC(hwndClient);
  559.   sizl.cx = 0;
  560.   sizl.cy = 0;
  561.   hps = GpiCreatePS(bkHab, hdc, &sizl,
  562.                     PU_PELS | GPIT_MICRO | GPIA_ASSOC | GPIF_DEFAULT);
  563. */
  564.   GpiSetBackMix( hps, BM_OVERPAINT );  // how it mixes,
  565.   GpiSetMix( hps, FM_OVERPAINT );  // how it mixes,
  566.   GpiSetColor(hps, CLR_WHITE);
  567.   GpiSetBackColor( hps, CLR_BLACK);
  568.  
  569.   /* Create presentation space for memory image of screen. */
  570.   hdcMemory = DevOpenDC(bkHab, OD_MEMORY, (PSZ) "*", 0L, 0L, 0L);
  571.   sizl.cx = 0;
  572.   sizl.cy = 0;
  573.   hpsMemory = GpiCreatePS(bkHab, hdcMemory, &sizl,
  574.                           PU_PELS | GPIT_MICRO | GPIA_ASSOC | GPIF_DEFAULT);
  575.  
  576.   /* Create bitmap for memory image of screen. */
  577.   memset(&bmih, 0, sizeof(bmih));
  578.   bmih.cbFix = sizeof(bmih);
  579.   bmih.cx = BLIT_X;
  580.   bmih.cy = BLIT_Y;
  581.   bmih.cPlanes = 1;
  582.   bmih.cBitCount = 8;
  583.   hbm = GpiCreateBitmap(hpsMemory, &bmih, 0L, NULL, NULL);
  584.   GpiSetBitmap(hpsMemory, hbm);
  585.  
  586.   DosSleep(200);
  587.  
  588.   runs = RUN_NUM;
  589.   while(notstop) {
  590.     // paint background pattern
  591.     rc.xLeft = 0;
  592.     rc.xRight = WIN_WIDTH;
  593.     rc.yBottom = 0;
  594.     rc.yTop = WIN_HEIGHT;
  595.     WinFillRect(hps, &rc, CLR_BLACK);
  596.     GpiSetColor(hps, CLR_GREEN);
  597.     for (x = -WIN_HEIGHT; x < WIN_WIDTH; x += 20) {
  598.       p1.x = x;
  599.       p1.y = 0;
  600.       p2.x = x+WIN_HEIGHT-1;
  601.       p2.y = WIN_HEIGHT-1;
  602.       GpiMove(hps, &p1);
  603.       GpiLine(hps, &p2);
  604.     }
  605.     GpiSetColor(hps, CLR_BLUE);
  606.     for (x = 0; x < (WIN_WIDTH+WIN_HEIGHT); x += 20) {
  607.       p1.x = x;
  608.       p1.y = 0;
  609.       p2.x = x-(WIN_HEIGHT-1);
  610.       p2.y = WIN_HEIGHT-1;
  611.       GpiMove(hps, &p1);
  612.       GpiLine(hps, &p2);
  613.     }
  614.  
  615.     tran[0].y = 0;
  616.     tran[1].y = BLIT_Y;
  617.     tran[2].y = WIN_HEIGHT-BLIT_Y;
  618.     tran[0].x = 0;
  619.     tran[1].x = BLIT_X;
  620.     tran[2].x = 0;
  621.  
  622.     GpiBitBlt(hpsMemory, hps, 3, tran, ROP_SRCCOPY, BBO_IGNORE);
  623.  
  624.     i = 0;
  625.     t1 = rtime();
  626.     while(notstop) {
  627.       tran[0].y = WIN_HEIGHT-BLIT_Y;
  628.       tran[1].y = WIN_HEIGHT;
  629.       tran[2].y = 0;
  630.       for (x = 1; x <= WIN_WIDTH-BLIT_X; x++) {
  631.         tran[0].x = x;
  632.         tran[1].x = x + BLIT_X;
  633.         tran[2].x = 0;
  634.         GpiBitBlt(hps, hpsMemory, 3, tran, ROP_SRCCOPY, BBO_IGNORE);
  635.         i++;
  636.         if (i == runs) {
  637.           goto done;
  638.         }
  639.       }
  640.       tran[0].x = WIN_WIDTH-BLIT_X;
  641.       tran[1].x = WIN_WIDTH;
  642.       tran[2].x = 0;
  643.       for (y = WIN_HEIGHT-BLIT_Y-1; y >= 0; y--) {
  644.         tran[0].y = y;
  645.         tran[1].y = y + BLIT_Y;
  646.         tran[2].y = 0;
  647.         GpiBitBlt(hps, hpsMemory, 3, tran, ROP_SRCCOPY, BBO_IGNORE);
  648.         i++;
  649.         if (i == runs) {
  650.           goto done;
  651.         }
  652.       }
  653.       tran[0].y = 0;
  654.       tran[1].y = BLIT_Y;
  655.       tran[2].y = 0;
  656.       for (x = WIN_WIDTH-BLIT_X-1; x >= 0; x--) {
  657.         tran[0].x = x;
  658.         tran[1].x = x + BLIT_X;
  659.         tran[2].x = 0;
  660.         GpiBitBlt(hps, hpsMemory, 3, tran, ROP_SRCCOPY, BBO_IGNORE);
  661.         i++;
  662.         if (i == runs) {
  663.           goto done;
  664.         }
  665.       }
  666.       tran[0].x = 0;
  667.       tran[1].x = BLIT_X;
  668.       tran[2].x = 0;
  669.       for (y = 1; y <= WIN_HEIGHT-BLIT_Y; y++) {
  670.         tran[0].y = y;
  671.         tran[1].y = y + BLIT_Y;
  672.         tran[2].y = 0;
  673.         GpiBitBlt(hps, hpsMemory, 3, tran, ROP_SRCCOPY, BBO_IGNORE);
  674.         i++;
  675.         if (i == runs) {
  676.           goto done;
  677.         }
  678.       }
  679.     }
  680. done:
  681.     t2 = rtime();
  682.     test_time = (t2-t1);
  683.     if (test_time < MIN_GFX_TIME)   /* if total time in test < min time */
  684.        {
  685.         if ((test_time) < MIN_MEASURE)  /* if total time in test < 0.1 */
  686.            {
  687.             runs = MIN_GFX_TIME/MIN_MEASURE*runs; /* increase number of runs by factor 100 */
  688.             runs_10 = runs/10;
  689.             }
  690.         else                         /* if 10 > total time in test > 0.1 */
  691.            {
  692.             runs = MIN_GFX_TIME*MARGINAL/(test_time)*runs; /* increase runs by enough to make tottime > 10 */
  693.             runs_10 = runs/10;
  694.             }
  695.         }
  696.     else                              /* if total time in test > 10 */
  697.      {
  698.       break;                          /* stop test */
  699.       }                               /* otherwise repeat with new run # */
  700.   }
  701.   result = runs/(test_time)*(BLIT_X*BLIT_Y);
  702.   WinReleasePS(hps);
  703. //  GpiDestroyPS(hpsMemory);
  704.   GpiDestroyPS(hps);
  705.   DevCloseDC(hdcMemory);
  706.   DevCloseDC(hdc);
  707.   GpiDeleteBitmap(hbm);
  708.   WinPostMsg( hwndClient, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  709. }
  710.  
  711. VOID APIENTRY paint_fillrect(ULONG unused) {
  712.   HPS hps;
  713.   POINTL p1, p2;
  714.   RECTL rc;
  715.   double t1, t2;
  716.   s32 i, j, c, runs, runs_10;
  717.   int notstop = 1;
  718.  
  719.   hps = WinGetPS(hwndClient);
  720.   GpiSetBackMix( hps, BM_OVERPAINT );  // how it mixes,
  721.   GpiSetMix( hps, FM_OVERPAINT );  // how it mixes,
  722.   GpiSetColor(hps, CLR_WHITE);
  723.   GpiSetBackColor( hps, CLR_BLACK);
  724.   rc.xLeft = 0;
  725.   rc.xRight = WIN_WIDTH;
  726.   rc.yBottom = 0;
  727.   rc.yTop = WIN_HEIGHT;
  728.   WinFillRect(hps, &rc, CLR_BLACK);
  729.  
  730.   DosSleep(200);
  731.  
  732.   p1.x = 1;
  733.   p1.y = 1;
  734.   p2.x = WIN_WIDTH-2;
  735.   p2.y = WIN_HEIGHT-2;
  736.   GpiMove(hps, &p1);
  737.   runs = RUN_NUM;
  738.   runs_10 = runs/10;
  739.   while(notstop) {
  740.     j = 0;
  741.     c = 0;
  742.     t1 = rtime();
  743.     for(i = 0; i < runs; i++) {
  744.       GpiBox(hps, DRO_FILL, &p2,0,0);
  745.       GpiBox(hps, DRO_FILL, &p1,0,0);
  746.       if (j++ == runs_10) {
  747.         GpiSetColor(hps, (c++)%6+1);
  748.         j = 0;
  749.       }
  750.     }
  751.     t2 = rtime();
  752.     test_time = (t2-t1);
  753.     if (test_time < MIN_GFX_TIME)   /* if total time in test < min time */
  754.        {
  755.         if ((test_time) < MIN_MEASURE)  /* if total time in test < 0.1 */
  756.            {
  757.             runs = MIN_GFX_TIME/MIN_MEASURE*runs; /* increase number of runs by factor 100 */
  758.             runs_10 = runs/10;
  759.             }
  760.         else                         /* if 10 > total time in test > 0.1 */
  761.            {
  762.             runs = MIN_GFX_TIME*MARGINAL/(test_time)*runs; /* increase runs by enough to make tottime > 10 */
  763.             runs_10 = runs/10;
  764.             }
  765.         }
  766.     else                              /* if total time in test > 10 */
  767.      {
  768.       break;                          /* stop test */
  769.       }                               /* otherwise repeat with new run # */
  770.   }
  771.  
  772.   result = runs*2.0/(test_time)*(WIN_HEIGHT-2)*(WIN_WIDTH-2);
  773.   WinReleasePS(hps);
  774.   WinPostMsg( hwndClient, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  775. }
  776.  
  777. VOID APIENTRY paint_patrect(ULONG unused) {
  778.   HPS hps;
  779.   POINTL p1, p2;
  780.   RECTL rc;
  781.   double t1, t2;
  782.   s32 i, j, c, runs, runs_10;
  783.   int notstop = 1;
  784.  
  785.   hps = WinGetPS(hwndClient);
  786.   GpiSetBackMix( hps, BM_OVERPAINT );  // how it mixes,
  787.   GpiSetMix( hps, FM_OVERPAINT );  // how it mixes,
  788.   GpiSetColor(hps, CLR_WHITE);
  789.   GpiSetBackColor( hps, CLR_WHITE);
  790. //  GpiSetPattern(hps, PATSYM_DIAG3);
  791.   GpiSetPattern(hps, PATSYM_HALFTONE);
  792.   rc.xLeft = 0;
  793.   rc.xRight = WIN_WIDTH;
  794.   rc.yBottom = 0;
  795.   rc.yTop = WIN_HEIGHT;
  796.   WinFillRect(hps, &rc, CLR_BLACK);
  797.  
  798.   DosSleep(200);
  799.  
  800.   p1.x = 1;
  801.   p1.y = 1;
  802.   p2.x = WIN_WIDTH-2;
  803.   p2.y = WIN_HEIGHT-2;
  804.   GpiMove(hps, &p1);
  805.   runs = RUN_NUM;
  806.   runs_10 = runs/10;
  807.  
  808.   while(notstop) {
  809.     j = 0;
  810.     c = 0;
  811.     t1 = rtime();
  812.     for(i = 0; i < runs; i++) {
  813.       GpiBox(hps, DRO_FILL, &p2,0,0);
  814.       GpiBox(hps, DRO_FILL, &p1,0,0);
  815.       if (j++ == runs_10) {
  816.         GpiSetColor(hps, (c++)%6+1);
  817.         j = 0;
  818.       }
  819.     }
  820.     t2 = rtime();
  821.     test_time = (t2-t1);
  822.     if (test_time < MIN_GFX_TIME)   /* if total time in test < min time */
  823.        {
  824.         if ((test_time) < MIN_MEASURE)  /* if total time in test < 0.1 */
  825.            {
  826.             runs = MIN_GFX_TIME/MIN_MEASURE*runs; /* increase number of runs by factor 100 */
  827.             runs_10 = runs/10;
  828.             }
  829.         else                         /* if 10 > total time in test > 0.1 */
  830.            {
  831.             runs = MIN_GFX_TIME*MARGINAL/(test_time)*runs; /* increase runs by enough to make tottime > 10 */
  832.             runs_10 = runs/10;
  833.             }
  834.         }
  835.     else                              /* if total time in test > 10 */
  836.      {
  837.       break;                          /* stop test */
  838.       }                               /* otherwise repeat with new run # */
  839.   }
  840.   result = runs*2.0/(test_time)*(WIN_HEIGHT-2)*(WIN_WIDTH-2);
  841.   WinReleasePS(hps);
  842.   WinPostMsg( hwndClient, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  843. }
  844.  
  845. VOID APIENTRY paint_text(ULONG unused) {
  846.   RECTL rc;
  847.   HPS hps;
  848.   FATTRS fat;
  849.   LONG match;
  850.   FONTMETRICS fmMetrics;
  851.   s32 fontw, fonth, row, col, xoff, yoff, slen;
  852.   RECTL printRect, winRect;
  853.   char* string = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789-+!@#$%^&*()";
  854.   POINTL p1;
  855.   double t1, t2;
  856.   s32 i, j, c, runs, runs_10;
  857.   s32 dlen;
  858.   char tmp[256];
  859.   s32 flag;
  860.   int notstop = 1;
  861.  
  862.   hps = WinGetPS(hwndClient);
  863.   GpiSetBackMix( hps, BM_OVERPAINT );  // how it mixes,
  864.   GpiSetMix( hps, FM_OVERPAINT );  // how it mixes,
  865.   GpiSetColor(hps, CLR_BLACK);
  866.   GpiSetBackColor( hps, CLR_WHITE);
  867.   rc.xLeft = 0;
  868.   rc.xRight = WIN_WIDTH;
  869.   rc.yBottom = 0;
  870.   rc.yTop = WIN_HEIGHT;
  871.   WinFillRect(hps, &rc, CLR_WHITE);
  872.  
  873.   WinQueryWindowRect(hwndClient, &winRect);
  874.  
  875.   // selecting fonts is a mess...
  876.  
  877.   fat.usRecordLength = sizeof(FATTRS); /* sets size of structure   */
  878.   fat.fsSelection = 0;         /* uses default selection           */
  879.   fat.lMatch = 0L;             /* does not force match             */
  880.   fat.idRegistry = 0;          /* uses default registry            */
  881.   fat.usCodePage = 850;        /* code-page 850                    */
  882.   fat.lMaxBaselineExt = 16L;   /* requested font height is 12 pels */
  883.   fat.lAveCharWidth = 8L;      /* requested font width is 12 pels  */
  884.   fat.fsType = 0;              /* uses default type                */
  885.   fat.fsFontUse = FATTR_FONTUSE_NOMIX;/* doesn't mix with graphics */
  886.  
  887.   /* "System Monospaced": valid lAveCharWidth, lMaxBaselineExt pairs: (8,8), (8,12), (8,16), (9,20)
  888.      "System VIO": valid lAveCharWidth, lMaxBaselineExt pairs: (8,16) (8,12) ...
  889.    */
  890.  
  891. //  strcpy(fat.szFacename ,"System Monospaced");
  892.   strcpy(fat.szFacename ,"System VIO");
  893. //  strcpy(fat.szFacename ,"Times Rmn");
  894.  
  895.   match = GpiCreateLogFont(hps,        /* presentation space               */
  896.                            NULL,       /* does not use logical font name   */
  897.                            1L,         /* local identifier                 */
  898.                            &fat);      /* structure with font attributes   */
  899.  
  900.   // match should now be 2 == FONT_MATCH */
  901.  
  902.   if (match != 2) {
  903.     logit("Can't get the right font, text render benchmark");
  904.     exit(1);
  905.   }
  906.  
  907.   GpiSetCharSet(hps, 1L);      /* sets font for presentation space */
  908.   GpiQueryFontMetrics ( hps,
  909.                         sizeof ( fmMetrics ) ,
  910.                         &fmMetrics ) ;
  911.   fonth = fmMetrics.lMaxBaselineExt;
  912.   fontw = fmMetrics.lMaxCharInc;
  913.  
  914.   col = 0;
  915.   row = 0;
  916.  
  917.   slen = strlen(string);
  918.   p1.x = 32;
  919.   p1.y = 50;
  920.   DosSleep(200);
  921.   GpiMove(hps, &p1);
  922.   GpiCharString(hps, slen, string);
  923.   flag = GpiQueryCurrentPosition(hps, &p1);
  924.   dlen = p1.x - 30;
  925.   if (p1.x > winRect.xRight) {
  926.     warn("The test string will be too long to fit inside the window. Benchmark result will not be reliable");
  927.   }
  928.   runs = RUN_NUM;
  929.   runs_10 = runs/10;
  930.   xoff = 0;
  931.   yoff = 0;
  932.   while(notstop) {
  933.     t1 = rtime();
  934.     for(i = 0; i < runs; i++) {
  935.       p1.x = xoff++ % 29 + 3;
  936.       yoff += fonth + 3;
  937.       p1.y = WIN_HEIGHT - (yoff % (WIN_HEIGHT - 3*fonth) + 2*fonth);
  938.       GpiCharStringAt(hps, &p1, slen, string);
  939.     }
  940.     xoff = yoff = 0;
  941.     t2 = rtime();
  942.     test_time = (t2-t1);
  943.     if (test_time < MIN_GFX_TIME)   /* if total time in test < min time */
  944.        {
  945.         if ((test_time) < MIN_MEASURE)  /* if total time in test < 0.1 */
  946.            {
  947.             runs = MIN_GFX_TIME/MIN_MEASURE*runs; /* increase number of runs by factor 100 */
  948.             runs_10 = runs/10;
  949.             }
  950.         else                         /* if 10 > total time in test > 0.1 */
  951.            {
  952.             runs = MIN_GFX_TIME*MARGINAL/(test_time)*runs; /* increase runs by enough to make tottime > 10 */
  953.             runs_10 = runs/10;
  954.             }
  955.         }
  956.     else                              /* if total time in test > 10 */
  957.      {
  958.       break;                          /* stop test */
  959.       }                               /* otherwise repeat with new run # */
  960.   }
  961.   result = runs*dlen*fonth/(test_time);
  962.   WinReleasePS(hps);
  963.   WinPostMsg( hwndClient, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  964. }
  965.  
  966.