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

« back to all changes in this revision

Viewing changes to hw/xgl/xglgeometry.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
 * Copyright Ā© 2004 David Reveman
 
3
 *
 
4
 * Permission to use, copy, modify, distribute, and sell this software
 
5
 * and its documentation for any purpose is hereby granted without
 
6
 * fee, provided that the above copyright notice appear in all copies
 
7
 * and that both that copyright notice and this permission notice
 
8
 * appear in supporting documentation, and that the name of
 
9
 * David Reveman not be used in advertising or publicity pertaining to
 
10
 * distribution of the software without specific, written prior permission.
 
11
 * David Reveman makes no representations about the suitability of this
 
12
 * software for any purpose. It is provided "as is" without express or
 
13
 * implied warranty.
 
14
 *
 
15
 * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
16
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
 
17
 * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
18
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 
19
 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 
20
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 
21
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
22
 *
 
23
 * Author: David Reveman <davidr@novell.com>
 
24
 */
 
25
 
 
26
#include "xgl.h"
 
27
#include <X11/fonts/fontstruct.h>
 
28
#include "dixfontstr.h"
 
29
 
 
30
xglDataTypeInfoRec xglGeometryDataTypes[2] = {
 
31
    { GLITZ_DATA_TYPE_SHORT, sizeof (glitz_short_t) },
 
32
    { GLITZ_DATA_TYPE_FLOAT, sizeof (glitz_float_t) }
 
33
};
 
34
 
 
35
glitz_buffer_hint_t usageTypes[] = {
 
36
    GLITZ_BUFFER_HINT_STREAM_DRAW,
 
37
    GLITZ_BUFFER_HINT_STATIC_DRAW,
 
38
    GLITZ_BUFFER_HINT_DYNAMIC_DRAW
 
39
};
 
40
 
 
41
void
 
42
xglGeometryResize (ScreenPtr      pScreen,
 
43
                   xglGeometryPtr pGeometry,
 
44
                   int            size)
 
45
{
 
46
    XGL_SCREEN_PRIV (pScreen);
 
47
 
 
48
    if (size == pGeometry->size)
 
49
        return;
 
50
 
 
51
    if (pGeometry->broken)
 
52
        return;
 
53
 
 
54
    if (pGeometry->usage == GEOMETRY_USAGE_SYSMEM)
 
55
    {
 
56
        pGeometry->data = xrealloc (pGeometry->data, size);
 
57
 
 
58
        if (pGeometry->buffer)
 
59
            glitz_buffer_destroy (pGeometry->buffer);
 
60
 
 
61
        pGeometry->buffer = NULL;
 
62
 
 
63
        if (pGeometry->data)
 
64
        {
 
65
            pGeometry->buffer = glitz_buffer_create_for_data (pGeometry->data);
 
66
            if (!pGeometry->buffer)
 
67
            {
 
68
                pGeometry->broken = TRUE;
 
69
                return;
 
70
            }
 
71
        }
 
72
        else if (size)
 
73
        {
 
74
            pGeometry->broken = TRUE;
 
75
            return;
 
76
        }
 
77
    }
 
78
    else
 
79
    {
 
80
        glitz_buffer_t *newBuffer;
 
81
 
 
82
        if (size)
 
83
        {
 
84
            newBuffer =
 
85
                glitz_vertex_buffer_create (pScreenPriv->drawable, NULL, size,
 
86
                                            usageTypes[pGeometry->usage]);
 
87
            if (!newBuffer)
 
88
            {
 
89
                pGeometry->broken = TRUE;
 
90
                return;
 
91
            }
 
92
        } else
 
93
            newBuffer = NULL;
 
94
 
 
95
        if (pGeometry->buffer && newBuffer)
 
96
        {
 
97
            void *oldData, *newData;
 
98
 
 
99
            oldData = glitz_buffer_map (pGeometry->buffer,
 
100
                                        GLITZ_BUFFER_ACCESS_READ_ONLY);
 
101
            newData = glitz_buffer_map (newBuffer,
 
102
                                        GLITZ_BUFFER_ACCESS_WRITE_ONLY);
 
103
 
 
104
            if (oldData && newData)
 
105
                memcpy (newData, oldData, MIN (size, pGeometry->size));
 
106
 
 
107
            glitz_buffer_unmap (pGeometry->buffer);
 
108
            glitz_buffer_unmap (newBuffer);
 
109
 
 
110
            glitz_buffer_destroy (pGeometry->buffer);
 
111
        }
 
112
        pGeometry->buffer = newBuffer;
 
113
    }
 
114
 
 
115
    pGeometry->size = size;
 
116
 
 
117
    if (pGeometry->endOffset > size)
 
118
        pGeometry->endOffset = size;
 
119
}
 
