vtxfmt.c revision 57ffddba9870a0e602ae454e13072a0af48fa150
157ffddba9870a0e602ae454e13072a0af48fa150Gareth Hughes/* $Id: vtxfmt.c,v 1.4 2001/03/11 23:55:19 gareth Exp $ */
2d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes
3d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes/*
4d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * Mesa 3-D graphics library
5d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * Version:  3.5
6d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes *
7d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
8d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes *
9d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * Permission is hereby granted, free of charge, to any person obtaining a
10d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * copy of this software and associated documentation files (the "Software"),
11d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * to deal in the Software without restriction, including without limitation
12d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * and/or sell copies of the Software, and to permit persons to whom the
14d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * Software is furnished to do so, subject to the following conditions:
15d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes *
16d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * The above copyright notice and this permission notice shall be included
17d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * in all copies or substantial portions of the Software.
18d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes *
19d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes *
26d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * Author:
27d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes *    Keith Whitwell <keithw@valinux.com>
28d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes *    Gareth Hughes <gareth@valinux.com>
29d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes */
30d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes
31b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell#include "glheader.h"
32b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell#include "api_loopback.h"
33d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes#include "context.h"
34b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell#include "mtypes.h"
35b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell#include "vtxfmt.h"
36b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell
37b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell
38d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes/* The neutral vertex format.  This wraps all tnl module functions,
39d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * verifying that the currently-installed module is valid and then
40d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * installing the function pointers in a lazy fashion.  It records the
41d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * function pointers that have been swapped out, which allows a fast
42d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * restoration of the neutral module in almost all cases -- a typical
43d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * app might only require 4-6 functions to be modified from the neutral
44d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * baseline, and only restoring these is certainly preferable to doing
45d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes * the entire module's 60 or so function pointers.
46d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes */
47d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes
48d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes#define PRE_LOOPBACK( FUNC )						\
49d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes{									\
50d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   GET_CURRENT_CONTEXT(ctx);						\
51d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   struct gl_tnl_module *tnl = &(ctx->TnlModule);			\
52d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   const GLuint new_state = ctx->NewState;				\
53d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes									\
54d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   if ( new_state )							\
55d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes      _mesa_update_state( ctx );					\
56d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes									\
57d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   /* Validate the current tnl module.					\
58d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes    */									\
59d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   if ( new_state & ctx->Driver.NeedValidate )				\
60d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes      ctx->Driver.ValidateTnlModule( ctx, new_state );			\
61d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes									\
62d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   ASSERT( tnl->Current );						\
63d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   ASSERT( tnl->SwapCount < NUM_VERTEX_FORMAT_ENTRIES );		\
64d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes									\
65d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   /* Save the swapped function's dispatch entry so it can be		\
66d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes    * restored later.							\
67d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes    */									\
68d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   tnl->Swapped[tnl->SwapCount][0] = (void *)&(ctx->Exec->FUNC);	\
69d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   tnl->Swapped[tnl->SwapCount][1] = (void *)TAG(FUNC);			\
70d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   tnl->SwapCount++;							\
71d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes									\
72d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   if ( 0 )								\
73d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes      fprintf( stderr, "   swapping gl" #FUNC"...\n" );			\
74d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes									\
75d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   /* Install the tnl function pointer.					\
76d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes    */									\
77d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   ctx->Exec->FUNC = tnl->Current->FUNC;				\
78d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes}
79d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes
80d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes#define TAG(x) neutral_##x
81d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes#include "vtxfmt_tmp.h"
82d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes
83d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes
84b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell
85b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwellstatic void install_vtxfmt( struct _glapi_table *tab, GLvertexformat *vfmt )
86b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell{
87b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->ArrayElement = vfmt->ArrayElement;
88b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Color3f = vfmt->Color3f;
89b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Color3fv = vfmt->Color3fv;
90b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Color3ub = vfmt->Color3ub;
91b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Color3ubv = vfmt->Color3ubv;
92b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Color4f = vfmt->Color4f;
93b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Color4fv = vfmt->Color4fv;
94b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Color4ub = vfmt->Color4ub;
95b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Color4ubv = vfmt->Color4ubv;
96b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->EdgeFlag = vfmt->EdgeFlag;
97b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->EdgeFlagv = vfmt->EdgeFlagv;
98b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->EvalCoord1f = vfmt->EvalCoord1f;
99b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->EvalCoord1fv = vfmt->EvalCoord1fv;
100b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->EvalCoord2f = vfmt->EvalCoord2f;
101b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->EvalCoord2fv = vfmt->EvalCoord2fv;
102b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->EvalPoint1 = vfmt->EvalPoint1;
103b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->EvalPoint2 = vfmt->EvalPoint2;
104b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->FogCoordfEXT = vfmt->FogCoordfEXT;
105b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->FogCoordfvEXT = vfmt->FogCoordfvEXT;
106b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Indexi = vfmt->Indexi;
107b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Indexiv = vfmt->Indexiv;
108b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Materialfv = vfmt->Materialfv;
109b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->MultiTexCoord1fARB = vfmt->MultiTexCoord1fARB;
110b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->MultiTexCoord1fvARB = vfmt->MultiTexCoord1fvARB;
111b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->MultiTexCoord2fARB = vfmt->MultiTexCoord2fARB;
112b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->MultiTexCoord2fvARB = vfmt->MultiTexCoord2fvARB;
113b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->MultiTexCoord3fARB = vfmt->MultiTexCoord3fARB;
114b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->MultiTexCoord3fvARB = vfmt->MultiTexCoord3fvARB;
115b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->MultiTexCoord4fARB = vfmt->MultiTexCoord4fARB;
116b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->MultiTexCoord4fvARB = vfmt->MultiTexCoord4fvARB;
117b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Normal3f = vfmt->Normal3f;
118b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Normal3fv = vfmt->Normal3fv;
119b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->SecondaryColor3fEXT = vfmt->SecondaryColor3fEXT;
120b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->SecondaryColor3fvEXT = vfmt->SecondaryColor3fvEXT;
121b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->SecondaryColor3ubEXT = vfmt->SecondaryColor3ubEXT;
122b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->SecondaryColor3ubvEXT = vfmt->SecondaryColor3ubvEXT;
123b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->TexCoord1f = vfmt->TexCoord1f;
124b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->TexCoord1fv = vfmt->TexCoord1fv;
125b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->TexCoord2f = vfmt->TexCoord2f;
126b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->TexCoord2fv = vfmt->TexCoord2fv;
127b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->TexCoord3f = vfmt->TexCoord3f;
128b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->TexCoord3fv = vfmt->TexCoord3fv;
129b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->TexCoord4f = vfmt->TexCoord4f;
130b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->TexCoord4fv = vfmt->TexCoord4fv;
131b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Vertex2f = vfmt->Vertex2f;
132b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Vertex2fv = vfmt->Vertex2fv;
133b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Vertex3f = vfmt->Vertex3f;
134b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Vertex3fv = vfmt->Vertex3fv;
135b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Vertex4f = vfmt->Vertex4f;
136b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Vertex4fv = vfmt->Vertex4fv;
137b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Begin = vfmt->Begin;
138b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->End = vfmt->End;
139d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes
140b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell/*     tab->NewList = vfmt->NewList; */
141b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->CallList = vfmt->CallList;
142b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell
143b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->Rectf = vfmt->Rectf;
144b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->DrawArrays = vfmt->DrawArrays;
145b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->DrawElements = vfmt->DrawElements;
146b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->DrawRangeElements = vfmt->DrawRangeElements;
147b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->EvalMesh1 = vfmt->EvalMesh1;
148b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   tab->EvalMesh2 = vfmt->EvalMesh2;
149b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell}
150b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell
151b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell
152de6a2e0d194d1afa1a917cff7e80d77773b73c39Gareth Hughesvoid _mesa_init_exec_vtxfmt( GLcontext *ctx )
153b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell{
154d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   install_vtxfmt( ctx->Exec, &neutral_vtxfmt );
155de6a2e0d194d1afa1a917cff7e80d77773b73c39Gareth Hughes}
156de6a2e0d194d1afa1a917cff7e80d77773b73c39Gareth Hughes
157de6a2e0d194d1afa1a917cff7e80d77773b73c39Gareth Hughesvoid _mesa_install_exec_vtxfmt( GLcontext *ctx, GLvertexformat *vfmt )
158de6a2e0d194d1afa1a917cff7e80d77773b73c39Gareth Hughes{
15957ffddba9870a0e602ae454e13072a0af48fa150Gareth Hughes   ctx->TnlModule.Current = vfmt;
160de6a2e0d194d1afa1a917cff7e80d77773b73c39Gareth Hughes   _mesa_restore_exec_vtxfmt( ctx );
161de6a2e0d194d1afa1a917cff7e80d77773b73c39Gareth Hughes   if ( ctx->ExecPrefersFloat != vfmt->prefer_float_colors )
162b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell      _mesa_loopback_prefer_float( ctx->Exec, vfmt->prefer_float_colors );
163b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell}
164b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell
165b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwellvoid _mesa_install_save_vtxfmt( GLcontext *ctx, GLvertexformat *vfmt )
166b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell{
167b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell   install_vtxfmt( ctx->Save, vfmt );
168de6a2e0d194d1afa1a917cff7e80d77773b73c39Gareth Hughes   if ( ctx->SavePrefersFloat != vfmt->prefer_float_colors )
169b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell      _mesa_loopback_prefer_float( ctx->Save, vfmt->prefer_float_colors );
170b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell}
171b014986fdb259eb60bd3e5a3fbcfcb218969f5f5Keith Whitwell
172de6a2e0d194d1afa1a917cff7e80d77773b73c39Gareth Hughesvoid _mesa_restore_exec_vtxfmt( GLcontext *ctx )
173d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes{
174d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   struct gl_tnl_module *tnl = &(ctx->TnlModule);
175d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   GLuint i;
176d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes
177d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   /* Restore the neutral tnl module wrapper.
178d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes    */
179d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   for ( i = 0 ; i < tnl->SwapCount ; i++ ) {
180d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes      *(void **)tnl->Swapped[i][0] = tnl->Swapped[i][1];
181d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   }
182d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes
183d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes   tnl->SwapCount = 0;
184d8aa0269cdadba1608522287bcb3b446c5848c09Gareth Hughes}
185