VirtualBox

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

Last change on this file since 31988 was 30440, checked in by vboxsync, 15 years ago

crOpenGL: wddm friendly windows info tracking + more consistent updates (disabled except windows yet)

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