void crServerRedirMuralFBO(CRMuralInfo *mural, GLboolean redir) { if (redir) { if (!crServerSupportRedirMuralFBO()) { crWarning("FBO not supported, can't redirect window output"); return; } cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, GL_FALSE); if (mural->idFBO==0) { crServerCreateMuralFBO(mural); } if (!crStateGetCurrent()->framebufferobject.drawFB) { cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, mural->idFBO); } if (!crStateGetCurrent()->framebufferobject.readFB) { cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, mural->idFBO); } if (cr_server.curClient && cr_server.curClient->currentMural == mural) { crStateGetCurrent()->buffer.width = 0; crStateGetCurrent()->buffer.height = 0; } } else { cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, mural->bVisible); if (mural->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); } } if (cr_server.curClient && cr_server.curClient->currentMural == mural) { crStateGetCurrent()->buffer.width = mural->width; crStateGetCurrent()->buffer.height = mural->height; } } mural->bUseFBO = redir; }
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 ); }
DECLEXPORT(int32_t) crVBoxServerSetOffscreenRendering(GLboolean value) { if (cr_server.bForceOffscreenRendering==value) { return VINF_SUCCESS; } if (value && !crServerSupportRedirMuralFBO()) { return VERR_NOT_SUPPORTED; } cr_server.bForceOffscreenRendering=value; crHashtableWalk(cr_server.muralTable, crVBoxServerCheckMuralCB, NULL); return VINF_SUCCESS; }
void SERVER_DISPATCH_APIENTRY crServerDispatchMakeCurrent( GLint window, GLint nativeWindow, GLint context ) { CRMuralInfo *mural, *oldMural; CRContextInfo *ctxInfo = NULL; 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; } cr_server.bForceMakeCurrentOnClientSwitch = GL_FALSE; ctx = ctxInfo->pContext; CRASSERT(ctx); oldMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, cr_server.currentWindow); /* 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; CRASSERT(cr_server.curClient->currentCtxInfo); CRASSERT(cr_server.curClient->currentCtxInfo->pContext); /* This is a hack to force updating the 'current' attribs */ crStateUpdateColorBits(); if (ctx) crStateSetCurrentPointers( ctx, &(cr_server.current) ); /* check if being made current for first time, update viewport */ #if 0 if (ctx) { /* initialize the viewport */ if (ctx->viewport.viewportW == 0) { ctx->viewport.viewportW = mural->width; ctx->viewport.viewportH = mural->height; ctx->viewport.scissorW = mural->width; ctx->viewport.scissorH = mural->height; } } #endif /* crDebug("**** %s currentWindow %d newWindow %d", __func__, cr_server.currentWindow, window); */ if (1/*cr_server.firstCallMakeCurrent || cr_server.currentWindow != window || cr_server.currentNativeWindow != nativeWindow*/) { /* Since the cr server serialized all incoming contexts/clients into * one output stream of GL commands, we only need to call the head * SPU's MakeCurrent() function once. * BUT, if we're rendering to multiple windows, we do have to issue * MakeCurrent() calls sometimes. The same GL context will always be * used though. */ cr_server.head_spu->dispatch_table.MakeCurrent( mural->spuWindow, nativeWindow, ctxInfo->SpuContext >= 0 ? ctxInfo->SpuContext : cr_server.MainContextInfo.SpuContext); cr_server.firstCallMakeCurrent = GL_FALSE; cr_server.currentCtxInfo = ctxInfo; cr_server.currentWindow = window; cr_server.currentNativeWindow = nativeWindow; } /* This used to be earlier, after crStateUpdateColorBits() call */ crStateMakeCurrent( ctx ); crStateSwichPostprocess(oldCtx, cr_server.bUseMultipleContexts, mural->bUseFBO && crServerSupportRedirMuralFBO() ? mural->idFBO : 0); if (!ctx->framebufferobject.drawFB && (ctx->buffer.drawBuffer == GL_FRONT || ctx->buffer.drawBuffer == GL_FRONT_LEFT)) cr_server.curClient->currentMural->bFbDraw = GL_TRUE; if (!mural->bUseFBO) { ctx->buffer.width = mural->width; ctx->buffer.height = mural->height; } else { ctx->buffer.width = 0; ctx->buffer.height = 0; } }
void crServerPerformMakeCurrent( CRMuralInfo *mural, CRContextInfo *ctxInfo ) { CRMuralInfo *oldMural; CRContext *ctx, *oldCtx = NULL; GLuint idDrawFBO, idReadFBO; GLint context = ctxInfo->CreateInfo.externalID; GLint window = mural->CreateInfo.externalID; cr_server.bForceMakeCurrentOnClientSwitch = GL_FALSE; ctx = ctxInfo->pContext; CRASSERT(ctx); oldMural = cr_server.currentMural; /* Ubuntu 11.04 hosts misbehave if context window switch is * done with non-default framebuffer object settings. * 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); 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(); if (ctx) crStateSetCurrentPointers( ctx, &(cr_server.current) ); /* check if being made current for first time, update viewport */ #if 0 if (ctx) { /* initialize the viewport */ if (ctx->viewport.viewportW == 0) { ctx->viewport.viewportW = mural->width; ctx->viewport.viewportH = mural->height; ctx->viewport.scissorW = mural->width; ctx->viewport.scissorH = mural->height; } } #endif /* crDebug("**** %s currentWindow %d newWindow %d", __func__, cr_server.currentWindow, window); */ if (1/*cr_server.firstCallMakeCurrent || cr_server.currentWindow != window || cr_server.currentNativeWindow != nativeWindow*/) { /* Since the cr server serialized all incoming contexts/clients into * one output stream of GL commands, we only need to call the head * SPU's MakeCurrent() function once. * BUT, if we're rendering to multiple windows, we do have to issue * MakeCurrent() calls sometimes. The same GL context will always be * used though. */ cr_server.head_spu->dispatch_table.MakeCurrent( mural->spuWindow, 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 = 0; cr_server.currentMural = mural; } /* This used to be earlier, after crStateUpdateColorBits() call */ crStateMakeCurrent( ctx ); 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) && cr_server.curClient) cr_server.curClient->currentMural->bFbDraw = GL_TRUE; if (!mural->fRedirected) { ctx->buffer.width = mural->width; ctx->buffer.height = mural->height; } else { ctx->buffer.width = 0; ctx->buffer.height = 0; } }