~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/extras/Mesa/src/tnl/t_imm_exec.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
 * Mesa 3-D graphics library
 
4
 * Version:  4.0.3
 
5
 *
 
6
 * Copyright (C) 1999-2002  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 <keithw@valinux.com>
 
27
 */
 
28
 
 
29
 
 
30
#include "glheader.h"
 
31
#include "colormac.h"
 
32
#include "context.h"
 
33
#include "enums.h"
 
34
#include "dlist.h"
 
35
#include "macros.h"
 
36
#include "mem.h"
 
37
#include "mmath.h"
 
38
#include "light.h"
 
39
#include "state.h"
 
40
#include "mtypes.h"
 
41
 
 
42
#include "math/m_matrix.h"
 
43
#include "math/m_xform.h"
 
44
 
 
45
#include "t_context.h"
 
46
#include "t_array_import.h"
 
47
#include "t_imm_alloc.h"
 
48
#include "t_imm_api.h"
 
49
#include "t_imm_debug.h"
 
50
#include "t_imm_dlist.h"
 
51
#include "t_imm_eval.h"
 
52
#include "t_imm_elt.h"
 
53
#include "t_imm_exec.h"
 
54
#include "t_imm_fixup.h"
 
55
#include "t_pipeline.h"
 
56
 
 
57
 
 
58
 
 
59
static void reset_input( GLcontext *ctx,
 
60
                         GLuint start,
 
61
                         GLuint beginstate,
 
62
                         GLuint savedbeginstate )
 
63
{
 
64
   struct immediate *IM = TNL_CURRENT_IM(ctx);
 
65
 
 
66
   /* Clear the dirty part of the flag array.
 
67
    */
 
68
   if (start < IM->Count+2)
 
69
      MEMSET(IM->Flag + start, 0, sizeof(GLuint) * (IM->Count+2-start));
 
70
 
 
71
   if (MESA_VERBOSE & VERBOSE_IMMEDIATE)
 
72
      fprintf(stderr, "reset_input: IM(%d) new %x\n", 
 
73
              IM->id, beginstate);
 
74
 
 
75
   IM->Start = start;
 
76
   IM->Count = start;
 
77
   IM->LastMaterial = start;
 
78
   IM->BeginState = beginstate;
 
79
   IM->SavedBeginState = savedbeginstate;
 
80
   IM->TexSize = 0;
 
81
   IM->MaterialOrMask = 0;
 
82
 
 
83
   if (IM->MaterialMask) 
 
84
      IM->MaterialMask[IM->Start] = 0;
 
85
 
 
86
   IM->ArrayEltFlags = ~ctx->Array._Enabled;
 
87
   IM->ArrayEltIncr = ctx->Array.Vertex.Enabled ? 1 : 0;
 
88
   IM->ArrayEltFlush = ctx->Array.LockCount ? FLUSH_ELT_LAZY : FLUSH_ELT_EAGER;
 
89
}
 
90
  
 
91
void _tnl_reset_exec_input( GLcontext *ctx,
 
92
                            GLuint start,
 
93
                            GLuint beginstate,
 
94
                            GLuint savedbeginstate )
 
95
{
 
96
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
97
   struct immediate *IM = TNL_CURRENT_IM(ctx);
 
98
 
 
99
   reset_input( ctx, start, beginstate, savedbeginstate );
 
100
 
 
101
   IM->CopyStart = start - tnl->ExecCopyCount;
 
102
   IM->Primitive[IM->CopyStart] = ctx->Driver.CurrentExecPrimitive;
 
103
   if (tnl->ExecParity)
 
104
      IM->Primitive[IM->CopyStart] |= PRIM_PARITY;
 
105
 
 
106
   IM->LastPrimitive = IM->CopyStart;
 
107
}
 
108
 
 
109
 
 
110
void _tnl_reset_compile_input( GLcontext *ctx,
 
111
                            GLuint start,
 
112
                            GLuint beginstate,
 
113
                            GLuint savedbeginstate )
 
114
{
 
115
   struct immediate *IM = TNL_CURRENT_IM(ctx);
 
116
 
 
117
   reset_input( ctx, start, beginstate, savedbeginstate );
 
118
   IM->CopyStart = start;
 
119
   IM->LastPrimitive = IM->Start;
 
120
}
 
