summaryrefslogtreecommitdiff
path: root/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-03-26 19:21:20 +0000
committer <>2014-05-08 15:03:54 +0000
commitfb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch)
treec2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/GuestHost/OpenGL/state_tracker/state_init.c
parent58ed4748338f9466599adfc8a9171280ed99e23f (diff)
downloadVirtualBox-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.c163
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);