120
 
 
121
#define MAP_GEOMETRY(pScreen, pGeometry, offset, units, ptr, _size)       \
 
122
    if ((pGeometry)->broken)                                              \
 
123
        return;                                                           \
 
124
    (_size) = (units) * xglGeometryDataTypes[(pGeometry)->dataType].size; \
 
125
    if (((pGeometry)->size - (offset)) < (_size))                         \
 
126
    {                                                                     \
 
127
        xglGeometryResize (pScreen, pGeometry,                            \
 
128
                           (pGeometry)->endOffset + (_size) + 500);       \
 
129
        if ((pGeometry)->broken)                                          \
 
130
            return;                                                       \
 
131
    }                                                                     \
 
132
    (ptr) = glitz_buffer_map ((pGeometry)->buffer,                        \
 
133
                              GLITZ_BUFFER_ACCESS_WRITE_ONLY);            \
 
134
    if (!(ptr))                                                           \
 
135
    {                                                                     \
 
136
        (pGeometry)->broken = TRUE;                                       \
 
137
        return;                                                           \
 
138
    }                                                                     \
 
139
    (ptr) += (offset)
 
140
 
 
141
#define UNMAP_GEOMETRY(pGeometry, offset, _size)                           \
 
142
    if (glitz_buffer_unmap ((pGeometry)->buffer))                          \
 
143
    {                                                                      \
 
144
        (pGeometry)->broken = TRUE;                                        \
 
145
        return;                                                            \
 
146
    }                                                                      \
 
147
    if (((offset) + (_size)) > (pGeometry)->endOffset)                     \
 
148
    {                                                                      \
 
149
        (pGeometry)->endOffset = (offset) + (_size);                       \
 
150
        (pGeometry)->count = (pGeometry)->endOffset /                      \
 
151
            (2 * xglGeometryDataTypes[(pGeometry)->dataType].size);        \
 
152
    }
 
153
 
 
154
/*
 
155
 * Adds a number of boxes as GL_QUAD primitives
 
156
 */
 
157
void
 
158
xglGeometryAddBox (ScreenPtr      pScreen,
 
159
                   xglGeometryPtr pGeometry,
 
160
                   BoxPtr         pBox,
 
161
                   int            nBox,
 
162
                   int            offset)
 
163
{
 
164
    int  size;
 
165
    char *ptr;
 
166
 
 
167
    if (nBox < 1)
 
168
        return;
 
169
 
 
170
    MAP_GEOMETRY (pScreen, pGeometry, offset, nBox * 8, ptr, size);
 
171
 
 
172
    switch (pGeometry->dataType) {
 
173
    case GEOMETRY_DATA_TYPE_SHORT:
 
174
    {
 
175
        glitz_short_t *data = (glitz_short_t *) ptr;
 
176
 
 
177
        while (nBox--)
 
178
        {
 
179
            *data++ = (glitz_short_t) pBox->x1;
 
180
            *data++ = (glitz_short_t) pBox->y1;
 
181
            *data++ = (glitz_short_t) pBox->x2;
 
182
            *data++ = (glitz_short_t) pBox->y1;
 
183
            *data++ = (glitz_short_t) pBox->x2;
 
184
            *data++ = (glitz_short_t) pBox->y2;
 
185
            *data++ = (glitz_short_t) pBox->x1;
 
186
            *data++ = (glitz_short_t) pBox->y2;
 
187
 
 
188
            pBox++;
 
189
        }
 
190
    } break;
 
191
    case GEOMETRY_DATA_TYPE_FLOAT:
 
192
    {
 
193
        glitz_float_t *data = (glitz_float_t *) ptr;
 
194
 
 
195
        while (nBox--)
 
196
        {
 
197
            *data++ = (glitz_float_t) pBox->x1;
 
198
            *data++ = (glitz_float_t) pBox->y1;
 
199
            *data++ = (glitz_float_t) pBox->x2;
 
200
            *data++ = (glitz_float_t) pBox->y1;
 
201
            *data++ = (glitz_float_t) pBox->x2;
 
202
            *data++ = (glitz_float_t) pBox->y2;
 
203
            *data++ = (glitz_float_t) pBox->x1;
 
204
            *data++ = (glitz_float_t) pBox->y2;
 
205
 
 
206
            pBox++;
 
207
        }
 
208
    } break;
 
209
    }
 
210
 
 
211
    UNMAP_GEOMETRY (pGeometry, offset, size);
 
212
}
 
