VirtualBox

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

Last change on this file since 78376 was 78375, checked in by vboxsync, 6 years ago

Additions/common/crOpengl,GuestHost/OpenGL,HostServices/SharedOpenGL: Eliminate all global variables from the state tracker library (state_tracker) in preparation of the SPU DLL merging, bugref:9435

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