diff options
| author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2014-03-26 19:21:20 +0000 |
|---|---|---|
| committer | <> | 2014-05-08 15:03:54 +0000 |
| commit | fb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch) | |
| tree | c2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/GuestHost/OpenGL/state_tracker/state_init.c | |
| parent | 58ed4748338f9466599adfc8a9171280ed99e23f (diff) | |
| download | VirtualBox-master.tar.gz | |
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/GuestHost/OpenGL/state_tracker/state_init.c')
| -rw-r--r-- | src/VBox/GuestHost/OpenGL/state_tracker/state_init.c | 163 |
1 files changed, 128 insertions, 35 deletions
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c index f8ac1f5a..49bcd38b 100644 --- a/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c +++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c @@ -17,13 +17,14 @@ CRContext *__currentContext = NULL; #endif CRStateBits *__currentBits = NULL; -GLboolean g_availableContexts[CR_MAX_CONTEXTS]; +CRContext *g_pAvailableContexts[CR_MAX_CONTEXTS]; +uint32_t g_cContexts = 0; static CRSharedState *gSharedState=NULL; static CRContext *defaultContext = NULL; -static GLboolean g_bVBoxEnableDiffOnMakeCurrent = GL_TRUE; +GLboolean g_bVBoxEnableDiffOnMakeCurrent = GL_TRUE; /** @@ -60,7 +61,6 @@ crStateDeleteTextureCallback(void *texObj) crStateDeleteTextureObject((CRTextureObj *) texObj); } -#ifndef IN_GUEST typedef struct CR_STATE_RELEASEOBJ { CRContext *pCtx; @@ -102,7 +102,7 @@ static void ReleaseRBOCallback(unsigned long key, void *data1, void *data2) if (!CR_STATE_SHAREDOBJ_USAGE_IS_USED(pObj)) crHashtableDelete(pData->s->rbTable, key, crStateFreeRBO); } -#endif + /** * Decrement shared state's refcount and delete when it hits zero. */ @@ -110,6 +110,7 @@ DECLEXPORT(void) crStateFreeShared(CRContext *pContext, CRSharedState *s) { s->refCount--; + Assert(s->refCount >= 0); if (s->refCount <= 0) { if (s==gSharedState) { @@ -122,8 +123,7 @@ crStateFreeShared(CRContext *pContext, CRSharedState *s) crFreeHashtable(s->rbTable, crStateFreeRBO); crFree(s); } -#ifndef IN_GUEST - else + else if (pContext) { /* evaluate usage bits*/ CR_STATE_RELEASEOBJ CbData; @@ -134,7 +134,22 @@ crStateFreeShared(CRContext *pContext, CRSharedState *s) crHashtableWalk(s->fbTable, ReleaseFBOCallback, &CbData); crHashtableWalk(s->rbTable, ReleaseRBOCallback, &CbData); } -#endif +} + +DECLEXPORT(CRSharedState *) crStateGlobalSharedAcquire() +{ + if (!gSharedState) + { + crWarning("No Global Shared State!"); + return NULL; + } + gSharedState->refCount++; + return gSharedState; +} + +DECLEXPORT(void) crStateGlobalSharedRelease() +{ + crStateFreeShared(NULL, gSharedState); } DECLEXPORT(void) STATE_APIENTRY @@ -218,11 +233,26 @@ static CRContext * crStateCreateContextId(int i, const CRLimitsState *limits, GLint visBits, CRContext *shareCtx) { - CRContext *ctx = (CRContext *) crCalloc( sizeof( *ctx ) ); + CRContext *ctx; int j; int node32 = i >> 5; int node = i & 0x1f; + if (g_pAvailableContexts[i] != NULL) + { + crWarning("trying to create context with used id"); + return NULL; + } + + ctx = (CRContext *) crCalloc( sizeof( *ctx ) ); + if (!ctx) + { + crWarning("failed to allocate context"); + return NULL; + } + g_pAvailableContexts[i] = ctx; + ++g_cContexts; + CRASSERT(g_cContexts < RT_ELEMENTS(g_pAvailableContexts)); ctx->id = i; #ifdef CHROMIUM_THREADSAFE VBoxTlsRefInit(ctx, crStateContextDtor); @@ -252,7 +282,7 @@ crStateCreateContextId(int i, const CRLimitsState *limits, crStateExtensionsInit( &(ctx->limits), &(ctx->extensions) ); crStateBufferObjectInit( ctx ); /* must precede client state init! */ - crStateClientInit( &(ctx->client) ); + crStateClientInit( ctx ); crStateBufferInit( ctx ); crStateCurrentInit( ctx ); @@ -330,7 +360,23 @@ crStateCreateContextId(int i, const CRLimitsState *limits, static void crStateFreeContext(CRContext *ctx) { - crStateClientDestroy( &(ctx->client) ); +#ifndef DEBUG_misha + CRASSERT(g_pAvailableContexts[ctx->id] == ctx); +#endif + if (g_pAvailableContexts[ctx->id] == ctx) + { + g_pAvailableContexts[ctx->id] = NULL; + --g_cContexts; + CRASSERT(g_cContexts < RT_ELEMENTS(g_pAvailableContexts)); + } + else + { +#ifndef DEBUG_misha + crWarning("freeing context %p, id(%d) not being in the context list", ctx, ctx->id); +#endif + } + + crStateClientDestroy( ctx ); crStateLimitsDestroy( &(ctx->limits) ); crStateBufferObjectDestroy( ctx ); crStateEvaluatorDestroy( ctx ); @@ -377,10 +423,15 @@ void crStateInit(void) crStateClientInitBits( &(__currentBits->client) ); crStateLightingInitBits( &(__currentBits->lighting) ); } else + { +#ifndef DEBUG_misha crWarning("State tracker is being re-initialized..\n"); +#endif + } for (i=0;i<CR_MAX_CONTEXTS;i++) - g_availableContexts[i] = 0; + g_pAvailableContexts[i] = NULL; + g_cContexts = 0; #ifdef CHROMIUM_THREADSAFE if (!__isContextTLSInited) @@ -411,11 +462,14 @@ void crStateInit(void) /* Reset diff_api */ crMemZero(&diff_api, sizeof(SPUDispatchTable)); + Assert(!gSharedState); + gSharedState = NULL; + /* Allocate the default/NULL context */ + CRASSERT(g_pAvailableContexts[0] == NULL); defaultContext = crStateCreateContextId(0, NULL, CR_RGB_BIT, NULL); - CRASSERT(g_availableContexts[0] == 0); - g_availableContexts[0] = 1; /* in use forever */ - + CRASSERT(g_pAvailableContexts[0] == defaultContext); + CRASSERT(g_cContexts == 1); #ifdef CHROMIUM_THREADSAFE SetCurrentContext(defaultContext); #else @@ -425,6 +479,7 @@ void crStateInit(void) void crStateDestroy(void) { + int i; if (__currentBits) { crStateClientDestroyBits(&(__currentBits->client)); @@ -433,6 +488,25 @@ void crStateDestroy(void) __currentBits = NULL; } + SetCurrentContext(NULL); + + for (i = CR_MAX_CONTEXTS-1; i >= 0; i--) + { + if (g_pAvailableContexts[i]) + { +#ifdef CHROMIUM_THREADSAFE + if (VBoxTlsRefIsFunctional(g_pAvailableContexts[i])) + VBoxTlsRefRelease(g_pAvailableContexts[i]); +#else + crStateFreeContext(g_pAvailableContexts[i]); +#endif + } + } + + /* default context was stored in g_pAvailableContexts[0], so it was destroyed already */ + defaultContext = NULL; + + #ifdef CHROMIUM_THREADSAFE crFreeTSD(&__contextTSD); __isContextTLSInited = 0; @@ -452,7 +526,7 @@ void crStateDestroy(void) * (i.e. the old context to the new context). The transformation * is accomplished by calling GL functions through the 'diff_api' * so that the downstream GL machine (represented by the __currentContext - * structure) is updated to reflect the new context state. Finally, + * structure) is updated to reflect the new context state. Finally, * we point __currentContext to the new context. * * A subtle problem we have to deal with is context destruction. @@ -485,35 +559,46 @@ void crStateDestroy(void) CRContext * crStateCreateContext(const CRLimitsState *limits, GLint visBits, CRContext *share) { - int i; + return crStateCreateContextEx(limits, visBits, share, -1); +} +CRContext * +crStateCreateContextEx(const CRLimitsState *limits, GLint visBits, CRContext *share, GLint presetID) +{ /* Must have created the default context via crStateInit() first */ CRASSERT(defaultContext); - for (i = 1 ; i < CR_MAX_CONTEXTS ; i++) + if (presetID>0) { - if (!g_availableContexts[i]) + if(g_pAvailableContexts[presetID]) { - g_availableContexts[i] = 1; /* it's no longer available */ - return crStateCreateContextId( i, limits, visBits, share ); + crWarning("requesting to create context with already allocated id"); + return NULL; } } - crError( "Out of available contexts in crStateCreateContexts (max %d)", - CR_MAX_CONTEXTS ); - /* never get here */ - return NULL; -} - -CRContext * -crStateCreateContextEx(const CRLimitsState *limits, GLint visBits, CRContext *share, GLint presetID) -{ - if (presetID>0) + else { - CRASSERT(!g_availableContexts[presetID]); - g_availableContexts[presetID] = 1; - return crStateCreateContextId(presetID, limits, visBits, share); + int i; + + for (i = 1 ; i < CR_MAX_CONTEXTS ; i++) + { + if (!g_pAvailableContexts[i]) + { + presetID = i; + break; + } + } + + if (presetID<=0) + { + crError( "Out of available contexts in crStateCreateContexts (max %d)", + CR_MAX_CONTEXTS ); + /* never get here */ + return NULL; + } } - else return crStateCreateContext(limits, visBits, share); + + return crStateCreateContextId(presetID, limits, visBits, share); } void crStateDestroyContext( CRContext *ctx ) @@ -535,9 +620,17 @@ void crStateDestroyContext( CRContext *ctx ) /* ensure matrix state is also current */ crStateMatrixMode(defaultContext->transform.matrixMode); } - g_availableContexts[ctx->id] = 0; #ifdef CHROMIUM_THREADSAFE + VBoxTlsRefMarkDestroy(ctx); +# ifdef IN_GUEST + if (VBoxTlsRefCountGet(ctx) > 1 && ctx->shared == gSharedState) + { + /* 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 */ + crStateFreeShared(ctx, ctx->shared); + ctx->shared = crStateAllocShared(); + } +# endif VBoxTlsRefRelease(ctx); #else crStateFreeContext(ctx); |