213
 
 
214
/*
 
215
 * Adds a number of spans as GL_LINE primitives
 
216
 */
 
217
void
 
218
xglGeometryAddSpan (ScreenPtr      pScreen,
 
219
                    xglGeometryPtr pGeometry,
 
220
                    DDXPointPtr    ppt,
 
221
                    int            *pwidth,
 
222
                    int            n,
 
223
                    int            offset)
 
224
{
 
225
    int  size;
 
226
    char *ptr;
 
227
 
 
228
    if (n < 1)
 
229
        return;
 
230
 
 
231
    MAP_GEOMETRY (pScreen, pGeometry, offset, n * 4, ptr, size);
 
232
 
 
233
    switch (pGeometry->dataType) {
 
234
    case GEOMETRY_DATA_TYPE_SHORT:
 
235
    {
 
236
        glitz_short_t *data = (glitz_short_t *) ptr;
 
237
 
 
238
        while (n--)
 
239
        {
 
240
            *data++ = (glitz_short_t) ppt->x;
 
241
            *data++ = (glitz_short_t) ppt->y;
 
242
            *data++ = (glitz_short_t) (ppt->x + *pwidth);
 
243
            *data++ = (glitz_short_t) ppt->y;
 
244
 
 
245
            ppt++;
 
246
            pwidth++;
 
247
        }
 
248
    } break;
 
249
    case GEOMETRY_DATA_TYPE_FLOAT:
 
250
    {
 
251
        glitz_float_t *data = (glitz_float_t *) ptr;
 
252
 
 
253
        while (n--)
 
254
        {
 
255
            *data++ = (glitz_float_t) ppt->x;
 
256
            *data++ = (glitz_float_t) ppt->y;
 
257
            *data++ = (glitz_float_t) (ppt->x + *pwidth);
 
258
            *data++ = (glitz_float_t) ppt->y;
 
259
 
 
260
            ppt++;
 
261
            pwidth++;
 
262
        }
 
263
    } break;
 
264
    }
 
265
 
 
266
    UNMAP_GEOMETRY (pGeometry, offset, size);
 
267
}
 
268
 
 
269
/*
 
270
 * This macro is needed for end pixels to be rasterized correctly using
 
271
 * OpenGL as OpenGL line segments are half-opened.
 
272
 */
 
273
#define ADJUST_END_POINT(start, end, isPoint) \
 
274
    (((end) > (start)) ? (end) + 1:           \
 
275
     ((end) < (start)) ? (end) - 1:           \
 
276
     (isPoint)         ? (end) + 1:           \
 
277
     (end))
 
278
 
 
279
/*
 
280
 * Adds a number of connected lines as GL_LINE_STRIP primitives
 
281
 */
 
282
void
 
283
xglGeometryAddLine (ScreenPtr      pScreen,
 
284
                    xglGeometryPtr pGeometry,
 
285
                    int            loop,
 
286
                    int            mode,
 
287
                    int            npt,
 
288
                    DDXPointPtr    ppt,
 
289
                    int            offset)
 
