VirtualBox

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

Last change on this file since 62532 was 57423, checked in by vboxsync, 9 years ago

DECLCALLBACK fix

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