mga_arc.c revision fe5e51b7
1/************************************************************
2
3Copyright 1989, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25********************************************************/
26/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_arc.c,v 1.12tsi Exp $ */
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <limits.h>
33#include <X11/X.h>
34#include "gcstruct.h"
35#include "windowstr.h"
36#include "pixmapstr.h"
37#include "regionstr.h"
38#include <X11/Xprotostr.h>
39#include "regionstr.h"
40#include "mizerarc.h"
41#include "mi.h"
42#include "scrnintstr.h"
43#include "xaa.h"
44#include "xaalocal.h"
45#include "xf86.h"
46#include "xf86_OSproc.h"
47
48#include "xf86Pci.h"
49
50#include "mga.h"
51#include "mga_reg.h"
52#include "mga_macros.h"
53
54
55/*
56   This is only faster than cfb for stuff other than GXcopy.
57   And even then, only when pci_retries are on.
58*/
59
60
61#define DRAW_POINT(x, y) { \
62	tmp = x; \
63	OUTREG(MGAREG_FXBNDRY, (tmp) | (((tmp) + 1) << 16)); \
64	OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, ((y) << 16) | 1); \
65}
66
67static void
68MGAZeroArc(
69    DrawablePtr pDraw,
70    GCPtr pGC,
71    xArc *arc
72){
73    int yoffset, dyoffset, x, y, a, b, d, mask, k1, k3, dx, dy, tmp;
74    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
75    ScrnInfoPtr pScrn = infoRec->pScrn;
76    MGAPtr pMga = MGAPTR(pScrn);
77    miZeroArcRec info;
78    Bool do360;
79    DDXPointRec org, orgo;
80
81    CHECK_DMA_QUIESCENT( pMga, infoRec->pScrn );
82
83    (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel,
84		pGC->alu, pGC->planemask);
85
86    do360 = miZeroArcSetup(arc, &info, TRUE);
87    org.y = info.yorg + pDraw->y;
88    org.x = 0;
89    orgo.y = info.yorgo + pDraw->y;
90    orgo.x = 0;
91    info.xorg += pDraw->x;
92    info.xorgo += pDraw->x;
93
94    MIARCSETUP();
95    yoffset = y ? 1 : 0;
96    dyoffset = 0;
97    mask = info.initialMask;
98    if (!(arc->width & 1)) {
99	WAITFIFO(4);
100	if (mask & 2)
101	    DRAW_POINT(info.xorgo, org.y);
102	if (mask & 8)
103	    DRAW_POINT(info.xorgo, orgo.y);
104    }
105    if (!info.end.x || !info.end.y) {
106	mask = info.end.mask;
107	info.end = info.altend;
108    }
109    if (do360 && (arc->width == arc->height) && !(arc->width & 1)) {
110        int xoffset = 1;
111	DDXPointRec orghb, orgohb;
112
113	orghb.y = org.y + info.h;
114	orghb.x = org.x + info.xorg;
115	orgohb.y = orghb.y;
116	orgohb.x = orghb.x - info.h;
117
118	org.x += info.xorg;
119	orgo.x += info.xorg;
120	orghb.x += info.h;
121	while (1) {
122	    WAITFIFO(16);
123	    DRAW_POINT(org.x + x, org.y + yoffset);
124	    DRAW_POINT(org.x - x, org.y + yoffset);
125	    DRAW_POINT(orgo.x - x, orgo.y - yoffset);
126	    DRAW_POINT(orgo.x + x, orgo.y - yoffset);
127	    if (a < 0) break;
128	    DRAW_POINT(orghb.x - y, orghb.y - xoffset);
129	    DRAW_POINT(orgohb.x + y, orgohb.y - xoffset);
130	    DRAW_POINT(orgohb.x + y, orgohb.y + xoffset);
131	    DRAW_POINT(orghb.x - y, orghb.y + xoffset);
132	    xoffset ++;
133	    MIARCCIRCLESTEP(yoffset ++;);
134	}
135	org.x -= info.xorg;
136	orgo.x -= info.xorg;
137	x = info.w;
138	yoffset = info.h;
139    }
140    else if (do360) {
141	while (y < info.h || x < info.w) {
142	    MIARCOCTANTSHIFT(dyoffset = 1;);
143	    WAITFIFO(8);
144	    DRAW_POINT(org.x + info.xorg + x, org.y + yoffset);
145	    DRAW_POINT(org.x + info.xorgo - x, org.y + yoffset);
146	    DRAW_POINT(orgo.x + info.xorgo - x, orgo.y - yoffset);
147	    DRAW_POINT(orgo.x + info.xorg + x, orgo.y - yoffset);
148	    MIARCSTEP(yoffset += dyoffset;, yoffset++;);
149	}
150    }
151    else {
152	while (y < info.h || x < info.w) {
153	    MIARCOCTANTSHIFT(dyoffset = 1;);
154	    if ((x == info.start.x) || (y == info.start.y)) {
155		mask = info.start.mask;
156		info.start = info.altstart;
157	    }
158	    WAITFIFO(8);
159	    if (mask & 1)
160		DRAW_POINT(org.x + info.xorg + x, org.y + yoffset);
161	    if (mask & 2)
162		DRAW_POINT(org.x + info.xorgo - x, org.y + yoffset);
163	    if (mask & 4)
164		DRAW_POINT(orgo.x + info.xorgo - x, orgo.y - yoffset);
165	    if (mask & 8)
166		DRAW_POINT(orgo.x + info.xorg + x, orgo.y - yoffset);
167	    if ((x == info.end.x) || (y == info.end.y)) {
168		mask = info.end.mask;
169		info.end = info.altend;
170	    }
171	    MIARCSTEP(yoffset += dyoffset;, yoffset++;);
172	}
173    }
174    if ((x == info.start.x) || (y == info.start.y))
175	mask = info.start.mask;
176
177    WAITFIFO(4);
178    if (mask & 1)
179	DRAW_POINT(org.x + info.xorg + x, org.y + yoffset);
180    if (mask & 4)
181	DRAW_POINT(orgo.x + info.xorgo - x, orgo.y - yoffset);
182    if (arc->height & 1) {
183	WAITFIFO(4);
184	if (mask & 2)
185	    DRAW_POINT(org.x + info.xorgo - x, org.y + yoffset);
186	if (mask & 8)
187	    DRAW_POINT(orgo.x + info.xorg + x, orgo.y - yoffset);
188    }
189
190    SET_SYNC_FLAG(infoRec);
191}
192
193void
194MGAPolyArcThinSolid (
195    DrawablePtr	pDraw,
196    GCPtr	pGC,
197    int		narcs,
198    xArc	*parcs
199){
200    xArc *arc;
201    BoxRec box;
202    int i, x2, y2;
203    RegionPtr cclip;
204
205    cclip = pGC->pCompositeClip;
206
207    if(!REGION_NUM_RECTS(cclip))
208	return;
209
210    for (arc = parcs, i = narcs; --i >= 0; arc++) {
211	if (miCanZeroArc(arc)) {
212	    box.x1 = arc->x + pDraw->x;
213	    box.y1 = arc->y + pDraw->y;
214 	    x2 = box.x1 + (int)arc->width + 1;
215 	    box.x2 = x2;
216 	    y2 = box.y1 + (int)arc->height + 1;
217 	    box.y2 = y2;
218 	    if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) &&
219 		    (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
220		MGAZeroArc (pDraw, pGC, arc);
221	    else
222		miZeroPolyArc(pDraw, pGC, 1, arc);
223	}
224	else
225	    miPolyArc(pDraw, pGC, 1, arc);
226    }
227}
228
229