290
{
 
291
    DDXPointRec pt;
 
292
    int         size;
 
293
    char        *ptr;
 
294
 
 
295
    if (npt < 2)
 
296
        return;
 
297
 
 
298
    MAP_GEOMETRY (pScreen, pGeometry, offset, npt * 2, ptr, size);
 
299
 
 
300
    pt.x = 0;
 
301
    pt.y = 0;
 
302
 
 
303
    switch (pGeometry->dataType) {
 
304
    case GEOMETRY_DATA_TYPE_SHORT:
 
305
    {
 
306
        glitz_short_t *data = (glitz_short_t *) ptr;
 
307
 
 
308
        while (npt--)
 
309
        {
 
310
            if (mode == CoordModePrevious)
 
311
            {
 
312
                pt.x += ppt->x;
 
313
                pt.y += ppt->y;
 
314
            }
 
315
            else
 
316
            {
 
317
                pt.x = ppt->x;
 
318
                pt.y = ppt->y;
 
319
            }
 
320
 
 
321
            if (npt || loop)
 
322
            {
 
323
                *data++ = (glitz_short_t) pt.x;
 
324
                *data++ = (glitz_short_t) pt.y;
 
325
            }
 
326
            else
 
327
            {
 
328
                ppt--;
 
329
                *data++ = (glitz_short_t)
 
330
                    ADJUST_END_POINT (ppt->x, pt.x, ppt->y == pt.y);
 
331
                *data++ = (glitz_short_t) ADJUST_END_POINT (ppt->y, pt.y, 0);
 
332
            }
 
333
 
 
334
            ppt++;
 
335
        }
 
336
    } break;
 
337
    case GEOMETRY_DATA_TYPE_FLOAT:
 
338
    {
 
339
        glitz_float_t *data = (glitz_float_t *) ptr;
 
340
 
 
341
        while (npt--)
 
342
        {
 
343
            if (mode == CoordModePrevious)
 
344
            {
 
345
                pt.x += ppt->x;
 
346
                pt.y += ppt->y;
 
347
            }
 
348
            else
 
349
            {
 
350
                pt.x = ppt->x;
 
351
                pt.y = ppt->y;
 
352
            }
 
353
 
 
354
            if (npt || loop)
 
355
            {
 
356
                *data++ = (glitz_float_t) pt.x;
 
357
                *data++ = (glitz_float_t) pt.y;
 
358
            }
 
359
            else
 
360
            {
 
361
                ppt--;
 
362
                *data++ = (glitz_float_t)
 
363
                    ADJUST_END_POINT (ppt->x, pt.x, ppt->y == pt.y);
 
364
                *data++ = (glitz_float_t) ADJUST_END_POINT (ppt->y, pt.y, 0);
 
365
            }
 
366
 
 
367
            ppt++;
 
368
        }
 
369
    } break;
 
370
    }
 
371
 
 
372
    UNMAP_GEOMETRY (pGeometry, offset, size);
 
373
}
 
374
 
 
375
/*
 
376
 * Adds a number of line segments as GL_LINE primitives
 
377
 */
 
378
void
 
379
xglGeometryAddSegment (ScreenPtr      pScreen,
 
380
                       xglGeometryPtr pGeometry,
 
381
                       int            nsegInit,
 
382
                       xSegment       *pSegInit,
 
383
                       int            offset)
 
384
{
 
385
    int  size;
 
386
    char *ptr;
 
387
 
 
388
    if (nsegInit < 1)
 
389
        return;
 
390
 
 
391
    MAP_GEOMETRY (pScreen, pGeometry, offset, nsegInit * 4, ptr, size);
 
392
 
 
393
    switch (pGeometry->dataType) {
 
394
    case GEOMETRY_DATA_TYPE_SHORT:
 
395
    {
 
396
        glitz_short_t *data = (glitz_short_t *) ptr;
 
397
 
 
398
        while (nsegInit--)
 
399
        {
 
400
            *data++ = (glitz_short_t) pSegInit->x1;
 
401
            *data++ = (glitz_short_t) pSegInit->y1;
 
402
            *data++ = (glitz_short_t)
 
403
                ADJUST_END_POINT (pSegInit->x1, pSegInit->x2,
 
404
                                  pSegInit->y1 == pSegInit->y2);
 
405
            *data++ = (glitz_short_t)
 
406
                ADJUST_END_POINT (pSegInit->y1, pSegInit->y2, 0);
 
407
 
 
408
            pSegInit++;
 
409
        }
 
410
    } break;
 
411
    case GEOMETRY_DATA_TYPE_FLOAT:
 
412
    {
 
413
        glitz_float_t *data = (glitz_float_t *) ptr;
 
414
 
 
415
        while (nsegInit--)
 
416
        {
 
417
            *data++ = (glitz_float_t) pSegInit->x1;
 
418
            *data++ = (glitz_float_t) pSegInit->y1;
 
419
            *data++ = (glitz_float_t)
 
420
                ADJUST_END_POINT (pSegInit->x1, pSegInit->x2,
 
421
                                  pSegInit->y1 == pSegInit->y2);
 
422
            *data++ = (glitz_float_t)
 
423
                ADJUST_END_POINT (pSegInit->y1, pSegInit->y2, 0);
 
424
 
 
425
            pSegInit++;
 
426
        }
 
427
    } break;
 
428
    }
 
429
 
 
430
    UNMAP_GEOMETRY (pGeometry, offset, size);
 
431
}
 
