VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/include/cr_pack.h@ 32940

Last change on this file since 32940 was 20183, checked in by vboxsync, 16 years ago

crOpenGL: fix wrong ext opcodes packing

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 10.0 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved.
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#ifndef CR_PACK_H
8#define CR_PACK_H
9
10#include "cr_compiler.h"
11#include "cr_error.h"
12#include "cr_protocol.h"
13#include "cr_opcodes.h"
14#include "cr_endian.h"
15#include "state/cr_statetypes.h"
16#include "state/cr_currentpointers.h"
17#include "state/cr_client.h"
18#ifdef CHROMIUM_THREADSAFE
19#include "cr_threads.h"
20#endif
21
22#include <iprt/types.h>
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28typedef struct CRPackContext_t CRPackContext;
29
30/**
31 * Packer buffer
32 */
33typedef struct
34{
35 void *pack; /**< the actual storage space/buffer */
36 unsigned int size; /**< size of pack[] buffer */
37 unsigned int mtu;
38 unsigned char *data_start, *data_current, *data_end;
39 unsigned char *opcode_start, *opcode_current, *opcode_end;
40 GLboolean geometry_only; /**< just used for debugging */
41 GLboolean holds_BeginEnd;
42 GLboolean in_BeginEnd;
43 GLboolean canBarf;
44 GLboolean holds_List;
45 GLboolean in_List;
46 CRPackContext *context;
47} CRPackBuffer;
48
49typedef void (*CRPackFlushFunc)(void *arg);
50typedef void (*CRPackSendHugeFunc)(CROpcode, void *);
51typedef void (*CRPackErrorHandlerFunc)(int line, const char *file, GLenum error, const char *info);
52
53
54/**
55 * Packer context
56 */
57struct CRPackContext_t
58{
59 CRPackBuffer buffer; /**< not a pointer, see comments in pack_buffer.c */
60 CRPackFlushFunc Flush;
61 void *flush_arg;
62 CRPackSendHugeFunc SendHuge;
63 CRPackErrorHandlerFunc Error;
64 CRCurrentStatePointers current;
65 GLvectorf bounds_min, bounds_max;
66 int updateBBOX;
67 int swapping;
68 CRPackBuffer *currentBuffer;
69 char *file; /**< for debugging only */
70 int line; /**< for debugging only */
71};
72
73
74extern DECLEXPORT(CRPackContext *) crPackNewContext(int swapping);
75extern DECLEXPORT(void) crPackSetContext( CRPackContext *pc );
76extern DECLEXPORT(CRPackContext *) crPackGetContext( void );
77
78extern DECLEXPORT(void) crPackSetBuffer( CRPackContext *pc, CRPackBuffer *buffer );
79extern DECLEXPORT(void) crPackSetBufferDEBUG( const char *file, int line, CRPackContext *pc, CRPackBuffer *buffer );
80extern DECLEXPORT(void) crPackReleaseBuffer( CRPackContext *pc );
81extern DECLEXPORT(void) crPackResetPointers( CRPackContext *pc );
82
83extern DECLEXPORT(int) crPackMaxOpcodes( int buffer_size );
84extern DECLEXPORT(int) crPackMaxData( int buffer_size );
85extern DECLEXPORT(void) crPackInitBuffer( CRPackBuffer *buffer, void *buf, int size, int mtu );
86extern DECLEXPORT(void) crPackFlushFunc( CRPackContext *pc, CRPackFlushFunc ff );
87extern DECLEXPORT(void) crPackFlushArg( CRPackContext *pc, void *flush_arg );
88extern DECLEXPORT(void) crPackSendHugeFunc( CRPackContext *pc, CRPackSendHugeFunc shf );
89extern DECLEXPORT(void) crPackErrorFunction( CRPackContext *pc, CRPackErrorHandlerFunc errf );
90extern DECLEXPORT(void) crPackOffsetCurrentPointers( int offset );
91extern DECLEXPORT(void) crPackNullCurrentPointers( void );
92
93extern DECLEXPORT(void) crPackResetBoundingBox( CRPackContext *pc );
94extern DECLEXPORT(GLboolean) crPackGetBoundingBox( CRPackContext *pc,
95 GLfloat *xmin, GLfloat *ymin, GLfloat *zmin,
96 GLfloat *xmax, GLfloat *ymax, GLfloat *zmax);
97
98extern DECLEXPORT(void) crPackAppendBuffer( const CRPackBuffer *buffer );
99extern DECLEXPORT(void) crPackAppendBoundedBuffer( const CRPackBuffer *buffer, const CRrecti *bounds );
100extern DECLEXPORT(int) crPackCanHoldBuffer( const CRPackBuffer *buffer );
101extern DECLEXPORT(int) crPackCanHoldBoundedBuffer( const CRPackBuffer *buffer );
102
103#if defined(LINUX) || defined(WINDOWS)
104#define CR_UNALIGNED_ACCESS_OKAY
105#else
106#undef CR_UNALIGNED_ACCESS_OKAY
107#endif
108extern DECLEXPORT(void) crWriteUnalignedDouble( void *buffer, double d );
109extern DECLEXPORT(void) crWriteSwappedDouble( void *buffer, double d );
110
111extern DECLEXPORT(void) *crPackAlloc( unsigned int len );
112extern DECLEXPORT(void) crHugePacket( CROpcode op, void *ptr );
113extern DECLEXPORT(void) crPackFree( void *ptr );
114extern DECLEXPORT(void) crNetworkPointerWrite( CRNetworkPointer *, void * );
115
116extern DECLEXPORT(void) crPackExpandDrawArrays(GLenum mode, GLint first, GLsizei count, CRClientState *c);
117extern DECLEXPORT(void) crPackExpandDrawArraysSWAP(GLenum mode, GLint first, GLsizei count, CRClientState *c);
118
119extern DECLEXPORT(void) crPackUnrollDrawElements(GLsizei count, GLenum type, const GLvoid *indices);
120extern DECLEXPORT(void) crPackUnrollDrawElementsSWAP(GLsizei count, GLenum type, const GLvoid *indices);
121
122extern DECLEXPORT(void) crPackExpandDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, CRClientState *c);
123extern DECLEXPORT(void) crPackExpandDrawElementsSWAP(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, CRClientState *c);
124
125extern DECLEXPORT(void) crPackExpandDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, CRClientState *c);
126extern DECLEXPORT(void) crPackExpandDrawRangeElementsSWAP(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, CRClientState *c);
127
128extern DECLEXPORT(void) crPackExpandArrayElement(GLint index, CRClientState *c);
129extern DECLEXPORT(void) crPackExpandArrayElementSWAP(GLint index, CRClientState *c);
130
131extern DECLEXPORT(void) crPackExpandMultiDrawArraysEXT( GLenum mode, GLint *first, GLsizei *count, GLsizei primcount, CRClientState *c );
132extern DECLEXPORT(void) crPackExpandMultiDrawArraysEXTSWAP( GLenum mode, GLint *first, GLsizei *count, GLsizei primcount, CRClientState *c );
133
134extern DECLEXPORT(void) crPackExpandMultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount, CRClientState *c );
135extern DECLEXPORT(void) crPackExpandMultiDrawElementsEXTSWAP( GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount, CRClientState *c );
136
137
138#ifdef CHROMIUM_THREADSAFE
139extern CRtsd _PackerTSD;
140#define GET_PACKER_CONTEXT(C) CRPackContext *C = (CRPackContext *) crGetTSD(&_PackerTSD)
141#else
142extern DLLDATA(CRPackContext) cr_packer_globals;
143#define GET_PACKER_CONTEXT(C) CRPackContext *C = &cr_packer_globals
144#endif
145
146
147/**
148 * Return number of opcodes in given buffer.
149 */
150static INLINE int
151crPackNumOpcodes(const CRPackBuffer *buffer)
152{
153 CRASSERT(buffer->opcode_start - buffer->opcode_current >= 0);
154 return buffer->opcode_start - buffer->opcode_current;
155}
156
157
158/**
159 * Return amount of data (in bytes) in buffer.
160 */
161static INLINE int
162crPackNumData(const CRPackBuffer *buffer)
163{
164 CRASSERT(buffer->data_current - buffer->data_start >= 0);
165 return buffer->data_current - buffer->data_start; /* in bytes */
166}
167
168
169static INLINE int
170crPackCanHoldOpcode(const CRPackContext *pc, int num_opcode, int num_data)
171{
172 int fitsInMTU, opcodesFit, dataFits;
173
174 CRASSERT(pc->currentBuffer);
175
176 fitsInMTU = (((pc->buffer.data_current - pc->buffer.opcode_current - 1
177 + num_opcode + num_data
178 + 0x3 ) & ~0x3) + sizeof(CRMessageOpcodes)
179 <= pc->buffer.mtu);
180 opcodesFit = (pc->buffer.opcode_current - num_opcode >= pc->buffer.opcode_end);
181 dataFits = (pc->buffer.data_current + num_data <= pc->buffer.data_end);
182
183 return fitsInMTU && opcodesFit && dataFits;
184}
185
186
187/**
188 * Alloc space for a message of 'len' bytes (plus 1 opcode).
189 * Only flush if buffer is full.
190 */
191#define GET_BUFFERED_POINTER_NO_BEGINEND_FLUSH( pc, len ) \
192 do { \
193 THREADASSERT( pc ); \
194 CRASSERT( pc->currentBuffer ); \
195 if ( !crPackCanHoldOpcode( pc, 1, (len) ) ) { \
196 pc->Flush( pc->flush_arg ); \
197 CRASSERT(crPackCanHoldOpcode( pc, 1, (len) ) ); \
198 } \
199 data_ptr = pc->buffer.data_current; \
200 pc->buffer.data_current += (len); \
201 } while (0)
202
203
204/**
205 * As above, flush if the buffer contains vertex data and we're
206 * no longer inside glBegin/glEnd.
207 */
208#define GET_BUFFERED_POINTER( pc, len ) \
209 do { \
210 CRASSERT( pc->currentBuffer ); \
211 if ( pc->buffer.holds_BeginEnd && !pc->buffer.in_BeginEnd ) { \
212 pc->Flush( pc->flush_arg ); \
213 pc->buffer.holds_BeginEnd = 0; \
214 } \
215 GET_BUFFERED_POINTER_NO_BEGINEND_FLUSH( pc, len ); \
216 } while (0)
217
218
219/**
220 * As above, but for vertex data between glBegin/End (counts vertices).
221 */
222#define GET_BUFFERED_COUNT_POINTER( pc, len ) \
223 do { \
224 CRASSERT( pc->currentBuffer ); \
225 if ( !crPackCanHoldOpcode( pc, 1, (len) ) ) { \
226 pc->Flush( pc->flush_arg ); \
227 CRASSERT( crPackCanHoldOpcode( pc, 1, (len) ) ); \
228 } \
229 data_ptr = pc->buffer.data_current; \
230 pc->current.vtx_count++; \
231 pc->buffer.data_current += (len); \
232 } while (0)
233
234
235/**
236 * Allocate space for a msg/command that has no arguments, such
237 * as glFinish().
238 */
239#define GET_BUFFERED_POINTER_NO_ARGS( pc ) \
240 GET_BUFFERED_POINTER( pc, 4 ); \
241 WRITE_DATA( 0, GLuint, 0xdeadbeef )
242
243#define WRITE_DATA( offset, type, data ) \
244 *( (type *) (data_ptr + (offset))) = (data)
245
246/* Write data to current location and auto increment */
247#define WRITE_DATA_AI(type, data) \
248 { \
249 *((type*) (data_ptr)) = (data); \
250 data_ptr += sizeof(type); \
251 }
252
253#ifdef CR_UNALIGNED_ACCESS_OKAY
254#define WRITE_DOUBLE( offset, data ) \
255 WRITE_DATA( offset, GLdouble, data )
256#else
257#define WRITE_DOUBLE( offset, data ) \
258 crWriteUnalignedDouble( data_ptr + (offset), (data) )
259#endif
260
261#define WRITE_SWAPPED_DOUBLE( offset, data ) \
262 crWriteSwappedDouble( data_ptr + (offset), (data) )
263
264#define WRITE_OPCODE( pc, opcode ) \
265 *(pc->buffer.opcode_current--) = (unsigned char) opcode
266
267#define WRITE_NETWORK_POINTER( offset, data ) \
268 crNetworkPointerWrite( (CRNetworkPointer *) ( data_ptr + (offset) ), (data) )
269
270#ifdef __cplusplus
271}
272#endif
273
274#endif /* CR_PACK_H */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette