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