121
  
 
122
 
 
123
void _tnl_copy_to_current( GLcontext *ctx, struct immediate *IM,
 
124
                           GLuint flag, GLuint count )
 
125
{
 
126
   if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
 
127
      _tnl_print_vert_flags("copy to current", flag);
 
128
 
 
129
   if (flag & VERT_NORM)
 
130
      COPY_3FV( ctx->Current.Normal, IM->Normal[count]);
 
131
 
 
132
   if (flag & VERT_INDEX)
 
133
      ctx->Current.Index = IM->Index[count];
 
134
 
 
135
   if (flag & VERT_EDGE)
 
136
      ctx->Current.EdgeFlag = IM->EdgeFlag[count];
 
137
 
 
138
   if (flag & VERT_RGBA) {
 
139
      COPY_4FV(ctx->Current.Color, IM->Color[count]);
 
140
      if (ctx->Light.ColorMaterialEnabled) {
 
141
         _mesa_update_color_material( ctx, ctx->Current.Color );
 
142
         TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
 
143
      }
 
144
   }
 
145
 
 
146
   if (flag & VERT_SPEC_RGB)
 
147
      COPY_4FV(ctx->Current.SecondaryColor, IM->SecondaryColor[count]);
 
148
 
 
149
   if (flag & VERT_FOG_COORD)
 
150
      ctx->Current.FogCoord = IM->FogCoord[count];
 
151
 
 
152
   if (flag & VERT_TEX_ANY) {
 
153
      GLuint i;
 
154
      for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
 
155
         if (flag & VERT_TEX(i)) {
 
156
            COPY_4FV( ctx->Current.Texcoord[0], IM->TexCoord[0][count]);
 
157
         }
 
158
      }
 
159
   }
 
160
 
 
161
   if (flag & VERT_MATERIAL) {
 
162
      _mesa_update_material( ctx,
 
163
                          IM->Material[IM->LastMaterial],
 
164
                          IM->MaterialOrMask );
 
165
 
 
166
      TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
 
167
   }
 
168
}
 
169
 
 
170
 
 
171
 
 
172
void _tnl_compute_orflag( struct immediate *IM, GLuint start )
 
173
{
 
174
   GLuint count = IM->Count;
 
175
   GLuint orflag = 0;
 
176
   GLuint andflag = ~0U;
 
177
   GLuint i;
 
178
 
 
179
   IM->LastData = count-1;
 
180
 
 
181
 
 
182
   /* Compute the flags for the whole buffer.
 
183
    */
 
184
   for (i = start ; i < count ; i++) {
 
185
      andflag &= IM->Flag[i];
 
186
      orflag |= IM->Flag[i];
 
187
   }
 
188
 
 
189
   /* It is possible there will be data in the buffer arising from
 
190
    * calls like 'glNormal', 'glMaterial' that occur after the final
 
191
    * glVertex, glEval, etc.  Additionally, a buffer can consist of
 
192
    * eg. a single glMaterial call, in which case IM->Start ==
 
193
    * IM->Count, but the buffer is definitely not empty.
 
194
    */
 
195
   if (IM->Flag[i] & VERT_DATA) {
 
196
      IM->LastData++;
 
197
      orflag |= IM->Flag[i];
 
198
   }
 
199
 
 
200
   IM->Flag[IM->LastData+1] |= VERT_END_VB;
 
201
   IM->CopyAndFlag = IM->AndFlag = andflag;
 
202
   IM->OrFlag = orflag;
 
203
   IM->CopyOrFlag = orflag;
 
204
   IM->Evaluated = 0;
 
205
}
 
206
 
 
207
 
 
208
 
 
209
 
 
210
 
 
211
 
 
212
 
 
213
 
 
214
/* Note: The 'start' member of the GLvector structs is now redundant
 
215
 * because we always re-transform copied vertices, and the vectors
 
216
 * below are set up so that the first copied vertex (if any) appears
 
217
 * at position zero.
 
218
 */
 
219
static void _tnl_vb_bind_immediate( GLcontext *ctx, struct immediate *IM )
 
