bab6326ebafb67f936f3282893a0eb6e56bfb589
[mesa.git] / src / mesa / tnl / t_context.c
1 #include "types.h"
2 #include "mem.h"
3
4 #include "t_context.h"
5 #include "t_clip.h"
6 #include "t_cva.h"
7 #include "t_dlist.h"
8 #include "t_eval.h"
9 #include "t_pipeline.h"
10 #include "t_shade.h"
11 #include "t_light.h"
12 #include "t_texture.h"
13 #include "t_stages.h"
14 #include "t_varray.h"
15 #include "t_vb.h"
16 #include "t_vbrender.h"
17 #include "t_vbxform.h"
18 #include "tnl.h"
19
20 #if !defined(THREADS)
21 struct immediate *_mesa_CurrentInput = NULL;
22 #endif
23
24
25 GLboolean
26 _tnl_flush_vertices( GLcontext *ctx, GLuint flush_flags )
27 {
28 TNLcontext *tnl = TNL_CONTEXT(ctx);
29 struct immediate *IM = TNL_CURRENT_IM(ctx);
30
31 if ((IM->Flag[IM->Count] & (VERT_BEGIN|VERT_END)) != VERT_END ||
32 (flush_flags & (FLUSH_STORED_VERTICES|FLUSH_UPDATE_CURRENT)))
33 {
34 if (IM->Flag[IM->Start])
35 _mesa_flush_vb( ctx );
36
37 /* Although this code updates the ctx->Current values, that bit
38 * is left set as there is no easy mechanism to set it
39 * elsewhere. This means that each time core wants to examine
40 * ctx->Current, this function will be called. After the first
41 * time, however, it will be a no-op.
42 */
43 ctx->Driver.NeedFlush &= ~(FLUSH_STORED_VERTICES |
44 FLUSH_INSIDE_BEGIN_END);
45
46 return (tnl->_CurrentPrimitive == GL_POLYGON+1);
47 }
48 else
49 return GL_TRUE;
50 }
51
52
53 GLboolean
54 _tnl_CreateContext( GLcontext *ctx )
55 {
56 TNLcontext *tnl;
57 static int firsttime = 1;
58
59 /* Onetime initializations. Doesn't really matter if this gets
60 * done twice: no need for mutexes.
61 */
62 if (firsttime) {
63 firsttime = 0;
64 _tnl_clip_init( );
65 _tnl_eval_init( );
66 _tnl_shade_init( );
67 _tnl_texture_init( );
68 _tnl_trans_elt_init( );
69 _tnl_vbrender_init( );
70 _tnl_stages_init( );
71 }
72
73 /* Create the TNLcontext structure
74 */
75 ctx->swtnl_context = tnl = CALLOC( sizeof(TNLcontext) );
76 if (!tnl) {
77 return GL_FALSE;
78 }
79
80 /* Create and hook in the data structures available from ctx.
81 */
82 ctx->swtnl_vb = (void *)gl_vb_create_for_immediate( ctx );
83 if (!ctx->swtnl_vb) {
84 FREE(tnl);
85 ctx->swtnl_context = 0;
86 return GL_FALSE;
87 }
88
89 ctx->swtnl_im = (void *)TNL_VB(ctx)->IM;
90
91
92 /* Initialize tnl state.
93 */
94 _tnl_dlist_init( ctx );
95 _tnl_pipeline_init( ctx );
96
97 tnl->_CurrentFlag = (VERT_NORM |
98 VERT_INDEX |
99 VERT_RGBA |
100 VERT_SPEC_RGB |
101 VERT_FOG_COORD |
102 VERT_EDGE |
103 VERT_TEX0_12 |
104 VERT_TEX1_12 |
105 VERT_TEX2_12 |
106 VERT_TEX3_12 |
107 VERT_MATERIAL);
108
109 tnl->_CurrentPrimitive = GL_POLYGON+1;
110
111 gl_reset_vb( TNL_VB(ctx) );
112 gl_reset_input( ctx );
113
114
115 /* Set a few default values in the driver struct. This is a
116 * temporary mechanism.
117 */
118 ctx->Driver.RenderVBCulledTab = _tnl_render_tab_cull;
119 ctx->Driver.RenderVBClippedTab = _tnl_render_tab_clipped;
120 ctx->Driver.RenderVBRawTab = _tnl_render_tab_raw;
121 ctx->Driver.NewList = _tnl_NewList;
122 ctx->Driver.EndList = _tnl_EndList;
123 ctx->Driver.FlushVertices = _tnl_flush_vertices;
124 ctx->Driver.NeedFlush = FLUSH_UPDATE_CURRENT;
125 ctx->Driver.LightingSpaceChange = _tnl_LightingSpaceChange;
126 ctx->Driver.MakeCurrent = _tnl_MakeCurrent;
127 ctx->Driver.VertexPointer = _tnl_VertexPointer;
128 ctx->Driver.NormalPointer = _tnl_NormalPointer;
129 ctx->Driver.ColorPointer = _tnl_ColorPointer;
130 ctx->Driver.FogCoordPointer = _tnl_FogCoordPointer;
131 ctx->Driver.IndexPointer = _tnl_IndexPointer;
132 ctx->Driver.SecondaryColorPointer = _tnl_SecondaryColorPointer;
133 ctx->Driver.TexCoordPointer = _tnl_TexCoordPointer;
134 ctx->Driver.EdgeFlagPointer = _tnl_EdgeFlagPointer;
135
136 return GL_TRUE;
137 }
138
139
140 void
141 _tnl_DestroyContext( GLcontext *ctx )
142 {
143 TNLcontext *tnl = TNL_CONTEXT(ctx);
144
145 if (TNL_CURRENT_IM(ctx) != TNL_VB(ctx)->IM)
146 gl_immediate_free( TNL_CURRENT_IM(ctx) );
147
148 gl_vb_free( TNL_VB(ctx) );
149
150 /* Free cache of immediate buffers. */
151 while (tnl->nr_im_queued-- > 0) {
152 struct immediate * next = tnl->freed_im_queue->next;
153 ALIGN_FREE( tnl->freed_im_queue );
154 tnl->freed_im_queue = next;
155 }
156 }
157
158
159 /* Update all state that references _NeedEyeCoords
160 */
161 void
162 _tnl_LightingSpaceChange( GLcontext *ctx )
163 {
164 _tnl_update_normal_transform( ctx );
165 }
166
167
168 void
169 _tnl_InvalidateState( GLcontext *ctx, GLuint new_state )
170 {
171 if (new_state & _NEW_LIGHT)
172 gl_update_lighting_function(ctx);
173
174 if (new_state & _NEW_ARRAY)
175 gl_update_client_state( ctx );
176
177 if (new_state & _NEW_TEXTURE)
178 if (ctx->_Enabled & ENABLE_TEXGEN_ANY)
179 _tnl_update_texgen( ctx );
180
181 if (new_state & (_NEW_LIGHT|_NEW_TEXTURE|_NEW_FOG|
182 _DD_NEW_TRI_LIGHT_TWOSIDE |
183 _DD_NEW_SEPERATE_SPECULAR |
184 _DD_NEW_TRI_UNFILLED ))
185 gl_update_clipmask(ctx);
186
187 if (new_state & _TNL_NEW_NORMAL_TRANSFORM)
188 _tnl_update_normal_transform( ctx );
189
190 gl_update_pipelines(ctx);
191 }
192
193 void
194 _tnl_MakeCurrent( GLcontext *ctx,
195 GLframebuffer *drawBuffer,
196 GLframebuffer *readBuffer )
197 {
198 #ifndef THREADS
199 SET_IMMEDIATE(newCtx, newCtx->input);
200 #endif
201 }