432
 
 
433
void
 
434
xglGeometryForGlyph (ScreenPtr      pScreen,
 
435
                     xglGeometryPtr pGeometry,
 
436
                     unsigned int   nGlyph,
 
437
                     CharInfoPtr    *ppciInit,
 
438
                     pointer        pglyphBase)
 
439
{
 
440
    CharInfoPtr         *ppci;
 
441
    CharInfoPtr         pci;
 
442
    unsigned char       *glyphbase = (pointer) ~0;
 
443
    unsigned char       *pglyph;
 
444
    int                 x = 0;
 
445
    int                 gx, gy;
 
446
    int                 gWidth, gHeight;
 
447
    int                 n, lastX = 0, lastY = 0;
 
448
    glitz_multi_array_t *array;
 
449
    glitz_buffer_t      *buffer;
 
450
 
 
451
    ppci = ppciInit;
 
452
    n = nGlyph;
 
453
 
 
454
    while (n--)
 
455
    {
 
456
        pglyph = FONTGLYPHBITS (pglyphBase, *ppci++);
 
457
        if (pglyph < glyphbase)
 
458
            glyphbase = pglyph;
 
459
    }
 
460
 
 
461
    buffer = glitz_buffer_create_for_data (glyphbase);
 
462
    if (!buffer)
 
463
    {
 
464
        pGeometry->broken = TRUE;
 
465
        return;
 
466
    }
 
467
 
 
468
    GEOMETRY_SET_BUFFER (pGeometry, buffer);
 
469
 
 
470
    array = glitz_multi_array_create (nGlyph);
 
471
    if (!array)
 
472
    {
 
473
        pGeometry->broken = TRUE;
 
474
        return;
 
475
    }
 
476
 
 
477
    GEOMETRY_SET_MULTI_ARRAY (pGeometry, array);
 
478
 
 
479
    ppci = ppciInit;
 
480
    while (nGlyph--)
 
481
    {
 
482
        pci = *ppci++;
 
483
        pglyph = FONTGLYPHBITS (pglyphBase, pci);
 
484
        gWidth = GLYPHWIDTHPIXELS (pci);
 
485
        gHeight = GLYPHHEIGHTPIXELS (pci);
 
486
 
 
487
        if (gWidth && gHeight)
 
488
        {
 
489
            gx = x + pci->metrics.leftSideBearing;
 
490
            gy = -pci->metrics.ascent;
 
491
 
 
492
            glitz_multi_array_add (array,
 
493
                                   (pglyph - glyphbase) * 8,
 
494
                                   gWidth, gHeight,
 
495
                                   (gx - lastX) << 16, (gy - lastY) << 16);
 
496
            lastX = gx;
 
497
            lastY = gy;
 
498
        }
 
499
        x += pci->metrics.characterWidth;
 
500
    }
 
501
 
 
502
    glitz_buffer_destroy (buffer);
 
503
    glitz_multi_array_destroy (array);
 
504
}
 
505
 
 
506
#define FIXED_LINE_X_TO_FLOAT(line, v)            \
 
507
    (((glitz_float_t)                             \
 
508
        ((line).p1.x + (xFixed_16_16)             \
 
509
         (((xFixed_32_32) ((v) - (line).p1.y) *   \
 
510
           ((line).p2.x - (line).p1.x)) /         \
 
511
          ((line).p2.y - (line).p1.y)))) / 65536)
 
512
 
 
513
#define FIXED_LINE_X_CEIL_TO_FLOAT(line, v)     \
 
514
  (((glitz_float_t)                             \
 
515
      ((line).p1.x + (xFixed_16_16)             \
 
516
       (((((line).p2.y - (line).p1.y) - 1) +    \
 
517
         ((xFixed_32_32) ((v) - (line).p1.y) *  \
 
518
          ((line).p2.x - (line).p1.x))) /       \
 
519
        ((line).p2.y - (line).p1.y)))) / 65536)
 
520
 
 
521
/*
 
522
 * Adds a number of trapezoids as GL_QUAD primitives
 
523
 */
 
524
void
 