220
{
 
221
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
222
   struct vertex_buffer *VB = &tnl->vb;
 
223
   struct vertex_arrays *tmp = &tnl->imm_inputs;
 
224
   GLuint inputs = tnl->pipeline.inputs; /* for copy-to-current */
 
225
   GLuint start = IM->CopyStart;
 
226
   GLuint count = IM->Count - start;
 
227
 
 
228
   /* TODO: optimize the case where nothing has changed.  (Just bind
 
229
    * tmp to vb).
 
230
    */
 
231
 
 
232
   /* Setup constant data in the VB.
 
233
    */
 
234
   VB->Count = count;
 
235
   VB->FirstClipped = IMM_MAXDATA - IM->CopyStart;
 
236
   VB->import_data = 0;
 
237
   VB->importable_data = 0;
 
238
 
 
239
   /* Need an IM->FirstPrimitive?
 
240
    */
 
241
   VB->Primitive = IM->Primitive + IM->CopyStart;
 
242
   VB->PrimitiveLength = IM->PrimitiveLength + IM->CopyStart;
 
243
   VB->FirstPrimitive = 0;
 
244
 
 
245
   VB->Flag = IM->Flag + start;
 
246
 
 
247
   /* TexCoordPtr's are zeroed in loop below.
 
248
    */
 
249
   VB->NormalPtr = 0;
 
250
   VB->NormalLengthPtr = 0;
 
251
   VB->FogCoordPtr = 0;
 
252
   VB->EdgeFlag = 0;
 
253
   VB->IndexPtr[0] = 0;
 
254
   VB->IndexPtr[1] = 0;
 
255
   VB->ColorPtr[0] = 0;
 
256
   VB->ColorPtr[1] = 0;
 
257
   VB->SecondaryColorPtr[0] = 0;
 
258
   VB->SecondaryColorPtr[1] = 0;
 
259
   VB->Elts = 0;
 
260
   VB->MaterialMask = 0;
 
261
   VB->Material = 0;
 
262
 
 
263
/*     _tnl_print_vert_flags("copy-orflag", IM->CopyOrFlag); */
 
264
/*     _tnl_print_vert_flags("orflag", IM->OrFlag); */
 
265
/*     _tnl_print_vert_flags("inputs", inputs); */
 
266
 
 
267
   /* Setup the initial values of array pointers in the vb.
 
268
    */
 
269
   if (inputs & VERT_OBJ) {
 
270
      tmp->Obj.data = IM->Obj + start;
 
271
      tmp->Obj.start = (GLfloat *)(IM->Obj + start);
 
272
      tmp->Obj.count = count;
 
273
      VB->ObjPtr = &tmp->Obj;
 
274
      if ((IM->CopyOrFlag & VERT_OBJ_234) == VERT_OBJ_234)
 
275
         tmp->Obj.size = 4;
 
276
      else if ((IM->CopyOrFlag & VERT_OBJ_234) == VERT_OBJ_23)
 
277
         tmp->Obj.size = 3;
 
278
      else
 
279
         tmp->Obj.size = 2;
 
280
   }
 
281
 
 
282
   if (inputs & VERT_NORM) {
 
283
      tmp->Normal.data = IM->Normal + start;
 
284
      tmp->Normal.start = (GLfloat *)(IM->Normal + start);
 
285
      tmp->Normal.count = count;
 
286
      VB->NormalPtr = &tmp->Normal;
 
287
      if (IM->NormalLengthPtr)
 
288
         VB->NormalLengthPtr = IM->NormalLengthPtr + start;
 
289
   }
 
290
 
 
291
   if (inputs & VERT_INDEX) {
 
292
      tmp->Index.count = count;
 
293
      tmp->Index.data = IM->Index + start;
 
294
      tmp->Index.start = IM->Index + start;
 
295
      VB->IndexPtr[0] = &tmp->Index;
 
296
   }
 
297
 
 
298
   if (inputs & VERT_FOG_COORD) {
 
299
      tmp->FogCoord.data = IM->FogCoord + start;
 
300
      tmp->FogCoord.start = IM->FogCoord + start;
 
301
      tmp->FogCoord.count = count;
 
302
      VB->FogCoordPtr = &tmp->FogCoord;
 
303
   }
 
304
 
 
305
   if (inputs & VERT_SPEC_RGB) {
 
306
      tmp->SecondaryColor.Ptr = IM->SecondaryColor + start;
 
307
      VB->SecondaryColorPtr[0] = &tmp->SecondaryColor;
 
308
   }
 
309
 
 
310
   if (inputs & VERT_EDGE) {
 
311
      VB->EdgeFlag = IM->EdgeFlag + start;
 
312
   }
 
313
 
 
314
   if (inputs & VERT_RGBA) {
 
315
      if (IM->CopyOrFlag & VERT_RGBA) {
 
316
         tmp->Color.Ptr = IM->Color + start;
 
317
         tmp->Color.StrideB = 4 * sizeof(GLfloat);
 
318
         tmp->Color.Flags = 0;
 
319
      } else {
 
320
         tmp->Color.Ptr = ctx->Current.Color;
 
321
         tmp->Color.StrideB = 0;
 
322
         tmp->Color.Flags = CA_CLIENT_DATA; /* hack */
 
323
         VB->import_source = IM;
 
324
         VB->importable_data |= VERT_RGBA;
 
325
         VB->import_data = _tnl_upgrade_current_data;
 
326
      }
 
327
      VB->ColorPtr[0] = &tmp->Color;
 
328
   }
 
329
 
 
330
   if (inputs & VERT_TEX_ANY) {
 
331
      GLuint i;
 
332
      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
 
333
         VB->TexCoordPtr[i] = 0;
 
334
         if (inputs & VERT_TEX(i)) {
 
335
            tmp->TexCoord[i].count = count;
 
336
            tmp->TexCoord[i].data = IM->TexCoord[i] + start;
 
337
            tmp->TexCoord[i].start = (GLfloat *)(IM->TexCoord[i] + start);
 
338
            tmp->TexCoord[i].size = 2;
 
339
            if (IM->TexSize & TEX_SIZE_3(i)) {
 
340
               tmp->TexCoord[i].size = 3;
 
341
               if (IM->TexSize & TEX_SIZE_4(i))
 
342
                  tmp->TexCoord[i].size = 4;
 
343
            }
 
344
            VB->TexCoordPtr[i] = &tmp->TexCoord[i];
 
345
         }
 
346
      }
 
347
   }
 
