1 /**
2  ** speedtst.c ---- check all available frame drivers speed
3  **
4  ** Copyright (c) 1995 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221
5  ** [e-mail: csaba@vuse.vanderbilt.edu]
6  **
7  ** This is a test/demo file of the GRX graphics library.
8  ** You can use GRX test/demo files as you want.
9  **
10  ** The GRX graphics library is free software; you can redistribute it
11  ** and/or modify it under some conditions; see the "copying.grx" file
12  ** for details.
13  **
14  ** This library is distributed in the hope that it will be useful,
15  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17  **
18  ** 070512 M.Alvarez, new version more accurate, but still had problems
19  **                   in X11, because functions returns before the paint
20  **                   is done.
21  **/
22 
23 #include <string.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <ctype.h>
27 #include <assert.h>
28 #ifdef __WATCOMC__
29 /*#include <wcdefs.h>*/
30 #include <conio.h>
31 #else
32 #include <limits.h>
33 #endif
34 #include <math.h>
35 #include "rand.h"
36 
37 #include "grx20.h"
38 
39 #if GRX_VERSION_API-0 <= 0x0220
40 #define GrColor unsigned long
41 #define BLIT_FAIL(gp) ((gp)->fm!=GR_frameVGA8X)
42 #else
43 #define BLIT_FAIL(gp)  0
44 #endif
45 
46 #define MEASURE_RAM_MODES 1
47 
48 #define READPIX_loops      (384*1)
49 #define READPIX_X11_loops  (4*1)
50 #define DRAWPIX_loops      (256*1)
51 #define DRAWLIN_loops      (12*1)
52 #define DRAWHLIN_loops     (16*1)
53 #define DRAWVLIN_loops     (12*1)
54 #define DRAWBLK_loops      (1*1)
55 #define BLIT_loops         (1*1)
56 
57 typedef struct {
58     double rate, count;
59 } perfm;
60 
61 typedef struct {
62     GrFrameMode fm;
63     int    w,h,bpp;
64     int    flags;
65     perfm  readpix;
66     perfm  drawpix;
67     perfm  drawlin;
68     perfm  drawhlin;
69     perfm  drawvlin;
70     perfm  drawblk;
71     perfm  blitv2v;
72     perfm  blitv2r;
73     perfm  blitr2v;
74 } gvmode;
75 #define FLG_measured 0x0001
76 #define FLG_tagged   0x0002
77 #define FLG_rammode  0x0004
78 #define MEASURED(g) (((g)->flags&FLG_measured)!=0)
79 #define TAGGED(g)   (((g)->flags&FLG_tagged)!=0)
80 #define RAMMODE(g)  (((g)->flags&FLG_rammode)!=0)
81 #define SET_MEASURED(g)  (g)->flags |= FLG_measured
82 #define SET_TAGGED(g)    (g)->flags |= FLG_tagged
83 #define SET_RAMMODE(g)   (g)->flags |= FLG_rammode
84 #define TOGGLE_TAGGED(g) (g)->flags ^= FLG_tagged
85 
86 int  nmodes = 0;
87 #define MAX_MODES 256
88 gvmode *grmodes = NULL;
89 #if MEASURE_RAM_MODES
90 gvmode *rammodes = NULL;
91 #endif
92 
93 /* No of Points [(x,y) pairs]. Must be multiple of 2*3=6 */
94 #define PAIRS 4200
95 
96 #define UL(x)  ((unsigned long)(x))
97 #define DBL(x)  ((double)(x))
98 #define INT(x) ((int)(x))
99 
100 #ifndef min
101 #define min(a,b) ((a)<(b) ? (a) : (b))
102 #endif
103 #ifndef max
104 #define max(a,b) ((a)>(b) ? (a) : (b))
105 #endif
106 
107 typedef struct XYpairs {
108   int x[PAIRS];
109   int y[PAIRS];
110   int w, h;
111   struct XYpairs *nxt;
112 } XY_PAIRS;
113 
114 XY_PAIRS *xyp = NULL;
115 int *xb = NULL, *yb = NULL; /* need sorted pairs for block operations */
116 int measured_any = 0;
117 
checkpairs(int w,int h)118 XY_PAIRS *checkpairs(int w, int h) {
119   XY_PAIRS *res = xyp;
120   int i;
121 
122   if (xb == NULL) {
123     xb = malloc(sizeof(int) * PAIRS);
124     yb = malloc(sizeof(int) * PAIRS);
125   }
126 
127   while (res != NULL) {
128     if (res->w == w && res->h == h)
129       return res;
130     res = res->nxt;
131   }
132 
133   SRND(12345);
134 
135   res = malloc(sizeof(XY_PAIRS));
136   assert(res != NULL);
137   res->w = w;
138   res->h = h;
139   res->nxt = xyp;
140   xyp = res;
141   for (i=0; i < PAIRS; ++i) {
142     int x = RND() % w;
143     int y = RND() % h;
144     if (x < 0) x = 0; else
145     if (x >=w) x = w-1;
146     if (y < 0) y = 0; else
147     if (y >=h) y = h-1;
148     res->x[i] = x;
149     res->y[i] = y;
150   }
151   return res;
152 }
153 
SQR(int a,int b)154 double SQR(int a, int b) {
155   double r = DBL(a-b);
156   return r*r;
157 }
158 
ABS(int a,int b)159 double ABS(int a, int b) {
160   double r = DBL(a-b);
161   return fabs(r);
162 }
163 
FrameDriverName(GrFrameMode m)164 char *FrameDriverName(GrFrameMode m) {
165 
166 #if GRX_VERSION_API-0 >= 0x0229
167   unsigned sys = GrGetLibrarySystem();
168 #else
169   unsigned sys = (unsigned) GRX_VERSION;
170 #endif
171 
172   int x11 = ( (sys == GRX_VERSION_GENERIC_X11) ||
173               (sys == GRX_VERSION_GCC_386_X11) ||
174               (sys == GRX_VERSION_GCC_X86_64_X11) );
175   int w32 = ( (sys == GRX_VERSION_GCC_386_WIN32) ||
176               (sys == GRX_VERSION_MSC_386_WIN32) ||
177 	      (sys == GRX_VERSION_GCC_386_CYG32) );
178   int sdl = strcmp( GrCurrentVideoDriver()->name , "sdl") == 0;
179 
180   switch(m) {
181     case GR_frameUndef: return "Undef";
182     case GR_frameText : return "Text";
183     case GR_frameHERC1: return "HERC1";
184     case GR_frameEGAVGA1: return x11 ? "XWIN1" : w32 ? "WIN32_1" : "EGAVGA1";
185     case GR_frameEGA4: return "EGA4";
186     case GR_frameSVGA4: return x11 ? "XWIN4" : w32 ? "WIN32_4" : "SVGA4";
187     case GR_frameSVGA8: return sdl ? "SDL8" : x11 ? "XWIN8" : w32 ? "WIN32_8" : "SVGA8";
188     case GR_frameVGA8X: return "VGA8X";
189     case GR_frameSVGA16: return sdl ? "SDL16" : x11 ? "XWIN16" : w32 ? "WIN32_16" : "SVGA16";
190     case GR_frameSVGA24: return sdl ? "SDL24" : x11 ? "XWIN24" : w32 ? "WIN32_24" : "SVGA24";
191     case GR_frameSVGA32L: return sdl ? "SDL32L" : x11 ? "XWIN32L" : w32 ? "WIN32_32L" : "SVGA32L";
192     case GR_frameSVGA32H: return sdl ? "SDL32H" : x11 ? "XWIN32H" : w32 ? "WIN32_32H" : "SVGA32H";
193     case GR_frameSVGA8_LFB: return "LFB8";
194     case GR_frameSVGA16_LFB: return "LFB16";
195     case GR_frameSVGA24_LFB: return "LFB24";
196     case GR_frameSVGA32L_LFB: return "LFB32L";
197     case GR_frameSVGA32H_LFB: return "LFB32H";
198     case GR_frameRAM1: return "RAM1";
199     case GR_frameRAM4: return "RAM4";
200     case GR_frameRAM8: return "RAM8";
201     case GR_frameRAM16: return "RAM16";
202     case GR_frameRAM24: return "RAM24";
203     case GR_frameRAM32L: return "RAM32L";
204     case GR_frameRAM32H: return "RAM32H";
205     case GR_frameRAM3x8: return "RAM3x8";
206     default: return "UNKNOWN";
207   }
208   return "UNKNOWN";
209 }
210 
Message(int disp,char * txt,gvmode * gp)211 void Message(int disp, char *txt, gvmode *gp) {
212   char msg[200];
213   sprintf(msg, "%s: %d x %d x %dbpp",
214 		FrameDriverName(gp->fm), gp->w, gp->h, gp->bpp);
215 #if GRX_VERSION_API-0 >= 0x0229
216   unsigned sys = GrGetLibrarySystem();
217 #else
218   unsigned sys = (unsigned) GRX_VERSION;
219 #endif
220   if ( (sys == GRX_VERSION_GENERIC_X11) ||
221        (sys == GRX_VERSION_GCC_386_X11) ||
222        (sys == GRX_VERSION_GCC_X86_64_X11) )
223     fprintf(stderr,"%s\t%s\n", msg, txt);
224   if (disp) {
225     GrTextOption to;
226     GrContext save;
227     GrSaveContext(&save);
228     GrSetContext(NULL);
229     to.txo_font = &GrFont_PC6x8;
230     to.txo_fgcolor.v = GrWhite();
231     to.txo_bgcolor.v = GrBlack();
232     to.txo_chrtype = GR_BYTE_TEXT;
233     to.txo_direct  = GR_TEXT_RIGHT;
234     to.txo_xalign  = GR_ALIGN_LEFT;
235     to.txo_yalign  = GR_ALIGN_TOP;
236     GrDrawString(msg,strlen(msg),0,0,&to);
237     GrDrawString(txt,strlen(txt),0,10,&to);
238     GrSetContext(&save);
239   }
240 }
241 
printresultheader(FILE * f)242 void printresultheader(FILE *f) {
243   fprintf(f, "Driver               readp drawp line   hline vline  block  v2v    v2r    r2v\n");
244 }
245 
printresultline(FILE * f,gvmode * gp)246 void printresultline(FILE *f, gvmode * gp) {
247   fprintf(f, "%-9s %4dx%4d ", FrameDriverName(gp->fm), gp->w, gp->h);
248   fprintf(f, "%6.2f", gp->readpix.rate  / (1024.0 * 1024.0));
249   fprintf(f, "%6.2f", gp->drawpix.rate  / (1024.0 * 1024.0));
250   fprintf(f, "%6.2f", gp->drawlin.rate  / (1024.0 * 1024.0));
251   fprintf(f, "%7.2f", gp->drawhlin.rate / (1024.0 * 1024.0));
252   fprintf(f, "%6.2f", gp->drawvlin.rate / (1024.0 * 1024.0));
253   fprintf(f, "%7.2f", gp->drawblk.rate  / (1024.0 * 1024.0));
254   fprintf(f, "%7.2f", gp->blitv2v.rate  / (1024.0 * 1024.0));
255   fprintf(f, "%7.2f", gp->blitv2r.rate  / (1024.0 * 1024.0));
256   fprintf(f, "%7.2f", gp->blitr2v.rate  / (1024.0 * 1024.0));
257   fprintf(f, "\n");
258 }
259 
readpixeltest(gvmode * gp,XY_PAIRS * pairs,int loops)260 void readpixeltest(gvmode *gp, XY_PAIRS *pairs,int loops) {
261   int i, j;
262   long t1,t2;
263   double seconds;
264   int *x = pairs->x;
265   int *y = pairs->y;
266 
267   if (!MEASURED(gp)) {
268     gp->readpix.rate  = 0.0;
269     gp->readpix.count = DBL(PAIRS) * DBL(loops);
270   }
271 
272   t1 = GrMsecTime();
273   for (i=loops; i > 0; --i) {
274     for (j=PAIRS-1; j >= 0; j--)
275        GrPixelNC(x[j],y[j]);
276   }
277   t2 = GrMsecTime();
278   seconds = (double)(t2 - t1) / 1000.0;
279   if (seconds > 0)
280     gp->readpix.rate = gp->readpix.count / seconds;
281 }
282 
drawpixeltest(gvmode * gp,XY_PAIRS * pairs)283 void drawpixeltest(gvmode *gp, XY_PAIRS *pairs) {
284   int i, j;
285   GrColor c1 = GrWhite();
286   GrColor c2 = GrWhite() | GrXOR;
287   GrColor c3 = GrWhite() | GrOR;
288   GrColor c4 = GrBlack() | GrAND;
289   long t1,t2;
290   double seconds;
291   int *x = pairs->x;
292   int *y = pairs->y;
293 
294   if (!MEASURED(gp)) {
295     gp->drawpix.rate  = 0.0;
296     gp->drawpix.count = DBL(PAIRS) * DBL(DRAWPIX_loops) * 4.0;
297   }
298 
299   t1 = GrMsecTime();
300   for (i=0; i < DRAWPIX_loops; ++i) {
301     for (j=PAIRS-1; j >= 0; j--) GrPlotNC(x[j],y[j],c1);
302     for (j=PAIRS-1; j >= 0; j--) GrPlotNC(x[j],y[j],c2);
303     for (j=PAIRS-1; j >= 0; j--) GrPlotNC(x[j],y[j],c3);
304     for (j=PAIRS-1; j >= 0; j--) GrPlotNC(x[j],y[j],c4);
305   }
306   t2 = GrMsecTime();
307   seconds = (double)(t2 - t1) / 1000.0;
308   if (seconds > 0)
309     gp->drawpix.rate = gp->drawpix.count / seconds;
310 }
311 
drawlinetest(gvmode * gp,XY_PAIRS * pairs)312 void drawlinetest(gvmode *gp, XY_PAIRS *pairs) {
313   int i, j;
314   int *x = pairs->x;
315   int *y = pairs->y;
316   GrColor c1 = GrWhite();
317   GrColor c2 = GrWhite() | GrXOR;
318   GrColor c3 = GrWhite() | GrOR;
319   GrColor c4 = GrBlack() | GrAND;
320   long t1,t2;
321   double seconds;
322 
323   if (!MEASURED(gp)) {
324     gp->drawlin.rate  = 0.0;
325     gp->drawlin.count = 0.0;
326     for (j=0; j < PAIRS; j+=2)
327       gp->drawlin.count += sqrt(SQR(x[j],x[j+1])+SQR(y[j],y[j+1]));
328     gp->drawlin.count *= 4.0 * DRAWLIN_loops;
329   }
330 
331   t1 = GrMsecTime();
332   for (i=0; i < DRAWLIN_loops; ++i) {
333     for (j=PAIRS-2; j >= 0; j-=2)
334 	GrLineNC(x[j],y[j],x[j+1],y[j+1],c1);
335     for (j=PAIRS-2; j >= 0; j-=2)
336 	GrLineNC(x[j],y[j],x[j+1],y[j+1],c2);
337     for (j=PAIRS-2; j >= 0; j-=2)
338 	GrLineNC(x[j],y[j],x[j+1],y[j+1],c3);
339     for (j=PAIRS-2; j >= 0; j-=2)
340 	GrLineNC(x[j],y[j],x[j+1],y[j+1],c4);
341   }
342   t2 = GrMsecTime();
343   seconds = (double)(t2 - t1) / 1000.0;
344   if (seconds > 0)
345     gp->drawlin.rate = gp->drawlin.count / seconds;
346 }
347 
drawhlinetest(gvmode * gp,XY_PAIRS * pairs)348 void drawhlinetest(gvmode *gp, XY_PAIRS *pairs) {
349   int  i, j;
350   int *x = pairs->x;
351   int *y = pairs->y;
352   GrColor c1 = GrWhite();
353   GrColor c2 = GrWhite() | GrXOR;
354   GrColor c3 = GrWhite() | GrOR;
355   GrColor c4 = GrBlack() | GrAND;
356   long t1,t2;
357   double seconds;
358 
359   if (!MEASURED(gp)) {
360     gp->drawhlin.rate = 0.0;
361     gp->drawhlin.count = 0.0;
362     for (j=0; j < PAIRS; j+=2)
363       gp->drawhlin.count += ABS(x[j],x[j+1]);
364     gp->drawhlin.count *= 4.0 * DRAWHLIN_loops;
365   }
366 
367   t1 = GrMsecTime();
368   for (i=0; i < DRAWHLIN_loops; ++i) {
369     for (j=PAIRS-2; j >= 0; j-=2)
370       GrHLineNC(x[j],x[j+1],y[j],c1);
371     for (j=PAIRS-2; j >= 0; j-=2)
372       GrHLineNC(x[j],x[j+1],y[j],c2);
373     for (j=PAIRS-2; j >= 0; j-=2)
374       GrHLineNC(x[j],x[j+1],y[j],c3);
375     for (j=PAIRS-2; j >= 0; j-=2)
376       GrHLineNC(x[j],x[j+1],y[j],c4);
377   }
378   t2 = GrMsecTime();
379   seconds = (double)(t2 - t1) / 1000.0;
380   if (seconds > 0)
381     gp->drawhlin.rate = gp->drawhlin.count / seconds;
382 }
383 
drawvlinetest(gvmode * gp,XY_PAIRS * pairs)384 void drawvlinetest(gvmode *gp, XY_PAIRS *pairs) {
385   int i, j;
386   int *x = pairs->x;
387   int *y = pairs->y;
388   GrColor c1 = GrWhite();
389   GrColor c2 = GrWhite() | GrXOR;
390   GrColor c3 = GrWhite() | GrOR;
391   GrColor c4 = GrBlack() | GrAND;
392   long t1,t2;
393   double seconds;
394 
395   if (!MEASURED(gp)) {
396     gp->drawvlin.rate = 0.0;
397     gp->drawvlin.count = 0.0;
398     for (j=0; j < PAIRS; j+=2)
399       gp->drawvlin.count += ABS(y[j],y[j+1]);
400     gp->drawvlin.count *= 4.0 * DRAWVLIN_loops;
401   }
402 
403   t1 = GrMsecTime();
404   for (i=0; i < DRAWVLIN_loops; ++i) {
405     for (j=PAIRS-2; j >= 0; j-=2)
406        GrVLineNC(x[j],y[j],y[j+1],c1);
407     for (j=PAIRS-2; j >= 0; j-=2)
408        GrVLineNC(x[j],y[j],y[j+1],c2);
409     for (j=PAIRS-2; j >= 0; j-=2)
410        GrVLineNC(x[j],y[j],y[j+1],c3);
411     for (j=PAIRS-2; j >= 0; j-=2)
412        GrVLineNC(x[j],y[j],y[j+1],c4);
413   }
414   t2 = GrMsecTime();
415   seconds = (double)(t2 - t1) / 1000.0;
416   if (seconds > 0)
417     gp->drawvlin.rate = gp->drawvlin.count / seconds;
418 }
419 
drawblocktest(gvmode * gp,XY_PAIRS * pairs)420 void drawblocktest(gvmode *gp, XY_PAIRS *pairs) {
421   int i, j;
422   GrColor c1 = GrWhite();
423   GrColor c2 = GrWhite() | GrXOR;
424   GrColor c3 = GrWhite() | GrOR;
425   GrColor c4 = GrBlack() | GrAND;
426   long t1,t2;
427   double seconds;
428 
429   if (xb == NULL || yb == NULL) return;
430 
431   for (j=0; j < PAIRS; j+=2) {
432     xb[j]   = min(pairs->x[j],pairs->x[j+1]);
433     xb[j+1] = max(pairs->x[j],pairs->x[j+1]);
434     yb[j]   = min(pairs->y[j],pairs->y[j+1]);
435     yb[j+1] = max(pairs->y[j],pairs->y[j+1]);
436   }
437 
438   if (!MEASURED(gp)) {
439     gp->drawblk.rate = 0.0;
440     gp->drawblk.count = 0.0;
441     for (j=0; j < PAIRS; j+=2)
442       gp->drawblk.count += ABS(xb[j],xb[j+1]) * ABS(yb[j],yb[j+1]);
443     gp->drawblk.count *= 4.0 * DRAWBLK_loops;
444   }
445 
446   t1 = GrMsecTime();
447   for (i=0; i < DRAWBLK_loops; ++i) {
448     for (j=PAIRS-2; j >= 0; j-=2)
449       GrFilledBoxNC(xb[j],yb[j],xb[j+1],yb[j+1],c1);
450     for (j=PAIRS-2; j >= 0; j-=2)
451       GrFilledBoxNC(xb[j],yb[j],xb[j+1],yb[j+1],c2);
452     for (j=PAIRS-2; j >= 0; j-=2)
453       GrFilledBoxNC(xb[j],yb[j],xb[j+1],yb[j+1],c3);
454     for (j=PAIRS-2; j >= 0; j-=2)
455       GrFilledBoxNC(xb[j],yb[j],xb[j+1],yb[j+1],c4);
456   }
457   t2 = GrMsecTime();
458   seconds = (double)(t2 - t1) / 1000.0;
459   if (seconds > 0)
460     gp->drawblk.rate = gp->drawblk.count / seconds;
461 }
462 
xor_draw_blocks(GrContext * c)463 void xor_draw_blocks(GrContext *c) {
464   GrContext save;
465   int i;
466 
467   GrSaveContext(&save);
468   GrSetContext(c);
469   GrClearContext(GrBlack());
470   for (i=28; i > 1; --i)
471     GrFilledBox(GrMaxX()/i,GrMaxY()/i,
472 		(i-1)*GrMaxX()/i,(i-1)*GrMaxY()/i,GrWhite()|GrXOR);
473   GrSetContext(&save);
474 }
475 
blit_measure(gvmode * gp,perfm * p,int * xb,int * yb,GrContext * dst,GrContext * src)476 void blit_measure(gvmode *gp, perfm *p,
477 		  int *xb, int *yb,
478 		  GrContext *dst,GrContext *src) {
479   int i, j;
480   long t1,t2;
481   double seconds;
482   GrContext save;
483 
484   GrSaveContext(&save);
485   if (dst != src) {
486     GrSetContext(dst);
487     GrClearContext(GrBlack());
488   }
489   xor_draw_blocks(src);
490   GrSetContext(&save);
491 
492   if (dst != NULL) {
493     char *s = src != NULL ? "ram" : "video";
494     char *d = dst != NULL ? "ram" : "video";
495     char txt[50];
496     sprintf(txt, "blit test: %s -> %s", s, d);
497     Message(1,txt, gp);
498   }
499 
500   t1 = GrMsecTime();
501   for (i=0; i < BLIT_loops; ++i) {
502     for (j=PAIRS-3; j >= 0; j-=3)
503       GrBitBlt(dst,xb[j+2],yb[j+2],src,xb[j+1],yb[j+1],xb[j],yb[j],GrWRITE);
504     for (j=PAIRS-3; j >= 0; j-=3)
505       GrBitBlt(dst,xb[j+2],yb[j+2],src,xb[j+1],yb[j+1],xb[j],yb[j],GrXOR);
506     for (j=PAIRS-3; j >= 0; j-=3)
507       GrBitBlt(dst,xb[j+2],yb[j+2],src,xb[j+1],yb[j+1],xb[j],yb[j],GrOR);
508     for (j=PAIRS-3; j >= 0; j-=3)
509       GrBitBlt(dst,xb[j+2],yb[j+2],src,xb[j+1],yb[j+1],xb[j],yb[j],GrAND);
510   }
511   t2 = GrMsecTime();
512   seconds = (double)(t2 - t1) / 1000.0;
513   if (seconds > 0)
514     p->rate = p->count / seconds;
515 }
516 
blittest(gvmode * gp,XY_PAIRS * pairs,int ram)517 void blittest(gvmode *gp, XY_PAIRS *pairs, int ram) {
518   int j;
519 
520   if (xb == NULL || yb == NULL) return;
521 
522   for (j=0; j < PAIRS; j+=3) {
523     int wh;
524     xb[j]   = max(pairs->x[j],pairs->x[j+1]);
525     xb[j+1] = min(pairs->x[j],pairs->x[j+1]);
526     xb[j+2] = pairs->x[j+2];
527     wh      = xb[j]-xb[j+1];
528     if (xb[j+2]+wh >= gp->w) xb[j+2] = gp->w - wh - 1;
529     yb[j]   = max(pairs->y[j],pairs->y[j+1]);
530     yb[j+1] = min(pairs->y[j],pairs->y[j+1]);
531     yb[j+2] = pairs->y[j+2];
532     wh      = yb[j]-yb[j+1];
533     if (yb[j+2]+wh >= gp->h) yb[j+2] = gp->h - wh - 1;
534   }
535 
536   if (!MEASURED(gp)) {
537     double count = 0.0;
538     for (j=0; j < PAIRS; j+=3)
539       count += ABS(xb[j],xb[j+1]) * ABS(yb[j],yb[j+1]);
540     gp->blitv2v.count =
541     gp->blitr2v.count =
542     gp->blitv2r.count = count * 4.0 * BLIT_loops;
543     gp->blitv2v.rate  =
544     gp->blitr2v.rate  =
545     gp->blitv2r.rate  = 0.0;
546   }
547 
548 #if BLIT_loops-0
549   blit_measure(gp, &gp->blitv2v, xb, yb,
550 	       (GrContext *)(RAMMODE(gp) ? GrCurrentContext() : NULL),
551 	       (GrContext *)(RAMMODE(gp) ? GrCurrentContext() : NULL));
552   if (!BLIT_FAIL(gp) && !ram) {
553     GrContext rc;
554     GrContext *rcp = GrCreateContext(gp->w,gp->h,NULL,&rc);
555     if (rcp) {
556       blit_measure(gp, &gp->blitv2r, xb, yb, rcp, NULL);
557       blit_measure(gp, &gp->blitr2v, xb, yb, NULL, rcp);
558       GrDestroyContext(rcp);
559     }
560   }
561 #endif
562 }
563 
measure_one(gvmode * gp,int ram)564 void measure_one(gvmode *gp, int ram) {
565   XY_PAIRS *pairs;
566 
567   if (MEASURED(gp)) return;
568   pairs = checkpairs(gp->w, gp->h);
569   GrFilledBox( 0, 0, gp->w-1, gp->h-1, GrBlack());
570   Message(RAMMODE(gp),"read pixel test", gp);
571   { int rd_loops = READPIX_loops;
572 #if GRX_VERSION_API-0 >= 0x0229
573   unsigned sys = GrGetLibrarySystem();
574 #else
575   unsigned sys = (unsigned) GRX_VERSION;
576 #endif
577   if ( (sys == GRX_VERSION_GENERIC_X11) ||
578        (sys == GRX_VERSION_GCC_386_X11) ||
579        (sys == GRX_VERSION_GCC_X86_64_X11) )
580       if (!RAMMODE(gp)) rd_loops = READPIX_X11_loops;
581     readpixeltest(gp,pairs,rd_loops);
582   }
583   GrFilledBox( 0, 0, gp->w-1, gp->h-1, GrBlack());
584   Message(RAMMODE(gp),"draw pixel test", gp);
585   drawpixeltest(gp,pairs);
586   GrFilledBox( 0, 0, gp->w-1, gp->h-1, GrBlack());
587   Message(RAMMODE(gp),"draw line test ", gp);
588   drawlinetest(gp,pairs);
589   GrFilledBox( 0, 0, gp->w-1, gp->h-1, GrBlack());
590   Message(RAMMODE(gp),"draw hline test", gp);
591   drawhlinetest(gp,pairs);
592   GrFilledBox( 0, 0, gp->w-1, gp->h-1, GrBlack());
593   Message(RAMMODE(gp),"draw vline test", gp);
594   drawvlinetest(gp,pairs);
595   GrFilledBox( 0, 0, gp->w-1, gp->h-1, GrBlack());
596   Message(RAMMODE(gp),"draw block test", gp);
597   drawblocktest(gp,pairs);
598   GrFilledBox( 0, 0, gp->w-1, gp->h-1, GrBlack());
599   blittest(gp, pairs, ram);
600   GrFilledBox( 0, 0, gp->w-1, gp->h-1, GrBlack());
601   SET_MEASURED(gp);
602   measured_any = 1;
603 }
604 
605 #if MEASURE_RAM_MODES
identical_measured(gvmode * tm)606 int identical_measured(gvmode *tm) {
607   int i;
608   for (i=0; i < nmodes; ++i) {
609     if (tm      != &rammodes[i]    &&
610 	tm->fm  == rammodes[i].fm  &&
611 	tm->w   == rammodes[i].w   &&
612 	tm->h   == rammodes[i].h   &&
613 	tm->bpp == rammodes[i].bpp &&
614 	MEASURED(&rammodes[i])        ) return (1);
615   }
616   return 0;
617 }
618 #endif
619 
620 static int first = 0;
621 
speedcheck(gvmode * gp,int print,int wait)622 void speedcheck(gvmode *gp, int print, int wait) {
623   char m[41];
624   gvmode *rp = NULL;
625 
626   if (first) {
627     printf(
628       "speedtest may take some time to process.\n"
629       "Now press <CR> to continue..."
630     );
631     fflush(stdout);
632     fgets(m,40,stdin);
633   }
634 
635   GrSetMode(
636       GR_width_height_bpp_graphics,
637       gp->w, gp->h, gp->bpp
638   );
639 
640   if (first) {
641     /* xor_draw_blocks(NULL);
642        getch(); */
643     first = 0;
644   }
645 
646   if ( GrScreenFrameMode() != gp->fm) {
647     GrFrameMode act = GrScreenFrameMode();
648     GrSetMode(GR_default_text);
649     printf("Setup failed : %s != %s\n",
650     FrameDriverName(act),
651     FrameDriverName(gp->fm));
652     fgets(m,40,stdin);
653     return;
654   }
655 
656   if (!MEASURED(gp))
657     measure_one(gp, 0);
658 
659 #if MEASURE_RAM_MODES
660   rp = &rammodes[(unsigned)(gp-grmodes)];
661   rp->fm = GrCoreFrameMode();
662   if (!MEASURED(rp) && !identical_measured(rp)) {
663     GrContext rc;
664     if (GrCreateFrameContext(rp->fm,gp->w,gp->h,NULL,&rc)) {
665       GrSetContext(&rc);
666       measure_one(rp, 1);
667       GrDestroyContext(&rc);
668       GrSetContext(NULL);
669     }
670   }
671 #endif
672 
673   GrSetMode(GR_default_text);
674   if (print) {
675     printf("Results: \n");
676     printresultheader(stdout);
677     printresultline(stdout, gp);
678     if (rp)
679       printresultline(stdout, rp);
680   }
681   if (wait)
682     fgets(m,40,stdin);
683 }
684 
collectmodes(const GrVideoDriver * drv)685 int collectmodes(const GrVideoDriver *drv)
686 {
687 	gvmode *gp = grmodes;
688 	GrFrameMode fm;
689 	const GrVideoMode *mp;
690 	for(fm =GR_firstGraphicsFrameMode;
691 	      fm <= GR_lastGraphicsFrameMode; fm++) {
692 	    for(mp = GrFirstVideoMode(fm); mp; mp = GrNextVideoMode(mp)) {
693 		gp->fm    = fm;
694 		gp->w     = mp->width;
695 		gp->h     = mp->height;
696 		gp->bpp   = mp->bpp;
697 		gp->flags = 0;
698 		gp++;
699 		if (gp-grmodes >= MAX_MODES) return MAX_MODES;
700 	    }
701 	}
702 	return(int)(gp-grmodes);
703 }
704 
vmcmp(const void * m1,const void * m2)705 int vmcmp(const void *m1,const void *m2)
706 {
707 	gvmode *md1 = (gvmode *)m1;
708 	gvmode *md2 = (gvmode *)m2;
709 	if(md1->bpp != md2->bpp) return(md1->bpp - md2->bpp);
710 	if(md1->w   != md2->w  ) return(md1->w   - md2->w  );
711 	if(md1->h   != md2->h  ) return(md1->h   - md2->h  );
712 	return(0);
713 }
714 
715 #define LINES   20
716 #define COLUMNS 80
717 
ModeText(int i,int shrt,char * mdtxt)718 void ModeText(int i, int shrt,char *mdtxt) {
719 	char *flg;
720 
721 	if (MEASURED(&grmodes[i])) flg = " #"; else
722 	if (TAGGED(&grmodes[i]))   flg = " *"; else
723 				   flg = ") ";
724 	switch (shrt) {
725 	  case 2 : sprintf(mdtxt,"%2d%s %dx%d ", i+1, flg, grmodes[i].w, grmodes[i].h);
726 		   break;
727 	  case 1 : sprintf(mdtxt,"%2d%s %4dx%-4d ", i+1, flg, grmodes[i].w, grmodes[i].h);
728 		   break;
729 	  default: sprintf(mdtxt,"  %2d%s  %4dx%-4d ", i+1, flg, grmodes[i].w, grmodes[i].h);
730 		   break;
731 	}
732 	mdtxt += strlen(mdtxt);
733 
734 	if (grmodes[i].bpp > 20)
735 	  sprintf(mdtxt, "%ldM", 1L << (grmodes[i].bpp-20));
736 	else  if (grmodes[i].bpp > 10)
737 	  sprintf(mdtxt, "%ldk", 1L << (grmodes[i].bpp-10));
738 	else
739 	  sprintf(mdtxt, "%ld", 1L << grmodes[i].bpp);
740 	switch (shrt) {
741 	  case 2 : break;
742 	  case 1 : strcat(mdtxt, " col"); break;
743 	  default: strcat(mdtxt, " colors"); break;
744 	}
745 }
746 
ColsCheck(int cols,int ml,int sep)747 int ColsCheck(int cols, int ml, int sep) {
748   int len;
749 
750   len = ml * cols + (cols-1) * sep + 1;
751   return len <= COLUMNS;
752 }
753 
PrintModes(void)754 void PrintModes(void) {
755 	char mdtxt[100];
756 	unsigned int maxlen;
757 	int i, n, shrt, c, cols;
758 
759 	cols = (nmodes+LINES-1) / LINES;
760 	do {
761 	  for (shrt = 0; shrt <= 2; ++shrt) {
762 	    maxlen = 0;
763 	    for (i = 0; i < nmodes; ++i) {
764 	      ModeText(i,shrt,mdtxt);
765 	      if (strlen(mdtxt) > maxlen) maxlen = strlen(mdtxt);
766 	    }
767 	    n = 2;
768 	    if (cols>1 || shrt<2) {
769 	      if (!ColsCheck(cols, maxlen, n)) continue;
770 	      while (ColsCheck(cols, maxlen, n+1) && n < 4) ++n;
771 	    }
772 	    c = 0;
773 	    for (i = 0; i < nmodes; ++i) {
774 	      if (++c == cols) c = 0;
775 	      ModeText(i,shrt,mdtxt);
776 	      printf("%*s%s", (c ? -((int)(maxlen+n)) : -((int)maxlen)), mdtxt, (c || (i+1==nmodes) ? "" : "\n") );
777 	    }
778 	    return;
779 	  }
780 	  --cols;
781 	} while (1);
782 }
783 
main(int argc,char ** argv)784 int main(int argc, char **argv)
785 {
786 	int  i;
787 
788 	grmodes = malloc(MAX_MODES*sizeof(gvmode));
789 	assert(grmodes!=NULL);
790 #if MEASURE_RAM_MODES
791 	rammodes = malloc(MAX_MODES*sizeof(gvmode));
792 	assert(rammodes!=NULL);
793 #endif
794 
795 	GrSetDriver(NULL);
796 	if(GrCurrentVideoDriver() == NULL) {
797 	    printf("No graphics driver found\n");
798 	    exit(1);
799 	}
800 
801 	nmodes = collectmodes(GrCurrentVideoDriver());
802 	if(nmodes == 0) {
803 	    printf("No graphics modes found\n");
804 	    exit(1);
805 	}
806 	qsort(grmodes,nmodes,sizeof(grmodes[0]),vmcmp);
807 #if MEASURE_RAM_MODES
808 	for (i=0; i < nmodes; ++i) {
809 	  rammodes[i].fm    = GR_frameUndef;      /* filled in later */
810 	  rammodes[i].w     = grmodes[i].w;
811 	  rammodes[i].h     = grmodes[i].h;
812 	  rammodes[i].bpp   = grmodes[i].bpp;
813 	  rammodes[i].flags = FLG_rammode;
814 	}
815 #endif
816 
817 	if(argc >= 2 && (i = atoi(argv[1])) >= 1 && i <= nmodes) {
818 	    speedcheck(&grmodes[i - 1], 1, 0);
819 	    goto done;
820 	}
821 
822 	first = 1;
823 	for( ; ; ) {
824 	    char mb[41], *m = mb;
825 	    int tflag = 0;
826 	    GrSetMode(GR_default_text);
827 	    printf(
828 		"Graphics driver: \"%s\"\t"
829 		"graphics defaults: %dx%d %ld colors\n",
830 		GrCurrentVideoDriver()->name,
831 		GrDriverInfo->defgw,
832 		GrDriverInfo->defgh,
833 		(long)GrDriverInfo->defgc
834 	    );
835 	    PrintModes();
836 	    printf("\nEnter #, 't#' toggels tag, 'm' measure tagged and 'q' to quit> ");
837 	    fflush(stdout);
838 	    if(!fgets(m,40,stdin)) break;
839 	    switch (*m) {
840 	      case 't':
841 	      case 'T': tflag = 1;
842 			++m;
843 			break;
844 	      case 'A':
845 	      case 'a': for (i=0; i < nmodes; ++i)
846 			  SET_TAGGED(&grmodes[i]);
847 			break;
848 	      case 'M':
849 	      case 'm': for (i=0; i < nmodes; ++i)
850 			  if (TAGGED(&grmodes[i])) {
851 			    speedcheck(&grmodes[i], 0, 0);
852 			    TOGGLE_TAGGED(&grmodes[i]);
853 			  }
854 			break;
855 	      case 'Q':
856 	      case 'q': goto done;
857 	    }
858 	    if ((sscanf(m,"%d",&i) != 1) || (i < 1) || (i > nmodes))
859 		continue;
860 	    i--;
861 	    if (tflag) TOGGLE_TAGGED(&grmodes[i]);
862 		  else speedcheck(&grmodes[i], 1, 1);
863 	}
864 done:
865 	if (measured_any) {
866 	    int i;
867 	    FILE *log = fopen("speedtst.log", "a");
868 
869 	    if (!log) exit(1);
870 
871 	    fprintf( log, "\nGraphics driver: \"%s\"\n\n",
872 					       GrCurrentVideoDriver()->name);
873 	    printf("Results: \n");
874 	    printresultheader(log);
875 
876 	    for (i=0; i < nmodes; ++i)
877 	      if (MEASURED(&grmodes[i]))
878 		printresultline(log, &grmodes[i]);
879 #if MEASURE_RAM_MODES
880 	    for (i=0; i < nmodes; ++i)
881 	      if (MEASURED(&rammodes[i]))
882 		printresultline(log, &rammodes[i]);
883 #endif
884 	    fclose(log);
885 	}
886 	return(0);
887 }
888 
889