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