348
 
 
349
   if ((inputs & IM->OrFlag & VERT_MATERIAL) && IM->Material) {
 
350
      VB->MaterialMask = IM->MaterialMask + start;
 
351
      VB->Material = IM->Material + start;
 
352
   }
 
353
}
 
354
 
 
355
 
 
356
 
 
357
 
 
358
/* Called by exec_vert_cassette, execute_compiled_cassette, but not
 
359
 * exec_elt_cassette.
 
360
 */
 
361
void _tnl_run_cassette( GLcontext *ctx, struct immediate *IM )
 
362
{
 
363
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
364
 
 
365
/*      fprintf(stderr, "%s\n", __FUNCTION__);  */
 
366
 
 
367
   _tnl_vb_bind_immediate( ctx, IM );
 
368
 
 
369
   if (IM->OrFlag & VERT_EVAL_ANY)
 
370
      _tnl_eval_immediate( ctx, IM );
 
371
 
 
372
   /* Invalidate all stored data before and after run:
 
373
    */
 
374
   tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
 
375
   tnl->Driver.RunPipeline( ctx );
 
376
   tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
 
377
 
 
378
   _tnl_copy_to_current( ctx, IM, IM->OrFlag, IM->LastData );
 
379
}
 
380
 
 
381
 
 
382
/* Called for regular vertex cassettes.
 
383
 */
 
384
static void exec_vert_cassette( GLcontext *ctx, struct immediate *IM )
 
