VirtualBox

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

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

CrOpenGL: GetString inside DisplayLists

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