2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
25 * Keith Whitwell <keith@tungstengraphics.com>
33 #include "array_cache/ac_context.h"
37 * Initialize the array fallbacks. That is, by default the fallback arrays
38 * point into the current vertex attribute values in ctx->Current.Attrib[]
40 static void _ac_fallbacks_init( GLcontext
*ctx
)
42 ACcontext
*ac
= AC_CONTEXT(ctx
);
43 struct gl_client_array
*cl
;
46 cl
= &ac
->Fallback
.Normal
;
51 cl
->Ptr
= (GLubyte
*) ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
];
53 cl
->Flags
= CA_CLIENT_DATA
; /* hack */
54 #if FEATURE_ARB_vertex_buffer_object
55 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
58 cl
= &ac
->Fallback
.Color
;
63 cl
->Ptr
= (GLubyte
*) ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
];
65 cl
->Flags
= CA_CLIENT_DATA
; /* hack */
66 #if FEATURE_ARB_vertex_buffer_object
67 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
70 cl
= &ac
->Fallback
.SecondaryColor
;
75 cl
->Ptr
= (GLubyte
*) ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
];
77 cl
->Flags
= CA_CLIENT_DATA
; /* hack */
78 #if FEATURE_ARB_vertex_buffer_object
79 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
82 cl
= &ac
->Fallback
.FogCoord
;
87 cl
->Ptr
= (GLubyte
*) &ctx
->Current
.Attrib
[VERT_ATTRIB_FOG
];
89 cl
->Flags
= CA_CLIENT_DATA
; /* hack */
90 #if FEATURE_ARB_vertex_buffer_object
91 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
94 cl
= &ac
->Fallback
.Index
;
99 cl
->Ptr
= (GLubyte
*) &ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR_INDEX
];
101 cl
->Flags
= CA_CLIENT_DATA
; /* hack */
102 #if FEATURE_ARB_vertex_buffer_object
103 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
106 for (i
= 0 ; i
< MAX_TEXTURE_COORD_UNITS
; i
++) {
107 cl
= &ac
->Fallback
.TexCoord
[i
];
112 cl
->Ptr
= (GLubyte
*) ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+ i
];
114 cl
->Flags
= CA_CLIENT_DATA
; /* hack */
115 #if FEATURE_ARB_vertex_buffer_object
116 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
120 cl
= &ac
->Fallback
.EdgeFlag
;
122 cl
->Type
= GL_UNSIGNED_BYTE
;
125 cl
->Ptr
= (GLubyte
*) &ctx
->Current
.EdgeFlag
;
127 cl
->Flags
= CA_CLIENT_DATA
; /* hack */
128 #if FEATURE_ARB_vertex_buffer_object
129 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
132 for (i
= 0; i
< VERT_ATTRIB_MAX
; i
++) {
133 cl
= &ac
->Fallback
.Attrib
[i
];
138 cl
->Ptr
= (GLubyte
*) ctx
->Current
.Attrib
[i
];
140 cl
->Flags
= CA_CLIENT_DATA
; /* hack */
141 #if FEATURE_ARB_vertex_buffer_object
142 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
149 * Initialize the array cache pointers, types, strides, etc.
151 static void _ac_cache_init( GLcontext
*ctx
)
153 ACcontext
*ac
= AC_CONTEXT(ctx
);
154 struct gl_client_array
*cl
;
155 GLuint size
= ctx
->Const
.MaxArrayLockSize
+ MAX_CLIPPED_VERTICES
;
158 cl
= &ac
->Cache
.Vertex
;
162 cl
->StrideB
= 4 * sizeof(GLfloat
);
163 cl
->Ptr
= (GLubyte
*) MALLOC( cl
->StrideB
* size
);
166 #if FEATURE_ARB_vertex_buffer_object
167 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
170 cl
= &ac
->Cache
.Normal
;
174 cl
->StrideB
= 3 * sizeof(GLfloat
);
175 cl
->Ptr
= (GLubyte
*) MALLOC( cl
->StrideB
* size
);
178 #if FEATURE_ARB_vertex_buffer_object
179 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
182 cl
= &ac
->Cache
.Color
;
186 cl
->StrideB
= 4 * sizeof(GLfloat
);
187 cl
->Ptr
= (GLubyte
*) MALLOC( cl
->StrideB
* size
);
190 #if FEATURE_ARB_vertex_buffer_object
191 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
194 cl
= &ac
->Cache
.SecondaryColor
;
198 cl
->StrideB
= 4 * sizeof(GLfloat
);
199 cl
->Ptr
= (GLubyte
*) MALLOC( cl
->StrideB
* size
);
202 #if FEATURE_ARB_vertex_buffer_object
203 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
206 cl
= &ac
->Cache
.FogCoord
;
210 cl
->StrideB
= sizeof(GLfloat
);
211 cl
->Ptr
= (GLubyte
*) MALLOC( cl
->StrideB
* size
);
214 #if FEATURE_ARB_vertex_buffer_object
215 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
218 cl
= &ac
->Cache
.Index
;
222 cl
->StrideB
= sizeof(GLfloat
);
223 cl
->Ptr
= (GLubyte
*) MALLOC( cl
->StrideB
* size
);
226 #if FEATURE_ARB_vertex_buffer_object
227 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
230 for (i
= 0; i
< MAX_TEXTURE_COORD_UNITS
; i
++) {
231 cl
= &ac
->Cache
.TexCoord
[i
];
235 cl
->StrideB
= 4 * sizeof(GLfloat
);
236 cl
->Ptr
= (GLubyte
*) MALLOC( cl
->StrideB
* size
);
239 #if FEATURE_ARB_vertex_buffer_object
240 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
244 cl
= &ac
->Cache
.EdgeFlag
;
246 cl
->Type
= GL_UNSIGNED_BYTE
;
248 cl
->StrideB
= sizeof(GLubyte
);
249 cl
->Ptr
= (GLubyte
*) MALLOC( cl
->StrideB
* size
);
252 #if FEATURE_ARB_vertex_buffer_object
253 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
256 for (i
= 0 ; i
< VERT_ATTRIB_MAX
; i
++) {
257 cl
= &ac
->Cache
.Attrib
[i
];
261 cl
->StrideB
= 4 * sizeof(GLfloat
);
262 cl
->Ptr
= (GLubyte
*) MALLOC( cl
->StrideB
* size
);
265 #if FEATURE_ARB_vertex_buffer_object
266 cl
->BufferObj
= ctx
->Array
.NullBufferObj
;
272 /* This storage used to hold translated client data if type or stride
275 static void _ac_elts_init( GLcontext
*ctx
)
277 ACcontext
*ac
= AC_CONTEXT(ctx
);
280 ac
->Elts
= (GLuint
*)MALLOC( sizeof(GLuint
) * size
);
284 static void _ac_raw_init( GLcontext
*ctx
)
286 ACcontext
*ac
= AC_CONTEXT(ctx
);
289 ac
->Raw
.Color
= ac
->Fallback
.Color
;
290 ac
->Raw
.EdgeFlag
= ac
->Fallback
.EdgeFlag
;
291 ac
->Raw
.FogCoord
= ac
->Fallback
.FogCoord
;
292 ac
->Raw
.Index
= ac
->Fallback
.Index
;
293 ac
->Raw
.Normal
= ac
->Fallback
.Normal
;
294 ac
->Raw
.SecondaryColor
= ac
->Fallback
.SecondaryColor
;
295 ac
->Raw
.Vertex
= ctx
->Array
.ArrayObj
->Vertex
;
297 ac
->IsCached
.Color
= GL_FALSE
;
298 ac
->IsCached
.EdgeFlag
= GL_FALSE
;
299 ac
->IsCached
.FogCoord
= GL_FALSE
;
300 ac
->IsCached
.Index
= GL_FALSE
;
301 ac
->IsCached
.Normal
= GL_FALSE
;
302 ac
->IsCached
.SecondaryColor
= GL_FALSE
;
303 ac
->IsCached
.Vertex
= GL_FALSE
;
305 for (i
= 0 ; i
< MAX_TEXTURE_COORD_UNITS
; i
++) {
306 ac
->Raw
.TexCoord
[i
] = ac
->Fallback
.TexCoord
[i
];
307 ac
->IsCached
.TexCoord
[i
] = GL_FALSE
;
310 for (i
= 0 ; i
< VERT_ATTRIB_MAX
; i
++) {
311 ac
->Raw
.Attrib
[i
] = ac
->Fallback
.Attrib
[i
];
312 ac
->IsCached
.Attrib
[i
] = GL_FALSE
;
316 GLboolean
_ac_CreateContext( GLcontext
*ctx
)
318 ctx
->acache_context
= CALLOC(sizeof(ACcontext
));
319 if (ctx
->acache_context
) {
320 _ac_cache_init( ctx
);
321 _ac_fallbacks_init( ctx
);
323 _ac_elts_init( ctx
);
329 void _ac_DestroyContext( GLcontext
*ctx
)
331 struct gl_buffer_object
*nullObj
= ctx
->Array
.NullBufferObj
;
332 ACcontext
*ac
= AC_CONTEXT(ctx
);
335 /* only free vertex data if it's really a pointer to vertex data and
336 * not an offset into a buffer object.
338 if (ac
->Cache
.Vertex
.Ptr
&& ac
->Cache
.Vertex
.BufferObj
== nullObj
)
339 FREE( (void *) ac
->Cache
.Vertex
.Ptr
);
340 if (ac
->Cache
.Normal
.Ptr
&& ac
->Cache
.Normal
.BufferObj
== nullObj
)
341 FREE( (void *) ac
->Cache
.Normal
.Ptr
);
342 if (ac
->Cache
.Color
.Ptr
&& ac
->Cache
.Color
.BufferObj
== nullObj
)
343 FREE( (void *) ac
->Cache
.Color
.Ptr
);
344 if (ac
->Cache
.SecondaryColor
.Ptr
&& ac
->Cache
.SecondaryColor
.BufferObj
== nullObj
)
345 FREE( (void *) ac
->Cache
.SecondaryColor
.Ptr
);
346 if (ac
->Cache
.EdgeFlag
.Ptr
&& ac
->Cache
.EdgeFlag
.BufferObj
== nullObj
)
347 FREE( (void *) ac
->Cache
.EdgeFlag
.Ptr
);
348 if (ac
->Cache
.Index
.Ptr
&& ac
->Cache
.Index
.BufferObj
== nullObj
)
349 FREE( (void *) ac
->Cache
.Index
.Ptr
);
350 if (ac
->Cache
.FogCoord
.Ptr
&& ac
->Cache
.FogCoord
.BufferObj
== nullObj
)
351 FREE( (void *) ac
->Cache
.FogCoord
.Ptr
);
353 for (i
= 0; i
< MAX_TEXTURE_COORD_UNITS
; i
++) {
354 if (ac
->Cache
.TexCoord
[i
].Ptr
&& ac
->Cache
.TexCoord
[i
].BufferObj
== nullObj
)
355 FREE( (void *) ac
->Cache
.TexCoord
[i
].Ptr
);
358 for (i
= 0; i
< VERT_ATTRIB_MAX
; i
++) {
359 if (ac
->Cache
.Attrib
[i
].Ptr
&& ac
->Cache
.Attrib
[i
].BufferObj
== nullObj
)
360 FREE( (void *) ac
->Cache
.Attrib
[i
].Ptr
);
366 /* Free the context structure itself */
368 ctx
->acache_context
= NULL
;
371 void _ac_InvalidateState( GLcontext
*ctx
, GLuint new_state
)
373 AC_CONTEXT(ctx
)->NewState
|= new_state
;
374 AC_CONTEXT(ctx
)->NewArrayState
|= ctx
->Array
.NewState
;