385
{
 
386
/*     fprintf(stderr, "%s\n", __FUNCTION__); */
 
387
 
 
388
   if (IM->FlushElt) {
 
389
      /* Orflag is computed twice, but only reach this code if app is
 
390
       * using a mixture of glArrayElement() and glVertex() while
 
391
       * arrays are locked (else would be in exec_elt_cassette now).
 
392
       */
 
393
      ASSERT(ctx->Array.LockCount);
 
394
      ASSERT(IM->FlushElt == FLUSH_ELT_LAZY);
 
395
      _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->Count );
 
396
      _tnl_compute_orflag( IM, IM->CopyStart ); 
 
397
   }
 
398
 
 
399
   _tnl_fixup_input( ctx, IM );
 
400
/*     _tnl_print_cassette( IM ); */
 
401
   _tnl_run_cassette( ctx, IM );
 
402
}
 
403
 
 
404
 
 
405
/* Called for pure, locked VERT_ELT cassettes instead of
 
406
 * _tnl_run_cassette.
 
407
 */
 
408
static void exec_elt_cassette( GLcontext *ctx, struct immediate *IM )
 
409
{
 
410
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
411
   struct vertex_buffer *VB = &tnl->vb;
 
412
 
 
413
/*     fprintf(stderr, "%s\n", __FUNCTION__);  */
 
414
 
 
415
   _tnl_vb_bind_arrays( ctx, ctx->Array.LockFirst, ctx->Array.LockCount );
 
416
 
 
417
   /* Take only elements and primitive information from the immediate:
 
418
    */
 
419
   VB->Elts = IM->Elt + IM->CopyStart;
 
420
   VB->Primitive = IM->Primitive + IM->CopyStart;
 
421
   VB->PrimitiveLength = IM->PrimitiveLength + IM->CopyStart;
 
422
   VB->FirstPrimitive = 0;
 
423
 
 
424
   /* Run the pipeline.  No input changes as a result of this action.
 
425
    */
 
426
   tnl->Driver.RunPipeline( ctx );
 
427
 
 
428
   /* Still need to update current values:  
 
429
    */
 
430
   if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) {
 
431
      _tnl_translate_array_elts( ctx, IM, IM->LastData, IM->LastData );
 
432
      _tnl_copy_to_current( ctx, IM, ctx->Array._Enabled, IM->LastData );
 
433
   }
 
434
}
 
435
 
 
436
 
 
437
static void
 
438
exec_empty_cassette( GLcontext *ctx, struct immediate *IM )
 
439
{
 
440
   if (IM->FlushElt)
 
441
      _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->CopyStart );
 
442
 
 
443
   _tnl_copy_to_current( ctx, IM, IM->OrFlag, IM->LastData );
 
444
}
 
445
 
 
446
 
 
447
 
 
448
/* Called for all cassettes when not compiling or playing a display
 
449
 * list.
 
450
 */
 
451
void _tnl_execute_cassette( GLcontext *ctx, struct immediate *IM )
 
452
{
 
453
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
454
 
 
455
   _tnl_compute_orflag( IM, IM->Start );
 
456
   _tnl_copy_immediate_vertices( ctx, IM ); 
 
457
   _tnl_get_exec_copy_verts( ctx, IM );
 
458
 
 
459
   if (tnl->pipeline.build_state_changes)
 
460
      _tnl_validate_pipeline( ctx );
 
461
 
 
462
   if (IM->CopyStart == IM->Count) {
 
463
      exec_empty_cassette( ctx, IM );
 
464
   }
 
465
   else if ((IM->CopyOrFlag & VERT_DATA) == VERT_ELT &&
 
466
            ctx->Array.LockCount &&
 
467
            ctx->Array.Vertex.Enabled) {
 
468
      exec_elt_cassette( ctx, IM );
 
469
   }
 
470
   else {
 
471
      exec_vert_cassette( ctx, IM );
 
472
   }
 
473
 
 
474
   /* Only reuse the immediate if there are no copied vertices living
 
475
    * inside it:
 
476
    */
 
477
   { 
 
478
      GLuint begin_state = IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1);
 
479
      GLuint saved_begin_state = IM->SavedBeginState;
 
480
 
 
481
      if (--IM->ref_count != 0) {
 
482
         IM = _tnl_alloc_immediate( ctx );
 
483
         SET_IMMEDIATE( ctx, IM );
 
484
      }
 
485
 
 
486
      IM->ref_count++;
 
487
         
 
488
      _tnl_reset_exec_input( ctx, IMM_MAX_COPIED_VERTS, 
 
489
                             begin_state, saved_begin_state );
 
490
   }
 
