VirtualBox

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

Last change on this file since 39012 was 38374, checked in by vboxsync, 13 years ago

crOpenGL: don't add explicit writebacks to guest buffers

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