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