525
xglGeometryAddTrapezoid (ScreenPtr      pScreen,
 
526
                         xglGeometryPtr pGeometry,
 
527
                         xTrapezoid     *pTrap,
 
528
                         int            nTrap,
 
529
                         int            offset)
 
530
{
 
531
    int  size;
 
532
    char *ptr;
 
533
 
 
534
    if (nTrap < 1)
 
535
        return;
 
536
 
 
537
    MAP_GEOMETRY (pScreen, pGeometry, offset, nTrap * 8, ptr, size);
 
538
 
 
539
    switch (pGeometry->dataType) {
 
540
    case GEOMETRY_DATA_TYPE_SHORT:
 
541
        /* not supported */
 
542
        pGeometry->broken = TRUE;
 
543
        break;
 
544
    case GEOMETRY_DATA_TYPE_FLOAT:
 
545
    {
 
546
        glitz_float_t *data = (glitz_float_t *) ptr;
 
547
        glitz_float_t top, bottom;
 
548
 
 
549
        while (nTrap--)
 
550
        {
 
551
            top    = FIXED_TO_FLOAT (pTrap->top);
 
552
            bottom = FIXED_TO_FLOAT (pTrap->bottom);
 
553
 
 
554
            *data++ = FIXED_LINE_X_TO_FLOAT (pTrap->left, pTrap->top);
 
555
            *data++ = top;
 
556
            *data++ = FIXED_LINE_X_CEIL_TO_FLOAT (pTrap->right, pTrap->top);
 
557
            *data++ = top;
 
558
            *data++ = FIXED_LINE_X_CEIL_TO_FLOAT (pTrap->right, pTrap->bottom);
 
559
            *data++ = bottom;
 
560
            *data++ = FIXED_LINE_X_TO_FLOAT (pTrap->left, pTrap->bottom);
 
561
            *data++ = bottom;
 
562
 
 
563
            pTrap++;
 
564
        }
 
565
    } break;
 
566
    }
 
567
 
 
568
    UNMAP_GEOMETRY (pGeometry, offset, size);
 
569
}
 
570
 
 
571
/*
 
572
 * Adds a number of traps as GL_QUAD primitives
 
573
 */
 
574
void
 
575
xglGeometryAddTrap (ScreenPtr      pScreen,
 
576
                    xglGeometryPtr pGeometry,
 
577
                    xTrap          *pTrap,
 
578
                    int            nTrap,
 
579
                    int            offset)
 
580
{
 
581
    int  size;
 
582
    char *ptr;
 
583
 
 
584
    if (nTrap < 1)
 
585
        return;
 
586
 
 
587
    MAP_GEOMETRY (pScreen, pGeometry, offset, nTrap * 8, ptr, size);
 
588
 
 
589
    switch (pGeometry->dataType) {
 
590
    case GEOMETRY_DATA_TYPE_SHORT:
 
591
        /* not supported */
 
592
        pGeometry->broken = TRUE;
 
593
        break;
 
594
    case GEOMETRY_DATA_TYPE_FLOAT:
 
595
    {
 
596
        glitz_float_t *data = (glitz_float_t *) ptr;
 
597
        glitz_float_t top, bottom;
 
598
 
 
599
        while (nTrap--)
 
600
        {
 
601
            top    = FIXED_TO_FLOAT (pTrap->top.y);
 
602
            bottom = FIXED_TO_FLOAT (pTrap->bot.y);
 
603
 
 
604
            *data++ = FIXED_TO_FLOAT (pTrap->top.l);
 
605
            *data++ = top;
 
606
            *data++ = FIXED_TO_FLOAT (pTrap->top.r);
 
607
            *data++ = top;
 
608
            *data++ = FIXED_TO_FLOAT (pTrap->bot.r);
 
609
            *data++ = bottom;
 
610
            *data++ = FIXED_TO_FLOAT (pTrap->bot.l);
 
611
            *data++ = bottom;
 
612
 
 
613
            pTrap++;
 
614
        }
 
615
    } break;
 
616
    }
 
617
 
 
618
    UNMAP_GEOMETRY (pGeometry, offset, size);
 
619
}
 
620
 
 
621
/* XXX: scratch geometry size never shrinks, it just gets larger when
 
622
   required. this is not acceptable. */
 
623
xglGeometryPtr
 
