00e9df68f37dc8ae4300c944ffaa8b2dee1f5ef8
[mesa.git] / src / mesa / drivers / x11 / xm_line.c
1 /* $Id: xm_line.c,v 1.6 2000/11/05 18:26:12 keithw Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28 /*
29 * This file contains "accelerated" point, line, and triangle functions.
30 * It should be fairly easy to write new special-purpose point, line or
31 * triangle functions and hook them into this module.
32 */
33
34
35 #include "glxheader.h"
36 #include "depth.h"
37 #include "macros.h"
38 #include "vb.h"
39 #include "types.h"
40 #include "xmesaP.h"
41
42 /* Internal swrast includes:
43 */
44 #include "swrast/s_depth.h"
45 #include "swrast/s_points.h"
46 #include "swrast/s_lines.h"
47 #include "swrast/s_context.h"
48
49
50 /**********************************************************************/
51 /*** Point rendering ***/
52 /**********************************************************************/
53
54
55 /*
56 * Render an array of points into a pixmap, any pixel format.
57 */
58 static void draw_points_ANY_pixmap( GLcontext *ctx, SWvertex *vert )
59 {
60 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
61 XMesaDisplay *dpy = xmesa->xm_visual->display;
62 XMesaDrawable buffer = xmesa->xm_buffer->buffer;
63 XMesaGC gc = xmesa->xm_buffer->gc2;
64
65 if (xmesa->xm_visual->gl_visual->RGBAflag) {
66 register int x, y;
67 const GLubyte *color = vert->color;
68 unsigned long pixel = xmesa_color_to_pixel( xmesa,
69 color[0], color[1],
70 color[2], color[3],
71 xmesa->pixelformat);
72 XMesaSetForeground( dpy, gc, pixel );
73 x = (GLint) vert->win[0];
74 y = FLIP( xmesa->xm_buffer, (GLint) vert->win[1] );
75 XMesaDrawPoint( dpy, buffer, gc, x, y);
76 }
77 else {
78 /* Color index mode */
79 register int x, y;
80 XMesaSetForeground( dpy, gc, vert->index );
81 x = (GLint) vert->win[0];
82 y = FLIP( xmesa->xm_buffer, (GLint) vert->win[1] );
83 XMesaDrawPoint( dpy, buffer, gc, x, y);
84 }
85 }
86
87
88
89 /* Override the swrast point-selection function. Try to use one of
90 * our internal point functions, otherwise fall back to the standard
91 * swrast functions.
92 */
93 void xmesa_choose_point( GLcontext *ctx )
94 {
95 SWcontext *swrast = SWRAST_CONTEXT(ctx);
96
97 if (ctx->Point.Size==1.0F && !ctx->Point.SmoothFlag
98 && swrast->_RasterMask==0
99 && !ctx->Texture._ReallyEnabled) {
100 swrast->Point = draw_points_ANY_pixmap;
101 }
102 else {
103 _swrast_choose_point( ctx );
104 }
105 }
106
107
108
109 /**********************************************************************/
110 /*** Line rendering ***/
111 /**********************************************************************/
112
113
114 #if 0
115 /*
116 * Render a line into a pixmap, any pixel format.
117 */
118 static void flat_pixmap_line( GLcontext *ctx,
119 SWvertex *vert0, SWvertex *vert1 )
120 {
121 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
122 register int x0, y0, x1, y1;
123 XMesaGC gc;
124 unsigned long pixel;
125 if (xmesa->xm_visual->gl_visual->RGBAflag) {
126 const GLubyte *color = vert0->color;
127 pixel = xmesa_color_to_pixel( xmesa, color[0], color[1], color[2], color[3],
128 xmesa->pixelformat );
129 }
130 else {
131 pixel = vert0->index;
132 }
133 gc = xmesa->xm_buffer->gc2;
134 XMesaSetForeground( xmesa->display, gc, pixel );
135
136 x0 = (GLint) vert0->win[0];
137 y0 = FLIP( xmesa->xm_buffer, (GLint) vert0->win[1] );
138 x1 = (GLint) vert1->win[0];
139 y1 = FLIP( xmesa->xm_buffer, (GLint) vert1->win[1] );
140 XMesaDrawLine( xmesa->display, xmesa->xm_buffer->buffer, gc,
141 x0, y0, x1, y1 );
142 }
143 #endif
144
145
146 /*
147 * Draw a flat-shaded, PF_TRUECOLOR line into an XImage.
148 */
149 static void flat_TRUECOLOR_line( GLcontext *ctx,
150 SWvertex *vert0, SWvertex *vert1 )
151 {
152 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
153 const GLubyte *color = vert0->color;
154 XMesaImage *img = xmesa->xm_buffer->backimage;
155 unsigned long pixel;
156 PACK_TRUECOLOR( pixel, color[0], color[1], color[2] );
157
158 #define INTERP_XY 1
159 #define CLIP_HACK 1
160 #define PLOT(X,Y) XMesaPutPixel( img, X, FLIP(xmesa->xm_buffer, Y), pixel );
161
162 #include "swrast/s_linetemp.h"
163 }
164
165
166
167 /*
168 * Draw a flat-shaded, PF_8A8B8G8R line into an XImage.
169 */
170 static void flat_8A8B8G8R_line( GLcontext *ctx,
171 SWvertex *vert0, SWvertex *vert1 )
172 {
173 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
174 const GLubyte *color = vert0->color;
175 GLuint pixel = PACK_8B8G8R( color[0], color[1], color[2] );
176
177 #define PIXEL_TYPE GLuint
178 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
179 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y)
180 #define CLIP_HACK 1
181 #define PLOT(X,Y) *pixelPtr = pixel;
182
183 #include "swrast/s_linetemp.h"
184 }
185
186
187 /*
188 * Draw a flat-shaded, PF_8R8G8B line into an XImage.
189 */
190 static void flat_8R8G8B_line( GLcontext *ctx,
191 SWvertex *vert0, SWvertex *vert1 )
192 {
193 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
194 const GLubyte *color = vert0->color;
195 GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] );
196
197 #define PIXEL_TYPE GLuint
198 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
199 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y)
200 #define CLIP_HACK 1
201 #define PLOT(X,Y) *pixelPtr = pixel;
202
203 #include "swrast/s_linetemp.h"
204 }
205
206
207 /*
208 * Draw a flat-shaded, PF_8R8G8B24 line into an XImage.
209 */
210 static void flat_8R8G8B24_line( GLcontext *ctx,
211 SWvertex *vert0, SWvertex *vert1 )
212 {
213 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
214 const GLubyte *color = vert0->color;
215
216 #define PIXEL_TYPE bgr_t
217 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
218 #define PIXEL_ADDRESS(X,Y) PIXELADDR3(xmesa->xm_buffer,X,Y)
219 #define CLIP_HACK 1
220 #define PLOT(X,Y) { \
221 pixelPtr->r = color[RCOMP]; \
222 pixelPtr->g = color[GCOMP]; \
223 pixelPtr->b = color[BCOMP]; \
224 }
225
226 #include "swrast/s_linetemp.h"
227 }
228
229
230 /*
231 * Draw a flat-shaded, PF_5R6G5B line into an XImage.
232 */
233 static void flat_5R6G5B_line( GLcontext *ctx,
234 SWvertex *vert0, SWvertex *vert1 )
235 {
236 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
237 const GLubyte *color = vert0->color;
238 GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] );
239
240 #define PIXEL_TYPE GLushort
241 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
242 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y)
243 #define CLIP_HACK 1
244 #define PLOT(X,Y) *pixelPtr = pixel;
245
246 #include "swrast/s_linetemp.h"
247 }
248
249
250 /*
251 * Draw a flat-shaded, PF_DITHER_5R6G5B line into an XImage.
252 */
253 static void flat_DITHER_5R6G5B_line( GLcontext *ctx,
254 SWvertex *vert0, SWvertex *vert1 )
255 {
256 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
257 const GLubyte *color = vert0->color;
258
259 #define PIXEL_TYPE GLushort
260 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
261 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y)
262 #define CLIP_HACK 1
263 #define PLOT(X,Y) PACK_TRUEDITHER( *pixelPtr, X, Y, color[0], color[1], color[2] );
264
265 #include "swrast/s_linetemp.h"
266 }
267
268
269
270 /*
271 * Draw a flat-shaded, PF_DITHER 8-bit line into an XImage.
272 */
273 static void flat_DITHER8_line( GLcontext *ctx,
274 SWvertex *vert0, SWvertex *vert1 )
275 {
276 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
277 const GLubyte *color = vert0->color;
278 GLint r = color[0], g = color[1], b = color[2];
279 DITHER_SETUP;
280
281 #define INTERP_XY 1
282 #define PIXEL_TYPE GLubyte
283 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
284 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
285 #define CLIP_HACK 1
286 #define PLOT(X,Y) *pixelPtr = DITHER(X,Y,r,g,b);
287
288 #include "swrast/s_linetemp.h"
289 }
290
291
292 /*
293 * Draw a flat-shaded, PF_LOOKUP 8-bit line into an XImage.
294 */
295 static void flat_LOOKUP8_line( GLcontext *ctx,
296 SWvertex *vert0, SWvertex *vert1 )
297 {
298 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
299 const GLubyte *color = vert0->color;
300 GLubyte pixel;
301 LOOKUP_SETUP;
302 pixel = (GLubyte) LOOKUP( color[0], color[1], color[2] );
303
304 #define PIXEL_TYPE GLubyte
305 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
306 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
307 #define CLIP_HACK 1
308 #define PLOT(X,Y) *pixelPtr = pixel;
309
310 #include "swrast/s_linetemp.h"
311 }
312
313
314 /*
315 * Draw a flat-shaded, PF_HPCR line into an XImage.
316 */
317 static void flat_HPCR_line( GLcontext *ctx,
318 SWvertex *vert0, SWvertex *vert1 )
319 {
320 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
321 const GLubyte *color = vert0->color;
322 GLint r = color[0], g = color[1], b = color[2];
323
324 #define INTERP_XY 1
325 #define PIXEL_TYPE GLubyte
326 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
327 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
328 #define CLIP_HACK 1
329 #define PLOT(X,Y) *pixelPtr = (GLubyte) DITHER_HPCR(X,Y,r,g,b);
330
331 #include "swrast/s_linetemp.h"
332 }
333
334
335
336 /*
337 * Draw a flat-shaded, Z-less, PF_TRUECOLOR line into an XImage.
338 */
339 static void flat_TRUECOLOR_z_line( GLcontext *ctx,
340 SWvertex *vert0, SWvertex *vert1 )
341 {
342 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
343 const GLubyte *color = vert0->color;
344 XMesaImage *img = xmesa->xm_buffer->backimage;
345 unsigned long pixel;
346 PACK_TRUECOLOR( pixel, color[0], color[1], color[2] );
347
348 #define INTERP_XY 1
349 #define INTERP_Z 1
350 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
351 #define CLIP_HACK 1
352 #define PLOT(X,Y) \
353 if (Z < *zPtr) { \
354 *zPtr = Z; \
355 XMesaPutPixel( img, X, FLIP(xmesa->xm_buffer, Y), pixel ); \
356 }
357
358 #include "swrast/s_linetemp.h"
359 }
360
361
362 /*
363 * Draw a flat-shaded, Z-less, PF_8A8B8G8R line into an XImage.
364 */
365 static void flat_8A8B8G8R_z_line( GLcontext *ctx,
366 SWvertex *vert0, SWvertex *vert1 )
367 {
368 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
369 const GLubyte *color = vert0->color;
370 GLuint pixel = PACK_8B8G8R( color[0], color[1], color[2] );
371
372 #define INTERP_Z 1
373 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
374 #define PIXEL_TYPE GLuint
375 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
376 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y)
377 #define CLIP_HACK 1
378 #define PLOT(X,Y) \
379 if (Z < *zPtr) { \
380 *zPtr = Z; \
381 *pixelPtr = pixel; \
382 }
383
384 #include "swrast/s_linetemp.h"
385 }
386
387
388 /*
389 * Draw a flat-shaded, Z-less, PF_8R8G8B line into an XImage.
390 */
391 static void flat_8R8G8B_z_line( GLcontext *ctx,
392 SWvertex *vert0, SWvertex *vert1 )
393 {
394 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
395 const GLubyte *color = vert0->color;
396 GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] );
397
398 #define INTERP_Z 1
399 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
400 #define PIXEL_TYPE GLuint
401 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
402 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y)
403 #define CLIP_HACK 1
404 #define PLOT(X,Y) \
405 if (Z < *zPtr) { \
406 *zPtr = Z; \
407 *pixelPtr = pixel; \
408 }
409
410 #include "swrast/s_linetemp.h"
411 }
412
413
414 /*
415 * Draw a flat-shaded, Z-less, PF_8R8G8B24 line into an XImage.
416 */
417 static void flat_8R8G8B24_z_line( GLcontext *ctx,
418 SWvertex *vert0, SWvertex *vert1 )
419 {
420 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
421 const GLubyte *color = vert0->color;
422
423 #define INTERP_Z 1
424 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
425 #define PIXEL_TYPE bgr_t
426 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
427 #define PIXEL_ADDRESS(X,Y) PIXELADDR3(xmesa->xm_buffer,X,Y)
428 #define CLIP_HACK 1
429 #define PLOT(X,Y) \
430 if (Z < *zPtr) { \
431 *zPtr = Z; \
432 pixelPtr->r = color[RCOMP]; \
433 pixelPtr->g = color[GCOMP]; \
434 pixelPtr->b = color[BCOMP]; \
435 }
436
437 #include "swrast/s_linetemp.h"
438 }
439
440
441 /*
442 * Draw a flat-shaded, Z-less, PF_5R6G5B line into an XImage.
443 */
444 static void flat_5R6G5B_z_line( GLcontext *ctx,
445 SWvertex *vert0, SWvertex *vert1 )
446 {
447 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
448 const GLubyte *color = vert0->color;
449 GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] );
450
451 #define INTERP_Z 1
452 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
453 #define PIXEL_TYPE GLushort
454 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
455 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y)
456 #define CLIP_HACK 1
457 #define PLOT(X,Y) \
458 if (Z < *zPtr) { \
459 *zPtr = Z; \
460 *pixelPtr = pixel; \
461 }
462 #include "swrast/s_linetemp.h"
463 }
464
465
466 /*
467 * Draw a flat-shaded, Z-less, PF_DITHER_5R6G5B line into an XImage.
468 */
469 static void flat_DITHER_5R6G5B_z_line( GLcontext *ctx,
470 SWvertex *vert0, SWvertex *vert1 )
471 {
472 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
473 const GLubyte *color = vert0->color;
474
475 #define INTERP_Z 1
476 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
477 #define PIXEL_TYPE GLushort
478 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
479 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y)
480 #define CLIP_HACK 1
481 #define PLOT(X,Y) \
482 if (Z < *zPtr) { \
483 *zPtr = Z; \
484 PACK_TRUEDITHER(*pixelPtr, X, Y, color[0], color[1], color[2]); \
485 }
486 #include "swrast/s_linetemp.h"
487 }
488
489
490 /*
491 * Draw a flat-shaded, Z-less, PF_DITHER 8-bit line into an XImage.
492 */
493 static void flat_DITHER8_z_line( GLcontext *ctx,
494 SWvertex *vert0, SWvertex *vert1 )
495 {
496 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
497 const GLubyte *color = vert0->color;
498 GLint r = color[0], g = color[1], b = color[2];
499 DITHER_SETUP;
500
501 #define INTERP_XY 1
502 #define INTERP_Z 1
503 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
504 #define PIXEL_TYPE GLubyte
505 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
506 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
507 #define CLIP_HACK 1
508 #define PLOT(X,Y) \
509 if (Z < *zPtr) { \
510 *zPtr = Z; \
511 *pixelPtr = (GLubyte) DITHER( X, Y, r, g, b); \
512 }
513 #include "swrast/s_linetemp.h"
514 }
515
516
517 /*
518 * Draw a flat-shaded, Z-less, PF_LOOKUP 8-bit line into an XImage.
519 */
520 static void flat_LOOKUP8_z_line( GLcontext *ctx,
521 SWvertex *vert0, SWvertex *vert1 )
522 {
523 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
524 const GLubyte *color = vert0->color;
525 GLubyte pixel;
526 LOOKUP_SETUP;
527 pixel = (GLubyte) LOOKUP( color[0], color[1], color[2] );
528
529 #define INTERP_Z 1
530 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
531 #define PIXEL_TYPE GLubyte
532 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
533 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
534 #define CLIP_HACK 1
535 #define PLOT(X,Y) \
536 if (Z < *zPtr) { \
537 *zPtr = Z; \
538 *pixelPtr = pixel; \
539 }
540
541 #include "swrast/s_linetemp.h"
542 }
543
544
545 /*
546 * Draw a flat-shaded, Z-less, PF_HPCR line into an XImage.
547 */
548 static void flat_HPCR_z_line( GLcontext *ctx,
549 SWvertex *vert0, SWvertex *vert1 )
550 {
551 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
552 const GLubyte *color = vert0->color;
553 GLint r = color[0], g = color[1], b = color[2];
554
555 #define INTERP_XY 1
556 #define INTERP_Z 1
557 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
558 #define PIXEL_TYPE GLubyte
559 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
560 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
561 #define CLIP_HACK 1
562 #define PLOT(X,Y) \
563 if (Z < *zPtr) { \
564 *zPtr = Z; \
565 *pixelPtr = (GLubyte) DITHER_HPCR( X, Y, r, g, b); \
566 }
567
568 #include "swrast/s_linetemp.h"
569 }
570
571
572 #if 0
573 /*
574 * Examine ctx->Line attributes and set xmesa->xm_buffer->gc1
575 * and xmesa->xm_buffer->gc2 appropriately.
576 */
577 static void setup_x_line_options( GLcontext *ctx )
578 {
579 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
580 int i, state, state0, new_state, len, offs;
581 int tbit;
582 char *dptr;
583 int n_segments = 0;
584 char dashes[20];
585 int line_width, line_style;
586
587 /*** Line Stipple ***/
588 if (ctx->Line.StippleFlag) {
589 const int pattern = ctx->Line.StipplePattern;
590
591 dptr = dashes;
592 state0 = state = ((pattern & 1) != 0);
593
594 /* Decompose the pattern */
595 for (i=1,tbit=2,len=1;i<16;++i,tbit=(tbit<<1))
596 {
597 new_state = ((tbit & pattern) != 0);
598 if (state != new_state)
599 {
600 *dptr++ = ctx->Line.StippleFactor * len;
601 len = 1;
602 state = new_state;
603 }
604 else
605 ++len;
606 }
607 *dptr = ctx->Line.StippleFactor * len;
608 n_segments = 1 + (dptr - dashes);
609
610 /* ensure an even no. of segments, or X may toggle on/off for consecutive patterns */
611 /* if (n_segments & 1) dashes [n_segments++] = 0; value of 0 not allowed in dash list */
612
613 /* Handle case where line style starts OFF */
614 if (state0 == 0)
615 offs = dashes[0];
616 else
617 offs = 0;
618
619 #if 0
620 fprintf (stderr, "input pattern: 0x%04x, offset %d, %d segments:", pattern, offs, n_segments);
621 for (i = 0; i < n_segments; i++)
622 fprintf (stderr, " %d", dashes[i]);
623 fprintf (stderr, "\n");
624 #endif
625
626 XMesaSetDashes( xmesa->display, xmesa->xm_buffer->gc1,
627 offs, dashes, n_segments );
628 XMesaSetDashes( xmesa->display, xmesa->xm_buffer->gc2,
629 offs, dashes, n_segments );
630
631 line_style = LineOnOffDash;
632 }
633 else {
634 line_style = LineSolid;
635 }
636
637 /*** Line Width ***/
638 line_width = (int) (ctx->Line.Width+0.5F);
639 if (line_width < 2) {
640 /* Use fast lines when possible */
641 line_width = 0;
642 }
643
644 /*** Set GC attributes ***/
645 XMesaSetLineAttributes( xmesa->display, xmesa->xm_buffer->gc1,
646 line_width, line_style, CapButt, JoinBevel);
647 XMesaSetLineAttributes( xmesa->display, xmesa->xm_buffer->gc2,
648 line_width, line_style, CapButt, JoinBevel);
649 XMesaSetFillStyle( xmesa->display, xmesa->xm_buffer->gc1, FillSolid );
650 XMesaSetFillStyle( xmesa->display, xmesa->xm_buffer->gc2, FillSolid );
651 }
652 #endif
653
654
655 static swrast_line_func get_line_func( GLcontext *ctx )
656 {
657 XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
658 SWcontext *swrast = SWRAST_CONTEXT(ctx);
659 int depth = GET_VISUAL_DEPTH(xmesa->xm_visual);
660
661 (void) DitherValues; /* silence unused var warning */
662 (void) kernel1; /* silence unused var warning */
663
664 if (ctx->Line.SmoothFlag) return (swrast_line_func)NULL;
665 if (ctx->Texture._ReallyEnabled) return (swrast_line_func)NULL;
666 if (ctx->Light.ShadeModel!=GL_FLAT) return (swrast_line_func)NULL;
667 /* X line stippling doesn't match OpenGL stippling */
668 if (ctx->Line.StippleFlag==GL_TRUE) return (swrast_line_func)NULL;
669
670 if (xmesa->xm_buffer->buffer==XIMAGE
671 && swrast->_RasterMask==DEPTH_BIT
672 && ctx->Depth.Func==GL_LESS
673 && ctx->Depth.Mask==GL_TRUE
674 && ctx->Visual.DepthBits == DEFAULT_SOFTWARE_DEPTH_BITS
675 && ctx->Line.Width==1.0F) {
676 switch (xmesa->pixelformat) {
677 case PF_TRUECOLOR:
678 return flat_TRUECOLOR_z_line;
679 case PF_8A8B8G8R:
680 return flat_8A8B8G8R_z_line;
681 case PF_8R8G8B:
682 return flat_8R8G8B_z_line;
683 case PF_8R8G8B24:
684 return flat_8R8G8B24_z_line;
685 case PF_5R6G5B:
686 return flat_5R6G5B_z_line;
687 case PF_DITHER_5R6G5B:
688 return flat_DITHER_5R6G5B_z_line;
689 case PF_DITHER:
690 return (depth==8) ? flat_DITHER8_z_line : (swrast_line_func)NULL;
691 case PF_LOOKUP:
692 return (depth==8) ? flat_LOOKUP8_z_line : (swrast_line_func)NULL;
693 case PF_HPCR:
694 return flat_HPCR_z_line;
695 default:
696 return (swrast_line_func)NULL;
697 }
698 }
699 if (xmesa->xm_buffer->buffer==XIMAGE
700 && swrast->_RasterMask==0
701 && ctx->Line.Width==1.0F) {
702 switch (xmesa->pixelformat) {
703 case PF_TRUECOLOR:
704 return flat_TRUECOLOR_line;
705 case PF_8A8B8G8R:
706 return flat_8A8B8G8R_line;
707 case PF_8R8G8B:
708 return flat_8R8G8B_line;
709 case PF_8R8G8B24:
710 return flat_8R8G8B24_line;
711 case PF_5R6G5B:
712 return flat_5R6G5B_line;
713 case PF_DITHER_5R6G5B:
714 return flat_DITHER_5R6G5B_line;
715 case PF_DITHER:
716 return (depth==8) ? flat_DITHER8_line : (swrast_line_func)NULL;
717 case PF_LOOKUP:
718 return (depth==8) ? flat_LOOKUP8_line : (swrast_line_func)NULL;
719 case PF_HPCR:
720 return flat_HPCR_line;
721 default:
722 return (swrast_line_func)NULL;
723 }
724 }
725 #if 0
726 /* XXX have to disable this because X's rasterization rules don't match
727 * software Mesa's. This causes the linehv.c conformance test to fail.
728 * In the future, we might provide a config option to enable this.
729 */
730 if (xmesa->xm_buffer->buffer!=XIMAGE && ctx->_RasterMask==0) {
731 setup_x_line_options( ctx );
732 return flat_pixmap_line;
733 }
734 #endif
735 return (swrast_line_func)NULL;
736 }
737
738 /* Override for the swrast line-selection function. Try to use one
739 * of our internal line functions, otherwise fall back to the
740 * standard swrast functions.
741 */
742 void xmesa_choose_line( GLcontext *ctx )
743 {
744 SWcontext *swrast = SWRAST_CONTEXT(ctx);
745
746 if (!(swrast->Line = get_line_func( ctx )))
747 _swrast_choose_line( ctx );
748 }
749
750
751 #define XMESA_NEW_POINT (_NEW_POINT|_SWRAST_NEW_RASTERMASK)
752 #define XMESA_NEW_LINE (_NEW_LINE|_NEW_TEXTURE|_NEW_LIGHT|\
753 _NEW_DEPTH|_SWRAST_NEW_RASTERMASK)
754 #define XMESA_NEW_TRIANGLE (_NEW_POLYGON|_NEW_TEXTURE|_NEW_LIGHT|\
755 _SWRAST_NEW_RASTERMASK|_NEW_DEPTH)
756
757
758 /* Extend the software rasterizer with our line/point/triangle
759 * functions.
760 */
761 void xmesa_register_swrast_functions( GLcontext *ctx )
762 {
763 SWcontext *swrast = SWRAST_CONTEXT( ctx );
764
765 swrast->choose_point = xmesa_choose_point;
766 swrast->choose_line = xmesa_choose_line;
767 swrast->choose_triangle = xmesa_choose_triangle;
768
769 swrast->invalidate_point |= XMESA_NEW_POINT;
770 swrast->invalidate_line |= XMESA_NEW_LINE;
771 swrast->invalidate_triangle |= XMESA_NEW_TRIANGLE;
772 }