summaryrefslogtreecommitdiff
path: root/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c')
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c290
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