VirtualBox

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

最後變更 在這個檔案從44290是 44290,由 vboxsync 提交於 12 年 前

crOpenGL: saved state fixes & improvements

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

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