VirtualBox

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

Last change on this file since 51319 was 51319, checked in by vboxsync, 11 years ago

crOpenGL: adjusment

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 14.6 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 * Allocate a new ThreadInfo structure, setup a connection to the
17 * server, allocate/init a packer context, bind this ThreadInfo to
18 * the calling thread with crSetTSD().
19 * We'll always call this function at least once even if we're not
20 * using threads.
21 */
22ThreadInfo *packspuNewThread(
23#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
24 struct VBOXUHGSMI *pHgsmi
25#endif
26)
27{
28 ThreadInfo *thread=NULL;
29 int i;
30
31#ifdef CHROMIUM_THREADSAFE
32 crLockMutex(&_PackMutex);
33#else
34 CRASSERT(pack_spu.numThreads == 0);
35#endif
36
37#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
38 CRASSERT(!CRPACKSPU_IS_WDDM_CRHGSMI() == !pHgsmi);
39#endif
40
41 CRASSERT(pack_spu.numThreads < MAX_THREADS);
42 for (i=0; i<MAX_THREADS; ++i)
43 {
44 if (!pack_spu.thread[i].inUse)
45 {
46 thread = &pack_spu.thread[i];
47 break;
48 }
49 }
50 CRASSERT(thread);
51
52 thread->inUse = GL_TRUE;
53 if (!CRPACKSPU_IS_WDDM_CRHGSMI())
54 thread->id = crThreadID();
55 else
56 thread->id = THREAD_OFFSET_MAGIC + i;
57 thread->currentContext = NULL;
58 thread->bInjectThread = GL_FALSE;
59
60 /* connect to the server */
61 thread->netServer.name = crStrdup( pack_spu.name );
62 thread->netServer.buffer_size = pack_spu.buffer_size;
63 packspuConnectToServer( &(thread->netServer)
64#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
65 , pHgsmi
66#endif
67 );
68 CRASSERT(thread->netServer.conn);
69 /* packer setup */
70 CRASSERT(thread->packer == NULL);
71 thread->packer = crPackNewContext( pack_spu.swap );
72 CRASSERT(thread->packer);
73 crPackInitBuffer( &(thread->buffer), crNetAlloc(thread->netServer.conn),
74 thread->netServer.conn->buffer_size, thread->netServer.conn->mtu );
75 thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE;
76 crPackSetBuffer( thread->packer, &thread->buffer );
77 crPackFlushFunc( thread->packer, packspuFlush );
78 crPackFlushArg( thread->packer, (void *) thread );
79 crPackSendHugeFunc( thread->packer, packspuHuge );
80
81 if (!CRPACKSPU_IS_WDDM_CRHGSMI())
82 {
83 crPackSetContext( thread->packer );
84 }
85
86
87#ifdef CHROMIUM_THREADSAFE
88 if (!CRPACKSPU_IS_WDDM_CRHGSMI())
89 {
90 crSetTSD(&_PackTSD, thread);
91 }
92#endif
93
94 pack_spu.numThreads++;
95
96#ifdef CHROMIUM_THREADSAFE
97 crUnlockMutex(&_PackMutex);
98#endif
99 return thread;
100}
101
102GLint PACKSPU_APIENTRY
103packspu_VBoxConCreate(struct VBOXUHGSMI *pHgsmi)
104{
105#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
106 ThreadInfo * thread;
107 CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI());
108 CRASSERT(pHgsmi);
109
110 thread = packspuNewThread(pHgsmi);
111
112 if (thread)
113 {
114 CRASSERT(thread->id);
115 CRASSERT(thread->id - THREAD_OFFSET_MAGIC < RT_ELEMENTS(pack_spu.thread)
116 && GET_THREAD_VAL_ID(thread->id) == thread);
117 return thread->id;
118 }
119 crError("packspuNewThread failed");
120#endif
121 return 0;
122}
123
124void PACKSPU_APIENTRY
125packspu_VBoxConFlush(GLint con)
126{
127#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
128 GET_THREAD_ID(thread, con);
129 CRASSERT(con);
130 CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI());
131 CRASSERT(thread->packer);
132 packspuFlush((void *) thread);
133#else
134 crError("VBoxConFlush not implemented!");
135#endif
136}
137
138void PACKSPU_APIENTRY
139packspu_VBoxConDestroy(GLint con)
140{
141#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
142 GET_THREAD_ID(thread, con);
143 CRASSERT(con);
144 CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI());
145 CRASSERT(pack_spu.numThreads>0);
146 CRASSERT(thread->packer);
147 packspuFlush((void *) thread);
148
149 crLockMutex(&_PackMutex);
150
151 crPackDeleteContext(thread->packer);
152
153 if (thread->buffer.pack)
154 {
155 crNetFree(thread->netServer.conn, thread->buffer.pack);
156 thread->buffer.pack = NULL;
157 }
158
159 crNetFreeConnection(thread->netServer.conn);
160
161 if (thread->netServer.name)
162 crFree(thread->netServer.name);
163
164 pack_spu.numThreads--;
165 /*note can't shift the array here, because other threads have TLS references to array elements*/
166 crMemZero(thread, sizeof(ThreadInfo));
167
168#if 0
169 if (&pack_spu.thread[pack_spu.idxThreadInUse]==thread)
170 {
171 int i;
172 crError("Should not be here since idxThreadInUse should be always 0 for the dummy connection created in packSPUInit!");
173 for (i=0; i<MAX_THREADS; ++i)
174 {
175 if (pack_spu.thread[i].inUse)
176 {
177 pack_spu.idxThreadInUse=i;
178 break;
179 }
180 }
181 }
182#endif
183 crUnlockMutex(&_PackMutex);
184#endif
185}
186
187GLvoid PACKSPU_APIENTRY
188packspu_VBoxConChromiumParameteriCR(GLint con, GLenum param, GLint value)
189{
190 GET_THREAD(thread);
191 CRPackContext * curPacker = crPackGetContext();
192 ThreadInfo *curThread = thread;
193 int writeback = 1;
194 GLint serverCtx = (GLint) -1;
195
196 CRASSERT(!curThread == !curPacker);
197 CRASSERT(!curThread || !curPacker || curThread->packer == curPacker);
198#ifdef CHROMIUM_THREADSAFE
199 crLockMutex(&_PackMutex);
200#endif
201
202#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
203 CRASSERT(!con == !CRPACKSPU_IS_WDDM_CRHGSMI());
204#endif
205
206 if (CRPACKSPU_IS_WDDM_CRHGSMI())
207 {
208 if (!con)
209 {
210 crError("connection should be specified!");
211 return;
212 }
213 thread = GET_THREAD_VAL_ID(con);
214 }
215 else
216 {
217 CRASSERT(!con);
218 if (!thread)
219 {
220 thread = packspuNewThread(
221#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
222 NULL
223#endif
224 );
225 }
226 }
227 CRASSERT(thread);
228 CRASSERT(thread->packer);
229
230 crPackSetContext( thread->packer );
231
232 packspu_ChromiumParameteriCR(param, value);
233
234#ifdef CHROMIUM_THREADSAFE
235 crUnlockMutex(&_PackMutex);
236#endif
237
238 if (CRPACKSPU_IS_WDDM_CRHGSMI())
239 {
240 /* restore the packer context to the tls */
241 crPackSetContext(curPacker);
242 }
243}
244
245GLint PACKSPU_APIENTRY
246packspu_VBoxCreateContext( GLint con, const char *dpyName, GLint visual, GLint shareCtx )
247{
248 GET_THREAD(thread);
249 CRPackContext * curPacker = crPackGetContext();
250 ThreadInfo *curThread = thread;
251 int writeback = 1;
252 GLint serverCtx = (GLint) -1;
253 int slot;
254
255 CRASSERT(!curThread == !curPacker);
256 CRASSERT(!curThread || !curPacker || curThread->packer == curPacker);
257#ifdef CHROMIUM_THREADSAFE
258 crLockMutex(&_PackMutex);
259#endif
260
261#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
262 CRASSERT(!con == !CRPACKSPU_IS_WDDM_CRHGSMI());
263#endif
264
265 if (CRPACKSPU_IS_WDDM_CRHGSMI())
266 {
267 if (!con)
268 {
269 crError("connection should be specified!");
270 return -1;
271 }
272 thread = GET_THREAD_VAL_ID(con);
273 }
274 else
275 {
276 CRASSERT(!con);
277 if (!thread)
278 {
279 thread = packspuNewThread(
280#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
281 NULL
282#endif
283 );
284 }
285 }
286 CRASSERT(thread);
287 CRASSERT(thread->packer);
288
289 if (shareCtx > 0) {
290 /* translate to server ctx id */
291 shareCtx -= MAGIC_OFFSET;
292 if (shareCtx >= 0 && shareCtx < pack_spu.numContexts) {
293 shareCtx = pack_spu.context[shareCtx].serverCtx;
294 }
295 }
296
297 crPackSetContext( thread->packer );
298
299 /* Pack the command */
300 if (pack_spu.swap)
301 crPackCreateContextSWAP( dpyName, visual, shareCtx, &serverCtx, &writeback );
302 else
303 crPackCreateContext( dpyName, visual, shareCtx, &serverCtx, &writeback );
304
305 /* Flush buffer and get return value */
306 packspuFlush(thread);
307 if (!(thread->netServer.conn->actual_network))
308 {
309 /* HUMUNGOUS HACK TO MATCH SERVER NUMBERING
310 *
311 * The hack exists solely to make file networking work for now. This
312 * is totally gross, but since the server expects the numbers to start
313 * from 5000, we need to write them out this way. This would be
314 * marginally less gross if the numbers (500 and 5000) were maybe
315 * some sort of #define'd constants somewhere so the client and the
316 * server could be aware of how each other were numbering things in
317 * cases like file networking where they actually
318 * care.
319 *
320 * -Humper
321 *
322 */
323 serverCtx = 5000;
324 }
325 else {
326 CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
327
328 if (pack_spu.swap) {
329 serverCtx = (GLint) SWAP32(serverCtx);
330 }
331 if (serverCtx < 0) {
332#ifdef CHROMIUM_THREADSAFE
333 crUnlockMutex(&_PackMutex);
334#endif
335 crWarning("Failure in packspu_CreateContext");
336
337 if (CRPACKSPU_IS_WDDM_CRHGSMI())
338 {
339 /* restore the packer context to the tls */
340 crPackSetContext(curPacker);
341 }
342 return -1; /* failed */
343 }
344 }
345
346 /* find an empty context slot */
347 for (slot = 0; slot < pack_spu.numContexts; slot++) {
348 if (!pack_spu.context[slot].clientState) {
349 /* found empty slot */
350 break;
351 }
352 }
353 if (slot == pack_spu.numContexts) {
354 pack_spu.numContexts++;
355 }
356
357 if (CRPACKSPU_IS_WDDM_CRHGSMI())
358 {
359 thread->currentContext = &pack_spu.context[slot];
360 pack_spu.context[slot].currentThread = thread;
361 }
362
363 /* Fill in the new context info */
364 /* XXX fix-up sharedCtx param here */
365 pack_spu.context[slot].clientState = crStateCreateContext(NULL, visual, NULL);
366 pack_spu.context[slot].clientState->bufferobject.retainBufferData = GL_TRUE;
367 pack_spu.context[slot].serverCtx = serverCtx;
368
369#ifdef CHROMIUM_THREADSAFE
370 crUnlockMutex(&_PackMutex);
371#endif
372
373 if (CRPACKSPU_IS_WDDM_CRHGSMI())
374 {
375 /* restore the packer context to the tls */
376 crPackSetContext(curPacker);
377 }
378
379 return MAGIC_OFFSET + slot;
380}
381
382GLint PACKSPU_APIENTRY
383packspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx )
384{
385 return packspu_VBoxCreateContext( 0, dpyName, visual, shareCtx );
386}
387
388
389void PACKSPU_APIENTRY packspu_DestroyContext( GLint ctx )
390{
391 GET_THREAD(thread);
392 ThreadInfo *curThread = thread;
393 const int slot = ctx - MAGIC_OFFSET;
394 ContextInfo *context, *curContext;
395 CRPackContext * curPacker = crPackGetContext();
396
397 CRASSERT(slot >= 0);
398 CRASSERT(slot < pack_spu.numContexts);
399
400 context = &(pack_spu.context[slot]);
401
402 if (CRPACKSPU_IS_WDDM_CRHGSMI())
403 {
404 thread = context->currentThread;
405 crPackSetContext(thread->packer);
406 CRASSERT(!(thread->packer == curPacker) == !(thread == curThread));
407 }
408 CRASSERT(thread);
409 curContext = curThread ? curThread->currentContext : NULL;
410
411 if (pack_spu.swap)
412 crPackDestroyContextSWAP( context->serverCtx );
413 else
414 crPackDestroyContext( context->serverCtx );
415
416 crStateDestroyContext( context->clientState );
417
418 context->clientState = NULL;
419 context->serverCtx = 0;
420 context->currentThread = NULL;
421
422 crMemset (&context->zvaBufferInfo, 0, sizeof (context->zvaBufferInfo));
423
424 if (curContext == context)
425 {
426 if (!CRPACKSPU_IS_WDDM_CRHGSMI())
427 {
428 curThread->currentContext = NULL;
429 }
430 else
431 {
432 CRASSERT(thread == curThread);
433 crSetTSD(&_PackTSD, NULL);
434 crPackSetContext(NULL);
435 }
436 crStateMakeCurrent( NULL );
437 }
438 else
439 {
440 if (CRPACKSPU_IS_WDDM_CRHGSMI())
441 {
442 crPackSetContext(curPacker);
443 }
444 }
445}
446
447void PACKSPU_APIENTRY packspu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx )
448{
449 ThreadInfo *thread;
450 GLint serverCtx;
451 ContextInfo *newCtx;
452
453 if (!CRPACKSPU_IS_WDDM_CRHGSMI())
454 {
455 thread = GET_THREAD_VAL();
456 if (!thread) {
457 thread = packspuNewThread(
458#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
459 NULL
460#endif
461 );
462 }
463 CRASSERT(thread);
464 CRASSERT(thread->packer);
465 }
466
467 if (ctx) {
468 const int slot = ctx - MAGIC_OFFSET;
469
470 CRASSERT(slot >= 0);
471 CRASSERT(slot < pack_spu.numContexts);
472
473 newCtx = &pack_spu.context[slot];
474 CRASSERT(newCtx->clientState); /* verify valid */
475
476 if (CRPACKSPU_IS_WDDM_CRHGSMI())
477 {
478 thread = newCtx->currentThread;
479 CRASSERT(thread);
480 crSetTSD(&_PackTSD, thread);
481 crPackSetContext( thread->packer );
482 }
483 else
484 {
485 if (newCtx->fAutoFlush)
486 {
487 if (newCtx->currentThread && newCtx->currentThread != thread)
488 {
489 crLockMutex(&_PackMutex);
490 /* do a flush for the previously assigned thread
491 * to ensure all commands issued there are submitted */
492 if (newCtx->currentThread
493 && newCtx->currentThread->inUse
494 && newCtx->currentThread->netServer.conn
495 && newCtx->currentThread->packer && newCtx->currentThread->packer->currentBuffer)
496 {
497 packspuFlush((void *) newCtx->currentThread);
498 }
499 crUnlockMutex(&_PackMutex);
500 }
501 newCtx->currentThread = thread;
502 }
503
504 if (thread->currentContext && newCtx != thread->currentContext && thread->currentContext->fCheckZerroVertAttr)
505 crStateCurrentRecoverNew(thread->currentContext->clientState, &thread->packer->current);
506
507 thread->currentContext = newCtx;
508 crPackSetContext( thread->packer );
509 }
510
511 crStateMakeCurrent( newCtx->clientState );
512 //crStateSetCurrentPointers(newCtx->clientState, &thread->packer->current);
513 serverCtx = pack_spu.context[slot].serverCtx;
514 }
515 else {
516 crStateMakeCurrent( NULL );
517 if (CRPACKSPU_IS_WDDM_CRHGSMI())
518 {
519 thread = GET_THREAD_VAL();
520 if (!thread)
521 {
522 CRASSERT(crPackGetContext() == NULL);
523 return;
524 }
525 CRASSERT(thread->currentContext);
526 CRASSERT(thread->packer == crPackGetContext());
527 }
528 else
529 {
530 thread->currentContext = NULL;
531 }
532 newCtx = NULL;
533 serverCtx = 0;
534 }
535
536 if (pack_spu.swap)
537 crPackMakeCurrentSWAP( window, nativeWindow, serverCtx );
538 else
539 crPackMakeCurrent( window, nativeWindow, serverCtx );
540
541 {
542 GET_THREAD(t);
543 (void) t;
544 CRASSERT(t);
545 }
546}
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