VirtualBox

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

最後變更 在這個檔案從77693是 69310,由 vboxsync 提交於 7 年 前

common/crOpenGL: scm updates

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id Revision
檔案大小: 16.2 KB
 
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#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#else
121 RT_NOREF(pHgsmi);
122#endif
123 return 0;
124}
125
126void PACKSPU_APIENTRY
127packspu_VBoxConFlush(GLint con)
128{
129#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
130 GET_THREAD_ID(thread, con);
131 CRASSERT(con);
132 CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI());
133 CRASSERT(thread->packer);
134 packspuFlush((void *) thread);
135#else
136 RT_NOREF(con);
137 crError("VBoxConFlush not implemented!");
138#endif
139}
140
141void PACKSPU_APIENTRY
142packspu_VBoxConDestroy(GLint con)
143{
144#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
145 GET_THREAD_ID(thread, con);
146 CRASSERT(con);
147 CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI());
148 CRASSERT(pack_spu.numThreads>0);
149 CRASSERT(thread->packer);
150 packspuFlush((void *) thread);
151
152 crLockMutex(&_PackMutex);
153
154 crPackDeleteContext(thread->packer);
155
156 if (thread->buffer.pack)
157 {
158 crNetFree(thread->netServer.conn, thread->buffer.pack);
159 thread->buffer.pack = NULL;
160 }
161
162 crNetFreeConnection(thread->netServer.conn);
163
164 if (thread->netServer.name)
165 crFree(thread->netServer.name);
166
167 pack_spu.numThreads--;
168 /*note can't shift the array here, because other threads have TLS references to array elements*/
169 crMemZero(thread, sizeof(ThreadInfo));
170
171#if 0
172 if (&pack_spu.thread[pack_spu.idxThreadInUse]==thread)
173 {
174 int i;
175 crError("Should not be here since idxThreadInUse should be always 0 for the dummy connection created in packSPUInit!");
176 for (i=0; i<MAX_THREADS; ++i)
177 {
178 if (pack_spu.thread[i].inUse)
179 {
180 pack_spu.idxThreadInUse=i;
181 break;
182 }
183 }
184 }
185#endif
186 crUnlockMutex(&_PackMutex);
187#else
188 RT_NOREF(con);
189#endif
190}
191
192GLvoid PACKSPU_APIENTRY
193packspu_VBoxConChromiumParameteriCR(GLint con, GLenum param, GLint value)
194{
195 GET_THREAD(thread);
196 CRPackContext * curPacker = crPackGetContext();
197 ThreadInfo *curThread = thread;
198
199 CRASSERT(!curThread == !curPacker);
200 CRASSERT(!curThread || !curPacker || curThread->packer == curPacker);
201#ifdef CHROMIUM_THREADSAFE
202 crLockMutex(&_PackMutex);
203#endif
204
205#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
206 CRASSERT(!con == !CRPACKSPU_IS_WDDM_CRHGSMI());
207#endif
208
209 if (CRPACKSPU_IS_WDDM_CRHGSMI())
210 {
211 if (!con)
212 {
213 crError("connection should be specified!");
214 return;
215 }
216 thread = GET_THREAD_VAL_ID(con);
217 }
218 else
219 {
220 CRASSERT(!con);
221 if (!thread)
222 {
223 thread = packspuNewThread(
224#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
225 NULL
226#endif
227 );
228 }
229 }
230 CRASSERT(thread);
231 CRASSERT(thread->packer);
232
233 crPackSetContext( thread->packer );
234
235 packspu_ChromiumParameteriCR(param, value);
236
237#ifdef CHROMIUM_THREADSAFE
238 crUnlockMutex(&_PackMutex);
239#endif
240
241 if (CRPACKSPU_IS_WDDM_CRHGSMI())
242 {
243 /* restore the packer context to the tls */
244 crPackSetContext(curPacker);
245 }
246}
247
248GLvoid PACKSPU_APIENTRY
249packspu_VBoxConChromiumParametervCR(GLint con, GLenum target, GLenum type, GLsizei count, const GLvoid *values)
250{
251 GET_THREAD(thread);
252 CRPackContext * curPacker = crPackGetContext();
253 ThreadInfo *curThread = thread;
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;
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 crPackSetContext( thread->packer );
290
291 packspu_ChromiumParametervCR(target, type, count, values);
292
293#ifdef CHROMIUM_THREADSAFE
294 crUnlockMutex(&_PackMutex);
295#endif
296
297 if (CRPACKSPU_IS_WDDM_CRHGSMI())
298 {
299 /* restore the packer context to the tls */
300 crPackSetContext(curPacker);
301 }
302}
303
304GLint PACKSPU_APIENTRY
305packspu_VBoxCreateContext( GLint con, const char *dpyName, GLint visual, GLint shareCtx )
306{
307 GET_THREAD(thread);
308 CRPackContext * curPacker = crPackGetContext();
309 ThreadInfo *curThread = thread;
310 int writeback = 1;
311 GLint serverCtx = (GLint) -1;
312 int slot;
313
314 CRASSERT(!curThread == !curPacker);
315 CRASSERT(!curThread || !curPacker || curThread->packer == curPacker);
316#ifdef CHROMIUM_THREADSAFE
317 crLockMutex(&_PackMutex);
318#endif
319
320#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
321 CRASSERT(!con == !CRPACKSPU_IS_WDDM_CRHGSMI());
322#endif
323
324 if (CRPACKSPU_IS_WDDM_CRHGSMI())
325 {
326 if (!con)
327 {
328 crError("connection should be specified!");
329 return -1;
330 }
331 thread = GET_THREAD_VAL_ID(con);
332 }
333 else
334 {
335 CRASSERT(!con);
336 if (!thread)
337 {
338 thread = packspuNewThread(
339#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
340 NULL
341#endif
342 );
343 }
344 }
345 CRASSERT(thread);
346 CRASSERT(thread->packer);
347
348 if (shareCtx > 0) {
349 /* translate to server ctx id */
350 shareCtx -= MAGIC_OFFSET;
351 if (shareCtx >= 0 && shareCtx < pack_spu.numContexts) {
352 shareCtx = pack_spu.context[shareCtx].serverCtx;
353 }
354 }
355
356 crPackSetContext( thread->packer );
357
358 /* Pack the command */
359 if (pack_spu.swap)
360 crPackCreateContextSWAP( dpyName, visual, shareCtx, &serverCtx, &writeback );
361 else
362 crPackCreateContext( dpyName, visual, shareCtx, &serverCtx, &writeback );
363
364 /* Flush buffer and get return value */
365 packspuFlush(thread);
366 if (!(thread->netServer.conn->actual_network))
367 {
368 /* HUMUNGOUS HACK TO MATCH SERVER NUMBERING
369 *
370 * The hack exists solely to make file networking work for now. This
371 * is totally gross, but since the server expects the numbers to start
372 * from 5000, we need to write them out this way. This would be
373 * marginally less gross if the numbers (500 and 5000) were maybe
374 * some sort of #define'd constants somewhere so the client and the
375 * server could be aware of how each other were numbering things in
376 * cases like file networking where they actually
377 * care.
378 *
379 * -Humper
380 *
381 */
382 serverCtx = 5000;
383 }
384 else {
385 CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
386
387 if (pack_spu.swap) {
388 serverCtx = (GLint) SWAP32(serverCtx);
389 }
390 if (serverCtx < 0) {
391#ifdef CHROMIUM_THREADSAFE
392 crUnlockMutex(&_PackMutex);
393#endif
394 crWarning("Failure in packspu_CreateContext");
395
396 if (CRPACKSPU_IS_WDDM_CRHGSMI())
397 {
398 /* restore the packer context to the tls */
399 crPackSetContext(curPacker);
400 }
401 return -1; /* failed */
402 }
403 }
404
405 /* find an empty context slot */
406 for (slot = 0; slot < pack_spu.numContexts; slot++) {
407 if (!pack_spu.context[slot].clientState) {
408 /* found empty slot */
409 break;
410 }
411 }
412 if (slot == pack_spu.numContexts) {
413 pack_spu.numContexts++;
414 }
415
416 if (CRPACKSPU_IS_WDDM_CRHGSMI())
417 {
418 thread->currentContext = &pack_spu.context[slot];
419 pack_spu.context[slot].currentThread = thread;
420 }
421
422 /* Fill in the new context info */
423 /* XXX fix-up sharedCtx param here */
424 pack_spu.context[slot].clientState = crStateCreateContext(NULL, visual, NULL);
425 pack_spu.context[slot].clientState->bufferobject.retainBufferData = GL_TRUE;
426 pack_spu.context[slot].serverCtx = serverCtx;
427
428#ifdef CHROMIUM_THREADSAFE
429 crUnlockMutex(&_PackMutex);
430#endif
431
432 if (CRPACKSPU_IS_WDDM_CRHGSMI())
433 {
434 /* restore the packer context to the tls */
435 crPackSetContext(curPacker);
436 }
437
438 return MAGIC_OFFSET + slot;
439}
440
441GLint PACKSPU_APIENTRY
442packspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx )
443{
444 return packspu_VBoxCreateContext( 0, dpyName, visual, shareCtx );
445}
446
447
448void PACKSPU_APIENTRY packspu_DestroyContext( GLint ctx )
449{
450 GET_THREAD(thread);
451 ThreadInfo *curThread = thread;
452 const int slot = ctx - MAGIC_OFFSET;
453 ContextInfo *context, *curContext;
454 CRPackContext * curPacker = crPackGetContext();
455
456 CRASSERT(slot >= 0);
457 CRASSERT(slot < pack_spu.numContexts);
458
459 context = (slot >= 0 && slot < pack_spu.numContexts) ? &(pack_spu.context[slot]) : NULL;
460 curContext = curThread ? curThread->currentContext : NULL;
461
462 if (context)
463 {
464 if (CRPACKSPU_IS_WDDM_CRHGSMI())
465 {
466 thread = context->currentThread;
467 if (thread)
468 {
469 crPackSetContext(thread->packer);
470 CRASSERT(!(thread->packer == curPacker) == !(thread == curThread));
471 }
472 }
473
474 if (pack_spu.swap)
475 crPackDestroyContextSWAP( context->serverCtx );
476 else
477 crPackDestroyContext( context->serverCtx );
478
479 crStateDestroyContext( context->clientState );
480
481 context->clientState = NULL;
482 context->serverCtx = 0;
483 context->currentThread = NULL;
484
485 crMemset (&context->zvaBufferInfo, 0, sizeof (context->zvaBufferInfo));
486 }
487
488 if (curContext == context)
489 {
490 if (!CRPACKSPU_IS_WDDM_CRHGSMI())
491 {
492 curThread->currentContext = NULL;
493 }
494 else
495 {
496 CRASSERT(thread == curThread);
497 crSetTSD(&_PackTSD, NULL);
498 crPackSetContext(NULL);
499 }
500 crStateMakeCurrent( NULL );
501 }
502 else
503 {
504 if (CRPACKSPU_IS_WDDM_CRHGSMI())
505 {
506 crPackSetContext(curPacker);
507 }
508 }
509}
510
511void PACKSPU_APIENTRY packspu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx )
512{
513 ThreadInfo *thread = NULL;
514 GLint serverCtx;
515 ContextInfo *newCtx = NULL;
516
517 if (!CRPACKSPU_IS_WDDM_CRHGSMI())
518 {
519 thread = GET_THREAD_VAL();
520 if (!thread) {
521 thread = packspuNewThread(
522#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
523 NULL
524#endif
525 );
526 }
527 CRASSERT(thread);
528 CRASSERT(thread->packer);
529 }
530
531 if (ctx) {
532 const int slot = ctx - MAGIC_OFFSET;
533
534 CRASSERT(slot >= 0);
535 CRASSERT(slot < pack_spu.numContexts);
536
537 newCtx = &pack_spu.context[slot];
538 CRASSERT(newCtx);
539 CRASSERT(newCtx->clientState); /* verify valid */
540
541 if (CRPACKSPU_IS_WDDM_CRHGSMI())
542 {
543 thread = newCtx->currentThread;
544 CRASSERT(thread);
545 crSetTSD(&_PackTSD, thread);
546 crPackSetContext( thread->packer );
547 }
548 else
549 {
550 CRASSERT(thread);
551 if (newCtx->fAutoFlush)
552 {
553 if (newCtx->currentThread && newCtx->currentThread != thread)
554 {
555 crLockMutex(&_PackMutex);
556 /* do a flush for the previously assigned thread
557 * to ensure all commands issued there are submitted */
558 if (newCtx->currentThread
559 && newCtx->currentThread->inUse
560 && newCtx->currentThread->netServer.conn
561 && newCtx->currentThread->packer && newCtx->currentThread->packer->currentBuffer)
562 {
563 packspuFlush((void *) newCtx->currentThread);
564 }
565 crUnlockMutex(&_PackMutex);
566 }
567 newCtx->currentThread = thread;
568 }
569
570 if (thread->currentContext && newCtx != thread->currentContext && thread->currentContext->fCheckZerroVertAttr)
571 crStateCurrentRecoverNew(thread->currentContext->clientState, &thread->packer->current);
572
573 thread->currentContext = newCtx;
574 crPackSetContext( thread->packer );
575 }
576
577 crStateMakeCurrent( newCtx->clientState );
578 //crStateSetCurrentPointers(newCtx->clientState, &thread->packer->current);
579 serverCtx = pack_spu.context[slot].serverCtx;
580 }
581 else {
582 crStateMakeCurrent( NULL );
583 if (CRPACKSPU_IS_WDDM_CRHGSMI())
584 {
585 thread = GET_THREAD_VAL();
586 if (!thread)
587 {
588 CRASSERT(crPackGetContext() == NULL);
589 return;
590 }
591 CRASSERT(thread->currentContext);
592 CRASSERT(thread->packer == crPackGetContext());
593 }
594 else
595 {
596 thread->currentContext = NULL;
597 }
598 newCtx = NULL;
599 serverCtx = 0;
600 }
601
602 if (pack_spu.swap)
603 crPackMakeCurrentSWAP( window, nativeWindow, serverCtx );
604 else
605 crPackMakeCurrent( window, nativeWindow, serverCtx );
606
607 if (serverCtx)
608 {
609 packspuInitStrings();
610 }
611
612 {
613 GET_THREAD(t);
614 (void) t;
615 CRASSERT(t);
616 }
617}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette