diff options
Diffstat (limited to 'src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c')
-rw-r--r-- | src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c | 290 |
1 files changed, 234 insertions, 56 deletions
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c index 89b9c615b..1a7e360c6 100644 --- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c +++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c @@ -59,6 +59,8 @@ CRServer cr_server; int tearingdown = 0; /* can't be static */ +static DECLCALLBACK(int) crVBoxCrCmdCmd(HVBOXCRCMDSVR hSvr, PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd); + DECLINLINE(int32_t) crVBoxServerClientGet(uint32_t u32ClientID, CRClient **ppClient) { CRClient *pClient = NULL; @@ -161,7 +163,7 @@ static void crServerTearDown( void ) /* sync our state with renderspu, * do it before mural & context deletion to avoid deleting currently set murals/contexts*/ - cr_server.head_spu->dispatch_table.MakeCurrent(0, 0, 0); + cr_server.head_spu->dispatch_table.MakeCurrent(CR_RENDER_DEFAULT_WINDOW_ID, 0, CR_RENDER_DEFAULT_CONTEXT_ID); /* Deallocate all semaphores */ crFreeHashtable(cr_server.semaphores, crFree); @@ -529,6 +531,38 @@ GLboolean crVBoxServerInit(void) return GL_TRUE; } +static int32_t crVBoxServerAddClientObj(uint32_t u32ClientID, CRClient **ppNewClient) +{ + CRClient *newClient; + + if (cr_server.numClients>=CR_MAX_CLIENTS) + { + if (ppNewClient) + *ppNewClient = NULL; + return VERR_MAX_THRDS_REACHED; + } + + newClient = (CRClient *) crCalloc(sizeof(CRClient)); + crDebug("crServer: AddClient u32ClientID=%d", u32ClientID); + + newClient->spu_id = 0; + newClient->currentCtxInfo = &cr_server.MainContextInfo; + newClient->currentContextNumber = -1; + newClient->conn = crNetAcceptClient(cr_server.protocol, NULL, + cr_server.tcpip_port, + cr_server.mtu, 0); + newClient->conn->u32ClientID = u32ClientID; + + cr_server.clients[cr_server.numClients++] = newClient; + + crServerAddToRunQueue(newClient); + + if (ppNewClient) + *ppNewClient = newClient; + + return VINF_SUCCESS; +} + int32_t crVBoxServerAddClient(uint32_t u32ClientID) { CRClient *newClient; @@ -744,6 +778,17 @@ extern DECLEXPORT(int32_t) crVBoxServerClientGetCaps(uint32_t u32ClientID, uint3 return VINF_SUCCESS; } +static int32_t crVBoxServerClientObjSetVersion(CRClient *pClient, uint32_t vMajor, uint32_t vMinor) +{ + pClient->conn->vMajor = vMajor; + pClient->conn->vMinor = vMinor; + + if (vMajor != CR_PROTOCOL_VERSION_MAJOR + || vMinor != CR_PROTOCOL_VERSION_MINOR) + return VERR_NOT_SUPPORTED; + return VINF_SUCCESS; +} + int32_t crVBoxServerClientSetVersion(uint32_t u32ClientID, uint32_t vMajor, uint32_t vMinor) { CRClient *pClient=NULL; @@ -760,15 +805,14 @@ int32_t crVBoxServerClientSetVersion(uint32_t u32ClientID, uint32_t vMajor, uint } if (!pClient) return VERR_INVALID_PARAMETER; - pClient->conn->vMajor = vMajor; - pClient->conn->vMinor = vMinor; + return crVBoxServerClientObjSetVersion(pClient, vMajor, vMinor); +} - if (vMajor != CR_PROTOCOL_VERSION_MAJOR - || vMinor != CR_PROTOCOL_VERSION_MINOR) - { - return VERR_NOT_SUPPORTED; - } - else return VINF_SUCCESS; +static int32_t crVBoxServerClientObjSetPID(CRClient *pClient, uint64_t pid) +{ + pClient->pid = pid; + + return VINF_SUCCESS; } int32_t crVBoxServerClientSetPID(uint32_t u32ClientID, uint64_t pid) @@ -787,9 +831,7 @@ int32_t crVBoxServerClientSetPID(uint32_t u32ClientID, uint64_t pid) } if (!pClient) return VERR_INVALID_PARAMETER; - pClient->pid = pid; - - return VINF_SUCCESS; + return crVBoxServerClientObjSetPID(pClient, pid); } int @@ -1004,7 +1046,7 @@ CRMuralInfo * crServerGetDummyMural(GLint visualBits) crWarning("crCalloc failed!"); return NULL; } - id = crServerMuralInit(pMural, "", visualBits, 0); + id = crServerMuralInit(pMural, GL_FALSE, visualBits, 0); if (id < 0) { crWarning("crServerMuralInit failed!"); @@ -2599,8 +2641,6 @@ DECLEXPORT(int32_t) crVBoxServerLoadState(PSSMHANDLE pSSM, uint32_t version) if (version >= SHCROGL_SSM_VERSION_WITH_SCREEN_INFO) { - HCR_FRAMEBUFFER hFb; - rc = CrPMgrLoadState(pSSM, version); AssertRCReturn(rc, rc); } @@ -2885,10 +2925,37 @@ DECLEXPORT(int32_t) crVBoxServerSetScreenViewport(int sIndex, int32_t x, int32_t return VINF_SUCCESS; } +static void crVBoxServerDefaultContextSet() +{ + GLint spuWindow, spuCtx; + + if (cr_server.MainContextInfo.SpuContext) + { + CRMuralInfo *pMural = crServerGetDummyMural(cr_server.MainContextInfo.CreateInfo.realVisualBits); + if (!pMural) + { + WARN(("dummy mural is NULL")); + spuCtx = CR_RENDER_DEFAULT_CONTEXT_ID; + spuWindow = CR_RENDER_DEFAULT_WINDOW_ID; + } + else + { + spuCtx = cr_server.MainContextInfo.SpuContext; + spuWindow = pMural->CreateInfo.realVisualBits; + } + } + else + { + spuCtx = CR_RENDER_DEFAULT_CONTEXT_ID; + spuWindow = CR_RENDER_DEFAULT_WINDOW_ID; + } + + cr_server.head_spu->dispatch_table.MakeCurrent(spuWindow, 0, spuCtx); +} #ifdef VBOX_WITH_CRHGSMI -static int32_t crVBoxServerCmdVbvaCrCmdProcess(struct VBOXCMDVBVA_CRCMD_CMD *pCmd) +static int32_t crVBoxServerCmdVbvaCrCmdProcess(struct VBOXCMDVBVA_CRCMD_CMD *pCmd, uint32_t cbCmd) { int32_t rc; uint32_t cBuffers = pCmd->cBuffers; @@ -2901,29 +2968,35 @@ static int32_t crVBoxServerCmdVbvaCrCmdProcess(struct VBOXCMDVBVA_CRCMD_CMD *pCm if (!g_pvVRamBase) { - crWarning("g_pvVRamBase is not initialized"); + WARN(("g_pvVRamBase is not initialized")); return VERR_INVALID_STATE; } if (!cBuffers) { - crWarning("zero buffers passed in!"); + WARN(("zero buffers passed in!")); return VERR_INVALID_PARAMETER; } cParams = cBuffers-1; + if (cbCmd != RT_OFFSETOF(VBOXCMDVBVA_CRCMD_CMD, aBuffers[cBuffers])) + { + WARN(("invalid buffer size")); + return VERR_INVALID_PARAMETER; + } + cbHdr = pCmd->aBuffers[0].cbBuffer; pHdr = VBOXCRHGSMI_PTR_SAFE(pCmd->aBuffers[0].offBuffer, cbHdr, CRVBOXHGSMIHDR); if (!pHdr) { - crWarning("invalid header buffer!"); + WARN(("invalid header buffer!")); return VERR_INVALID_PARAMETER; } if (cbHdr < sizeof (*pHdr)) { - crWarning("invalid header buffer size!"); + WARN(("invalid header buffer size!")); return VERR_INVALID_PARAMETER; } @@ -3187,24 +3260,110 @@ static int32_t crVBoxServerCmdVbvaCrCmdProcess(struct VBOXCMDVBVA_CRCMD_CMD *pCm return rc; } -static int32_t crVBoxServerCrCmdProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd) +static DECLCALLBACK(int) crVBoxCrCmdEnable(HVBOXCRCMDSVR hSvr, VBOXCRCMD_SVRENABLE_INFO *pInfo) +{ + cr_server.CrCmdClientInfo = *pInfo; + + crVBoxServerDefaultContextSet(); + + return VINF_SUCCESS; +} + +static DECLCALLBACK(int) crVBoxCrCmdDisable(HVBOXCRCMDSVR hSvr) +{ + cr_server.head_spu->dispatch_table.MakeCurrent(0, 0, 0); + + memset(&cr_server.CrCmdClientInfo, 0, sizeof (cr_server.CrCmdClientInfo)); + + return VINF_SUCCESS; +} + +static DECLCALLBACK(int) crVBoxCrCmdHostCtl(HVBOXCRCMDSVR hSvr, uint8_t* pCmd, uint32_t cbCmd) { + return crVBoxServerHostCtl((VBOXCRCMDCTL*)pCmd, cbCmd); +} + +static DECLCALLBACK(int) crVBoxCrCmdGuestCtl(HVBOXCRCMDSVR hSvr, uint8_t* pCmd, uint32_t cbCmd) +{ + VBOXCMDVBVA_3DCTL *pCtl = (VBOXCMDVBVA_3DCTL*)pCmd; + if (cbCmd < sizeof (VBOXCMDVBVA_3DCTL)) + { + WARN(("invalid buffer size")); + return VERR_INVALID_PARAMETER; + } + + switch (pCtl->u32Type) + { + case VBOXCMDVBVA3DCTL_TYPE_CONNECT: + { + VBOXCMDVBVA_3DCTL_CONNECT *pConnect = (VBOXCMDVBVA_3DCTL_CONNECT*)pCtl; + + return VERR_NOT_SUPPORTED; + } + case VBOXCMDVBVA3DCTL_TYPE_DISCONNECT: + { + return VERR_NOT_SUPPORTED; + } + case VBOXCMDVBVA3DCTL_TYPE_CMD: + { + VBOXCMDVBVA_3DCTL_CMD *p3DCmd; + if (cbCmd < sizeof (VBOXCMDVBVA_3DCTL_CMD)) + { + WARN(("invalid size")); + return VERR_INVALID_PARAMETER; + } + + p3DCmd = (VBOXCMDVBVA_3DCTL_CMD*)pCmd; + + return crVBoxCrCmdCmd(NULL, &p3DCmd->Cmd, cbCmd - RT_OFFSETOF(VBOXCMDVBVA_3DCTL_CMD, Cmd)); + } + default: + WARN(("invalid function")); + return VERR_INVALID_PARAMETER; + } +} + +static DECLCALLBACK(int) crVBoxCrCmdSaveState(HVBOXCRCMDSVR hSvr, PSSMHANDLE pSSM) +{ + AssertFailed(); + return VERR_NOT_IMPLEMENTED; +} + +static DECLCALLBACK(int) crVBoxCrCmdLoadState(HVBOXCRCMDSVR hSvr, PSSMHANDLE pSSM, uint32_t u32Version) +{ + AssertFailed(); + return VERR_NOT_IMPLEMENTED; +} + + +static DECLCALLBACK(int) crVBoxCrCmdCmd(HVBOXCRCMDSVR hSvr, PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd) +{ + AssertFailed(); switch (pCmd->u8OpCode) { case VBOXCMDVBVA_OPTYPE_CRCMD: { - VBOXCMDVBVA_CRCMD *pCrCmdDr = (VBOXCMDVBVA_CRCMD*)pCmd; - VBOXCMDVBVA_CRCMD_CMD *pCrCmd = &pCrCmdDr->Cmd; - int rc = crVBoxServerCmdVbvaCrCmdProcess(pCrCmd); + VBOXCMDVBVA_CRCMD *pCrCmdDr; + VBOXCMDVBVA_CRCMD_CMD *pCrCmd; + int rc; + pCrCmdDr = (VBOXCMDVBVA_CRCMD*)pCmd; + pCrCmd = &pCrCmdDr->Cmd; + if (cbCmd < sizeof (VBOXCMDVBVA_CRCMD)) + { + WARN(("invalid buffer size")); + pCmd->u.i8Result = -1; + break; + } + rc = crVBoxServerCmdVbvaCrCmdProcess(pCrCmd, cbCmd - RT_OFFSETOF(VBOXCMDVBVA_CRCMD, Cmd)); if (RT_SUCCESS(rc)) { /* success */ - pCmd->i8Result = 0; + pCmd->u.i8Result = 0; } else { - crWarning("crVBoxServerCmdVbvaCrCmdProcess failed, rc %d", rc); - pCmd->i8Result = -1; + WARN(("crVBoxServerCmdVbvaCrCmdProcess failed, rc %d", rc)); + pCmd->u.i8Result = -1; } break; } @@ -3215,34 +3374,11 @@ static int32_t crVBoxServerCrCmdProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd) } default: WARN(("unsupported command")); - pCmd->i8Result = -1; + pCmd->u.i8Result = -1; } return VINF_SUCCESS; } -int32_t crVBoxServerCrCmdNotifyCmds() -{ - PVBOXCMDVBVA_HDR pCmd = NULL; - uint32_t cbCmd; - - for (;;) - { - int rc = cr_server.CltInfo.pfnCmdGet(cr_server.CltInfo.hClient, &pCmd, &cbCmd); - if (rc == VINF_EOF) - return VINF_SUCCESS; - if (!RT_SUCCESS(rc)) - return rc; - - rc = crVBoxServerCrCmdProcess(pCmd, cbCmd); - if (!RT_SUCCESS(rc)) - return rc; - } - - /* should not be here! */ - AssertFailed(); - return VERR_INTERNAL_ERROR; -} - /* We moved all CrHgsmi command processing to crserverlib to keep the logic of dealing with CrHgsmi commands in one place. * * For now we need the notion of CrHgdmi commands in the crserver_lib to be able to complete it asynchronously once it is really processed. @@ -3272,7 +3408,7 @@ int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t c if (!g_pvVRamBase) { - crWarning("g_pvVRamBase is not initialized"); + WARN(("g_pvVRamBase is not initialized")); crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_STATE); return VINF_SUCCESS; @@ -3280,7 +3416,7 @@ int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t c if (!cBuffers) { - crWarning("zero buffers passed in!"); + WARN(("zero buffers passed in!")); crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER); return VINF_SUCCESS; @@ -3292,7 +3428,7 @@ int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t c pHdr = VBOXCRHGSMI_PTR_SAFE(pCmd->aBuffers[0].offBuffer, cbHdr, CRVBOXHGSMIHDR); if (!pHdr) { - crWarning("invalid header buffer!"); + WARN(("invalid header buffer!")); crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER); return VINF_SUCCESS; @@ -3300,7 +3436,7 @@ int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t c if (cbHdr < sizeof (*pHdr)) { - crWarning("invalid header buffer size!"); + WARN(("invalid header buffer size!")); crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER); return VINF_SUCCESS; @@ -3595,7 +3731,14 @@ int32_t crVBoxServerCrHgsmiCtl(struct VBOXVDMACMD_CHROMIUM_CTL *pCtl, uint32_t c PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP pSetup = (PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP)pCtl; g_pvVRamBase = (uint8_t*)pSetup->pvVRamBase; g_cbVRam = pSetup->cbVRam; - cr_server.CltInfo = *pSetup->pCrCmdClientInfo; + pSetup->CrCmdServerInfo.hSvr = NULL; + pSetup->CrCmdServerInfo.pfnEnable = crVBoxCrCmdEnable; + pSetup->CrCmdServerInfo.pfnDisable = crVBoxCrCmdDisable; + pSetup->CrCmdServerInfo.pfnCmd = crVBoxCrCmdCmd; + pSetup->CrCmdServerInfo.pfnHostCtl = crVBoxCrCmdHostCtl; + pSetup->CrCmdServerInfo.pfnGuestCtl = crVBoxCrCmdGuestCtl; + pSetup->CrCmdServerInfo.pfnSaveState = crVBoxCrCmdSaveState; + pSetup->CrCmdServerInfo.pfnLoadState = crVBoxCrCmdLoadState; rc = VINF_SUCCESS; break; } @@ -3628,4 +3771,39 @@ int32_t crVBoxServerCrHgsmiCtl(struct VBOXVDMACMD_CHROMIUM_CTL *pCtl, uint32_t c return rc; } +int32_t crVBoxServerHgcmEnable(HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hRHCmd, PFNVBOXCRCMDCTL_REMAINING_HOST_COMMAND pfnRHCmd) +{ + int rc = VINF_SUCCESS; + uint8_t* pCtl; + uint32_t cbCtl; + + if (cr_server.numClients) + { + WARN(("cr_server.numClients(%d) is not NULL", cr_server.numClients)); + return VERR_INVALID_STATE; + } + + for (pCtl = pfnRHCmd(hRHCmd, &cbCtl, rc); pCtl; pCtl = pfnRHCmd(hRHCmd, &cbCtl, rc)) + { + rc = crVBoxCrCmdHostCtl(NULL, pCtl, cbCtl); + } + + crVBoxServerDefaultContextSet(); + + return VINF_SUCCESS; +} + +int32_t crVBoxServerHgcmDisable() +{ + if (cr_server.numClients) + { + WARN(("cr_server.numClients(%d) is not NULL", cr_server.numClients)); + return VERR_INVALID_STATE; + } + + cr_server.head_spu->dispatch_table.MakeCurrent(0, 0, 0); + + return VINF_SUCCESS; +} + #endif |