Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / tnl_dd / t_dd_rendertmp.h
1
2 /*
3  * Mesa 3-D graphics library
4  * Version:  3.5
5  *
6  * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included
16  * in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  * Authors:
26  *    Keith Whitwell <keith@tungstengraphics.com>
27  */
28
29
30 #ifndef POSTFIX
31 #define POSTFIX
32 #endif
33
34 #ifndef INIT
35 #define INIT(x)
36 #endif
37
38 #ifndef NEED_EDGEFLAG_SETUP
39 #define NEED_EDGEFLAG_SETUP 0
40 #define EDGEFLAG_GET(a) 0
41 #define EDGEFLAG_SET(a,b) (void)b
42 #endif
43
44 #ifndef RESET_STIPPLE
45 #define RESET_STIPPLE
46 #endif
47
48 #ifndef RESET_OCCLUSION
49 #define RESET_OCCLUSION
50 #endif
51
52 #ifndef TEST_PRIM_END
53 #define TEST_PRIM_END(flags) (flags & PRIM_END)
54 #define TEST_PRIM_BEGIN(flags) (flags & PRIM_BEGIN)
55 #define TEST_PRIM_PARITY(flags) (flags & PRIM_PARITY)
56 #endif
57
58 #ifndef ELT
59 #define ELT(x) x
60 #endif
61
62 #ifndef RENDER_TAB_QUALIFIER
63 #define RENDER_TAB_QUALIFIER static
64 #endif
65
66 static void TAG(render_points)( struct gl_context *ctx,
67                                 GLuint start,
68                                 GLuint count,
69                                 GLuint flags )
70 {
71    LOCAL_VARS;
72    (void) flags;
73
74    RESET_OCCLUSION;
75    INIT(GL_POINTS);
76    RENDER_POINTS( start, count );
77    POSTFIX;
78 }
79
80 static void TAG(render_lines)( struct gl_context *ctx,
81                                GLuint start,
82                                GLuint count,
83                                GLuint flags )
84 {
85    GLuint j;
86    LOCAL_VARS;
87    (void) flags;
88
89    RESET_OCCLUSION;
90    INIT(GL_LINES);
91    for (j=start+1; j<count; j+=2 ) {
92       RENDER_LINE( ELT(j-1), ELT(j) );
93       RESET_STIPPLE;
94    }
95    POSTFIX;
96 }
97
98
99 static void TAG(render_line_strip)( struct gl_context *ctx,
100                                     GLuint start,
101                                     GLuint count,
102                                     GLuint flags )
103 {
104    GLuint j;
105    LOCAL_VARS;
106    (void) flags;
107
108    RESET_OCCLUSION;
109    INIT(GL_LINE_STRIP);
110
111    for (j=start+1; j<count; j++ )
112       RENDER_LINE( ELT(j-1), ELT(j) );
113
114    if (TEST_PRIM_END(flags))
115       RESET_STIPPLE;
116
117    POSTFIX;
118 }
119
120
121 static void TAG(render_line_loop)( struct gl_context *ctx,
122                                    GLuint start,
123                                    GLuint count,
124                                    GLuint flags )
125 {
126    GLuint i;
127    LOCAL_VARS;
128
129    (void) flags;
130
131    RESET_OCCLUSION;
132    INIT(GL_LINE_LOOP);
133
134    if (start+1 < count) {
135       if (TEST_PRIM_BEGIN(flags)) {
136          RENDER_LINE( ELT(start), ELT(start+1) );
137       }
138
139       for ( i = start+2 ; i < count ; i++) {
140          RENDER_LINE( ELT(i-1), ELT(i) );
141       }
142
143       if ( TEST_PRIM_END(flags)) {
144          RENDER_LINE( ELT(count-1), ELT(start) );
145          RESET_STIPPLE;
146       }
147    }
148
149    POSTFIX;
150 }
151
152
153 static void TAG(render_triangles)( struct gl_context *ctx,
154                                    GLuint start,
155                                    GLuint count,
156                                    GLuint flags )
157 {
158    GLuint j;
159    LOCAL_VARS;
160    (void) flags;
161
162    INIT(GL_TRIANGLES);
163    if (NEED_EDGEFLAG_SETUP) {
164       for (j=start+2; j<count; j+=3) {
165          /* Leave the edgeflags as supplied by the user.
166           */
167          RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
168          RESET_STIPPLE;
169       }
170    } else {
171       for (j=start+2; j<count; j+=3) {
172          RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
173       }
174    }
175    POSTFIX;
176 }
177
178
179
180 static void TAG(render_tri_strip)( struct gl_context *ctx,
181                                    GLuint start,
182                                    GLuint count,
183                                    GLuint flags )
184 {
185    GLuint j;
186    GLuint parity = 0;
187    LOCAL_VARS;
188
189    INIT(GL_TRIANGLE_STRIP);
190    if (NEED_EDGEFLAG_SETUP) {
191       for (j=start+2;j<count;j++,parity^=1) {
192          GLuint ej2 = ELT(j-2+parity);
193          GLuint ej1 = ELT(j-1-parity);
194          GLuint ej = ELT(j);
195          GLboolean ef2 = EDGEFLAG_GET( ej2 );
196          GLboolean ef1 = EDGEFLAG_GET( ej1 );
197          GLboolean ef = EDGEFLAG_GET( ej );
198          EDGEFLAG_SET( ej2, GL_TRUE );
199          EDGEFLAG_SET( ej1, GL_TRUE );
200          EDGEFLAG_SET( ej, GL_TRUE );
201          RENDER_TRI( ej2, ej1, ej );
202          EDGEFLAG_SET( ej2, ef2 );
203          EDGEFLAG_SET( ej1, ef1 );
204          EDGEFLAG_SET( ej, ef );
205          RESET_STIPPLE;
206       }
207    } else {
208       for (j=start+2; j<count ; j++, parity^=1) {
209          RENDER_TRI( ELT(j-2+parity), ELT(j-1-parity), ELT(j) );
210       }
211    }
212    POSTFIX;
213 }
214
215
216 static void TAG(render_tri_fan)( struct gl_context *ctx,
217                                  GLuint start,
218                                  GLuint count,
219                                  GLuint flags )
220 {
221    GLuint j;
222    LOCAL_VARS;
223    (void) flags;
224
225    INIT(GL_TRIANGLE_FAN);
226    if (NEED_EDGEFLAG_SETUP) {
227       for (j=start+2;j<count;j++) {
228          /* For trifans, all edges are boundary.
229           */
230          GLuint ejs = ELT(start);
231          GLuint ej1 = ELT(j-1);
232          GLuint ej = ELT(j);
233          GLboolean efs = EDGEFLAG_GET( ejs );
234          GLboolean ef1 = EDGEFLAG_GET( ej1 );
235          GLboolean ef = EDGEFLAG_GET( ej );
236          EDGEFLAG_SET( ejs, GL_TRUE );
237          EDGEFLAG_SET( ej1, GL_TRUE );
238          EDGEFLAG_SET( ej, GL_TRUE );
239          RENDER_TRI( ejs, ej1, ej);
240          EDGEFLAG_SET( ejs, efs );
241          EDGEFLAG_SET( ej1, ef1 );
242          EDGEFLAG_SET( ej, ef );
243          RESET_STIPPLE;
244       }
245    } else {
246       for (j=start+2;j<count;j++) {
247          RENDER_TRI( ELT(start), ELT(j-1), ELT(j) );
248       }
249    }
250
251    POSTFIX;
252 }
253
254
255 static void TAG(render_poly)( struct gl_context *ctx,
256                               GLuint start,
257                               GLuint count,
258                               GLuint flags )
259 {
260    GLuint j = start+2;
261    LOCAL_VARS;
262    (void) flags;
263
264    INIT(GL_POLYGON);
265    if (NEED_EDGEFLAG_SETUP) {
266       GLboolean efstart = EDGEFLAG_GET( ELT(start) );
267       GLboolean efcount = EDGEFLAG_GET( ELT(count-1) );
268
269       /* If the primitive does not begin here, the first edge
270        * is non-boundary.
271        */
272       if (!TEST_PRIM_BEGIN(flags))
273          EDGEFLAG_SET( ELT(start), GL_FALSE );
274
275       /* If the primitive does not end here, the final edge is
276        * non-boundary.
277        */
278       if (!TEST_PRIM_END(flags))
279          EDGEFLAG_SET( ELT(count-1), GL_FALSE );
280
281       /* Draw the first triangles (possibly zero)
282        */
283       if (j<count-1) {
284          GLboolean ef = EDGEFLAG_GET( ELT(j) );
285          EDGEFLAG_SET( ELT(j), GL_FALSE );
286          RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
287          EDGEFLAG_SET( ELT(j), ef );
288          j++;
289
290          /* Don't render the first edge again:
291           */
292          EDGEFLAG_SET( ELT(start), GL_FALSE );
293
294          for (;j<count-1;j++) {
295             GLboolean efj = EDGEFLAG_GET( ELT(j) );
296             EDGEFLAG_SET( ELT(j), GL_FALSE );
297             RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
298             EDGEFLAG_SET( ELT(j), efj );
299          }
300       }
301
302       /* Draw the last or only triangle
303        */
304       if (j < count)
305          RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
306
307       /* Restore the first and last edgeflags:
308        */
309       EDGEFLAG_SET( ELT(count-1), efcount );
310       EDGEFLAG_SET( ELT(start), efstart );
311
312       if (TEST_PRIM_END(flags)) {
313          RESET_STIPPLE;
314       }
315    }
316    else {
317       for (j=start+2;j<count;j++) {
318          RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
319       }
320    }
321    POSTFIX;
322 }
323
324 static void TAG(render_quads)( struct gl_context *ctx,
325                                GLuint start,
326                                GLuint count,
327                                GLuint flags )
328 {
329    GLuint j;
330    LOCAL_VARS;
331    (void) flags;
332
333    INIT(GL_QUADS);
334    if (NEED_EDGEFLAG_SETUP) {
335       for (j=start+3; j<count; j+=4) {
336          /* Use user-specified edgeflags for quads.
337           */
338          RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
339          RESET_STIPPLE;
340       }
341    } else {
342       for (j=start+3; j<count; j+=4) {
343          RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
344       }
345    }
346    POSTFIX;
347 }
348
349 static void TAG(render_quad_strip)( struct gl_context *ctx,
350                                     GLuint start,
351                                     GLuint count,
352                                     GLuint flags )
353 {
354    GLuint j;
355    LOCAL_VARS;
356    (void) flags;
357
358    INIT(GL_QUAD_STRIP);
359    if (NEED_EDGEFLAG_SETUP) {
360       for (j=start+3;j<count;j+=2) {
361          /* All edges are boundary.  Set edgeflags to 1, draw the
362           * quad, and restore them to the original values.
363           */
364          GLboolean ef3 = EDGEFLAG_GET( ELT(j-3) );
365          GLboolean ef2 = EDGEFLAG_GET( ELT(j-2) );
366          GLboolean ef1 = EDGEFLAG_GET( ELT(j-1) );
367          GLboolean ef = EDGEFLAG_GET( ELT(j) );
368          EDGEFLAG_SET( ELT(j-3), GL_TRUE );
369          EDGEFLAG_SET( ELT(j-2), GL_TRUE );
370          EDGEFLAG_SET( ELT(j-1), GL_TRUE );
371          EDGEFLAG_SET( ELT(j), GL_TRUE );
372          RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
373          EDGEFLAG_SET( ELT(j-3), ef3 );
374          EDGEFLAG_SET( ELT(j-2), ef2 );
375          EDGEFLAG_SET( ELT(j-1), ef1 );
376          EDGEFLAG_SET( ELT(j), ef );
377          RESET_STIPPLE;
378       }
379    } else {
380       for (j=start+3;j<count;j+=2) {
381          RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
382       }
383    }
384    POSTFIX;
385 }
386
387 static void TAG(render_noop)( struct gl_context *ctx,
388                               GLuint start,
389                               GLuint count,
390                               GLuint flags )
391 {
392    (void)(ctx && start && count && flags);
393 }
394
395 RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON+2])(struct gl_context *,
396                                                            GLuint,
397                                                            GLuint,
398                                                            GLuint) =
399 {
400    TAG(render_points),
401    TAG(render_lines),
402    TAG(render_line_loop),
403    TAG(render_line_strip),
404    TAG(render_triangles),
405    TAG(render_tri_strip),
406    TAG(render_tri_fan),
407    TAG(render_quads),
408    TAG(render_quad_strip),
409    TAG(render_poly),
410    TAG(render_noop),
411 };
412
413
414
415 #ifndef PRESERVE_VB_DEFS
416 #undef RENDER_TRI
417 #undef RENDER_QUAD
418 #undef RENDER_LINE
419 #undef RENDER_POINTS
420 #undef LOCAL_VARS
421 #undef INIT
422 #undef POSTFIX
423 #undef RESET_STIPPLE
424 #undef DBG
425 #undef ELT
426 #undef RENDER_TAB_QUALIFIER
427 #endif
428
429 #ifndef PRESERVE_TAG
430 #undef TAG
431 #endif
432
433 #undef PRESERVE_VB_DEFS
434 #undef PRESERVE_TAG