VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c@ 64766

Last change on this file since 64766 was 63199, checked in by vboxsync, 8 years ago

GuestHost/OpenGL: warnings (gcc).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 23.8 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 "state.h"
8#include "cr_mem.h"
9#include "cr_error.h"
10#include "cr_spu.h"
11
12#include <iprt/asm.h>
13
14#ifdef CHROMIUM_THREADSAFE
15static bool __isContextTLSInited = false;
16CRtsd __contextTSD;
17#else
18CRContext *__currentContext = NULL;
19#endif
20
21CRStateBits *__currentBits = NULL;
22CRContext *g_pAvailableContexts[CR_MAX_CONTEXTS];
23uint32_t g_cContexts = 0;
24
25static CRSharedState *gSharedState=NULL;
26
27static CRContext *defaultContext = NULL;
28
29GLboolean g_bVBoxEnableDiffOnMakeCurrent = GL_TRUE;
30
31
32/**
33 * Allocate a new shared state object.
34 * Contains texture objects, display lists, etc.
35 */
36static CRSharedState *
37crStateAllocShared(void)
38{
39 CRSharedState *s = (CRSharedState *) crCalloc(sizeof(CRSharedState));
40 if (s) {
41 s->textureTable = crAllocHashtable();
42 s->dlistTable = crAllocHashtable();
43 s->buffersTable = crAllocHashtable();
44 s->fbTable = crAllocHashtable();
45 s->rbTable = crAllocHashtable();
46 s->refCount = 1; /* refcount is number of contexts using this state */
47 s->saveCount = 0;
48 }
49 return s;
50}
51
52/**
53 * Callback used for crFreeHashtable().
54 */
55DECLEXPORT(void)
56crStateDeleteTextureCallback(void *texObj)
57{
58#ifndef IN_GUEST
59 diff_api.DeleteTextures(1, &((CRTextureObj *)texObj)->hwid);
60#endif
61 crStateDeleteTextureObject((CRTextureObj *) texObj);
62}
63
64typedef struct CR_STATE_RELEASEOBJ
65{
66 CRContext *pCtx;
67 CRSharedState *s;
68} CR_STATE_RELEASEOBJ, *PCR_STATE_RELEASEOBJ;
69
70void crStateOnTextureUsageRelease(CRSharedState *pS, CRTextureObj *pObj)
71{
72 if (!pObj->pinned)
73 crHashtableDelete(pS->textureTable, pObj->id, crStateDeleteTextureCallback);
74 else
75 Assert(crHashtableSearch(pS->textureTable, pObj->id));
76}
77
78static void crStateReleaseTextureInternal(CRSharedState *pS, CRContext *pCtx, CRTextureObj *pObj)
79{
80 Assert(CR_STATE_SHAREDOBJ_USAGE_IS_USED(pObj) || pObj->pinned);
81 CR_STATE_SHAREDOBJ_USAGE_CLEAR(pObj, pCtx);
82 if (CR_STATE_SHAREDOBJ_USAGE_IS_USED(pObj))
83 return;
84
85 crStateOnTextureUsageRelease(pS, pObj);
86}
87
88DECLEXPORT(void) crStateReleaseTexture(CRContext *pCtx, CRTextureObj *pObj)
89{
90 Assert(CR_STATE_SHAREDOBJ_USAGE_IS_USED(pObj));
91 CR_STATE_SHAREDOBJ_USAGE_CLEAR(pObj, pCtx);
92 if (CR_STATE_SHAREDOBJ_USAGE_IS_USED(pObj))
93 return;
94
95 if (!gSharedState)
96 {
97 WARN(("no global shared"));
98 return;
99 }
100
101 crStateOnTextureUsageRelease(gSharedState, pObj);
102}
103
104static void crStateReleaseBufferObjectInternal(CRSharedState *pS, CRContext *pCtx, CRBufferObject *pObj)
105{
106 Assert(CR_STATE_SHAREDOBJ_USAGE_IS_USED(pObj));
107 CR_STATE_SHAREDOBJ_USAGE_CLEAR(pObj, pCtx);
108 if (!CR_STATE_SHAREDOBJ_USAGE_IS_USED(pObj))
109 crHashtableDelete(pS->buffersTable, pObj->id, crStateFreeBufferObject);
110}
111
112static void crStateReleaseFBOInternal(CRSharedState *pS, CRContext *pCtx, CRFramebufferObject *pObj)
113{
114 Assert(CR_STATE_SHAREDOBJ_USAGE_IS_USED(pObj));
115 CR_STATE_SHAREDOBJ_USAGE_CLEAR(pObj, pCtx);
116 if (!CR_STATE_SHAREDOBJ_USAGE_IS_USED(pObj))
117 crHashtableDelete(pS->fbTable, pObj->id, crStateFreeFBO);
118}
119
120static void crStateReleaseRBOInternal(CRSharedState *pS, CRContext *pCtx, CRRenderbufferObject *pObj)
121{
122 Assert(CR_STATE_SHAREDOBJ_USAGE_IS_USED(pObj));
123 CR_STATE_SHAREDOBJ_USAGE_CLEAR(pObj, pCtx);
124 if (!CR_STATE_SHAREDOBJ_USAGE_IS_USED(pObj))
125 crHashtableDelete(pS->rbTable, pObj->id, crStateFreeRBO);
126}
127
128static void ReleaseTextureCallback(unsigned long key, void *data1, void *data2)
129{
130 PCR_STATE_RELEASEOBJ pData = (PCR_STATE_RELEASEOBJ)data2;
131 CRTextureObj *pObj = (CRTextureObj *)data1;
132 (void)key;
133 crStateReleaseTextureInternal(pData->s, pData->pCtx, pObj);
134}
135
136static void ReleaseBufferObjectCallback(unsigned long key, void *data1, void *data2)
137{
138 PCR_STATE_RELEASEOBJ pData = (PCR_STATE_RELEASEOBJ)data2;
139 CRBufferObject *pObj = (CRBufferObject *)data1;
140 (void)key;
141 crStateReleaseBufferObjectInternal(pData->s, pData->pCtx, pObj);
142}
143
144static void ReleaseFBOCallback(unsigned long key, void *data1, void *data2)
145{
146 PCR_STATE_RELEASEOBJ pData = (PCR_STATE_RELEASEOBJ)data2;
147 CRFramebufferObject *pObj = (CRFramebufferObject *)data1;
148 (void)key;
149 crStateReleaseFBOInternal(pData->s, pData->pCtx, pObj);
150}
151
152static void ReleaseRBOCallback(unsigned long key, void *data1, void *data2)
153{
154 PCR_STATE_RELEASEOBJ pData = (PCR_STATE_RELEASEOBJ)data2;
155 CRRenderbufferObject *pObj = (CRRenderbufferObject *)data1;
156 (void)key;
157 crStateReleaseRBOInternal(pData->s, pData->pCtx, pObj);
158}
159
160
161/**
162 * Decrement shared state's refcount and delete when it hits zero.
163 */
164#ifndef IN_GUEST
165DECLEXPORT(void) crStateFreeShared(CRContext *pContext, CRSharedState *s)
166#else
167static void crStateFreeShared(CRContext *pContext, CRSharedState *s)
168#endif
169{
170 int32_t refCount = ASMAtomicDecS32(&s->refCount);
171
172 Assert(refCount >= 0);
173 if (refCount <= 0) {
174 if (s==gSharedState)
175 {
176 gSharedState = NULL;
177 }
178 crFreeHashtable(s->textureTable, crStateDeleteTextureCallback);
179 crFreeHashtable(s->dlistTable, crFree); /* call crFree for each entry */
180 crFreeHashtable(s->buffersTable, crStateFreeBufferObject);
181 crFreeHashtable(s->fbTable, crStateFreeFBO);
182 crFreeHashtable(s->rbTable, crStateFreeRBO);
183 crFree(s);
184 }
185 else if (pContext)
186 {
187 /* evaluate usage bits*/
188 CR_STATE_RELEASEOBJ CbData;
189 CbData.pCtx = pContext;
190 CbData.s = s;
191 crHashtableWalk(s->textureTable, ReleaseTextureCallback, &CbData);
192 crHashtableWalk(s->buffersTable, ReleaseBufferObjectCallback , &CbData);
193 crHashtableWalk(s->fbTable, ReleaseFBOCallback, &CbData);
194 crHashtableWalk(s->rbTable, ReleaseRBOCallback, &CbData);
195 }
196}
197
198#ifndef IN_GUEST
199
200DECLEXPORT(CRSharedState *) crStateGlobalSharedAcquire(void)
201{
202 if (!gSharedState)
203 {
204 crWarning("No Global Shared State!");
205 return NULL;
206 }
207 ASMAtomicIncS32(&gSharedState->refCount);
208 return gSharedState;
209}
210
211DECLEXPORT(void) crStateGlobalSharedRelease(void)
212{
213 crStateFreeShared(NULL, gSharedState);
214}
215
216#endif /* IN_GUEST */
217
218DECLEXPORT(void) STATE_APIENTRY
219crStateShareContext(GLboolean value)
220{
221 CRContext *pCtx = GetCurrentContext();
222 CRASSERT(pCtx && pCtx->shared);
223
224 if (value)
225 {
226 if (pCtx->shared == gSharedState)
227 {
228 return;
229 }
230
231 crDebug("Context(%i) shared", pCtx->id);
232
233 if (!gSharedState)
234 {
235 gSharedState = pCtx->shared;
236 }
237 else
238 {
239 crStateFreeShared(pCtx, pCtx->shared);
240 pCtx->shared = gSharedState;
241 ASMAtomicIncS32(&gSharedState->refCount);
242 }
243 }
244 else
245 {
246 if (pCtx->shared != gSharedState)
247 {
248 return;
249 }
250
251 crDebug("Context(%i) unshared", pCtx->id);
252
253 if (gSharedState->refCount==1)
254 {
255 gSharedState = NULL;
256 }
257 else
258 {
259 pCtx->shared = crStateAllocShared();
260 pCtx->shared->id = pCtx->id;
261 crStateFreeShared(pCtx, gSharedState);
262 }
263 }
264}
265
266DECLEXPORT(void) STATE_APIENTRY
267crStateShareLists(CRContext *pContext1, CRContext *pContext2)
268{
269 CRASSERT(pContext1->shared);
270 CRASSERT(pContext2->shared);
271
272 if (pContext2->shared == pContext1->shared)
273 {
274 return;
275 }
276
277 crStateFreeShared(pContext1, pContext1->shared);
278 pContext1->shared = pContext2->shared;
279 ASMAtomicIncS32(&pContext2->shared->refCount);
280}
281
282DECLEXPORT(GLboolean) STATE_APIENTRY
283crStateContextIsShared(CRContext *pCtx)
284{
285 return pCtx->shared==gSharedState;
286}
287
288DECLEXPORT(void) STATE_APIENTRY
289crStateSetSharedContext(CRContext *pCtx)
290{
291 if (gSharedState)
292 {
293 crWarning("crStateSetSharedContext: shared is being changed from %p to %p", gSharedState, pCtx->shared);
294 }
295
296 gSharedState = pCtx->shared;
297}
298
299#ifdef CHROMIUM_THREADSAFE
300static void
301crStateFreeContext(CRContext *ctx);
302static DECLCALLBACK(void) crStateContextDtor(void *pvCtx)
303{
304 crStateFreeContext((CRContext*)pvCtx);
305}
306#endif
307
308/*
309 * Helper for crStateCreateContext, below.
310 */
311static CRContext *
312crStateCreateContextId(int i, const CRLimitsState *limits, GLint visBits, CRContext *shareCtx)
313{
314 CRContext *ctx;
315 int j;
316 int node32 = i >> 5;
317 int node = i & 0x1f;
318 (void)limits;
319
320 if (g_pAvailableContexts[i] != NULL)
321 {
322 crWarning("trying to create context with used id");
323 return NULL;
324 }
325
326 ctx = (CRContext *) crCalloc( sizeof( *ctx ) );
327 if (!ctx)
328 {
329 crWarning("failed to allocate context");
330 return NULL;
331 }
332 g_pAvailableContexts[i] = ctx;
333 ++g_cContexts;
334 CRASSERT(g_cContexts < RT_ELEMENTS(g_pAvailableContexts));
335 ctx->id = i;
336#ifdef CHROMIUM_THREADSAFE
337 VBoxTlsRefInit(ctx, crStateContextDtor);
338#endif
339 ctx->flush_func = NULL;
340 for (j=0;j<CR_MAX_BITARRAY;j++){
341 if (j == node32) {
342 ctx->bitid[j] = (1 << node);
343 } else {
344 ctx->bitid[j] = 0;
345 }
346 ctx->neg_bitid[j] = ~(ctx->bitid[j]);
347 }
348
349 if (shareCtx) {
350 CRASSERT(shareCtx->shared);
351 ctx->shared = shareCtx->shared;
352 ASMAtomicIncS32(&ctx->shared->refCount);
353 }
354 else {
355 ctx->shared = crStateAllocShared();
356 ctx->shared->id = ctx->id;
357 }
358
359 /* use Chromium's OpenGL defaults */
360 crStateLimitsInit( &(ctx->limits) );
361 crStateExtensionsInit( &(ctx->limits), &(ctx->extensions) );
362
363 crStateBufferObjectInit( ctx ); /* must precede client state init! */
364 crStateClientInit( ctx );
365
366 crStateBufferInit( ctx );
367 crStateCurrentInit( ctx );
368 crStateEvaluatorInit( ctx );
369 crStateFogInit( ctx );
370 crStateHintInit( ctx );
371 crStateLightingInit( ctx );
372 crStateLineInit( ctx );
373 crStateListsInit( ctx );
374 crStateMultisampleInit( ctx );
375 crStateOcclusionInit( ctx );
376 crStatePixelInit( ctx );
377 crStatePolygonInit( ctx );
378 crStatePointInit( ctx );
379 crStateProgramInit( ctx );
380 crStateRegCombinerInit( ctx );
381 crStateStencilInit( ctx );
382 crStateTextureInit( ctx );
383 crStateTransformInit( ctx );
384 crStateViewportInit ( ctx );
385 crStateFramebufferObjectInit(ctx);
386 crStateGLSLInit(ctx);
387
388 /* This has to come last. */
389 crStateAttribInit( &(ctx->attrib) );
390
391 ctx->renderMode = GL_RENDER;
392
393 /* Initialize values that depend on the visual mode */
394 if (visBits & CR_DOUBLE_BIT) {
395 ctx->limits.doubleBuffer = GL_TRUE;
396 }
397 if (visBits & CR_RGB_BIT) {
398 ctx->limits.redBits = 8;
399 ctx->limits.greenBits = 8;
400 ctx->limits.blueBits = 8;
401 if (visBits & CR_ALPHA_BIT) {
402 ctx->limits.alphaBits = 8;
403 }
404 }
405 else {
406 ctx->limits.indexBits = 8;
407 }
408 if (visBits & CR_DEPTH_BIT) {
409 ctx->limits.depthBits = 24;
410 }
411 if (visBits & CR_STENCIL_BIT) {
412 ctx->limits.stencilBits = 8;
413 }
414 if (visBits & CR_ACCUM_BIT) {
415 ctx->limits.accumRedBits = 16;
416 ctx->limits.accumGreenBits = 16;
417 ctx->limits.accumBlueBits = 16;
418 if (visBits & CR_ALPHA_BIT) {
419 ctx->limits.accumAlphaBits = 16;
420 }
421 }
422 if (visBits & CR_STEREO_BIT) {
423 ctx->limits.stereo = GL_TRUE;
424 }
425 if (visBits & CR_MULTISAMPLE_BIT) {
426 ctx->limits.sampleBuffers = 1;
427 ctx->limits.samples = 4;
428 ctx->multisample.enabled = GL_TRUE;
429 }
430
431 if (visBits & CR_OVERLAY_BIT) {
432 ctx->limits.level = 1;
433 }
434
435 return ctx;
436}
437
438/*@todo crStateAttribDestroy*/
439static void
440crStateFreeContext(CRContext *ctx)
441{
442#ifndef DEBUG_misha
443 CRASSERT(g_pAvailableContexts[ctx->id] == ctx);
444#endif
445 if (g_pAvailableContexts[ctx->id] == ctx)
446 {
447 g_pAvailableContexts[ctx->id] = NULL;
448 --g_cContexts;
449 CRASSERT(g_cContexts < RT_ELEMENTS(g_pAvailableContexts));
450 }
451 else
452 {
453#ifndef DEBUG_misha
454 crWarning("freeing context %p, id(%d) not being in the context list", ctx, ctx->id);
455#endif
456 }
457
458 crStateClientDestroy( ctx );
459 crStateLimitsDestroy( &(ctx->limits) );
460 crStateBufferObjectDestroy( ctx );
461 crStateEvaluatorDestroy( ctx );
462 crStateListsDestroy( ctx );
463 crStateLightingDestroy( ctx );
464 crStateOcclusionDestroy( ctx );
465 crStateProgramDestroy( ctx );
466 crStateTextureDestroy( ctx );
467 crStateTransformDestroy( ctx );
468 crStateFreeShared(ctx, ctx->shared);
469 crStateFramebufferObjectDestroy(ctx);
470 crStateGLSLDestroy(ctx);
471 if (ctx->buffer.pFrontImg) crFree(ctx->buffer.pFrontImg);
472 if (ctx->buffer.pBackImg) crFree(ctx->buffer.pBackImg);
473 crFree( ctx );
474}
475
476#ifdef CHROMIUM_THREADSAFE
477# ifndef RT_OS_WINDOWS
478static void crStateThreadTlsDtor(void *pvValue)
479{
480 CRContext *pCtx = (CRContext*)pvValue;
481 VBoxTlsRefRelease(pCtx);
482}
483# endif
484#endif
485
486/*
487 * Allocate the state (dirty) bits data structures.
488 * This should be called before we create any contexts.
489 * We'll also create the default/NULL context at this time and make
490 * it the current context by default. This means that if someone
491 * tries to set GL state before calling MakeCurrent() they'll be
492 * modifying the default state object, and not segfaulting on a NULL
493 * pointer somewhere.
494 */
495void crStateInit(void)
496{
497 unsigned int i;
498
499 /* Purely initialize the context bits */
500 if (!__currentBits) {
501 __currentBits = (CRStateBits *) crCalloc( sizeof(CRStateBits) );
502 crStateClientInitBits( &(__currentBits->client) );
503 crStateLightingInitBits( &(__currentBits->lighting) );
504 } else
505 {
506#ifndef DEBUG_misha
507 crWarning("State tracker is being re-initialized..\n");
508#endif
509 }
510
511 for (i=0;i<CR_MAX_CONTEXTS;i++)
512 g_pAvailableContexts[i] = NULL;
513 g_cContexts = 0;
514
515#ifdef CHROMIUM_THREADSAFE
516 if (!__isContextTLSInited)
517 {
518# ifndef RT_OS_WINDOWS
519 /* tls destructor is implemented for all platforms except windows*/
520 crInitTSDF(&__contextTSD, crStateThreadTlsDtor);
521# else
522 /* windows should do cleanup via DllMain THREAD_DETACH notification */
523 crInitTSD(&__contextTSD);
524# endif
525 __isContextTLSInited = 1;
526 }
527#endif
528
529 if (defaultContext) {
530 /* Free the default/NULL context.
531 * Ensures context bits are reset */
532#ifdef CHROMIUM_THREADSAFE
533 SetCurrentContext(NULL);
534 VBoxTlsRefRelease(defaultContext);
535#else
536 crStateFreeContext(defaultContext);
537 __currentContext = NULL;
538#endif
539 }
540
541 /* Reset diff_api */
542 crMemZero(&diff_api, sizeof(SPUDispatchTable));
543
544 Assert(!gSharedState);
545 gSharedState = NULL;
546
547 /* Allocate the default/NULL context */
548 CRASSERT(g_pAvailableContexts[0] == NULL);
549 defaultContext = crStateCreateContextId(0, NULL, CR_RGB_BIT, NULL);
550 CRASSERT(g_pAvailableContexts[0] == defaultContext);
551 CRASSERT(g_cContexts == 1);
552#ifdef CHROMIUM_THREADSAFE
553 SetCurrentContext(defaultContext);
554#else
555 __currentContext = defaultContext;
556#endif
557}
558
559void crStateDestroy(void)
560{
561 int i;
562 if (__currentBits)
563 {
564 crStateClientDestroyBits(&(__currentBits->client));
565 crStateLightingDestroyBits(&(__currentBits->lighting));
566 crFree(__currentBits);
567 __currentBits = NULL;
568 }
569
570 SetCurrentContext(NULL);
571
572 for (i = CR_MAX_CONTEXTS-1; i >= 0; i--)
573 {
574 if (g_pAvailableContexts[i])
575 {
576#ifdef CHROMIUM_THREADSAFE
577 if (VBoxTlsRefIsFunctional(g_pAvailableContexts[i]))
578 VBoxTlsRefRelease(g_pAvailableContexts[i]);
579#else
580 crStateFreeContext(g_pAvailableContexts[i]);
581#endif
582 }
583 }
584
585 /* default context was stored in g_pAvailableContexts[0], so it was destroyed already */
586 defaultContext = NULL;
587
588
589#ifdef CHROMIUM_THREADSAFE
590 crFreeTSD(&__contextTSD);
591 __isContextTLSInited = 0;
592#endif
593}
594
595/*
596 * Notes on context switching and the "default context".
597 *
598 * See the paper "Tracking Graphics State for Networked Rendering"
599 * by Ian Buck, Greg Humphries and Pat Hanrahan for background
600 * information about how the state tracker and context switching
601 * works.
602 *
603 * When we make a new context current, we call crStateSwitchContext()
604 * in order to transform the 'from' context into the 'to' context
605 * (i.e. the old context to the new context). The transformation
606 * is accomplished by calling GL functions through the 'diff_api'
607 * so that the downstream GL machine (represented by the __currentContext
608 * structure) is updated to reflect the new context state. Finally,
609 * we point __currentContext to the new context.
610 *
611 * A subtle problem we have to deal with is context destruction.
612 * This issue arose while testing with Glean. We found that when
613 * the currently bound context was getting destroyed that state
614 * tracking was incorrect when a subsequent new context was activated.
615 * In DestroyContext, the __hwcontext was being set to NULL and effectively
616 * going away. Later in MakeCurrent we had no idea what the state of the
617 * downstream GL machine was (since __hwcontext was gone). This meant
618 * we had nothing to 'diff' against and the downstream GL machine was
619 * in an unknown state.
620 *
621 * The solution to this problem is the "default/NULL" context. The
622 * default context is created the first time CreateContext is called
623 * and is never freed. Whenever we get a crStateMakeCurrent(NULL) call
624 * or destroy the currently bound context in crStateDestroyContext()
625 * we call crStateSwitchContext() to switch to the default context and
626 * then set the __currentContext pointer to point to the default context.
627 * This ensures that the dirty bits are updated and the diff_api functions
628 * are called to keep the downstream GL machine in a known state.
629 * Finally, the __hwcontext variable is no longer needed now.
630 *
631 * Yeah, this is kind of a mind-bender, but it really solves the problem
632 * pretty cleanly.
633 *
634 * -Brian
635 */
636
637
638CRContext *
639crStateCreateContext(const CRLimitsState *limits, GLint visBits, CRContext *share)
640{
641 return crStateCreateContextEx(limits, visBits, share, -1);
642}
643
644CRContext *
645crStateCreateContextEx(const CRLimitsState *limits, GLint visBits, CRContext *share, GLint presetID)
646{
647 /* Must have created the default context via crStateInit() first */
648 CRASSERT(defaultContext);
649
650 if (presetID>0)
651 {
652 if(g_pAvailableContexts[presetID])
653 {
654 crWarning("requesting to create context with already allocated id");
655 return NULL;
656 }
657 }
658 else
659 {
660 int i;
661
662 for (i = 1 ; i < CR_MAX_CONTEXTS ; i++)
663 {
664 if (!g_pAvailableContexts[i])
665 {
666 presetID = i;
667 break;
668 }
669 }
670
671 if (presetID<=0)
672 {
673 crError( "Out of available contexts in crStateCreateContexts (max %d)",
674 CR_MAX_CONTEXTS );
675 /* never get here */
676 return NULL;
677 }
678 }
679
680 return crStateCreateContextId(presetID, limits, visBits, share);
681}
682
683void crStateDestroyContext( CRContext *ctx )
684{
685 CRContext *current = GetCurrentContext();
686
687 if (current == ctx) {
688 /* destroying the current context - have to be careful here */
689 CRASSERT(defaultContext);
690 /* Check to see if the differencer exists first,
691 we may not have one, aka the packspu */
692 if (diff_api.AlphaFunc)
693 crStateSwitchContext(current, defaultContext);
694#ifdef CHROMIUM_THREADSAFE
695 SetCurrentContext(defaultContext);
696#else
697 __currentContext = defaultContext;
698#endif
699 /* ensure matrix state is also current */
700 crStateMatrixMode(defaultContext->transform.matrixMode);
701 }
702
703#ifdef CHROMIUM_THREADSAFE
704 VBoxTlsRefMarkDestroy(ctx);
705# ifdef IN_GUEST
706 if (VBoxTlsRefCountGet(ctx) > 1 && ctx->shared == gSharedState)
707 {
708 /* we always need to free the global shared state to prevent the situation when guest thinks the shared objects are still valid, while host destroys them */
709 crStateFreeShared(ctx, ctx->shared);
710 ctx->shared = crStateAllocShared();
711 }
712# endif
713 VBoxTlsRefRelease(ctx);
714#else
715 crStateFreeContext(ctx);
716#endif
717}
718
719GLboolean crStateEnableDiffOnMakeCurrent(GLboolean fEnable)
720{
721 GLboolean bOld = g_bVBoxEnableDiffOnMakeCurrent;
722 g_bVBoxEnableDiffOnMakeCurrent = fEnable;
723 return bOld;
724}
725
726void crStateMakeCurrent( CRContext *ctx )
727{
728 CRContext *current = GetCurrentContext();
729 CRContext *pLocalCtx = ctx;
730
731 if (pLocalCtx == NULL)
732 pLocalCtx = defaultContext;
733
734 if (current == pLocalCtx)
735 return; /* no-op */
736
737 CRASSERT(pLocalCtx);
738
739 if (g_bVBoxEnableDiffOnMakeCurrent && current) {
740 /* Check to see if the differencer exists first,
741 we may not have one, aka the packspu */
742 if (diff_api.AlphaFunc)
743 crStateSwitchContext( current, pLocalCtx );
744 }
745
746#ifdef CHROMIUM_THREADSAFE
747 SetCurrentContext(pLocalCtx);
748#else
749 __currentContext = pLocalCtx;
750#endif
751
752 /* ensure matrix state is also current */
753 crStateMatrixMode(pLocalCtx->transform.matrixMode);
754}
755
756
757/*
758 * As above, but don't call crStateSwitchContext().
759 */
760static void crStateSetCurrentEx( CRContext *ctx, GLboolean fCleanupDefault )
761{
762 CRContext *current = GetCurrentContext();
763 CRContext *pLocalCtx = ctx;
764
765 if (pLocalCtx == NULL && !fCleanupDefault)
766 pLocalCtx = defaultContext;
767
768 if (current == pLocalCtx)
769 return; /* no-op */
770
771#ifdef CHROMIUM_THREADSAFE
772 SetCurrentContext(pLocalCtx);
773#else
774 __currentContext = pLocalCtx;
775#endif
776
777 if (pLocalCtx)
778 {
779 /* ensure matrix state is also current */
780 crStateMatrixMode(pLocalCtx->transform.matrixMode);
781 }
782}
783
784void crStateSetCurrent( CRContext *ctx )
785{
786 crStateSetCurrentEx( ctx, GL_FALSE );
787}
788
789void crStateCleanupCurrent()
790{
791 crStateSetCurrentEx( NULL, GL_TRUE );
792}
793
794
795CRContext *crStateGetCurrent(void)
796{
797 return GetCurrentContext();
798}
799
800
801void crStateUpdateColorBits(void)
802{
803 /* This is a hack to force updating the 'current' attribs */
804 CRStateBits *sb = GetCurrentBits();
805 FILLDIRTY(sb->current.dirty);
806 FILLDIRTY(sb->current.vertexAttrib[VERT_ATTRIB_COLOR0]);
807}
808
809
810void STATE_APIENTRY
811crStateChromiumParameteriCR( GLenum target, GLint value )
812{
813 /* This no-op function helps smooth code-gen */
814 (void)target; (void)value;
815}
816
817void STATE_APIENTRY
818crStateChromiumParameterfCR( GLenum target, GLfloat value )
819{
820 /* This no-op function helps smooth code-gen */
821 (void)target; (void)value;
822}
823
824void STATE_APIENTRY
825crStateChromiumParametervCR( GLenum target, GLenum type, GLsizei count, const GLvoid *values )
826{
827 /* This no-op function helps smooth code-gen */
828 (void)target; (void)type; (void)count; (void)values;
829}
830
831void STATE_APIENTRY
832crStateGetChromiumParametervCR( GLenum target, GLuint index, GLenum type, GLsizei count, GLvoid *values )
833{
834 /* This no-op function helps smooth code-gen */
835 (void)target; (void)index; (void)type; (void)count; (void)values;
836}
837
838void STATE_APIENTRY
839crStateReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
840 GLenum format, GLenum type, GLvoid *pixels )
841{
842 /* This no-op function helps smooth code-gen */
843 (void)x; (void)y; (void)width; (void)height; (void)format; (void)type; (void)pixels;
844}
845
846void crStateVBoxDetachThread(void)
847{
848 /* release the context ref so that it can be freed */
849 SetCurrentContext(NULL);
850}
851
852
853void crStateVBoxAttachThread(void)
854{
855}
856
857#if 0 /* who's refering to these? */
858
859GLint crStateVBoxCreateContext( GLint con, const char * dpyName, GLint visual, GLint shareCtx )
860{
861 (void)con; (void)dpyName; (void)visual; (void)shareCtx;
862 return 0;
863}
864
865GLint crStateVBoxWindowCreate( GLint con, const char *dpyName, GLint visBits )
866{
867 (void)con; (void)dpyName; (void)visBits;
868 return 0;
869}
870
871void crStateVBoxWindowDestroy( GLint con, GLint window )
872{
873 (void)con; (void)window;
874}
875
876GLint crStateVBoxConCreate(struct VBOXUHGSMI *pHgsmi)
877{
878 (void)pHgsmi;
879 return 0;
880}
881
882void crStateVBoxConDestroy(GLint con)
883{
884 (void)con;
885}
886
887void crStateVBoxConFlush(GLint con)
888{
889 (void)con;
890}
891
892#endif /* unused? */
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