diff options
Diffstat (limited to 'src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c')
| -rw-r--r-- | src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c | 264 |
1 files changed, 166 insertions, 98 deletions
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c index 5c2ce040..afa2a208 100644 --- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c +++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c @@ -27,6 +27,8 @@ GLint crServerDispatchCreateContextEx(const char *dpyName, GLint visualBits, GLi CRContextInfo *pContextInfo; GLboolean fFirst = GL_FALSE; + dpyName = ""; + if (shareCtx > 0) { crWarning("CRServer: context sharing not implemented."); shareCtx = 0; @@ -39,16 +41,23 @@ GLint crServerDispatchCreateContextEx(const char *dpyName, GLint visualBits, GLi return -1; } - pContextInfo->CreateInfo.visualBits = visualBits; + pContextInfo->currentMural = NULL; + + pContextInfo->CreateInfo.requestedVisualBits = visualBits; + + if (cr_server.fVisualBitsDefault) + visualBits = cr_server.fVisualBitsDefault; + + pContextInfo->CreateInfo.realVisualBits = visualBits; /* Since the Cr server serialized all incoming clients/contexts into * one outgoing GL stream, we only need to create one context for the * head SPU. We'll only have to make it current once too, below. */ if (cr_server.firstCallCreateContext) { - cr_server.MainContextInfo.CreateInfo.visualBits = visualBits; + cr_server.MainContextInfo.CreateInfo.realVisualBits = visualBits; cr_server.MainContextInfo.SpuContext = cr_server.head_spu->dispatch_table. - CreateContext(dpyName, cr_server.MainContextInfo.CreateInfo.visualBits, shareCtx); + CreateContext(dpyName, cr_server.MainContextInfo.CreateInfo.realVisualBits, shareCtx); if (cr_server.MainContextInfo.SpuContext < 0) { crWarning("crServerDispatchCreateContext() failed."); crFree(pContextInfo); @@ -58,16 +67,19 @@ GLint crServerDispatchCreateContextEx(const char *dpyName, GLint visualBits, GLi CRASSERT(cr_server.MainContextInfo.pContext); cr_server.firstCallCreateContext = GL_FALSE; fFirst = GL_TRUE; + + cr_server.head_spu->dispatch_table.ChromiumParameteriCR(GL_HH_SET_DEFAULT_SHARED_CTX, cr_server.MainContextInfo.SpuContext); } else { /* second or third or ... context */ - if (!cr_server.bUseMultipleContexts && ((visualBits & cr_server.MainContextInfo.CreateInfo.visualBits) != visualBits)) { + if (!cr_server.bUseMultipleContexts && ((visualBits & cr_server.MainContextInfo.CreateInfo.realVisualBits) != visualBits)) { int oldSpuContext; - + /* should never be here */ + CRASSERT(0); /* the new context needs new visual attributes */ - cr_server.MainContextInfo.CreateInfo.visualBits |= visualBits; - crDebug("crServerDispatchCreateContext requires new visual (0x%x).", - cr_server.MainContextInfo.CreateInfo.visualBits); + cr_server.MainContextInfo.CreateInfo.realVisualBits |= visualBits; + crWarning("crServerDispatchCreateContext requires new visual (0x%x).", + cr_server.MainContextInfo.CreateInfo.realVisualBits); /* Here, we used to just destroy the old rendering context. * Unfortunately, this had the side effect of destroying @@ -82,7 +94,7 @@ GLint crServerDispatchCreateContextEx(const char *dpyName, GLint visualBits, GLi /* create new rendering context with suitable visual */ oldSpuContext = cr_server.MainContextInfo.SpuContext; cr_server.MainContextInfo.SpuContext = cr_server.head_spu->dispatch_table. - CreateContext(dpyName, cr_server.MainContextInfo.CreateInfo.visualBits, cr_server.MainContextInfo.SpuContext); + CreateContext(dpyName, cr_server.MainContextInfo.CreateInfo.realVisualBits, cr_server.MainContextInfo.SpuContext); /* destroy old rendering context */ cr_server.head_spu->dispatch_table.DestroyContext(oldSpuContext); if (cr_server.MainContextInfo.SpuContext < 0) { @@ -90,12 +102,16 @@ GLint crServerDispatchCreateContextEx(const char *dpyName, GLint visualBits, GLi crFree(pContextInfo); return -1; } + + /* we do not need to clean up the old default context explicitly, since the above cr_server.head_spu->dispatch_table.DestroyContext call + * will do that for us */ + cr_server.head_spu->dispatch_table.ChromiumParameteriCR(GL_HH_SET_DEFAULT_SHARED_CTX, cr_server.MainContextInfo.SpuContext); } } if (cr_server.bUseMultipleContexts) { pContextInfo->SpuContext = cr_server.head_spu->dispatch_table. - CreateContext(dpyName, cr_server.MainContextInfo.CreateInfo.visualBits, cr_server.MainContextInfo.SpuContext); + CreateContext(dpyName, cr_server.MainContextInfo.CreateInfo.realVisualBits, cr_server.MainContextInfo.SpuContext); if (pContextInfo->SpuContext < 0) { crWarning("crServerDispatchCreateContext() failed."); crStateEnableDiffOnMakeCurrent(GL_TRUE); @@ -120,10 +136,10 @@ GLint crServerDispatchCreateContextEx(const char *dpyName, GLint visualBits, GLi if (newCtx) { crStateSetCurrentPointers( newCtx, &(cr_server.current) ); crStateResetCurrentPointers(&(cr_server.current)); - retVal = preloadCtxID<0 ? crServerGenerateID(&cr_server.idsPool.freeContextID) : preloadCtxID; + retVal = preloadCtxID<0 ? (GLint)crHashtableAllocKeys( cr_server.contextTable, 1 ) : preloadCtxID; pContextInfo->pContext = newCtx; - pContextInfo->CreateInfo.visualBits = visualBits; + Assert(pContextInfo->CreateInfo.realVisualBits == visualBits); pContextInfo->CreateInfo.externalID = retVal; pContextInfo->CreateInfo.pszDpyName = dpyName ? crStrdup(dpyName) : NULL; crHashtableAdd(cr_server.contextTable, retVal, pContextInfo); @@ -139,25 +155,6 @@ GLint crServerDispatchCreateContextEx(const char *dpyName, GLint visualBits, GLi } } - { - /* As we're using only one host context to serve all client contexts, newly created context will still - * hold last error value from any previous failed opengl call. Proper solution would be to redirect any - * client glGetError calls to our state tracker, but right now it's missing quite a lot of checks and doesn't - * reflect host driver/gpu specific issues. Thus we just reset last opengl error at context creation. - */ - GLint err; - - err = cr_server.head_spu->dispatch_table.GetError(); - if (err!=GL_NO_ERROR) - { -#ifdef DEBUG_misha - crDebug("Cleared gl error %#x on context creation", err); -#else - crWarning("Cleared gl error %#x on context creation", err); -#endif - } - } - crServerReturnValue( &retVal, sizeof(retVal) ); return retVal; @@ -179,6 +176,14 @@ static int crServerRemoveClientContext(CRClient *pClient, GLint ctx) return false; } +static void crServerCleanupMuralCtxUsageCB(unsigned long key, void *data1, void *data2) +{ + CRMuralInfo *mural = (CRMuralInfo *) data1; + CRContext *ctx = (CRContext *) data2; + + CR_STATE_SHAREDOBJ_USAGE_CLEAR(mural, ctx); +} + void SERVER_DISPATCH_APIENTRY crServerDispatchDestroyContext( GLint ctx ) { @@ -198,6 +203,15 @@ crServerDispatchDestroyContext( GLint ctx ) crDebug("CRServer: DestroyContext context %d", ctx); + if (cr_server.currentCtxInfo == crCtxInfo) + { + CRMuralInfo *dummyMural = crServerGetDummyMural(cr_server.MainContextInfo.CreateInfo.realVisualBits); + crServerPerformMakeCurrent(dummyMural, &cr_server.MainContextInfo); + CRASSERT(cr_server.currentCtxInfo == &cr_server.MainContextInfo); + } + + crHashtableWalk(cr_server.muralTable, crServerCleanupMuralCtxUsageCB, crCtx); + crCtxInfo->currentMural = NULL; crHashtableDelete(cr_server.contextTable, ctx, NULL); crStateDestroyContext( crCtx ); @@ -268,82 +282,56 @@ crServerDispatchDestroyContext( GLint ctx ) pNode = pNode->next; } - if (cr_server.currentCtxInfo == crCtxInfo) - { - cr_server.currentCtxInfo = &cr_server.MainContextInfo; - } + CRASSERT(cr_server.currentCtxInfo != crCtxInfo); } -void SERVER_DISPATCH_APIENTRY -crServerDispatchMakeCurrent( GLint window, GLint nativeWindow, GLint context ) +void crServerPerformMakeCurrent( CRMuralInfo *mural, CRContextInfo *ctxInfo ) { - CRMuralInfo *mural, *oldMural; - CRContextInfo *ctxInfo = NULL; + CRMuralInfo *oldMural; CRContext *ctx, *oldCtx = NULL; - - if (context >= 0 && window >= 0) { - mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window); - if (!mural) - { - crWarning("CRServer: invalid window %d passed to crServerDispatchMakeCurrent()", window); - return; - } - - /* Update the state tracker's current context */ - ctxInfo = (CRContextInfo *) crHashtableSearch(cr_server.contextTable, context); - if (!ctxInfo) { - crWarning("CRserver: NULL context in MakeCurrent %d", context); - return; - } - } - else { -#if 0 - oldMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, cr_server.currentWindow); - if (oldMural && oldMural->bUseFBO && crServerSupportRedirMuralFBO()) - { - if (!crStateGetCurrent()->framebufferobject.drawFB) - { - cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0); - } - if (!crStateGetCurrent()->framebufferobject.readFB) - { - cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0); - } - } - - ctxInfo = &cr_server.MainContextInfo; - window = -1; - mural = NULL; -#endif - cr_server.bForceMakeCurrentOnClientSwitch = GL_TRUE; - return; - } + GLuint idDrawFBO, idReadFBO; + GLint context = ctxInfo->CreateInfo.externalID; + GLint window = mural->CreateInfo.externalID; cr_server.bForceMakeCurrentOnClientSwitch = GL_FALSE; ctx = ctxInfo->pContext; CRASSERT(ctx); - oldMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, cr_server.currentWindow); + oldMural = cr_server.currentMural; /* Ubuntu 11.04 hosts misbehave if context window switch is * done with non-default framebuffer object settings. - * crStateSwichPrepare & crStateSwichPostprocess are supposed to work around this problem - * crStateSwichPrepare restores the FBO state to its default values before the context window switch, - * while crStateSwichPostprocess restores it back to the original values */ - oldCtx = crStateSwichPrepare(ctx, cr_server.bUseMultipleContexts, oldMural && oldMural->bUseFBO && crServerSupportRedirMuralFBO() ? oldMural->idFBO : 0); - - /* - crDebug("**** %s client %d curCtx=%d curWin=%d", __func__, - cr_server.curClient->number, ctxPos, window); - */ - cr_server.curClient->currentContextNumber = context; - cr_server.curClient->currentCtxInfo = ctxInfo; - cr_server.curClient->currentMural = mural; - cr_server.curClient->currentWindow = window; + * crStateSwitchPrepare & crStateSwitchPostprocess are supposed to work around this problem + * crStateSwitchPrepare restores the FBO state to its default values before the context window switch, + * while crStateSwitchPostprocess restores it back to the original values */ + oldCtx = crStateGetCurrent(); + if (oldMural && oldMural->fRedirected && crServerSupportRedirMuralFBO()) + { + idDrawFBO = CR_SERVER_FBO_FOR_IDX(oldMural, oldMural->iCurDrawBuffer); + idReadFBO = CR_SERVER_FBO_FOR_IDX(oldMural, oldMural->iCurReadBuffer); + } + else + { + idDrawFBO = 0; + idReadFBO = 0; + } + crStateSwitchPrepare(cr_server.bUseMultipleContexts ? NULL : ctx, oldCtx, idDrawFBO, idReadFBO); - CRASSERT(cr_server.curClient->currentCtxInfo); - CRASSERT(cr_server.curClient->currentCtxInfo->pContext); + if (cr_server.curClient) + { + /* + crDebug("**** %s client %d curCtx=%d curWin=%d", __func__, + cr_server.curClient->number, ctxPos, window); + */ + cr_server.curClient->currentContextNumber = context; + cr_server.curClient->currentCtxInfo = ctxInfo; + cr_server.curClient->currentMural = mural; + cr_server.curClient->currentWindow = window; + + CRASSERT(cr_server.curClient->currentCtxInfo); + CRASSERT(cr_server.curClient->currentCtxInfo->pContext); + } /* This is a hack to force updating the 'current' attribs */ crStateUpdateColorBits(); @@ -380,26 +368,58 @@ crServerDispatchMakeCurrent( GLint window, GLint nativeWindow, GLint context ) * used though. */ cr_server.head_spu->dispatch_table.MakeCurrent( mural->spuWindow, - nativeWindow, + 0, ctxInfo->SpuContext >= 0 ? ctxInfo->SpuContext : cr_server.MainContextInfo.SpuContext); + + CR_STATE_SHAREDOBJ_USAGE_SET(mural, ctx); + if (cr_server.currentCtxInfo) + cr_server.currentCtxInfo->currentMural = NULL; + ctxInfo->currentMural = mural; + cr_server.firstCallMakeCurrent = GL_FALSE; cr_server.currentCtxInfo = ctxInfo; cr_server.currentWindow = window; - cr_server.currentNativeWindow = nativeWindow; + cr_server.currentNativeWindow = 0; + cr_server.currentMural = mural; } /* This used to be earlier, after crStateUpdateColorBits() call */ crStateMakeCurrent( ctx ); - crStateSwichPostprocess(oldCtx, cr_server.bUseMultipleContexts, mural->bUseFBO && crServerSupportRedirMuralFBO() ? mural->idFBO : 0); + if (mural && mural->fRedirected && crServerSupportRedirMuralFBO()) + { + GLuint id = crServerMuralFBOIdxFromBufferName(mural, ctx->buffer.drawBuffer); + if (id != mural->iCurDrawBuffer) + { + crDebug("DBO draw buffer changed on make current"); + mural->iCurDrawBuffer = id; + } + + id = crServerMuralFBOIdxFromBufferName(mural, ctx->buffer.readBuffer); + if (id != mural->iCurReadBuffer) + { + crDebug("DBO read buffer changed on make current"); + mural->iCurReadBuffer = id; + } + + idDrawFBO = CR_SERVER_FBO_FOR_IDX(mural, mural->iCurDrawBuffer); + idReadFBO = CR_SERVER_FBO_FOR_IDX(mural, mural->iCurReadBuffer); + } + else + { + idDrawFBO = 0; + idReadFBO = 0; + } + crStateSwitchPostprocess(ctx, cr_server.bUseMultipleContexts ? NULL : oldCtx, idDrawFBO, idReadFBO); if (!ctx->framebufferobject.drawFB - && (ctx->buffer.drawBuffer == GL_FRONT || ctx->buffer.drawBuffer == GL_FRONT_LEFT)) + && (ctx->buffer.drawBuffer == GL_FRONT || ctx->buffer.drawBuffer == GL_FRONT_LEFT) + && cr_server.curClient) cr_server.curClient->currentMural->bFbDraw = GL_TRUE; - if (!mural->bUseFBO) + if (!mural->fRedirected) { ctx->buffer.width = mural->width; ctx->buffer.height = mural->height; @@ -411,3 +431,51 @@ crServerDispatchMakeCurrent( GLint window, GLint nativeWindow, GLint context ) } } + +void SERVER_DISPATCH_APIENTRY +crServerDispatchMakeCurrent( GLint window, GLint nativeWindow, GLint context ) +{ + CRMuralInfo *mural; + CRContextInfo *ctxInfo = NULL; + + if (context >= 0 && window >= 0) { + mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window); + if (!mural) + { + crWarning("CRServer: invalid window %d passed to crServerDispatchMakeCurrent()", window); + return; + } + + /* Update the state tracker's current context */ + ctxInfo = (CRContextInfo *) crHashtableSearch(cr_server.contextTable, context); + if (!ctxInfo) { + crWarning("CRserver: NULL context in MakeCurrent %d", context); + return; + } + } + else { +#if 0 + oldMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, cr_server.currentWindow); + if (oldMural && oldMural->bUseFBO && crServerSupportRedirMuralFBO()) + { + if (!crStateGetCurrent()->framebufferobject.drawFB) + { + cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0); + } + if (!crStateGetCurrent()->framebufferobject.readFB) + { + cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0); + } + } + + ctxInfo = &cr_server.MainContextInfo; + window = -1; + mural = NULL; +#endif + cr_server.bForceMakeCurrentOnClientSwitch = GL_TRUE; + return; + } + + crServerPerformMakeCurrent( mural, ctxInfo ); +} + |
