VirtualBox

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

Last change on this file since 20509 was 15758, checked in by vboxsync, 16 years ago

crOpenGL: tabs to spaces

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.5 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 int writeback = 1;
85 GLint serverCtx = (GLint) -1;
86 int slot;
87
88#ifdef CHROMIUM_THREADSAFE
89 crLockMutex(&_PackMutex);
90#endif
91
92 if (shareCtx > 0) {
93 /* translate to server ctx id */
94 shareCtx -= MAGIC_OFFSET;
95 if (shareCtx >= 0 && shareCtx < pack_spu.numContexts) {
96 shareCtx = pack_spu.context[shareCtx].serverCtx;
97 }
98 }
99
100 crPackSetContext( pack_spu.thread[0].packer );
101
102 /* Pack the command */
103 if (pack_spu.swap)
104 crPackCreateContextSWAP( dpyName, visual, shareCtx, &serverCtx, &writeback );
105 else
106 crPackCreateContext( dpyName, visual, shareCtx, &serverCtx, &writeback );
107
108 /* Flush buffer and get return value */
109 packspuFlush( &(pack_spu.thread[0]) );
110 if (!(pack_spu.thread[0].netServer.conn->actual_network))
111 {
112 /* HUMUNGOUS HACK TO MATCH SERVER NUMBERING
113 *
114 * The hack exists solely to make file networking work for now. This
115 * is totally gross, but since the server expects the numbers to start
116 * from 5000, we need to write them out this way. This would be
117 * marginally less gross if the numbers (500 and 5000) were maybe
118 * some sort of #define'd constants somewhere so the client and the
119 * server could be aware of how each other were numbering things in
120 * cases like file networking where they actually
121 * care.
122 *
123 * -Humper
124 *
125 */
126 serverCtx = 5000;
127 }
128 else {
129 while (writeback)
130 crNetRecv();
131
132 if (pack_spu.swap) {
133 serverCtx = (GLint) SWAP32(serverCtx);
134 }
135 if (serverCtx < 0) {
136#ifdef CHROMIUM_THREADSAFE
137 crUnlockMutex(&_PackMutex);
138#endif
139 crWarning("Failure in packspu_CreateContext");
140 return -1; /* failed */
141 }
142 }
143
144 /* find an empty context slot */
145 for (slot = 0; slot < pack_spu.numContexts; slot++) {
146 if (!pack_spu.context[slot].clientState) {
147 /* found empty slot */
148 break;
149 }
150 }
151 if (slot == pack_spu.numContexts) {
152 pack_spu.numContexts++;
153 }
154
155 /* Fill in the new context info */
156 /* XXX fix-up sharedCtx param here */
157 pack_spu.context[slot].clientState = crStateCreateContext(NULL, visual, NULL);
158 pack_spu.context[slot].serverCtx = serverCtx;
159
160#ifdef CHROMIUM_THREADSAFE
161 crUnlockMutex(&_PackMutex);
162#endif
163
164 return MAGIC_OFFSET + slot;
165}
166
167
168void PACKSPU_APIENTRY packspu_DestroyContext( GLint ctx )
169{
170 const int slot = ctx - MAGIC_OFFSET;
171 ContextInfo *context;
172 GET_THREAD(thread);
173
174 CRASSERT(slot >= 0);
175 CRASSERT(slot < pack_spu.numContexts);
176 CRASSERT(thread);
177
178 context = &(pack_spu.context[slot]);
179
180 if (pack_spu.swap)
181 crPackDestroyContextSWAP( context->serverCtx );
182 else
183 crPackDestroyContext( context->serverCtx );
184
185 crStateDestroyContext( context->clientState );
186
187 context->clientState = NULL;
188 context->serverCtx = 0;
189
190 if (thread->currentContext == context) {
191 thread->currentContext = NULL;
192 crStateMakeCurrent( NULL );
193 }
194}
195
196
197void PACKSPU_APIENTRY packspu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx )
198{
199 GET_THREAD(thread);
200 GLint serverCtx;
201 ContextInfo *newCtx;
202
203 if (!thread) {
204 thread = packspuNewThread( crThreadID() );
205 }
206 CRASSERT(thread);
207 CRASSERT(thread->packer);
208
209 if (ctx) {
210 const int slot = ctx - MAGIC_OFFSET;
211
212 CRASSERT(slot >= 0);
213 CRASSERT(slot < pack_spu.numContexts);
214
215 newCtx = &pack_spu.context[slot];
216 CRASSERT(newCtx->clientState); /* verify valid */
217
218 thread->currentContext = newCtx;
219
220 crPackSetContext( thread->packer );
221 crStateMakeCurrent( newCtx->clientState );
222 serverCtx = pack_spu.context[slot].serverCtx;
223 }
224 else {
225 thread->currentContext = NULL;
226 crStateMakeCurrent( NULL );
227 newCtx = NULL;
228 serverCtx = 0;
229 }
230
231 if (pack_spu.swap)
232 crPackMakeCurrentSWAP( window, nativeWindow, serverCtx );
233 else
234 crPackMakeCurrent( window, nativeWindow, serverCtx );
235
236 {
237 GET_THREAD(t);
238 (void) t;
239 CRASSERT(t);
240 }
241}
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