diff options
| author | Felix Geyer <fgeyer@debian.org> | 2014-04-05 22:17:15 +0200 |
|---|---|---|
| committer | Felix Geyer <fgeyer@debian.org> | 2014-04-05 22:17:15 +0200 |
| commit | 1700c7d32f7d9d101cbba9f1fcb8bb57ed16a727 (patch) | |
| tree | 727251ad65172262944f82bb0f28601c3fb6f6b3 /src/VBox/HostServices | |
| parent | 1e85aed889b772c2f2daa7a6d9e8bd967aa213d8 (diff) | |
| download | virtualbox-upstream.tar.gz | |
Imported Upstream version 4.3.10-dfsgupstream/4.3.10-dfsgupstream
Diffstat (limited to 'src/VBox/HostServices')
9 files changed, 735 insertions, 162 deletions
diff --git a/src/VBox/HostServices/SharedOpenGL/Makefile.kmk b/src/VBox/HostServices/SharedOpenGL/Makefile.kmk index baf6c702e..971c1c9ae 100644 --- a/src/VBox/HostServices/SharedOpenGL/Makefile.kmk +++ b/src/VBox/HostServices/SharedOpenGL/Makefile.kmk @@ -264,6 +264,12 @@ VBoxOGLrenderspu_OBJCFLAGS.darwin = -Wno-shadow VBoxOGLrenderspu_SOURCES.darwin = \ render/renderspu_cocoa.c \ render/renderspu_cocoa_helper.m +ifdef VBOX_WITH_CRHGSMI +VBoxOGLrenderspu_DEFS += VBOX_WITH_CRHGSMI +endif +ifdef VBOX_WITH_VDMA +VBoxOGLrenderspu_DEFS += VBOX_WITH_VDMA +endif VBoxOGLrenderspu_LDFLAGS.darwin += -install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VBoxOGLrenderspu.dylib VBoxOGLrenderspu_LIBS = \ $(PATH_STAGE_LIB)/VBoxOGLhostspuload$(VBOX_SUFF_LIB) \ diff --git a/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp b/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp index 4388fde94..77ddf197f 100644 --- a/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp +++ b/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp @@ -961,7 +961,7 @@ static void crScreenshotHandle(CRVBOXHGCMTAKESCREENSHOT *pScreenshot, uint32_t i /* * We differentiate between a function handler for the guest and one for the host. */ -static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) +static int svcHostCallPerform(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) { int rc = VINF_SUCCESS; @@ -979,10 +979,6 @@ static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cPa switch (u32Function) { - case SHCRGL_HOST_FN_CRCMD_NOTIFY_CMDS: - { - rc = crVBoxServerCrCmdNotifyCmds(); - } break; #ifdef VBOX_WITH_CRHGSMI case SHCRGL_HOST_FN_CRHGSMI_CMD: { @@ -1476,6 +1472,73 @@ static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cPa return rc; } +int crVBoxServerHostCtl(VBOXCRCMDCTL *pCtl, uint32_t cbCtl) +{ + if ((cbCtl - sizeof (VBOXCRCMDCTL)) % sizeof(VBOXHGCMSVCPARM)) + { + WARN(("invalid param size")); + return VERR_INVALID_PARAMETER; + } + uint32_t cParams = (cbCtl - sizeof (VBOXCRCMDCTL)) / sizeof (VBOXHGCMSVCPARM); + return svcHostCallPerform(pCtl->u32Function, cParams, (VBOXHGCMSVCPARM*)(pCtl + 1)); +} + +static DECLCALLBACK(int) svcHostCall(void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) +{ + switch (u32Function) + { + case SHCRGL_HOST_FN_CTL: + { + if (cParms != 1) + { + WARN(("cParams != 1")); + return VERR_INVALID_PARAMETER; + } + + if (paParms->type != VBOX_HGCM_SVC_PARM_PTR) + { + WARN(("invalid param type")); + return VERR_INVALID_PARAMETER; + } + + if (paParms->u.pointer.size < sizeof (VBOXCRCMDCTL)) + { + WARN(("invalid param size")); + return VERR_INVALID_PARAMETER; + } + + VBOXCRCMDCTL *pCtl = (VBOXCRCMDCTL*)paParms->u.pointer.addr; + switch (pCtl->enmType) + { + case VBOXCRCMDCTL_TYPE_HGCM: + { + return crVBoxServerHostCtl(pCtl, paParms->u.pointer.size); + } + case VBOXCRCMDCTL_TYPE_DISABLE: + { + if (paParms->u.pointer.size != sizeof (VBOXCRCMDCTL)) + WARN(("invalid param size")); + return crVBoxServerHgcmDisable(); + } + case VBOXCRCMDCTL_TYPE_ENABLE: + { + if (paParms->u.pointer.size != sizeof (VBOXCRCMDCTL_ENABLE)) + WARN(("invalid param size")); + VBOXCRCMDCTL_ENABLE *pEnable = (VBOXCRCMDCTL_ENABLE*)pCtl; + return crVBoxServerHgcmEnable(pEnable->hRHCmd, pEnable->pfnRHCmd); + } + default: + WARN(("invalid function")); + return VERR_INVALID_PARAMETER; + } + WARN(("should not be here!")); + return VERR_INTERNAL_ERROR; + } + default: + return svcHostCallPerform(u32Function, cParms, paParms); + } +} + extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable) { int rc = VINF_SUCCESS; diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h b/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h index 0b8b46432..677bcf0ee 100644 --- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h +++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h @@ -115,7 +115,7 @@ GLboolean crServerClientInBeginEnd(const CRClient *client); GLint crServerDispatchCreateContextEx(const char *dpyName, GLint visualBits, GLint shareCtx, GLint preloadCtxID, int32_t internalID); GLint crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preloadWinID); -GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID); +GLint crServerMuralInit(CRMuralInfo *mural, GLboolean fGuestWindow, GLint visBits, GLint preloadWinID); void crServerMuralTerm(CRMuralInfo *mural); GLboolean crServerMuralSize(CRMuralInfo *mural, GLint width, GLint height); void crServerMuralPosition(CRMuralInfo *mural, GLint x, GLint y); @@ -155,6 +155,8 @@ HCR_FRAMEBUFFER CrPMgrFbGetNextEnabled(HCR_FRAMEBUFFER hFb); HCR_FRAMEBUFFER CrPMgrFbGetFirstInitialized(); HCR_FRAMEBUFFER CrPMgrFbGetNextInitialized(HCR_FRAMEBUFFER hFb); +int CrFbRegionsClear(HCR_FRAMEBUFFER hFb); + #define CR_SERVER_FBO_BB_IDX(_mural) ((_mural)->iBbBuffer) #define CR_SERVER_FBO_FB_IDX(_mural) (((_mural)->iBbBuffer + 1) % ((_mural)->cBuffers)) @@ -425,7 +427,7 @@ typedef DECLCALLBACKPTR(bool, PFNCR_FRAMEBUFFER_ENTRIES_VISITOR_CB)(HCR_FRAMEBUF bool CrFbHas3DData(HCR_FRAMEBUFFER hFb); void CrFbVisitCreatedEntries(HCR_FRAMEBUFFER hFb, PFNCR_FRAMEBUFFER_ENTRIES_VISITOR_CB pfnVisitorCb, void *pvContext); int CrFbResize(HCR_FRAMEBUFFER hFb, const struct VBVAINFOSCREEN * pScreen, void *pvVRAM); -int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, uint32_t cRects, const RTRECT *pPrects, CR_BLITTER_IMG *pImg); +int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pPrects, CR_BLITTER_IMG *pImg); bool CrFbIsEnabled(HCR_FRAMEBUFFER hFb); int CrFbEntryCreateForTexId(HCR_FRAMEBUFFER hFb, GLuint idTex, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry); int CrFbEntryCreateForTexData(HCR_FRAMEBUFFER hFb, struct CR_TEXDATA *pTex, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry); 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 diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp index e9ae9e78c..10cdf5cfb 100644 --- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp +++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp @@ -194,7 +194,6 @@ static int crServerRedirMuralDbSyncFb(CRMuralInfo *mural, HCR_FRAMEBUFFER hFb, C for (uint32_t i = 0; i < mural->cBuffers; ++i) { VBOXVR_TEXTURE Tex; - int rc; Tex.width = mural->width; Tex.height = mural->height; Tex.hwid = mural->aidColorTexs[i]; @@ -687,7 +686,8 @@ DECLEXPORT(int) crServerVBoxScreenshotGet(uint32_t u32Screen, uint32_t width, ui || pScreen->u32LineSize != pitch || pScreen->u16BitsPerPixel != 32) { - RTRECT Rect; + RTRECT SrcRect; + RTRECT DstRect; pScreenshot->Img.cbData = pScreen->u32LineSize * pScreen->u32Height; if (!pvBuffer) @@ -711,11 +711,15 @@ DECLEXPORT(int) crServerVBoxScreenshotGet(uint32_t u32Screen, uint32_t width, ui pScreenshot->Img.height = height; pScreenshot->Img.bpp = 32; pScreenshot->Img.pitch = pitch; - Rect.xLeft = 0; - Rect.yTop = 0; - Rect.xRight = pScreen->u32Width; - Rect.yBottom = pScreen->u32Height; - int rc = CrFbBltGetContents(hFb, &Rect, 1, &Rect, &pScreenshot->Img); + SrcRect.xLeft = 0; + SrcRect.yTop = 0; + SrcRect.xRight = pScreen->u32Width; + SrcRect.yBottom = pScreen->u32Height; + DstRect.xLeft = 0; + DstRect.yTop = 0; + DstRect.xRight = width; + DstRect.yBottom = height; + int rc = CrFbBltGetContents(hFb, &SrcRect, &DstRect, 1, &DstRect, &pScreenshot->Img); if (!RT_SUCCESS(rc)) { WARN(("CrFbBltGetContents failed %d", rc)); diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp index 49fa537cd..e1dca8288 100644 --- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp +++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp @@ -247,8 +247,8 @@ static void crFbBltImg(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcDataPoint, int32_t srcY = pCopyRect->yTop - pSrcDataPoint->y; Assert(srcX >= 0); Assert(srcY >= 0); - Assert(srcX < pSrc->width); - Assert(srcY < pSrc->height); + Assert(srcX < (int32_t)pSrc->width); + Assert(srcY < (int32_t)pSrc->height); int32_t dstX = pCopyRect->xLeft - pDstDataPoint->x; int32_t dstY = pCopyRect->yTop - pDstDataPoint->y; @@ -258,7 +258,7 @@ static void crFbBltImg(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcDataPoint, uint8_t *pu8Src = ((uint8_t*)pSrc->pvData) + pSrc->pitch * (!fSrcInvert ? srcY : pSrc->height - srcY - 1) + srcX * 4; uint8_t *pu8Dst = ((uint8_t*)pDst->pvData) + pDst->pitch * dstY + dstX * 4; - crFbBltMem(pu8Src, fSrcInvert ? -pSrc->pitch : pSrc->pitch, pu8Dst, pDst->pitch, pCopyRect->xRight - pCopyRect->xLeft, pCopyRect->yBottom - pCopyRect->yTop); + crFbBltMem(pu8Src, fSrcInvert ? -((int32_t)pSrc->pitch) : (int32_t)pSrc->pitch, pu8Dst, pDst->pitch, pCopyRect->xRight - pCopyRect->xLeft, pCopyRect->yBottom - pCopyRect->yTop); } static void crFbBltImgScaled(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcDataPoint, bool fSrcInvert, const RTRECT *pCopyRect, const RTPOINT *pDstDataPoint, float strX, float strY, CR_BLITTER_IMG *pDst) @@ -267,8 +267,8 @@ static void crFbBltImgScaled(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcData int32_t srcY = pCopyRect->yTop - pSrcDataPoint->y; Assert(srcX >= 0); Assert(srcY >= 0); - Assert(srcX < pSrc->width); - Assert(srcY < pSrc->height); + Assert(srcX < (int32_t)pSrc->width); + Assert(srcY < (int32_t)pSrc->height); RTPOINT ScaledDtsDataPoint; RTRECT ScaledCopyRect; @@ -315,10 +315,68 @@ static void crFbBltImgScaled(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcData ScaledDstWidth, ScaledDstHeight, pu8Src, - fSrcInvert ? -pSrc->pitch : pSrc->pitch, + fSrcInvert ? -((int32_t)pSrc->pitch) : (int32_t)pSrc->pitch, pCopyRect->xRight - pCopyRect->xLeft, pCopyRect->yBottom - pCopyRect->yTop); } +static void crFbBltImgScaledRects(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcDataPoint, bool fSrcInvert, const RTRECT *pCopyRect, const RTPOINT *pDstDataPoint, float strX, float strY, CR_BLITTER_IMG *pDst) +{ + int32_t srcX = pCopyRect->xLeft - pSrcDataPoint->x; + int32_t srcY = pCopyRect->yTop - pSrcDataPoint->y; + Assert(srcX >= 0); + Assert(srcY >= 0); + + RTRECT UnscaledCopyRect; + VBoxRectUnscaled(pCopyRect, strX, strY, &UnscaledCopyRect); + + srcX = CR_FLOAT_RCAST(int32_t, srcX / strX); + srcY = CR_FLOAT_RCAST(int32_t, srcY / strY); + + int32_t UnscaledSrcWidth = UnscaledCopyRect.xRight - UnscaledCopyRect.xLeft; + int32_t delta = (int32_t)pSrc->width - srcX - UnscaledSrcWidth; + if (delta < 0) + UnscaledSrcWidth += delta; + + if (UnscaledSrcWidth <= 0) + { + LOG(("UnscaledSrcWidth <= 0")); + if (UnscaledSrcWidth < 0) + WARN(("src width (%d) < 0", UnscaledSrcWidth)); + return; + } + + int32_t UnscaledSrcHeight = UnscaledCopyRect.yBottom - UnscaledCopyRect.yTop; + delta = (int32_t)pSrc->height - srcY - UnscaledSrcHeight; + if (delta < 0) + UnscaledSrcHeight += delta; + + if (UnscaledSrcHeight <= 0) + { + LOG(("UnscaledSrcHeight <= 0")); + if (UnscaledSrcHeight < 0) + WARN(("src height (%d) < 0", UnscaledSrcHeight)); + return; + } + + int32_t dstX = pCopyRect->xLeft - pDstDataPoint->x; + int32_t dstY = pCopyRect->yTop - pDstDataPoint->y; + Assert(dstX >= 0); + Assert(dstY >= 0); + + + uint8_t *pu8Src = ((uint8_t*)pSrc->pvData) + pSrc->pitch * (!fSrcInvert ? srcY : pSrc->height - srcY - 1) + srcX * 4; + uint8_t *pu8Dst = ((uint8_t*)pDst->pvData) + pDst->pitch * dstY + dstX * 4; + + CrBmpScale32(pu8Dst, pDst->pitch, + pCopyRect->xRight - pCopyRect->xLeft, + pCopyRect->yBottom - pCopyRect->yTop, + pu8Src, + fSrcInvert ? -pSrc->pitch : pSrc->pitch, + UnscaledSrcWidth, + UnscaledSrcHeight + ); +} + static void crFbImgFromScreenVram(const VBVAINFOSCREEN *pScreen, void *pvVram, CR_BLITTER_IMG *pImg) { pImg->pvData = pvVram; @@ -337,7 +395,7 @@ static void crFbImgFromFb(HCR_FRAMEBUFFER hFb, CR_BLITTER_IMG *pImg) crFbImgFromScreenVram(pScreen, pvVram, pImg); } -static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg) +static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg) { VBOXVR_LIST List; uint32_t c2DRects = 0; @@ -347,15 +405,17 @@ static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, RTPOINT ScaledEntryPoint = {0}; VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter; - RTPOINT SrcPoint = {pSrcRect->xLeft, pSrcRect->yTop}; - float strX = ((float)pImg->width) / (pSrcRect->xRight - pSrcRect->xLeft); - float strY = ((float)pImg->height) / (pSrcRect->yBottom - pSrcRect->yTop); + int32_t srcWidth = pSrcRect->xRight - pSrcRect->xLeft; + int32_t srcHeight = pSrcRect->yBottom - pSrcRect->yTop; + int32_t dstWidth = pDstRect->xRight - pDstRect->xLeft; + int32_t dstHeight = pDstRect->yBottom - pDstRect->yTop; - RTPOINT ScaledSrcPoint; - ScaledSrcPoint.x = CR_FLOAT_RCAST(int32_t, strX * SrcPoint.x); - ScaledSrcPoint.y = CR_FLOAT_RCAST(int32_t, strY * SrcPoint.y); + RTPOINT DstPoint = {pDstRect->xLeft, pDstRect->yTop}; + float strX = ((float)dstWidth) / srcWidth; + float strY = ((float)dstHeight) / srcHeight; + bool fScale = (dstWidth != srcWidth || dstHeight != srcHeight); - RTPOINT ZeroPoint = {0, 0}; + const RTPOINT ZeroPoint = {0, 0}; VBoxVrListInit(&List); int rc = VBoxVrListRectsAdd(&List, 1, CrVrScrCompositorRectGet(&hFb->Compositor), NULL); @@ -387,18 +447,24 @@ static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, goto end; } - for (uint32_t i = 0; i < cRects; ++i) + for (uint32_t j = 0; j < cRegions; ++j) { - const RTRECT * pRect = &pRects[i]; - for (uint32_t j = 0; j < cRegions; ++j) + /* rects are in dst coordinates, + * while the pReg is in source coords + * convert */ + const RTRECT * pReg = &pRegions[j]; + RTRECT ScaledReg; + /* scale */ + VBoxRectScaled(pReg, strX, strY, &ScaledReg); + /* translate */ + VBoxRectTranslate(&ScaledReg, pDstRect->xLeft, pDstRect->yTop); + + for (uint32_t i = 0; i < cRects; ++i) { - const RTRECT * pReg = &pRegions[j]; - RTRECT Intersection; - VBoxRectIntersected(pRect, pReg, &Intersection); - if (VBoxRectIsZero(&Intersection)) - continue; + const RTRECT * pRect = &pRects[i]; - VBoxRectScale(&Intersection, strX, strY); + RTRECT Intersection; + VBoxRectIntersected(pRect, &ScaledReg, &Intersection); if (VBoxRectIsZero(&Intersection)) continue; @@ -454,8 +520,8 @@ static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, width = CR_FLOAT_RCAST(uint32_t, strX * pVrTex->width); height = CR_FLOAT_RCAST(uint32_t, strY * pVrTex->height); - ScaledEntryPoint.x = CR_FLOAT_RCAST(int32_t, strX * CrVrScrCompositorEntryRectGet(pEntry)->xLeft); - ScaledEntryPoint.y = CR_FLOAT_RCAST(int32_t, strY * CrVrScrCompositorEntryRectGet(pEntry)->yTop); + ScaledEntryPoint.x = CR_FLOAT_RCAST(int32_t, strX * CrVrScrCompositorEntryRectGet(pEntry)->xLeft) + pDstRect->xLeft; + ScaledEntryPoint.y = CR_FLOAT_RCAST(int32_t, strY * CrVrScrCompositorEntryRectGet(pEntry)->yTop) + pDstRect->yTop; } rc = CrTdBltDataAcquireScaled(pTex, GL_BGRA, false, width, height, &pSrcImg); @@ -467,7 +533,7 @@ static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, bool fInvert = !(CrVrScrCompositorEntryFlagsGet(pEntry) & CRBLT_F_INVERT_SRC_YCOORDS); - crFbBltImg(pSrcImg, &ScaledEntryPoint, fInvert, &Intersection, &ScaledSrcPoint, pImg); + crFbBltImg(pSrcImg, &ScaledEntryPoint, fInvert, &Intersection, &ZeroPoint, pImg); CrTdBltDataReleaseScaled(pTex, pSrcImg); } @@ -502,36 +568,34 @@ static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, goto end; } - RTPOINT Pos = {0}; const RTRECT *pCompRect = CrVrScrCompositorRectGet(&hFb->Compositor); - uint32_t fbWidth = (pCompRect->xRight - pCompRect->xLeft); - uint32_t fbHeight = pCompRect->yBottom - pCompRect->yTop; - - uint32_t stretchedWidth = CR_FLOAT_RCAST(uint32_t, strX * fbWidth); - uint32_t stretchedHeight = CR_FLOAT_RCAST(uint32_t, strY * fbHeight); - CR_BLITTER_IMG FbImg; - bool fScale = fbWidth != stretchedWidth || fbHeight != stretchedHeight; - crFbImgFromFb(hFb, &FbImg); - for (uint32_t i = 0; i < cRects; ++i) + for (uint32_t j = 0; j < c2DRects; ++j) { - const RTRECT * pRect = &pRects[i]; - for (uint32_t j = 0; j < c2DRects; ++j) + const RTRECT * p2DRect = &p2DRects[j]; + RTRECT ScaledReg; + /* scale */ + VBoxRectScaled(p2DRect, strX, strY, &ScaledReg); + /* translate */ + VBoxRectTranslate(&ScaledReg, pDstRect->xLeft, pDstRect->yTop); + + for (uint32_t i = 0; i < cRects; ++i) { - const RTRECT * p2DRect = &p2DRects[j]; + const RTRECT * pRect = &pRects[i]; RTRECT Intersection; - VBoxRectIntersected(pRect, p2DRect, &Intersection); + + VBoxRectIntersected(pRect, &ScaledReg, &Intersection); if (VBoxRectIsZero(&Intersection)) continue; if (!fScale) - crFbBltImg(&FbImg, &ZeroPoint, false, &Intersection, &SrcPoint, pImg); + crFbBltImg(&FbImg, &DstPoint, false, &Intersection, &ZeroPoint, pImg); else - crFbBltImgScaled(&FbImg, &ZeroPoint, false, &Intersection, &SrcPoint, strX, strY, pImg); + crFbBltImgScaledRects(&FbImg, &DstPoint, false, &Intersection, &ZeroPoint, strX, strY, pImg); } } } @@ -549,10 +613,21 @@ end: return rc; } -static int crFbBltGetContentsScaleCPU(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg) +static int crFbBltGetContentsScaleCPU(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg) { - uint32_t srcWidth = pSrcRect->xRight - pSrcRect->xLeft; - uint32_t srcHeight = pSrcRect->yBottom - pSrcRect->yTop; + int32_t srcWidth = pSrcRect->xRight - pSrcRect->xLeft; + int32_t srcHeight = pSrcRect->yBottom - pSrcRect->yTop; + int32_t dstWidth = pDstRect->xRight - pDstRect->xLeft; + int32_t dstHeight = pDstRect->yBottom - pDstRect->yTop; + + RTPOINT DstPoint = {pDstRect->xLeft, pDstRect->yTop}; + float strX = ((float)dstWidth) / srcWidth; + float strY = ((float)dstHeight) / srcHeight; + + RTRECT DstRect; + VBoxRectUnscaled(pDstRect, strX, strY, &DstRect); + DstRect.xRight = DstRect.xLeft + srcWidth; + DstRect.yBottom = DstRect.yTop + srcHeight; /* destination is bigger than the source, do 3D data stretching with CPU */ CR_BLITTER_IMG Img; @@ -569,7 +644,7 @@ static int crFbBltGetContentsScaleCPU(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRec Img.bpp = pImg->bpp; Img.pitch = Img.width * 4; - int rc = CrFbBltGetContents(hFb, pSrcRect, cRects, pRects, &Img); + int rc = CrFbBltGetContents(hFb, pSrcRect, &DstRect, cRects, pRects, &Img); if (RT_SUCCESS(rc)) { CrBmpScale32((uint8_t *)pImg->pvData, @@ -588,21 +663,187 @@ static int crFbBltGetContentsScaleCPU(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRec } -int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg) +int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg) { uint32_t srcWidth = pSrcRect->xRight - pSrcRect->xLeft; uint32_t srcHeight = pSrcRect->yBottom - pSrcRect->yTop; - if ((srcWidth == pImg->width - && srcHeight == pImg->height) + uint32_t dstWidth = pDstRect->xRight - pDstRect->xLeft; + uint32_t dstHeight = pDstRect->yBottom - pDstRect->yTop; + if ((srcWidth == dstWidth + && srcHeight == dstHeight) || !CrFbHas3DData(hFb) - || (srcWidth * srcHeight > pImg->width * pImg->height)) + || (srcWidth * srcHeight > dstWidth * dstHeight)) { - return crFbBltGetContentsDirect(hFb, pSrcRect, cRects, pRects, pImg); + return crFbBltGetContentsDirect(hFb, pSrcRect, pDstRect, cRects, pRects, pImg); } - return crFbBltGetContentsScaleCPU(hFb, pSrcRect, cRects, pRects, pImg); + return crFbBltGetContentsScaleCPU(hFb, pSrcRect, pDstRect, cRects, pRects, pImg); } +#if 0 +static int crFbBltPutContentsVram(HCR_FRAMEBUFFER hFb, const RTPOINT *pDstPoint, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg, float strX, float strY) +{ + const RTRECT *pCompRect = CrVrScrCompositorRectGet(&hFb->Compositor); + const RTPOINT ZeroPoint = {0}; + + uint32_t fbWidth = (pCompRect->xRight - pCompRect->xLeft); + uint32_t fbHeight = pCompRect->yBottom - pCompRect->yTop; + + uint32_t stretchedWidth = CR_FLOAT_RCAST(uint32_t, strX * fbWidth); + uint32_t stretchedHeight = CR_FLOAT_RCAST(uint32_t, strY * fbHeight); + + CR_BLITTER_IMG FbImg; + + bool fScale = fbWidth != stretchedWidth || fbHeight != stretchedHeight; + + crFbImgFromFb(hFb, &FbImg); + + RTRECT Intersection; + + for (uint32_t i = 0; i < cRects; ++i) + { + const RTRECT * pRect = &pRects[i]; + VBoxRectIntersected(pRect, pCompRect, &Intersection); + + if (VBoxRectIsZero(&Intersection)) + continue; + + if (!fScale) + crFbBltImg(pImg, pDstPoint, false, &Intersection, &ZeroPoint, &FbImg); + else + crFbBltImgScaled(pImg, pDstPoint, false, &Intersection, &ZeroPoint, strX, strY, &FbImg); + } + + return VINF_SUCCESS; +} + +int CrFbBltPutContents(HCR_FRAMEBUFFER hFb, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg) +{ + RTPOINT DstPoint = {pDstRect->xLeft, pDstRect->yTop}; + float strX = ((float)pImg->width) / (pDstRect->xRight - pDstRect->xLeft); + float strY = ((float)pImg->height) / (pDstRect->yBottom - pDstRect->yTop); + + int rc = CrFbEntryRegionsAdd(hFb, NULL, const RTPOINT *pPos, cRects, pRects, true) + if (!hFb->cUpdating) + { + WARN(("not updating\n")); + return VERR_INVALID_STATE; + } +} + +int CrFbBltPutContentsNe(HCR_FRAMEBUFFER hFb, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg) +{ + uint32_t cCompRects; + const RTRECT *pCompRects; + int rc = CrVrScrCompositorRegionsGet(&hFb->Compositor, &cCompRects, NULL, NULL, &pCompRects); + if (!RT_SUCCESS(rc)) + { + WARN(("CrVrScrCompositorRegionsGet failed rc %d", rc)); + return rc; + } + + bool fRegChanged = false; + for (uint32_t i = 0; i < cCompRects; ++i) + { + const RTRECT *pCompRect = pCompRects[i]; + for (uint32_t j = 0; j < cRects; ++j) + { + const RTRECT *pRect = pRects[j]; + if (VBoxRectIsIntersect(pCompRect, pRect)) + { + fRegChanged = true; + break; + } + } + } + + if (fRegChanged) + { + rc = CrFbUpdateBegin(hFb); + if (RT_SUCCESS(rc)) + { + rc = CrFbBltPutContents(hFb, pDstRect, cRects, pRects, pImg); + if (!RT_SUCCESS(rc)) + WARN(("CrFbBltPutContents failed rc %d", rc)); + CrFbUpdateEnd(hFb); + } + else + WARN(("CrFbUpdateBegin failed rc %d", rc)); + + return rc; + } + + return crFbBltPutContentsVram(HCR_FRAMEBUFFER hFb, const RTPOINT *pDstPoint, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg, float strX, float strY); + + const RTPOINT ZeroPoint = {0, 0}; + + c2DRects = VBoxVrListRectsCount(&List); + if (c2DRects) + { + if (g_CrPresenter.cbTmpBuf2 < c2DRects * sizeof (RTRECT)) + { + if (g_CrPresenter.pvTmpBuf2) + RTMemFree(g_CrPresenter.pvTmpBuf2); + + g_CrPresenter.cbTmpBuf2 = (c2DRects + 10) * sizeof (RTRECT); + g_CrPresenter.pvTmpBuf2 = RTMemAlloc(g_CrPresenter.cbTmpBuf2); + if (!g_CrPresenter.pvTmpBuf2) + { + WARN(("RTMemAlloc failed!")); + g_CrPresenter.cbTmpBuf2 = 0; + rc = VERR_NO_MEMORY; + goto end; + } + } + + RTRECT *p2DRects = (RTRECT *)g_CrPresenter.pvTmpBuf2; + + rc = VBoxVrListRectsGet(&List, c2DRects, p2DRects); + if (!RT_SUCCESS(rc)) + { + WARN(("VBoxVrListRectsGet failed, rc %d", rc)); + goto end; + } + + RTPOINT Pos = {0}; + const RTRECT *pCompRect = CrVrScrCompositorRectGet(&hFb->Compositor); + + CR_BLITTER_IMG FbImg; + + crFbImgFromFb(hFb, &FbImg); + + for (uint32_t i = 0; i < cRects; ++i) + { + const RTRECT * pRect = &pRects[i]; + for (uint32_t j = 0; j < c2DRects; ++j) + { + const RTRECT * p2DRect = &p2DRects[j]; + RTRECT Intersection; + VBoxRectIntersected(pRect, p2DRect, &Intersection); + if (VBoxRectIsZero(&Intersection)) + continue; + + if (!fScale) + crFbBltImg(&FbImg, &ZeroPoint, false, &Intersection, &SrcPoint, pImg); + else + crFbBltImgScaled(&FbImg, &ZeroPoint, false, &Intersection, &SrcPoint, strX, strY, pImg); + } + } + } + +end: + + if (pEnteredTex) + CrTdBltLeave(pEnteredTex); + + if (pEnteredBlitter) + CrBltLeave(pEnteredBlitter); + + VBoxVrListClear(&List); + + return rc; +} +#endif int CrFbResize(CR_FRAMEBUFFER *pFb, const struct VBVAINFOSCREEN * pScreen, void *pvVRAM) { @@ -3583,7 +3824,7 @@ HCR_FRAMEBUFFER CrPMgrFbGetEnabled(uint32_t idScreen) static HCR_FRAMEBUFFER crPMgrFbGetNextEnabled(uint32_t i) { - for (;i < cr_server.screenCount; ++i) + for (;i < (uint32_t)cr_server.screenCount; ++i) { HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(i); if (hFb) @@ -3595,7 +3836,7 @@ static HCR_FRAMEBUFFER crPMgrFbGetNextEnabled(uint32_t i) static HCR_FRAMEBUFFER crPMgrFbGetNextInitialized(uint32_t i) { - for (;i < cr_server.screenCount; ++i) + for (;i < (uint32_t)cr_server.screenCount; ++i) { HCR_FRAMEBUFFER hFb = CrPMgrFbGetInitialized(i); if (hFb) @@ -3943,7 +4184,7 @@ int CrPMgrHlpGlblUpdateBegin(CR_FBMAP *pMap) /*helper function that calls CrFbUpdateEnd for all framebuffers being updated */ void CrPMgrHlpGlblUpdateEnd(CR_FBMAP *pMap) { - for (uint32_t i = 0; i < cr_server.screenCount; ++i) + for (uint32_t i = 0; i < (uint32_t)cr_server.screenCount; ++i) { if (!CrFBmIsSet(pMap, i)) continue; @@ -4412,12 +4653,12 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd) if (u8Flags & (VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY | VBOXCMDVBVA_OPF_ALLOC_SRCPRIMARY)) { VBOXCMDVBVA_BLT_PRIMARY *pBlt = (VBOXCMDVBVA_BLT_PRIMARY*)pCmd; - uint8_t u8PrimaryID = pBlt->Hdr.u8PrimaryID; + uint8_t u8PrimaryID = pBlt->Hdr.u.u8PrimaryID; HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(u8PrimaryID); if (!hFb) { WARN(("request to present on disabled framebuffer, ignore")); - pCmd->i8Result = -1; + pCmd->u.i8Result = -1; return VINF_SUCCESS; } @@ -4435,7 +4676,7 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd) { WARN(("RTMemAlloc failed!")); g_CrPresenter.cbTmpBuf = 0; - pCmd->i8Result = -1; + pCmd->u.i8Result = -1; return VINF_SUCCESS; } } @@ -4455,23 +4696,24 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd) if (u8Flags & VBOXCMDVBVA_OPF_ALLOC_DSTID) { /* TexPresent */ - texId = pBlt->alloc.id; + texId = pBlt->alloc.u.id; } else { - VBOXCMDVBVAOFFSET offVRAM = pBlt->alloc.offVRAM; + VBOXCMDVBVAOFFSET offVRAM = pBlt->alloc.u.offVRAM; const VBVAINFOSCREEN *pScreen = CrFbGetScreenInfo(hFb); uint32_t cbScreen = pScreen->u32LineSize * pScreen->u32Height; if (offVRAM >= g_cbVRam || offVRAM + cbScreen >= g_cbVRam) { WARN(("invalid param")); - pCmd->i8Result = -1; + pCmd->u.i8Result = -1; return VINF_SUCCESS; } uint8_t *pu8Buf = g_pvVRamBase + offVRAM; texId = 0; +// cr_server.CrCmdClientInfo.pfnCltScrUpdateBegin(cr_server.CrCmdClientInfo.hCltScr); /*todo: notify VGA device to perform updates */ } @@ -4481,7 +4723,7 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd) { /* blit from one primary to another primary, wow */ WARN(("not implemented")); - pCmd->i8Result = -1; + pCmd->u.i8Result = -1; return VINF_SUCCESS; } } @@ -4491,38 +4733,43 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd) /* blit from primary to non-primary */ if (u8Flags & VBOXCMDVBVA_OPF_ALLOC_DSTID) { - uint32_t texId = pBlt->alloc.id; + uint32_t texId = pBlt->alloc.u.id; WARN(("not implemented")); - pCmd->i8Result = -1; + pCmd->u.i8Result = -1; return VINF_SUCCESS; } else { - VBOXCMDVBVAOFFSET offVRAM = pBlt->alloc.offVRAM; + VBOXCMDVBVAOFFSET offVRAM = pBlt->alloc.u.offVRAM; const VBVAINFOSCREEN *pScreen = CrFbGetScreenInfo(hFb); uint32_t cbScreen = pScreen->u32LineSize * pScreen->u32Height; if (offVRAM >= g_cbVRam || offVRAM + cbScreen >= g_cbVRam) { WARN(("invalid param")); - pCmd->i8Result = -1; + pCmd->u.i8Result = -1; return VINF_SUCCESS; } uint8_t *pu8Buf = g_pvVRamBase + offVRAM; - RTRECT Rect; - Rect.xLeft = pBlt->Pos.x; - Rect.yTop = pBlt->Pos.y; - Rect.xRight = Rect.xLeft + pScreen->u32Width; - Rect.yBottom = Rect.yTop + pScreen->u32Height; + RTRECT SrcRect; + SrcRect.xLeft = 0; + SrcRect.yTop = 0; + SrcRect.xRight = pScreen->u32Width; + SrcRect.yBottom = pScreen->u32Height; + RTRECT DstRect; + DstRect.xLeft = pBlt->Pos.x; + DstRect.yTop = pBlt->Pos.y; + DstRect.xRight = DstRect.xLeft + pScreen->u32Width; + DstRect.yBottom = DstRect.yTop + pScreen->u32Height; CR_BLITTER_IMG Img; crFbImgFromScreenVram(pScreen, pu8Buf, &Img); - int rc = CrFbBltGetContents(hFb, &Rect, cRects, pRects, &Img); + int rc = CrFbBltGetContents(hFb, &SrcRect, &DstRect, cRects, pRects, &Img); if (!RT_SUCCESS(rc)) { WARN(("CrFbBltGetContents failed %d", rc)); - pCmd->i8Result = -1; + pCmd->u.i8Result = -1; return VINF_SUCCESS; } } @@ -4531,10 +4778,10 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd) else { WARN(("not implemented")); - pCmd->i8Result = -1; + pCmd->u.i8Result = -1; return VINF_SUCCESS; } - pCmd->i8Result = 0; + pCmd->u.i8Result = 0; return VINF_SUCCESS; } diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c index bfadeda92..29670790a 100644 --- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c +++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c @@ -281,6 +281,28 @@ crServerDeleteClient( CRClient *client ) pNode->next = cr_server.pCleanupClient; cr_server.pCleanupClient = pNode; } + + if (!cr_server.numClients) + { + /* if no clients, the guest driver may be unloaded, + * and thus the visible regions situation might not be under control anymore, + * so cleanup the 3D framebuffer data here + * @todo: what really should happen is that guest driver on unload + * posts some request to host that would copy the current framebuffer 3D data to the 2D buffer + * (i.e. to the memory used by the standard IFramebuffer API) */ + HCR_FRAMEBUFFER hFb; + for (hFb = CrPMgrFbGetFirstEnabled(); hFb; hFb = CrPMgrFbGetNextEnabled(hFb)) + { + int rc = CrFbUpdateBegin(hFb); + if (RT_SUCCESS(rc)) + { + CrFbRegionsClear(hFb); + CrFbUpdateEnd(hFb); + } + else + WARN(("CrFbUpdateBegin failed %d", rc)); + } + } } /** diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c index b74c6224f..693512557 100644 --- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c +++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c @@ -18,26 +18,43 @@ crServerDispatchWindowCreate(const char *dpyName, GLint visBits) return crServerDispatchWindowCreateEx(dpyName, visBits, -1); } -GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID) +GLint crServerMuralInit(CRMuralInfo *mural, GLboolean fGuestWindow, GLint visBits, GLint preloadWinID) { CRMuralInfo *defaultMural; GLint dims[2]; GLint windowID = -1; - GLint spuWindow; - int rc; + GLint spuWindow = 0; GLint realVisBits = visBits; + const char *dpyName = ""; crMemset(mural, 0, sizeof (*mural)); if (cr_server.fVisualBitsDefault) realVisBits = cr_server.fVisualBitsDefault; - /* - * Have first SPU make a new window. - */ - spuWindow = cr_server.head_spu->dispatch_table.WindowCreate( dpyName, realVisBits ); - if (spuWindow < 0) { - return spuWindow; +#ifdef RT_OS_DARWIN + if (fGuestWindow) + { + CRMuralInfo *dummy = crServerGetDummyMural(visBits); + if (!dummy) + { + WARN(("crServerGetDummyMural failed")); + return -1; + } + spuWindow = dummy->spuWindow; + mural->fIsDummyRefference = GL_TRUE; + } + else +#endif + { + /* + * Have first SPU make a new window. + */ + spuWindow = cr_server.head_spu->dispatch_table.WindowCreate( dpyName, realVisBits ); + if (spuWindow < 0) { + return spuWindow; + } + mural->fIsDummyRefference = GL_FALSE; } /* get initial window size */ @@ -121,7 +138,7 @@ GLint crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint p return -1; } - windowID = crServerMuralInit(mural, dpyName, visBits, preloadWinID); + windowID = crServerMuralInit(mural, GL_TRUE, visBits, preloadWinID); if (windowID < 0) { crWarning("crServerMuralInit failed!"); @@ -181,7 +198,7 @@ void crServerMuralTerm(CRMuralInfo *mural) * which might lead to muralFBO (offscreen rendering) gl entities being created in a scope of that context */ cr_server.head_spu->dispatch_table.MakeCurrent(dummyMural->spuWindow, 0, cr_server.MainContextInfo.SpuContext); cr_server.currentWindow = -1; - cr_server.currentMural = NULL; + cr_server.currentMural = dummyMural; } else { @@ -202,7 +219,10 @@ void crServerMuralTerm(CRMuralInfo *mural) } } - cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow ); + if (!mural->fIsDummyRefference) + cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow ); + + mural->spuWindow = 0; if (mural->pVisibleRects) { diff --git a/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c b/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c index 1175b29f6..1bd745a80 100644 --- a/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c +++ b/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c @@ -1232,13 +1232,42 @@ GLboolean renderspu_SystemVBoxCreateWindow( VisualInfo *visual, GLboolean showIt return GL_TRUE; } +static void renderspuWindowRgnApply(WindowInfo *window) +{ + HRGN hRgn = window->hRgn; + if (hRgn) + { + /* note: according to the docs, SetWindowRgn owns the regions after it is called, + * and the regions will be freed automatically when needed, + * i.e. the caller should not do that. + * this is why we need to make a copy of the regions to be passed in */ + + int result; + hRgn = CreateRectRgn(0, 0, 0, 0); + if (!hRgn) + { + WARN(("CreateRectRgn failed")); + return; + } + + result = CombineRgn(hRgn, window->hRgn, NULL, RGN_COPY); + if (result == ERROR) + { + WARN(("CombineRgn failed")); + return; + } + } + + SetWindowRgn(window->hWnd, hRgn, true); +} + /* Either show or hide the render SPU's window. */ void renderspu_SystemShowWindow( WindowInfo *window, GLboolean showIt ) { if (showIt) { crDebug("SHOW renderspu_SystemShowWindow: %x", window->hWnd); - SetWindowRgn(window->hWnd, window->hRgn, true); + renderspuWindowRgnApply(window); } else { @@ -1246,7 +1275,9 @@ void renderspu_SystemShowWindow( WindowInfo *window, GLboolean showIt ) crDebug("HIDE renderspu_SystemShowWindow: %x", window->hWnd); hRgn = CreateRectRgn(0, 0, 0, 0); SetWindowRgn(window->hWnd, hRgn, true); - DeleteObject(hRgn); + /* note: according to the docs, SetWindowRgn owns the regions after it is called, + * and the regions will be freed automatically when needed, + * i.e. the caller should not do that */ } window->visible = showIt; } @@ -1571,12 +1602,12 @@ void renderspu_SystemWindowVisibleRegion(WindowInfo *window, GLint cRects, const DeleteObject(hTmpRgn); } + window->hRgn = hRgn; + if (window->visible) - SetWindowRgn(window->hWnd, hRgn, true); + renderspuWindowRgnApply(window); crDebug("Render SPU: SetWindowRgn (%x, cRects=%i)", window->hWnd, cRects); - - window->hRgn = hRgn; } static void renderspuHandleWindowMessages( HWND hWnd ) |
