~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to fb/fbtrap.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
Import upstream version 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: fbtrap.c,v 1.5 2005/07/03 07:01:23 daniels Exp $
 
3
 *
 
4
 * Copyright © 2004 Keith Packard
 
5
 *
 
6
 * Permission to use, copy, modify, distribute, and sell this software and its
 
7
 * documentation for any purpose is hereby granted without fee, provided that
 
8
 * the above copyright notice appear in all copies and that both that
 
9
 * copyright notice and this permission notice appear in supporting
 
10
 * documentation, and that the name of Keith Packard not be used in
 
11
 * advertising or publicity pertaining to distribution of the software without
 
12
 * specific, written prior permission.  Keith Packard makes no
 
13
 * representations about the suitability of this software for any purpose.  It
 
14
 * is provided "as is" without express or implied warranty.
 
15
 *
 
16
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
17
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 
18
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
19
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 
20
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 
21
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 
22
 * PERFORMANCE OF THIS SOFTWARE.
 
23
 */
 
24
 
 
25
#ifdef HAVE_DIX_CONFIG_H
 
26
#include <dix-config.h>
 
27
#endif
 
28
 
 
29
#include "fb.h"
 
30
 
 
31
#ifdef RENDER
 
32
 
 
33
#include "picturestr.h"
 
34
#include "mipict.h"
 
35
#include "renderedge.h"
 
36
#include "fbpict.h"
 
37
 
 
38
void
 
39
fbAddTraps (PicturePtr  pPicture,
 
40
            INT16       x_off,
 
41
            INT16       y_off,
 
42
            int         ntrap,
 
43
            xTrap       *traps)
 
44
{
 
45
    FbBits      *buf;
 
46
    int         bpp;
 
47
    int         width;
 
48
    int         stride;
 
49
    int         height;
 
50
    int         pxoff, pyoff;
 
51
 
 
52
    xFixed      x_off_fixed;
 
53
    xFixed      y_off_fixed;
 
54
    RenderEdge  l, r;
 
55
    xFixed      t, b;
 
56
    
 
57
    fbGetDrawable (pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff);
 
58
 
 
59
    width = pPicture->pDrawable->width;
 
60
    height = pPicture->pDrawable->height;
 
61
    x_off += pxoff;
 
62
    y_off += pyoff;
 
63
    
 
64
    x_off_fixed = IntToxFixed(y_off);
 
65
    y_off_fixed = IntToxFixed(y_off);
 
66
 
 
67
    while (ntrap--)
 
68
    {
 
69
        t = traps->top.y + y_off_fixed;
 
70
        if (t < 0)
 
71
            t = 0;
 
72
        t = RenderSampleCeilY (t, bpp);
 
73
    
 
74
        b = traps->bot.y + y_off_fixed;
 
75
        if (xFixedToInt (b) >= height)
 
76
            b = IntToxFixed (height) - 1;
 
77
        b = RenderSampleFloorY (b, bpp);
 
78
        
 
79
        if (b >= t)
 
80
        {
 
81
            /* initialize edge walkers */
 
82
            RenderEdgeInit (&l, bpp, t,
 
83
                            traps->top.l + x_off_fixed,
 
84
                            traps->top.y + y_off_fixed,
 
85
                            traps->bot.l + x_off_fixed,
 
86
                            traps->bot.y + y_off_fixed);
 
87
        
 
88
            RenderEdgeInit (&r, bpp, t,
 
89
                            traps->top.r + x_off_fixed,
 
90
                            traps->top.y + y_off_fixed,
 
91
                            traps->bot.r + x_off_fixed,
 
92
                            traps->bot.y + y_off_fixed);
 
93
            
 
94
            fbRasterizeEdges (buf, bpp, width, stride, &l, &r, t, b);
 
95
        }
 
96
        traps++;
 
97
    }
 
98
}
 
99
 
 
100
void
 
101
fbRasterizeTrapezoid (PicturePtr    pPicture,
 
102
                      xTrapezoid  *trap,
 
103
                      int           x_off,
 
104
                      int           y_off)
 
