do_tris.c revision 264fa531
1/* $Xorg: do_tris.c,v 1.3 2000/08/17 19:54:10 cpqbld Exp $ */
2/*****************************************************************************
3Copyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
4
5                        All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the name of Digital not be
12used in advertising or publicity pertaining to distribution of the
13software without specific, written prior permission.
14
15DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21SOFTWARE.
22
23******************************************************************************/
24/* $XFree86: xc/programs/x11perf/do_tris.c,v 1.4 2000/11/29 08:58:20 keithp Exp $ */
25
26
27#undef POLYTRIANGLE_HACK    /* don't use this code */
28#ifdef POLYTRIANGLE_HACK
29#include <X11/Xlibint.h>
30#endif
31
32#include "x11perf.h"
33#include "bitmaps.h"
34#include <stdio.h>
35#include <math.h>
36
37#define NUM_POINTS 3   /* 3 points to a triangle */
38static XPoint *points;
39static GC     pgc;
40
41#ifndef PI
42#define PI  3.14159265357989
43#endif
44
45static double
46Area(XPoint p1, XPoint p2, XPoint p3)
47{
48    return
49      (p1.x*p2.y - p1.x*p3.y + p2.x*p3.y - p2.x*p1.y + p3.x*p1.y - p3.x*p2.y)/2;
50}
51
52/*
53static double
54Distance(XPoint p1, XPoint p2)
55{
56    return sqrt((float) ((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y)));
57}
58*/
59
60int
61InitTriangles(XParms xp, Parms p, int reps)
62{
63    int     i, j, numPoints;
64    int     rows;
65    int     x, y;
66    int     size, iradius;
67    double  phi, phiinc, radius, delta, phi2, area, aarea;
68    XPoint  *curPoint;
69
70    pgc = xp->fggc;
71
72    size = p->special;
73    phi = 0.0;
74    delta = 2.0 * PI / ((double) NUM_POINTS);
75    if (xp->version == VERSION1_2) {
76	radius = ((double) size) * sqrt(3.0)/2.0;
77	phiinc = delta/10.0;
78    } else {
79	/* Version 1.2's radius computation was completely bogus, and resulted
80	   in triangles with sides about 50% longer than advertised.  However,
81	   this inadvertently resulted in triangles with areas just a little bit
82	   smaller than the triangle that covers size^2 pixels, which would
83	   make the area directly comparable to 10x10 rectangles and 10x10
84	   trapezoids.  So here's the new computation so -triangleN has the same
85	   area as -rectN.
86	 */
87	radius = ((double) size) * sqrt(sqrt(16.0/27.0));
88	phiinc = 1.75*PI / ((double) p->objects);
89    }
90    iradius = (int) (radius + 0.5);
91
92    numPoints = (p->objects) * NUM_POINTS;
93    points = (XPoint *)malloc(numPoints * sizeof(XPoint));
94    curPoint = points;
95    x = iradius;
96    y = iradius;
97    rows = 0;
98    aarea = 0.0;
99
100    for (i = 0; i != p->objects; i++) {
101	for (j = 0; j != NUM_POINTS; j++) {
102	    phi2 = phi + ((double) j) * delta;
103	    curPoint->x = (int) ((double)x + (radius * cos(phi2)) + 0.5);
104	    curPoint->y = (int) ((double)y + (radius * sin(phi2)) + 0.5);
105	    curPoint++;
106	}
107	area = Area(curPoint[-1], curPoint[-2], curPoint[-3]);
108	aarea += area;
109/*	printf("%6.1lf %6.1lf %6.1lf   %6.1lf\n",
110	    Distance(curPoint[-1], curPoint[-2]),
111	    Distance(curPoint[-1], curPoint[-3]),
112	    Distance(curPoint[-2], curPoint[-3]),
113	    area);
114*/
115	phi += phiinc;
116	y += 2 * iradius;
117	rows++;
118	if (y + iradius > HEIGHT || rows == MAXROWS) {
119	    rows = 0;
120	    y = iradius;
121	    x += 2 * iradius;
122	    if (x + iradius > WIDTH) {
123		x = iradius;
124	    }
125	}
126    }
127/*    printf("Average area = %6.2lf\n", aarea/p->objects); */
128
129    SetFillStyle(xp, p);
130
131    return reps;
132}
133
134#ifndef POLYTRIANGLE_HACK
135
136void
137DoTriangles(XParms xp, Parms p, int reps)
138{
139    int     i, j;
140    XPoint  *curPoint;
141
142    for (i = 0; i != reps; i++) {
143        curPoint = points;
144        for (j = 0; j != p->objects; j++) {
145            XFillPolygon(xp->d, xp->w, pgc, curPoint, NUM_POINTS, Convex,
146			 CoordModeOrigin);
147            curPoint += NUM_POINTS;
148	}
149        if (pgc == xp->bggc)
150            pgc = xp->fggc;
151        else
152            pgc = xp->bggc;
153	CheckAbort ();
154    }
155}
156
157#else
158
159static xReq _dummy_request = {
160	0, 0, 0
161};
162
163static void
164XPolyTriangle(register Display *dpy,
165	      Drawable d, GC gc, XPoint *points,
166	      int n_triangles, int shape, int mode)
167{
168    register xFillPolyReq *req;
169    register long nbytes;
170    int		max_triangles;
171    int		n_this_time;
172    int		*buf, *pts;
173    int		gcid;
174    int		last;
175
176    max_triangles = (dpy->bufmax - dpy->buffer) / 28;
177    LockDisplay(dpy);
178    FlushGC(dpy, gc);
179    dpy->request += n_triangles;
180    pts = (int *) points;
181    gcid = gc->gid;
182    last = shape | (mode << 8);
183    while (n_triangles)
184    {
185	if ((n_this_time = max_triangles) > n_triangles)
186	    n_this_time = n_triangles;
187	n_triangles -= n_this_time;
188	GetReqExtra(FillPoly,
189	    (SIZEOF(xFillPolyReq) + 12) * n_this_time - SIZEOF(xFillPolyReq), req);
190	--dpy->request;
191
192	buf = req;
193        while (n_this_time--)
194	{
195	    buf[0] = X_FillPoly | (7 << 16);
196	    buf[1] = d;
197	    buf[2] = gcid;
198	    buf[3] = last;
199	    buf[4] = pts[0];
200	    buf[5] = pts[1];
201	    buf[6] = pts[2];
202	    buf += 7;
203	    pts += 3;
204	}
205    }
206    dpy->last_req = &_dummy_request;
207    UnlockDisplay(dpy);
208    SyncHandle();
209}
210
211void
212DoTriangles(XParms xp, Parms p, int reps)
213{
214    int     i, j;
215    XPoint  *curPoint;
216
217    for (i = 0; i != reps; i++) {
218        XPolyTriangle (xp->d, xp->w, pgc, points, p->objects, Convex,
219			 CoordModeOrigin);
220        if (pgc == xp->bggc)
221            pgc = xp->fggc;
222        else
223            pgc = xp->bggc;
224	CheckAbort ();
225    }
226}
227#endif
228
229void
230EndTriangles(XParms xp, Parms p)
231{
232    free(points);
233}
234
235