624
xglGetScratchGeometryWithSize (ScreenPtr pScreen,
 
625
                               int       size)
 
626
{
 
627
    xglGeometryPtr pGeometry;
 
628
 
 
629
    XGL_SCREEN_PRIV (pScreen);
 
630
 
 
631
    pGeometry = &pScreenPriv->scratchGeometry;
 
632
 
 
633
    if (pGeometry->broken || pGeometry->size < size)
 
634
    {
 
635
        GEOMETRY_UNINIT (pGeometry);
 
636
        GEOMETRY_INIT (pScreen, pGeometry, pGeometry->type,
 
637
                       pScreenPriv->geometryUsage, size);
 
638
    }
 
639
    else
 
640
    {
 
641
        if (pGeometry->array)
 
642
        {
 
643
            glitz_multi_array_destroy (pGeometry->array);
 
644
            pGeometry->array = NULL;
 
645
        }
 
646
        pGeometry->endOffset = 0;
 
647
        pGeometry->xOff      = 0;
 
648
        pGeometry->yOff      = 0;
 
649
        pGeometry->first     = 0;
 
650
        pGeometry->count     = 0;
 
651
        pGeometry->width     = 2;
 
652
    }
 
653
 
 
654
    return pGeometry;
 
655
}
 
656
 
 
657
xglGeometryPtr
 
658
xglGetScratchVertexGeometryWithType (ScreenPtr pScreen,
 
659
                                     int       type,
 
660
                                     int       count)
 
661
{
 
662
    xglGeometryPtr pGeometry;
 
663
    int            stride;
 
664
 
 
665
    stride = 2 * xglGeometryDataTypes[type].size;
 
666
 
 
667
    pGeometry = xglGetScratchGeometryWithSize (pScreen, count * stride);
 
668
 
 
669
    pGeometry->type     = GLITZ_GEOMETRY_TYPE_VERTEX;
 
670
    pGeometry->dataType = type;
 
671
 
 
672
    pGeometry->f.vertex.primitive        = GLITZ_PRIMITIVE_QUADS;
 
673
    pGeometry->f.vertex.type             = xglGeometryDataTypes[type].type;
 
674
    pGeometry->f.vertex.bytes_per_vertex = stride;
 
675
    pGeometry->f.vertex.attributes       = 0;
 
676
 
 
677
    return pGeometry;
 
678
}
 
679
 
 
680
xglGeometryPtr
 
681
xglGetScratchVertexGeometry (ScreenPtr pScreen,
 
682
                             int         count)
 
683
{
 
684
    xglGeometryPtr pGeometry;
 
685
    int            type, stride;
 
686
 
 
687
    XGL_SCREEN_PRIV (pScreen);
 
688
 
 
689
    type   = pScreenPriv->geometryDataType;
 
690
    stride = 2 * xglGeometryDataTypes[type].size;
 
691
 
 
692
    pGeometry = xglGetScratchGeometryWithSize (pScreen, count * stride);
 
693
 
 
694
    pGeometry->type     = GLITZ_GEOMETRY_TYPE_VERTEX;
 
695
    pGeometry->dataType = type;
 
696
 
 
697
    pGeometry->f.vertex.primitive        = GLITZ_PRIMITIVE_QUADS;
 
698
    pGeometry->f.vertex.type             = xglGeometryDataTypes[type].type;
 
699
    pGeometry->f.vertex.bytes_per_vertex = stride;
 
700
    pGeometry->f.vertex.attributes       = 0;
 
701
 
 
702
    return pGeometry;
 
703
}
 
704
 
 
705
Bool
 
706
xglSetGeometry (xglGeometryPtr  pGeometry,
 
707
                glitz_surface_t *surface)
 
708
{
 
709
    if (pGeometry->broken)
 
710
        return FALSE;
 
711
 
 
712
    glitz_set_geometry (surface, pGeometry->type, &pGeometry->f,
 
713
                        pGeometry->buffer);
 
714
 
 
715
    if (pGeometry->array)
 
716
        glitz_set_multi_array (surface, pGeometry->array,
 
717
                               pGeometry->xOff, pGeometry->yOff);
 
718
    else
 
719
        glitz_set_array (surface,
 
720
                         pGeometry->first, pGeometry->width, pGeometry->count,
 
721
                         pGeometry->xOff, pGeometry->yOff);
 
722
 
 
723
    return TRUE;
 
724
}