105
{
 
106
    FbBits      *buf;
 
107
    int         bpp;
 
108
    int         width;
 
109
    int         stride;
 
110
    int         height;
 
111
    int         pxoff, pyoff;
 
112
 
 
113
    xFixed      x_off_fixed;
 
114
    xFixed      y_off_fixed;
 
115
    RenderEdge  l, r;
 
116
    xFixed      t, b;
 
117
    
 
118
    fbGetDrawable (pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff);
 
119
 
 
120
    width = pPicture->pDrawable->width;
 
121
    height = pPicture->pDrawable->height;
 
122
    x_off += pxoff;
 
123
    y_off += pyoff;
 
124
    
 
125
    x_off_fixed = IntToxFixed(x_off);
 
126
    y_off_fixed = IntToxFixed(y_off);
 
127
    t = trap->top + y_off_fixed;
 
128
    if (t < 0)
 
129
        t = 0;
 
130
    t = RenderSampleCeilY (t, bpp);
 
131
 
 
132
    b = trap->bottom + y_off_fixed;
 
133
    if (xFixedToInt (b) >= height)
 
134
        b = IntToxFixed (height) - 1;
 
135
    b = RenderSampleFloorY (b, bpp);
 
136
    
 
137
    if (b >= t)
 
138
    {
 
139
        /* initialize edge walkers */
 
140
        RenderLineFixedEdgeInit (&l, bpp, t, &trap->left, x_off, y_off);
 
141
        RenderLineFixedEdgeInit (&r, bpp, t, &trap->right, x_off, y_off);
 
142
        
 
143
        fbRasterizeEdges (buf, bpp, width, stride, &l, &r, t, b);
 
144
    }
 
145
}
 
146
 
 
147
static int
 
148
_GreaterY (xPointFixed *a, xPointFixed *b)
 
149
{
 
150
    if (a->y == b->y)
 
151
        return a->x > b->x;
 
152
    return a->y > b->y;
 
153
}
 
154
 
 
155
/*
 
156
 * Note that the definition of this function is a bit odd because
 
157
 * of the X coordinate space (y increasing downwards).
 
158
 */
 
159
static int
 
160
_Clockwise (xPointFixed *ref, xPointFixed *a, xPointFixed *b)
 
161
{
 
162
    xPointFixed ad, bd;
 
163
 
 
164
    ad.x = a->x - ref->x;
 
165
    ad.y = a->y - ref->y;
 
166
    bd.x = b->x - ref->x;
 
167
    bd.y = b->y - ref->y;
 
168
 
 
169
    return ((xFixed_32_32) bd.y * ad.x - (xFixed_32_32) ad.y * bd.x) < 0;
 
170
}
 
171
 
 
172
/* FIXME -- this could be made more efficient */
 
173
void
 
174
fbAddTriangles (PicturePtr  pPicture,
 
175
                INT16       x_off,
 
176
                INT16       y_off,
 
177
                int         ntri,
 
178
                xTriangle *tris)
 
179
{
 
180
    xPointFixed   *top, *left, *right, *tmp;
 
181
    xTrapezoid      trap;
 
182
 
 
183
    for (; ntri; ntri--, tris++)
 
184
    {
 
185
        top = &tris->p1;
 
186
        left = &tris->p2;
 
187
        right = &tris->p3;
 
188
        if (_GreaterY (top, left)) {
 
189
            tmp = left; left = top; top = tmp;
 
190
        }
 
191
        if (_GreaterY (top, right)) {
 
192
            tmp = right; right = top; top = tmp;
 
193
        }
 
194
        if (_Clockwise (top, right, left)) {
 
195
            tmp = right; right = left; left = tmp;
 
196
        }
 
197
        
 
198
        /*
 
199
         * Two cases:
 
200
         *
 
201
         *              +               +
 
202
         *             / \             / \
 
203
         *            /   \           /   \
 
204
         *           /     +         +     \
 
205
         *      /    --           --    \
 
206
         *     /   --               --   \
 
207
         *    / ---                   --- \
 
208
         *       +--                         --+
 
209
         */
 
210
        
 
211
        trap.top = top->y;
 
212
        trap.left.p1 = *top;
 
213
        trap.left.p2 = *left;
 
214
        trap.right.p1 = *top;
 
215
        trap.right.p2 = *right;
 
216
        if (right->y < left->y)
 
217
            trap.bottom = right->y;
 
218
        else
 
219
            trap.bottom = left->y;
 
220
        fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off);
 
221
        if (right->y < left->y)
 
222
        {
 
223
            trap.top = right->y;
 
224
            trap.bottom = left->y;
 
225
            trap.right.p1 = *right;
 
226
            trap.right.p2 = *left;
 
227
        }
 
228
        else
 
229
        {
 
230
            trap.top = left->y;
 
231
            trap.bottom = right->y;
 
232
            trap.left.p1 = *left;
 
233
            trap.left.p2 = *right;
 
234
        }
 
235
        fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off);
 
236
    }
 
237
}
 
238
 
 
239
#endif /* RENDER */