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