VirtualBox

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

最後變更 在這個檔案從80272是 78375,由 vboxsync 提交於 6 年 前

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

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

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