VirtualBox

Ignore:
Timestamp:
Nov 14, 2011 9:58:38 AM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
74838
Message:

CrOpenGL: avoid blocked client polling & extra memcpy (block hgsmi command until completion)

Location:
trunk/src/VBox/HostServices/SharedOpenGL
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk

    r38082 r39288  
    147147VBoxOGLcrserverlib_DEFS += VBOXCR_LOGFPS
    148148endif
     149ifdef VBOX_WITH_CRHGSMI
     150VBoxOGLcrserverlib_DEFS += ifdef VBOX_WITH_CRHGSMI
     151endif
    149152
    150153#
  • trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp

    r38505 r39288  
    5353#endif /* RT_OS_WINDOWS */
    5454
    55 #ifdef VBOX_WITH_CRHGSMI
    56 # include <VBox/VBoxVideo.h>
    57 #endif
    58 
    5955#include <VBox/com/errorprint.h>
    6056#include <iprt/thread.h>
     
    6864static IConsole* g_pConsole = NULL;
    6965static PVM g_pVM = NULL;
    70 #ifdef VBOX_WITH_CRHGSMI
    71 static uint8_t* g_pvVRamBase;
    72 #endif
    7366
    7467#ifndef RT_OS_WINDOWS
     
    919912}
    920913
    921 #ifdef VBOX_WITH_CRHGSMI
    922 static int vboxCrHgsmiCtl(PVBOXVDMACMD_CHROMIUM_CTL pCtl)
    923 {
    924     int rc;
    925 
    926     switch (pCtl->enmType)
    927     {
    928         case VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP:
    929         {
    930             PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP pSetup = (PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP)pCtl;
    931             g_pvVRamBase = (uint8_t*)pSetup->pvRamBase;
    932             rc = VINF_SUCCESS;
    933         } break;
    934         case VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_BEGIN:
    935         case VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_END:
    936             rc = VINF_SUCCESS;
    937             break;
    938         default:
    939             Assert(0);
    940             rc = VERR_INVALID_PARAMETER;
    941     }
    942 
    943     return rc;
    944 }
    945 
    946 #define VBOXCRHGSMI_PTR(_off, _t) ((_t*)(g_pvVRamBase + (_off)))
    947 static int vboxCrHgsmiCmd(PVBOXVDMACMD_CHROMIUM_CMD pCmd)
    948 {
    949     int rc;
    950     uint32_t cBuffers = pCmd->cBuffers;
    951     uint32_t cParams;
    952 
    953     if (!g_pvVRamBase)
    954     {
    955         Assert(0);
    956         return VERR_INVALID_STATE;
    957     }
    958 
    959     if (!cBuffers)
    960     {
    961         Assert(0);
    962         return VERR_INVALID_PARAMETER;
    963     }
    964 
    965     cParams = cBuffers-1;
    966 
    967     CRVBOXHGSMIHDR *pHdr = VBOXCRHGSMI_PTR(pCmd->aBuffers[0].offBuffer, CRVBOXHGSMIHDR);
    968     uint32_t u32Function = pHdr->u32Function;
    969     uint32_t u32ClientID = pHdr->u32ClientID;
    970     /* now we compile HGCM params out of HGSMI
    971      * @todo: can we avoid this ? */
    972     switch (u32Function)
    973     {
    974 
    975         case SHCRGL_GUEST_FN_WRITE:
    976         {
    977             Log(("svcCall: SHCRGL_GUEST_FN_WRITE\n"));
    978 
    979             CRVBOXHGSMIWRITE* pFnCmd = (CRVBOXHGSMIWRITE*)pHdr;
    980 
    981             /* @todo: Verify  */
    982             if (cParams == 1)
    983             {
    984                 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
    985                 /* Fetch parameters. */
    986                 uint8_t *pBuffer  = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
    987                 uint32_t cbBuffer = pBuf->cbBuffer;
    988 
    989                 /* Execute the function. */
    990                 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
    991                 if (!RT_SUCCESS(rc))
    992                 {
    993                     Assert(VERR_NOT_SUPPORTED==rc);
    994                     svcClientVersionUnsupported(0, 0);
    995                 }
    996             }
    997             else
    998             {
    999                 Assert(0);
    1000                 rc = VERR_INVALID_PARAMETER;
    1001             }
    1002             break;
    1003         }
    1004 
    1005         case SHCRGL_GUEST_FN_INJECT:
    1006         {
    1007             Log(("svcCall: SHCRGL_GUEST_FN_INJECT\n"));
    1008 
    1009             CRVBOXHGSMIINJECT *pFnCmd = (CRVBOXHGSMIINJECT*)pHdr;
    1010 
    1011             /* @todo: Verify  */
    1012             if (cParams == 1)
    1013             {
    1014                 /* Fetch parameters. */
    1015                 uint32_t u32InjectClientID = pFnCmd->u32ClientID;
    1016                 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
    1017                 uint8_t *pBuffer  = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
    1018                 uint32_t cbBuffer = pBuf->cbBuffer;
    1019 
    1020                 /* Execute the function. */
    1021                 rc = crVBoxServerClientWrite(u32InjectClientID, pBuffer, cbBuffer);
    1022                 if (!RT_SUCCESS(rc))
    1023                 {
    1024                     if (VERR_NOT_SUPPORTED==rc)
    1025                     {
    1026                         svcClientVersionUnsupported(0, 0);
    1027                     }
    1028                     else
    1029                     {
    1030                         crWarning("SHCRGL_GUEST_FN_INJECT failed to inject for %i from %i", u32InjectClientID, u32ClientID);
    1031                     }
    1032                 }
    1033             }
    1034             else
    1035             {
    1036                 Assert(0);
    1037                 rc = VERR_INVALID_PARAMETER;
    1038             }
    1039             break;
    1040         }
    1041 
    1042         case SHCRGL_GUEST_FN_READ:
    1043         {
    1044             Log(("svcCall: SHCRGL_GUEST_FN_READ\n"));
    1045 
    1046             /* @todo: Verify  */
    1047             if (cParams == 1)
    1048             {
    1049                 CRVBOXHGSMIREAD *pFnCmd = (CRVBOXHGSMIREAD*)pHdr;
    1050                 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
    1051                 /* Fetch parameters. */
    1052                 uint8_t *pBuffer  = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
    1053                 uint32_t cbBuffer = pBuf->cbBuffer;
    1054 
    1055                 /* Execute the function. */
    1056                 rc = crVBoxServerClientRead(u32ClientID, pBuffer, &cbBuffer);
    1057 
    1058                 if (RT_SUCCESS(rc))
    1059                 {
    1060                     /* Update parameters.*/
    1061 //                    paParms[0].u.pointer.size = cbBuffer; //@todo guest doesn't see this change somehow?
    1062                 } else if (VERR_NOT_SUPPORTED==rc)
    1063                 {
    1064                     svcClientVersionUnsupported(0, 0);
    1065                 }
    1066 
    1067                 /* Return the required buffer size always */
    1068                 pFnCmd->cbBuffer = cbBuffer;
    1069             }
    1070             else
    1071             {
    1072                 Assert(0);
    1073                 rc = VERR_INVALID_PARAMETER;
    1074             }
    1075 
    1076             break;
    1077         }
    1078 
    1079         case SHCRGL_GUEST_FN_WRITE_READ:
    1080         {
    1081             Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
    1082 
    1083             /* @todo: Verify  */
    1084             if (cParams == 2)
    1085             {
    1086                 CRVBOXHGSMIWRITEREAD *pFnCmd = (CRVBOXHGSMIWRITEREAD*)pHdr;
    1087                 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
    1088                 VBOXVDMACMD_CHROMIUM_BUFFER *pWbBuf = &pCmd->aBuffers[2];
    1089 
    1090                 /* Fetch parameters. */
    1091                 uint8_t *pBuffer  = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
    1092                 uint32_t cbBuffer = pBuf->cbBuffer;
    1093 
    1094                 uint8_t *pWriteback  = VBOXCRHGSMI_PTR(pWbBuf->offBuffer, uint8_t);
    1095                 uint32_t cbWriteback = pWbBuf->cbBuffer;
    1096 
    1097                 /* Execute the function. */
    1098                 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
    1099                 if (!RT_SUCCESS(rc))
    1100                 {
    1101                     Assert(VERR_NOT_SUPPORTED==rc);
    1102                     svcClientVersionUnsupported(0, 0);
    1103                 }
    1104 
    1105                 rc = crVBoxServerClientRead(u32ClientID, pWriteback, &cbWriteback);
    1106 
    1107 //                if (RT_SUCCESS(rc))
    1108 //                {
    1109 //                    /* Update parameters.*/
    1110 //                    paParms[1].u.pointer.size = cbWriteback;
    1111 //                }
    1112                 /* Return the required buffer size always */
    1113                 pFnCmd->cbWriteback = cbWriteback;
    1114             }
    1115             else
    1116             {
    1117                 Assert(0);
    1118                 rc = VERR_INVALID_PARAMETER;
    1119             }
    1120 
    1121             break;
    1122         }
    1123 
    1124         case SHCRGL_GUEST_FN_SET_VERSION:
    1125         {
    1126             Assert(0);
    1127             rc = VERR_NOT_IMPLEMENTED;
    1128             break;
    1129         }
    1130 
    1131         case SHCRGL_GUEST_FN_SET_PID:
    1132         {
    1133             Assert(0);
    1134             rc = VERR_NOT_IMPLEMENTED;
    1135             break;
    1136         }
    1137 
    1138         default:
    1139         {
    1140             Assert(0);
    1141             rc = VERR_NOT_IMPLEMENTED;
    1142         }
    1143 
    1144     }
    1145 
    1146     pHdr->result = rc;
    1147 
    1148     return VINF_SUCCESS;
    1149 }
    1150 #endif
    1151 
    1152914/*
    1153915 * We differentiate between a function handler for the guest and one for the host.
     
    1176938            Assert(cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR);
    1177939            if (cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR)
    1178                 rc = vboxCrHgsmiCmd((PVBOXVDMACMD_CHROMIUM_CMD)paParms[0].u.pointer.addr);
     940            {
     941                rc = crVBoxServerCrHgsmiCmd((PVBOXVDMACMD_CHROMIUM_CMD)paParms[0].u.pointer.addr);
     942                if (VERR_NOT_SUPPORTED == rc)
     943                {
     944                    svcClientVersionUnsupported(0, 0);
     945                }
     946            }
    1179947            else
    1180948                rc = VERR_INVALID_PARAMETER;
     
    1184952            Assert(cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR);
    1185953            if (cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR)
    1186                 rc = vboxCrHgsmiCtl((PVBOXVDMACMD_CHROMIUM_CTL)paParms[0].u.pointer.addr);
     954                rc = crVBoxServerCrHgsmiCtl((PVBOXVDMACMD_CHROMIUM_CTL)paParms[0].u.pointer.addr);
    1187955            else
    1188956                rc = VERR_INVALID_PARAMETER;
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/crserverlib.def

    r15532 r39288  
    1111crVBoxServerClientWrite
    1212crVBoxServerClientRead
     13crVBoxServerCrHgsmiCmd
     14crVBoxServerCrHgsmiCtl
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h

    r36843 r39288  
    1515
    1616#include "cr_server.h"
     17
     18#ifdef VBOX_WITH_CRHGSMI
     19# include <VBox/VBoxVideo.h>
     20
     21extern uint8_t* g_pvVRamBase;
     22extern HCRHGSMICMDCOMPLETION g_hCrHgsmiCompletion;
     23extern PFNCRHGSMICMDCOMPLETION g_pfnCrHgsmiCompletion;
     24
     25#define VBOXCRHGSMI_PTR(_off, _t) ((_t*)(g_pvVRamBase + (_off)))
     26
     27DECLINLINE(void) crServerCrHgsmiCmdComplete(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, int cmdProcessingRc)
     28{
     29    g_pfnCrHgsmiCompletion(g_hCrHgsmiCompletion, pCmd, cmdProcessingRc);
     30}
     31
     32#define VBOXCRHGSMI_CMD_COMPLETE(_pData, _rc) do { \
     33        CRVBOXHGSMI_CMDDATA_ASSERT_ISSET(_pData); \
     34        CRVBOXHGSMI_CMDDATA_RC(_pData, _rc); \
     35        crServerCrHgsmiCmdComplete((_pData)->pCmd, VINF_SUCCESS); \
     36    } while (0)
     37
     38#define VBOXCRHGSMI_CMD_CHECK_COMPLETE(_pData, _rc) do { \
     39        if (CRVBOXHGSMI_CMDDATA_IS_SET(_pData)) { \
     40            VBOXCRHGSMI_CMD_COMPLETE(_pData, _rc); \
     41        } \
     42    } while (0)
     43
     44#endif
    1745
    1846/*
     
    98126GLboolean crServerIsRedirectedToFBO();
    99127
     128int32_t crVBoxServerInternalClientRead(CRClient *pClient, uint8_t *pBuffer, uint32_t *pcbBuffer);
     129
    100130#endif /* CR_SERVER_H */
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c

    r38505 r39288  
    3030#endif
    3131
     32#ifdef VBOX_WITH_CRHGSMI
     33# include <VBox/HostServices/VBoxCrOpenGLSvc.h>
     34uint8_t* g_pvVRamBase = NULL;
     35HCRHGSMICMDCOMPLETION g_hCrHgsmiCompletion = NULL;
     36PFNCRHGSMICMDCOMPLETION g_pfnCrHgsmiCompletion = NULL;
     37#endif
     38
    3239/**
    3340 * \mainpage CrServerLib
     
    4855int tearingdown = 0; /* can't be static */
    4956
     57DECLINLINE(int32_t) crVBoxServerClientGet(uint32_t u32ClientID, CRClient **ppClient)
     58{
     59    CRClient *pClient = NULL;
     60    int32_t i;
     61
     62    *ppClient = NULL;
     63
     64    for (i = 0; i < cr_server.numClients; i++)
     65    {
     66        if (cr_server.clients[i] && cr_server.clients[i]->conn
     67            && cr_server.clients[i]->conn->u32ClientID==u32ClientID)
     68        {
     69            pClient = cr_server.clients[i];
     70            break;
     71        }
     72    }
     73    if (!pClient)
     74    {
     75        crWarning("client not found!");
     76        return VERR_INVALID_PARAMETER;
     77    }
     78
     79    if (!pClient->conn->vMajor)
     80    {
     81        crWarning("no major version specified for client!");
     82        return VERR_NOT_SUPPORTED;
     83    }
     84
     85    *ppClient = pClient;
     86
     87    return VINF_SUCCESS;
     88}
     89
    5090
    5191/**
     
    398438    }
    399439
     440#ifdef VBOX_WITH_CRHGSMI
     441    CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     442#endif
     443
    400444    /* Disconnect the client */
    401445    pClient->conn->Disconnect(pClient->conn);
     
    405449}
    406450
    407 int32_t crVBoxServerClientWrite(uint32_t u32ClientID, uint8_t *pBuffer, uint32_t cbBuffer)
    408 {
    409     CRClient *pClient = NULL;
    410     int32_t i;
     451static int32_t crVBoxServerInternalClientWriteRead(CRClient *pClient)
     452{
    411453#ifdef VBOXCR_LOGFPS
    412454    uint64_t tstart, tend;
     
    415457    /*crDebug("=>crServer: ClientWrite u32ClientID=%d", u32ClientID);*/
    416458
    417     for (i = 0; i < cr_server.numClients; i++)
    418     {
    419         if (cr_server.clients[i] && cr_server.clients[i]->conn
    420             && cr_server.clients[i]->conn->u32ClientID==u32ClientID)
    421         {
    422             pClient = cr_server.clients[i];
    423             break;
    424         }
    425     }
    426     if (!pClient) return VERR_INVALID_PARAMETER;
    427 
    428     if (!pClient->conn->vMajor) return VERR_NOT_SUPPORTED;
    429459
    430460#ifdef VBOXCR_LOGFPS
     
    432462#endif
    433463
    434     CRASSERT(pBuffer);
    435 
    436     /* This should never fire unless we start to multithread */
    437     CRASSERT(pClient->conn->pBuffer==NULL && pClient->conn->cbBuffer==0);
    438 
    439     /* Check if there's a blocker in queue and it's not this client */
    440     if (cr_server.run_queue->client != pClient
    441         && crServerClientInBeginEnd(cr_server.run_queue->client))
    442     {
    443         crDebug("crServer: client %d blocked, allow_redir_ptr = 0", u32ClientID);
     464    /* This should be setup already */
     465    CRASSERT(pClient->conn->pBuffer);
     466    CRASSERT(pClient->conn->cbBuffer);
     467#ifdef VBOX_WITH_CRHGSMI
     468    CRVBOXHGSMI_CMDDATA_ASSERT_CONSISTENT(&pClient->conn->CmdData);
     469#endif
     470
     471    if (
     472#ifdef VBOX_WITH_CRHGSMI
     473         !CRVBOXHGSMI_CMDDATA_IS_SET(&pClient->conn->CmdData) &&
     474#endif
     475         cr_server.run_queue->client != pClient
     476         && crServerClientInBeginEnd(cr_server.run_queue->client))
     477    {
     478        crDebug("crServer: client %d blocked, allow_redir_ptr = 0", pClient->conn->u32ClientID);
    444479        pClient->conn->allow_redir_ptr = 0;
    445480    }
     
    448483        pClient->conn->allow_redir_ptr = 1;
    449484    }
    450 
    451     pClient->conn->pBuffer = pBuffer;
    452     pClient->conn->cbBuffer = cbBuffer;
    453485
    454486    crNetRecv();
    455487    CRASSERT(pClient->conn->pBuffer==NULL && pClient->conn->cbBuffer==0);
     488    CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
    456489
    457490    crServerServiceClients();
     
    486519    crStateResetCurrentPointers(&cr_server.current);
    487520
     521#ifndef VBOX_WITH_CRHGSMI
    488522    CRASSERT(!pClient->conn->allow_redir_ptr || crNetNumMessages(pClient->conn)==0);
     523#endif
    489524
    490525#ifdef VBOXCR_LOGFPS
     
    497532}
    498533
    499 int32_t crVBoxServerClientRead(uint32_t u32ClientID, uint8_t *pBuffer, uint32_t *pcbBuffer)
     534
     535int32_t crVBoxServerClientWrite(uint32_t u32ClientID, uint8_t *pBuffer, uint32_t cbBuffer)
    500536{
    501537    CRClient *pClient=NULL;
    502     int32_t i;
    503 
    504     //crDebug("crServer: [%x] ClientRead u32ClientID=%d", crThreadID(), u32ClientID);
    505 
    506     for (i = 0; i < cr_server.numClients; i++)
    507     {
    508         if (cr_server.clients[i] && cr_server.clients[i]->conn
    509             && cr_server.clients[i]->conn->u32ClientID==u32ClientID)
    510         {
    511             pClient = cr_server.clients[i];
    512             break;
    513         }
    514     }
    515     if (!pClient) return VERR_INVALID_PARAMETER;   
    516 
    517     if (!pClient->conn->vMajor) return VERR_NOT_SUPPORTED;
    518 
     538    int32_t rc = crVBoxServerClientGet(u32ClientID, &pClient);
     539
     540    if (RT_FAILURE(rc))
     541        return rc;
     542
     543
     544    CRASSERT(pBuffer);
     545
     546    /* This should never fire unless we start to multithread */
     547    CRASSERT(pClient->conn->pBuffer==NULL && pClient->conn->cbBuffer==0);
     548
     549    pClient->conn->pBuffer = pBuffer;
     550    pClient->conn->cbBuffer = cbBuffer;
     551#ifdef VBOX_WITH_CRHGSMI
     552    CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     553#endif
     554
     555    return crVBoxServerInternalClientWriteRead(pClient);
     556}
     557
     558int32_t crVBoxServerInternalClientRead(CRClient *pClient, uint8_t *pBuffer, uint32_t *pcbBuffer)
     559{
    519560    if (pClient->conn->cbHostBuffer > *pcbBuffer)
    520561    {
    521562        crDebug("crServer: [%lx] ClientRead u32ClientID=%d FAIL, host buffer too small %d of %d",
    522                   crThreadID(), u32ClientID, *pcbBuffer, pClient->conn->cbHostBuffer);
     563                  crThreadID(), pClient->conn->u32ClientID, *pcbBuffer, pClient->conn->cbHostBuffer);
    523564
    524565        /* Return the size of needed buffer */
     
    539580
    540581    return VINF_SUCCESS;
     582}
     583
     584int32_t crVBoxServerClientRead(uint32_t u32ClientID, uint8_t *pBuffer, uint32_t *pcbBuffer)
     585{
     586    CRClient *pClient=NULL;
     587    int32_t rc = crVBoxServerClientGet(u32ClientID, &pClient);
     588
     589    if (RT_FAILURE(rc))
     590        return rc;
     591
     592#ifdef VBOX_WITH_CRHGSMI
     593    CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     594#endif
     595
     596    return crVBoxServerInternalClientRead(pClient, pBuffer, pcbBuffer);
    541597}
    542598
     
    10301086            if (0)
    10311087            {
    1032             CRContext *tmpCtx;
    1033             CRCreateInfo_t *createInfo;
     1088//            CRContext *tmpCtx;
     1089//            CRCreateInfo_t *createInfo;
    10341090            GLfloat one[4] = { 1, 1, 1, 1 };
    10351091            GLfloat amb[4] = { 0.4f, 0.4f, 0.4f, 1.0f };
     
    12811337    return VINF_SUCCESS;
    12821338}
     1339
     1340
     1341#ifdef VBOX_WITH_CRHGSMI
     1342/* We moved all CrHgsmi command processing to crserverlib to keep the logic of dealing with CrHgsmi commands in one place.
     1343 *
     1344 * 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.
     1345 * This help avoiding the "blocked-client" issues. The client is blocked if another client is doing begin-end stuff.
     1346 * For now we eliminated polling that could occur on block, which caused a higher-priority thread (in guest) polling for the blocked command complition
     1347 * to block the lower-priority thread trying to complete the blocking command.
     1348 * And removed extra memcpy done on blocked command arrival.
     1349 *
     1350 * In the future we will extend CrHgsmi functionality to maintain texture data directly in CrHgsmi allocation to avoid extra memcpy-ing with PBO,
     1351 * implement command completion and stuff necessary for GPU scheduling to work properly for WDDM Windows guests, etc.
     1352 *
     1353 * NOTE: it is ALWAYS responsibility of the crVBoxServerCrHgsmiCmd to complete the command!
     1354 * */
     1355int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd)
     1356{
     1357    int32_t rc;
     1358    uint32_t cBuffers = pCmd->cBuffers;
     1359    uint32_t cParams;
     1360    CRVBOXHGSMIHDR *pHdr;
     1361    uint32_t u32Function;
     1362    uint32_t u32ClientID;
     1363    CRClient *pClient;
     1364
     1365    if (!g_pvVRamBase)
     1366    {
     1367        CRASSERT(0);
     1368        crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_STATE);
     1369        return VINF_SUCCESS;
     1370    }
     1371
     1372    if (!cBuffers)
     1373    {
     1374        CRASSERT(0);
     1375        crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
     1376        return VINF_SUCCESS;
     1377    }
     1378
     1379    cParams = cBuffers-1;
     1380
     1381    pHdr = VBOXCRHGSMI_PTR(pCmd->aBuffers[0].offBuffer, CRVBOXHGSMIHDR);
     1382    u32Function = pHdr->u32Function;
     1383    u32ClientID = pHdr->u32ClientID;
     1384
     1385    switch (u32Function)
     1386    {
     1387        case SHCRGL_GUEST_FN_WRITE:
     1388        {
     1389            crDebug(("svcCall: SHCRGL_GUEST_FN_WRITE\n"));
     1390
     1391            /* @todo: Verify  */
     1392            if (cParams == 1)
     1393            {
     1394                CRVBOXHGSMIWRITE* pFnCmd = (CRVBOXHGSMIWRITE*)pHdr;
     1395                VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
     1396                /* Fetch parameters. */
     1397                uint8_t *pBuffer  = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
     1398                uint32_t cbBuffer = pBuf->cbBuffer;
     1399
     1400                CRASSERT(pBuffer);
     1401                CRASSERT(cbBuffer);
     1402
     1403                rc = crVBoxServerClientGet(u32ClientID, &pClient);
     1404                if (RT_FAILURE(rc))
     1405                {
     1406                    break;
     1407                }
     1408
     1409                /* This should never fire unless we start to multithread */
     1410                CRASSERT(pClient->conn->pBuffer==NULL && pClient->conn->cbBuffer==0);
     1411                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     1412
     1413                pClient->conn->pBuffer = pBuffer;
     1414                pClient->conn->cbBuffer = cbBuffer;
     1415                CRVBOXHGSMI_CMDDATA_SET(&pClient->conn->CmdData, pCmd, pHdr);
     1416                rc = crVBoxServerInternalClientWriteRead(pClient);
     1417                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     1418                return rc;
     1419            }
     1420            else
     1421            {
     1422                crWarning("invalid number of args");
     1423                rc = VERR_INVALID_PARAMETER;
     1424                break;
     1425            }
     1426            break;
     1427        }
     1428
     1429        case SHCRGL_GUEST_FN_INJECT:
     1430        {
     1431            crDebug(("svcCall: SHCRGL_GUEST_FN_INJECT\n"));
     1432
     1433            /* @todo: Verify  */
     1434            if (cParams == 1)
     1435            {
     1436                CRVBOXHGSMIINJECT *pFnCmd = (CRVBOXHGSMIINJECT*)pHdr;
     1437                /* Fetch parameters. */
     1438                uint32_t u32InjectClientID = pFnCmd->u32ClientID;
     1439                VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
     1440                uint8_t *pBuffer  = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
     1441                uint32_t cbBuffer = pBuf->cbBuffer;
     1442
     1443                CRASSERT(pBuffer);
     1444                CRASSERT(cbBuffer);
     1445
     1446                rc = crVBoxServerClientGet(u32InjectClientID, &pClient);
     1447                if (RT_FAILURE(rc))
     1448                {
     1449                    break;
     1450                }
     1451
     1452                /* This should never fire unless we start to multithread */
     1453                CRASSERT(pClient->conn->pBuffer==NULL && pClient->conn->cbBuffer==0);
     1454                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     1455
     1456                pClient->conn->pBuffer = pBuffer;
     1457                pClient->conn->cbBuffer = cbBuffer;
     1458                CRVBOXHGSMI_CMDDATA_SET(&pClient->conn->CmdData, pCmd, pHdr);
     1459                rc = crVBoxServerInternalClientWriteRead(pClient);
     1460                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     1461                return rc;
     1462            }
     1463
     1464            crWarning("invalid number of args");
     1465            rc = VERR_INVALID_PARAMETER;
     1466            break;
     1467        }
     1468
     1469        case SHCRGL_GUEST_FN_READ:
     1470        {
     1471            crDebug(("svcCall: SHCRGL_GUEST_FN_READ\n"));
     1472
     1473            /* @todo: Verify  */
     1474            if (cParams == 1)
     1475            {
     1476                CRVBOXHGSMIREAD *pFnCmd = (CRVBOXHGSMIREAD*)pHdr;
     1477                VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
     1478                /* Fetch parameters. */
     1479                uint8_t *pBuffer  = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
     1480                uint32_t cbBuffer = pBuf->cbBuffer;
     1481
     1482                rc = crVBoxServerClientGet(u32ClientID, &pClient);
     1483                if (RT_FAILURE(rc))
     1484                {
     1485                    break;
     1486                }
     1487
     1488                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     1489
     1490                rc = crVBoxServerInternalClientRead(pClient, pBuffer, &cbBuffer);
     1491
     1492                /* Return the required buffer size always */
     1493                pFnCmd->cbBuffer = cbBuffer;
     1494
     1495                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     1496
     1497                /* the read command is never pended, complete it right away */
     1498                pHdr->result = rc;
     1499                crServerCrHgsmiCmdComplete(pCmd, VINF_SUCCESS);
     1500                return VINF_SUCCESS;
     1501            }
     1502
     1503            crWarning("invalid number of args");
     1504            rc = VERR_INVALID_PARAMETER;
     1505            break;
     1506        }
     1507
     1508        case SHCRGL_GUEST_FN_WRITE_READ:
     1509        {
     1510            crDebug(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
     1511
     1512            /* @todo: Verify  */
     1513            if (cParams == 2)
     1514            {
     1515                CRVBOXHGSMIWRITEREAD *pFnCmd = (CRVBOXHGSMIWRITEREAD*)pHdr;
     1516                VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
     1517                VBOXVDMACMD_CHROMIUM_BUFFER *pWbBuf = &pCmd->aBuffers[2];
     1518
     1519                /* Fetch parameters. */
     1520                uint8_t *pBuffer  = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
     1521                uint32_t cbBuffer = pBuf->cbBuffer;
     1522
     1523                uint8_t *pWriteback  = VBOXCRHGSMI_PTR(pWbBuf->offBuffer, uint8_t);
     1524                uint32_t cbWriteback = pWbBuf->cbBuffer;
     1525
     1526                CRASSERT(pBuffer);
     1527                CRASSERT(cbBuffer);
     1528
     1529                rc = crVBoxServerClientGet(u32ClientID, &pClient);
     1530                if (RT_FAILURE(rc))
     1531                {
     1532                    pHdr->result = rc;
     1533                    crServerCrHgsmiCmdComplete(pCmd, VINF_SUCCESS);
     1534                    return rc;
     1535                }
     1536
     1537                /* This should never fire unless we start to multithread */
     1538                CRASSERT(pClient->conn->pBuffer==NULL && pClient->conn->cbBuffer==0);
     1539                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     1540
     1541                pClient->conn->pBuffer = pBuffer;
     1542                pClient->conn->cbBuffer = cbBuffer;
     1543                CRVBOXHGSMI_CMDDATA_SETWB(&pClient->conn->CmdData, pCmd, pHdr, pWriteback, cbWriteback, &pFnCmd->cbWriteback);
     1544                rc = crVBoxServerInternalClientWriteRead(pClient);
     1545                CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(&pClient->conn->CmdData);
     1546                return rc;
     1547            }
     1548
     1549            crWarning("invalid number of args");
     1550            rc = VERR_INVALID_PARAMETER;
     1551            break;
     1552        }
     1553
     1554        case SHCRGL_GUEST_FN_SET_VERSION:
     1555        {
     1556            crWarning("invalid function");
     1557            rc = VERR_NOT_IMPLEMENTED;
     1558            break;
     1559        }
     1560
     1561        case SHCRGL_GUEST_FN_SET_PID:
     1562        {
     1563            crWarning("invalid function");
     1564            rc = VERR_NOT_IMPLEMENTED;
     1565            break;
     1566        }
     1567
     1568        default:
     1569        {
     1570            crWarning("invalid function");
     1571            rc = VERR_NOT_IMPLEMENTED;
     1572            break;
     1573        }
     1574
     1575    }
     1576
     1577    /* we can be on fail only here */
     1578    CRASSERT(RT_FAILURE(rc));
     1579    pHdr->result = rc;
     1580    crServerCrHgsmiCmdComplete(pCmd, VINF_SUCCESS);
     1581    return rc;
     1582}
     1583
     1584int32_t crVBoxServerCrHgsmiCtl(struct VBOXVDMACMD_CHROMIUM_CTL *pCtl)
     1585{
     1586    int rc = VINF_SUCCESS;
     1587
     1588    switch (pCtl->enmType)
     1589    {
     1590        case VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP:
     1591        {
     1592            PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP pSetup = (PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP)pCtl;
     1593            g_pvVRamBase = (uint8_t*)pSetup->pvRamBase;
     1594            rc = VINF_SUCCESS;
     1595            break;
     1596        }
     1597        case VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_BEGIN:
     1598        case VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_END:
     1599            rc = VINF_SUCCESS;
     1600            break;
     1601        case VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP_COMPLETION:
     1602        {
     1603            PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION pSetup = (PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION)pCtl;
     1604            g_hCrHgsmiCompletion = pSetup->hCompletion;
     1605            g_pfnCrHgsmiCompletion = pSetup->pfnCompletion;
     1606            rc = VINF_SUCCESS;
     1607            break;
     1608        }
     1609        default:
     1610            AssertMsgFailed(("invalid param %d", pCtl->enmType));
     1611            rc = VERR_INVALID_PARAMETER;
     1612    }
     1613
     1614    /* NOTE: Control commands can NEVER be pended here, this is why its a task of a caller (Main)
     1615     * to complete them accordingly.
     1616     * This approach allows using host->host and host->guest commands in the same way here
     1617     * making the command completion to be the responsibility of the command originator.
     1618     * E.g. ctl commands can be both Hgcm Host synchronous commands that do not require completion at all,
     1619     * or Hgcm Host Fast Call commands that do require completion. All this details are hidden here */
     1620    return rc;
     1621}
     1622#endif
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_retval.py

    r30458 r39288  
    3636
    3737    rb->header.type = CR_MESSAGE_READBACK;
     38    CRDBGPTR_PRINTWB(cr_server.curClient->conn->u32ClientID, &cr_server.writeback_ptr);
     39    CRDBGPTR_CHECKNZ(&cr_server.writeback_ptr);
     40    CRDBGPTR_CHECKNZ(&cr_server.return_ptr);
    3841    crMemcpy( &(rb->writeback_ptr), &(cr_server.writeback_ptr), sizeof( rb->writeback_ptr ) );
    3942    crMemcpy( &(rb->readback_ptr), &(cr_server.return_ptr), sizeof( rb->readback_ptr ) );
    4043    crMemcpy( rb+1, payload, payload_len );
    4144    crNetSend( cr_server.curClient->conn, NULL, rb, msg_len );
     45    CRDBGPTR_SETZ(&cr_server.writeback_ptr);
     46    CRDBGPTR_SETZ(&cr_server.return_ptr);
    4247    crFree( rb );
    4348}
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c

    r33989 r39288  
    2525                                                                                 cr_server.tcpip_port,
    2626                                                                                 cr_server.mtu, 1 );
     27
    2728        newClient->currentCtx = cr_server.DummyContext;
    2829
     
    7677{
    7778    RunQueue *q = (RunQueue *) crAlloc( sizeof( *q ) );
     79
     80#ifdef VBOX_WITH_CRHGSMI
     81    client->conn->pClient = client;
     82    CRVBOXHGSMI_CMDDATA_CLEANUP(&client->conn->CmdData);
     83#endif
    7884
    7985    /* give this client a unique number if needed */
     
    393399 */
    394400static void
    395 crServerDispatchMessage(CRMessage *msg)
     401crServerDispatchMessage(CRConnection *conn, CRMessage *msg)
    396402{
    397403    const CRMessageOpcodes *msg_opcodes;
    398404    int opcodeBytes;
    399405    const char *data_ptr;
     406#ifdef VBOX_WITH_CRHGSMI
     407    PCRVBOXHGSMI_CMDDATA pCmdData = NULL;
     408#endif
    400409
    401410    if (msg->header.type == CR_MESSAGE_REDIR_PTR)
    402411    {
     412#ifdef VBOX_WITH_CRHGSMI
     413        pCmdData = &msg->redirptr.CmdData;
     414#endif
    403415        msg = (CRMessage *) msg->redirptr.pMessage;
    404416    }
     
    419431             msg_opcodes->numOpcodes,  /* how many opcodes */
    420432             &(cr_server.dispatch));   /* the CR dispatch table */
     433
     434#ifdef VBOX_WITH_CRHGSMI
     435    if (pCmdData)
     436    {
     437        int rc = VINF_SUCCESS;
     438        CRVBOXHGSMI_CMDDATA_ASSERT_CONSISTENT(pCmdData);
     439        if (CRVBOXHGSMI_CMDDATA_IS_SETWB(pCmdData))
     440        {
     441            uint32_t cbWriteback = pCmdData->cbWriteback;
     442            rc = crVBoxServerInternalClientRead(conn->pClient, pCmdData->pWriteback, &cbWriteback);
     443            CRASSERT(rc == VINF_SUCCESS || rc == VERR_BUFFER_OVERFLOW);
     444            *pCmdData->pcbWriteback = cbWriteback;
     445        }
     446        VBOXCRHGSMI_CMD_CHECK_COMPLETE(pCmdData, rc);
     447    }
     448#endif
    421449}
    422450
     
    532560
    533561        /* Commands get dispatched here */
    534         crServerDispatchMessage(msg);
     562        crServerDispatchMessage( conn, msg );
    535563
    536564        crNetFree( conn, msg );
     
    540568             * glEndList pair at this time!
    541569             */
     570            CRASSERT(0);
    542571            return CLIENT_NEXT;
    543572        }
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_writeback.c

    r15532 r39288  
    2020        CRMessageWriteback *wb = (CRMessageWriteback *) crAlloc( sizeof( *wb ) );
    2121        wb->header.type = CR_MESSAGE_WRITEBACK;
     22        CRDBGPTR_PRINTWB(cr_server.curClient->conn->u32ClientID, &cr_server.writeback_ptr);
     23        CRDBGPTR_CHECKNZ(&cr_server.writeback_ptr);
    2224        crMemcpy( &(wb->writeback_ptr), &(cr_server.writeback_ptr), sizeof( wb->writeback_ptr ) );
    2325        crNetSend( cr_server.curClient->conn, NULL, wb, sizeof( *wb ) );
     26        CRDBGPTR_SETZ(&cr_server.writeback_ptr);
    2427        crFree( wb );
    2528}
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette