VirtualBox

source: vbox/trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_context.c@ 24306

Last change on this file since 24306 was 21308, checked in by vboxsync, 16 years ago

crOpenGL: use host side VBO when possible

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.8 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#include "packspu.h"
8#include "cr_mem.h"
9#include "cr_packfunctions.h"
10#include "cr_string.h"
11#include "packspu_proto.h"
12
13#define MAGIC_OFFSET 3000
14
15
16/*
17 * Allocate a new ThreadInfo structure, setup a connection to the
18 * server, allocate/init a packer context, bind this ThreadInfo to
19 * the calling thread with crSetTSD().
20 * We'll always call this function at least once even if we're not
21 * using threads.
22 */
23ThreadInfo *packspuNewThread( unsigned long id )
24{
25 ThreadInfo *thread;
26
27#ifdef CHROMIUM_THREADSAFE
28 crLockMutex(&_PackMutex);
29#else
30 CRASSERT(pack_spu.numThreads == 0);
31#endif
32
33 CRASSERT(pack_spu.numThreads < MAX_THREADS);
34 thread = &(pack_spu.thread[pack_spu.numThreads]);
35
36 thread->id = id;
37 thread->currentContext = NULL;
38
39 /* connect to the server */
40 thread->netServer.name = crStrdup( pack_spu.name );
41 thread->netServer.buffer_size = pack_spu.buffer_size;
42 if (pack_spu.numThreads == 0) {
43 packspuConnectToServer( &(thread->netServer) );
44 if (!thread->netServer.conn) {
45 return NULL;
46 }
47 pack_spu.swap = thread->netServer.conn->swap;
48 }
49 else {
50 /* a new pthread */
51 crNetNewClient(pack_spu.thread[0].netServer.conn, &(thread->netServer));
52 CRASSERT(thread->netServer.conn);
53 }
54
55 /* packer setup */
56 CRASSERT(thread->packer == NULL);
57 thread->packer = crPackNewContext( pack_spu.swap );
58 CRASSERT(thread->packer);
59 crPackInitBuffer( &(thread->buffer), crNetAlloc(thread->netServer.conn),
60 thread->netServer.conn->buffer_size, thread->netServer.conn->mtu );
61 thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE;
62 crPackSetBuffer( thread->packer, &thread->buffer );
63 crPackFlushFunc( thread->packer, packspuFlush );
64 crPackFlushArg( thread->packer, (void *) thread );
65 crPackSendHugeFunc( thread->packer, packspuHuge );
66 crPackSetContext( thread->packer );
67
68#ifdef CHROMIUM_THREADSAFE
69 crSetTSD(&_PackTSD, thread);
70#endif
71
72 pack_spu.numThreads++;
73
74#ifdef CHROMIUM_THREADSAFE
75 crUnlockMutex(&_PackMutex);
76#endif
77 return thread;
78}
79
80
81GLint PACKSPU_APIENTRY
82packspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx )
83{
84 GET_THREAD(thread);
85 int writeback = 1;
86 GLint serverCtx = (GLint) -1;
87 int slot;
88
89#ifdef CHROMIUM_THREADSAFE
90 crLockMutex(&_PackMutex);
91#endif
92
93 if (!thread) {
94 thread = packspuNewThread(crThreadID());
95 }
96 CRASSERT(thread);
97 CRASSERT(thread->packer);
98
99 if (shareCtx > 0) {
100 /* translate to server ctx id */
101 shareCtx -= MAGIC_OFFSET;
102 if (shareCtx >= 0 && shareCtx < pack_spu.numContexts) {
103 shareCtx = pack_spu.context[shareCtx].serverCtx;
104 }
105 }
106
107 crPackSetContext( thread->packer );
108
109 /* Pack the command */
110 if (pack_spu.swap)
111 crPackCreateContextSWAP( dpyName, visual, shareCtx, &serverCtx, &writeback );
112 else
113 crPackCreateContext( dpyName, visual, shareCtx, &serverCtx, &writeback );
114
115 /* Flush buffer and get return value */
116 packspuFlush(thread);
117 if (!(thread->netServer.conn->actual_network))
118 {
119 /* HUMUNGOUS HACK TO MATCH SERVER NUMBERING
120 *
121 * The hack exists solely to make file networking work for now. This
122 * is totally gross, but since the server expects the numbers to start
123 * from 5000, we need to write them out this way. This would be
124 * marginally less gross if the numbers (500 and 5000) were maybe
125 * some sort of #define'd constants somewhere so the client and the
126 * server could be aware of how each other were numbering things in
127 * cases like file networking where they actually
128 * care.
129 *
130 * -Humper
131 *
132 */
133 serverCtx = 5000;
134 }
135 else {
136 while (writeback)
137 crNetRecv();
138
139 if (pack_spu.swap) {
140 serverCtx = (GLint) SWAP32(serverCtx);
141 }
142 if (serverCtx < 0) {
143#ifdef CHROMIUM_THREADSAFE
144 crUnlockMutex(&_PackMutex);
145#endif
146 crWarning("Failure in packspu_CreateContext");
147 return -1; /* failed */
148 }
149 }
150
151 /* find an empty context slot */
152 for (slot = 0; slot < pack_spu.numContexts; slot++) {
153 if (!pack_spu.context[slot].clientState) {
154 /* found empty slot */
155 break;
156 }
157 }
158 if (slot == pack_spu.numContexts) {
159 pack_spu.numContexts++;
160 }
161
162 /* Fill in the new context info */
163 /* XXX fix-up sharedCtx param here */
164 pack_spu.context[slot].clientState = crStateCreateContext(NULL, visual, NULL);
165 pack_spu.context[slot].clientState->bufferobject.retainBufferData = GL_TRUE;
166 pack_spu.context[slot].serverCtx = serverCtx;
167
168#ifdef CHROMIUM_THREADSAFE
169 crUnlockMutex(&_PackMutex);
170#endif
171
172 return MAGIC_OFFSET + slot;
173}
174
175
176void PACKSPU_APIENTRY packspu_DestroyContext( GLint ctx )
177{
178 const int slot = ctx - MAGIC_OFFSET;
179 ContextInfo *context;
180 GET_THREAD(thread);
181
182 CRASSERT(slot >= 0);
183 CRASSERT(slot < pack_spu.numContexts);
184 CRASSERT(thread);
185
186 context = &(pack_spu.context[slot]);
187
188 if (pack_spu.swap)
189 crPackDestroyContextSWAP( context->serverCtx );
190 else
191 crPackDestroyContext( context->serverCtx );
192
193 crStateDestroyContext( context->clientState );
194
195 context->clientState = NULL;
196 context->serverCtx = 0;
197
198 if (thread->currentContext == context) {
199 thread->currentContext = NULL;
200 crStateMakeCurrent( NULL );
201 }
202}
203
204
205void PACKSPU_APIENTRY packspu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx )
206{
207 GET_THREAD(thread);
208 GLint serverCtx;
209 ContextInfo *newCtx;
210
211 if (!thread) {
212 thread = packspuNewThread( crThreadID() );
213 }
214 CRASSERT(thread);
215 CRASSERT(thread->packer);
216
217 if (ctx) {
218 const int slot = ctx - MAGIC_OFFSET;
219
220 CRASSERT(slot >= 0);
221 CRASSERT(slot < pack_spu.numContexts);
222
223 newCtx = &pack_spu.context[slot];
224 CRASSERT(newCtx->clientState); /* verify valid */
225
226 thread->currentContext = newCtx;
227
228 crPackSetContext( thread->packer );
229 crStateMakeCurrent( newCtx->clientState );
230 //crStateSetCurrentPointers(newCtx->clientState, &thread->packer->current);
231 serverCtx = pack_spu.context[slot].serverCtx;
232 }
233 else {
234 thread->currentContext = NULL;
235 crStateMakeCurrent( NULL );
236 newCtx = NULL;
237 serverCtx = 0;
238 }
239
240 if (pack_spu.swap)
241 crPackMakeCurrentSWAP( window, nativeWindow, serverCtx );
242 else
243 crPackMakeCurrent( window, nativeWindow, serverCtx );
244
245 {
246 GET_THREAD(t);
247 (void) t;
248 CRASSERT(t);
249 }
250}
Note: See TracBrowser for help on using the repository browser.

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