491
 
 
492
   if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1)
 
493
      ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES;
 
494
 
 
495
/*     fprintf(stderr, "%s: NeedFlush: %x\n", __FUNCTION__,  */
 
496
/*         ctx->Driver.NeedFlush); */
 
497
}
 
498
 
 
499
 
 
500
 
 
501
 
 
502
/* Setup vector pointers that will be used to bind immediates to VB's.
 
503
 */
 
504
void _tnl_imm_init( GLcontext *ctx )
 
505
{
 
506
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
507
   struct vertex_arrays *tmp = &tnl->imm_inputs;
 
508
   GLuint i;
 
509
   static int firsttime = 1;
 
510
 
 
511
   if (firsttime) {
 
512
      firsttime = 0;
 
513
      _tnl_imm_elt_init();
 
514
   }
 
515
 
 
516
   ctx->swtnl_im = _tnl_alloc_immediate( ctx );
 
517
   TNL_CURRENT_IM(ctx)->ref_count++;
 
518
 
 
519
   tnl->ExecCopyTexSize = 0;
 
520
   tnl->ExecCopyCount = 0;
 
521
   tnl->ExecCopySource = 0;
 
522
 
 
523
   TNL_CURRENT_IM(ctx)->CopyStart = IMM_MAX_COPIED_VERTS;
 
524
 
 
525
   _mesa_vector4f_init( &tmp->Obj, 0, 0 );
 
526
   _mesa_vector3f_init( &tmp->Normal, 0, 0 );
 
527
 
 
528
   tmp->Color.Ptr = 0;
 
529
   tmp->Color.Type = GL_FLOAT;
 
530
   tmp->Color.Size = 4;
 
531
   tmp->Color.Stride = 0;
 
532
   tmp->Color.StrideB = 4 * sizeof(GLfloat);
 
533
   tmp->Color.Flags = 0;
 
534
 
 
535
   tmp->SecondaryColor.Ptr = 0;
 
536
   tmp->SecondaryColor.Type = GL_FLOAT;
 
537
   tmp->SecondaryColor.Size = 4;
 
538
   tmp->SecondaryColor.Stride = 0;
 
539
   tmp->SecondaryColor.StrideB = 4 * sizeof(GLfloat);
 
540
   tmp->SecondaryColor.Flags = 0;
 
541
 
 
542
   _mesa_vector1f_init( &tmp->FogCoord, 0, 0 );
 
543
   _mesa_vector1ui_init( &tmp->Index, 0, 0 );
 
544
   _mesa_vector1ub_init( &tmp->EdgeFlag, 0, 0 );
 
545
 
 
546
   for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
 
547
      _mesa_vector4f_init( &tmp->TexCoord[i], 0, 0);
 
548
 
 
549
   /* Install the first immediate.  Intially outside begin/end.
 
550
    */
 
551
   _tnl_reset_exec_input( ctx, IMM_MAX_COPIED_VERTS, 0, 0 );
 
552
   tnl->ReplayHardBeginEnd = 0;
 
553
 
 
554
   _tnl_imm_vtxfmt_init( ctx );
 
555
}
 
556
 
 
557
 
 
558
void _tnl_imm_destroy( GLcontext *ctx )
 
559
{
 
560
   if (TNL_CURRENT_IM(ctx)) {
 
561
      TNL_CURRENT_IM(ctx)->ref_count--;
 
562
      if (TNL_CURRENT_IM(ctx)->ref_count == 0)
 
563
         _tnl_free_immediate( ctx, TNL_CURRENT_IM(ctx) );
 
564
      /* 
 
565
       * Don't use SET_IMMEDIATE here, or else we'll whack the
 
566
       * _tnl_CurrentInput pointer - not good when another 
 
567
       * context has already been made current.
 
568
       * So we just set the context's own tnl immediate pointer
 
569
       * to 0.
 
570
       */
 
571
      ctx->swtnl_im = 0;
 
572
   }
 
573
}