VirtualBox

Ignore:
Timestamp:
Oct 28, 2010 2:28:37 PM (14 years ago)
Author:
vboxsync
Message:

wddm/3d: merge chromium hgcm and hgsmi connection into one

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c

    r33366 r33561  
    4646#include <VBox/HostServices/VBoxCrOpenGLSvc.h>
    4747
     48#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
     49#include <VBox/VBoxCrHgsmi.h>
     50#endif
     51
     52//#define IN_GUEST
    4853//#if defined(IN_GUEST)
    4954//#define VBOX_WITH_CRHGSMIPROFILE
     
    5257#include <iprt/time.h>
    5358#include <stdio.h>
    54 
    55 #ifdef VBOX_WITH_CRHGSMI
    56 #include <VBox/VBoxCrHgsmi.h>
    57 #endif
    5859
    5960typedef struct VBOXCRHGSMIPROFILE
     
    170171    int                  iGuestDrv;
    171172#endif
     173#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
     174    bool bHgsmiOn;
     175#endif
    172176} CRVBOXHGCMDATA;
    173177
     
    181185    ,CR_VBOXHGCM_DDRAW_SURFACE
    182186#endif
     187#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
     188    ,CR_VBOXHGCM_UHGSMI_BUFFER
     189#endif
    183190} CRVBOXHGCMBUFFERKIND;
    184191
     
    188195    uint32_t             magic;
    189196    CRVBOXHGCMBUFFERKIND kind;
    190     uint32_t             len;
    191     uint32_t             allocated;
     197    union
     198    {
     199        struct
     200        {
     201            uint32_t             len;
     202            uint32_t             allocated;
     203        };
     204
     205#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
     206        PVBOXUHGSMI_BUFFER pBuffer;
     207#endif
     208    };
    192209#ifdef RT_OS_WINDOWS
    193210    LPDIRECTDRAWSURFACE  pDDS;
     
    199216    #define FALSE false
    200217    #define INVALID_HANDLE_VALUE (-1)
     218#endif
     219
     220
     221#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
     222typedef struct CRVBOXHGSMI_CLIENT {
     223    PVBOXUHGSMI pHgsmi;
     224    PVBOXUHGSMI_BUFFER pCmdBuffer;
     225    PVBOXUHGSMI_BUFFER pHGBuffer;
     226    void *pvHGBuffer;
     227    CRBufferPool *bufpool;
     228} CRVBOXHGSMI_CLIENT, *PCRVBOXHGSMI_CLIENT;
     229
     230/* add sizeof header + page align */
     231#define CRVBOXHGSMI_PAGE_ALIGN(_s) (((_s)  + 0xfff) & ~0xfff)
     232#define CRVBOXHGSMI_BUF_HDR_SIZE() (sizeof (CRVBOXHGCMBUFFER))
     233#define CRVBOXHGSMI_BUF_SIZE(_s) CRVBOXHGSMI_PAGE_ALIGN((_s) + CRVBOXHGSMI_BUF_HDR_SIZE())
     234#define CRVBOXHGSMI_BUF_LOCK_SIZE(_s) ((_s) + CRVBOXHGSMI_BUF_HDR_SIZE())
     235#define CRVBOXHGSMI_BUF_DATA(_p) ((void*)(((CRVBOXHGCMBUFFER*)(_p)) + 1))
     236#define CRVBOXHGSMI_BUF_HDR(_p) (((CRVBOXHGCMBUFFER*)(_p)) - 1)
     237#define CRVBOXHGSMI_BUF_OFFSET(_st2, _st1) ((uint32_t)(((uint8_t*)(_st2)) - ((uint8_t*)(_st1))))
     238
     239DECLINLINE(PCRVBOXHGSMI_CLIENT) _crVBoxHGSMIClientGet(CRConnection *conn)
     240{
     241    PCRVBOXHGSMI_CLIENT pClient = (PCRVBOXHGSMI_CLIENT)VBoxCrHgsmiQueryClient();
     242    Assert(pClient);
     243    return pClient;
     244}
     245
     246static PVBOXUHGSMI_BUFFER _crVBoxHGSMIBufAlloc(PCRVBOXHGSMI_CLIENT pClient, uint32_t cbSize)
     247{
     248    PVBOXUHGSMI_BUFFER buf;
     249    int rc;
     250
     251    buf = (PVBOXUHGSMI_BUFFER ) crBufferPoolPop(pClient->bufpool, cbSize);
     252
     253    if (!buf)
     254    {
     255        crDebug("Buffer pool %p was empty; allocating new %d byte buffer.",
     256                        (void *) pClient->bufpool,
     257                        cbSize);
     258        rc = pClient->pHgsmi->pfnBufferCreate(pClient->pHgsmi, cbSize,
     259                                VBOXUHGSMI_SYNCHOBJECT_TYPE_NONE, NULL,
     260                                &buf);
     261        AssertRC(rc);
     262        if (RT_FAILURE(rc))
     263            crWarning("Failed to Create a buffer of size(%d), rc(%d)\n", cbSize, rc);
     264    }
     265    return buf;
     266}
     267
     268static PVBOXUHGSMI_BUFFER _crVBoxHGSMIBufFromHdr(CRVBOXHGCMBUFFER *pHdr)
     269{
     270    PVBOXUHGSMI_BUFFER pBuf;
     271    int rc;
     272    CRASSERT(pHdr->magic == CR_VBOXHGCM_BUFFER_MAGIC);
     273    CRASSERT(pHdr->kind == CR_VBOXHGCM_UHGSMI_BUFFER);
     274    pBuf = pHdr->pBuffer;
     275    rc = pBuf->pfnUnlock(pBuf);
     276    AssertRC(rc);
     277    if (RT_FAILURE(rc))
     278    {
     279        return NULL;
     280    }
     281    return pBuf;
     282}
     283
     284static void _crVBoxHGSMIBufFree(PCRVBOXHGSMI_CLIENT pClient, PVBOXUHGSMI_BUFFER pBuf)
     285{
     286    crBufferPoolPush(pClient->bufpool, pBuf, pBuf->cbBuffer);
     287}
     288
     289static CRVBOXHGSMIHDR *_crVBoxHGSMICmdBufferLock(PCRVBOXHGSMI_CLIENT pClient, uint32_t cbBuffer)
     290{
     291    /* in theory it is OK to use one cmd buffer for asynch cmd submission
     292     * because bDiscard flag should result in allocating a new memory backend if the
     293     * allocation is still in use.
     294     * However, NOTE: since one and the same semaphore synch event is used for completion notification,
     295     * for the notification mechanism working as expected
     296     * 1. host must complete commands in the same order as it receives them
     297     * (to avoid situation when guest receives notification for another command completion)
     298     * 2. guest must eventually wait for command completion unless he specified bDoNotSignalCompletion
     299     * 3. guest must wait for command completion in the same order as it submits them
     300     * in case we can not satisfy any of the above, we should introduce multiple command buffers */
     301    CRVBOXHGSMIHDR * pHdr;
     302    VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags;
     303    int rc;
     304    fFlags.Value = 0;
     305    fFlags.bDiscard = 1;
     306    rc = pClient->pCmdBuffer->pfnLock(pClient->pCmdBuffer, 0, cbBuffer, fFlags, (void**)&pHdr);
     307    AssertRC(rc);
     308    if (RT_SUCCESS(rc))
     309        return pHdr;
     310
     311    crWarning("Failed to Lock the command buffer of size(%d), rc(%d)\n", cbBuffer, rc);
     312    return NULL;
     313}
     314
     315static CRVBOXHGSMIHDR *_crVBoxHGSMICmdBufferLockRo(PCRVBOXHGSMI_CLIENT pClient, uint32_t cbBuffer)
     316{
     317    /* in theory it is OK to use one cmd buffer for asynch cmd submission
     318     * because bDiscard flag should result in allocating a new memory backend if the
     319     * allocation is still in use.
     320     * However, NOTE: since one and the same semaphore synch event is used for completion notification,
     321     * for the notification mechanism working as expected
     322     * 1. host must complete commands in the same order as it receives them
     323     * (to avoid situation when guest receives notification for another command completion)
     324     * 2. guest must eventually wait for command completion unless he specified bDoNotSignalCompletion
     325     * 3. guest must wait for command completion in the same order as it submits them
     326     * in case we can not satisfy any of the above, we should introduce multiple command buffers */
     327    CRVBOXHGSMIHDR * pHdr;
     328    VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags;
     329    int rc;
     330    fFlags.Value = 0;
     331    fFlags.bReadOnly = 1;
     332    rc = pClient->pCmdBuffer->pfnLock(pClient->pCmdBuffer, 0, cbBuffer, fFlags, (void**)&pHdr);
     333    AssertRC(rc);
     334    if (RT_FAILURE(rc))
     335        crWarning("Failed to Lock the command buffer of size(%d), rc(%d)\n", cbBuffer, rc);
     336    return pHdr;
     337}
     338
     339static void _crVBoxHGSMICmdBufferUnlock(PCRVBOXHGSMI_CLIENT pClient)
     340{
     341    int rc = pClient->pCmdBuffer->pfnUnlock(pClient->pCmdBuffer);
     342    AssertRC(rc);
     343    if (RT_FAILURE(rc))
     344        crWarning("Failed to Unlock the command buffer rc(%d)\n", rc);
     345}
     346
     347static int32_t _crVBoxHGSMICmdBufferGetRc(PCRVBOXHGSMI_CLIENT pClient)
     348{
     349    CRVBOXHGSMIHDR * pHdr;
     350    VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags;
     351    int rc;
     352
     353    fFlags.Value = 0;
     354    fFlags.bReadOnly = 1;
     355    rc = pClient->pCmdBuffer->pfnLock(pClient->pCmdBuffer, 0, sizeof (*pHdr), fFlags, (void**)&pHdr);
     356    AssertRC(rc);
     357    if (RT_FAILURE(rc))
     358    {
     359        crWarning("Failed to Lock the command buffer of size(%d), rc(%d)\n", sizeof (*pHdr), rc);
     360        return rc;
     361    }
     362
     363    rc = pHdr->result;
     364    AssertRC(rc);
     365    pClient->pCmdBuffer->pfnUnlock(pClient->pCmdBuffer);
     366
     367    return rc;
     368}
     369
     370DECLINLINE(PVBOXUHGSMI_BUFFER) _crVBoxHGSMIRecvBufGet(PCRVBOXHGSMI_CLIENT pClient)
     371{
     372    if (pClient->pvHGBuffer)
     373    {
     374        int rc = pClient->pHGBuffer->pfnUnlock(pClient->pHGBuffer);
     375        if (RT_FAILURE(rc))
     376        {
     377            return NULL;
     378        }
     379        pClient->pvHGBuffer = NULL;
     380    }
     381    return pClient->pHGBuffer;
     382}
     383
     384DECLINLINE(void*) _crVBoxHGSMIRecvBufData(PCRVBOXHGSMI_CLIENT pClient, uint32_t cbBuffer)
     385{
     386    VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags;
     387    int rc;
     388    Assert(!pClient->pvHGBuffer);
     389    fFlags.Value = 0;
     390    rc = pClient->pHGBuffer->pfnLock(pClient->pHGBuffer, 0, cbBuffer, fFlags, &pClient->pvHGBuffer);
     391    AssertRC(rc);
     392    if (RT_SUCCESS(rc))
     393    {
     394        return pClient->pvHGBuffer;
     395    }
     396    return NULL;
     397}
     398
     399DECLINLINE(void) _crVBoxHGSMIFillCmd(VBOXUHGSMI_BUFFER_SUBMIT *pSubm, PCRVBOXHGSMI_CLIENT pClient, uint32_t cbData)
     400{
     401    pSubm->pBuf = pClient->pCmdBuffer;
     402    pSubm->offData = 0;
     403    pSubm->cbData = cbData;
     404    pSubm->fFlags.Value = 0;
     405    pSubm->fFlags.bDoNotRetire = 1;
     406//    pSubm->fFlags.bDoNotSignalCompletion = 1; /* <- we do not need that actually since
     407//                                                       * in case we want completion,
     408//                                                       * we will block in _crVBoxHGSMICmdBufferGetRc (when locking the buffer)
     409//                                                       * which is needed for getting the result */
     410}
     411
     412#ifdef RT_OS_WINDOWS
     413#define CRVBOXHGSMI_BUF_WAIT(_pBub) WaitForSingleObject((_pBub)->hSynch, INFINITE);
     414#else
     415# error "Port Me!!"
     416#endif
     417
     418DECLINLINE(void) _crVBoxHGSMIWaitCmd(PCRVBOXHGSMI_CLIENT pClient)
     419{
     420    int rc = CRVBOXHGSMI_BUF_WAIT(pClient->pCmdBuffer);
     421    Assert(rc == 0);
     422}
    201423#endif
    202424
     
    8431065
    8441066        hgcm_buffer->len = len;
    845 
    8461067        _crVBoxHGCMReadBytes(conn, hgcm_buffer + 1, len);
    8471068
     
    11411362}
    11421363
     1364#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
     1365DECLCALLBACK(HVBOXCRHGSMI_CLIENT) _crVBoxHGSMIClientCreate(PVBOXUHGSMI pHgsmi)
     1366{
     1367    PCRVBOXHGSMI_CLIENT pClient = crAlloc(sizeof (CRVBOXHGSMI_CLIENT));
     1368
     1369    if (pClient)
     1370    {
     1371        int rc;
     1372        pClient->pHgsmi = pHgsmi;
     1373        rc = pHgsmi->pfnBufferCreate(pHgsmi, CRVBOXHGSMI_PAGE_ALIGN(1),
     1374                                VBOXUHGSMI_SYNCHOBJECT_TYPE_EVENT,
     1375                                NULL,
     1376                                &pClient->pCmdBuffer);
     1377        AssertRC(rc);
     1378        if (RT_SUCCESS(rc))
     1379        {
     1380            rc = pHgsmi->pfnBufferCreate(pHgsmi, CRVBOXHGSMI_PAGE_ALIGN(0x800000),
     1381                                            VBOXUHGSMI_SYNCHOBJECT_TYPE_EVENT,
     1382                                            NULL,
     1383                                            &pClient->pHGBuffer);
     1384            AssertRC(rc);
     1385            if (RT_SUCCESS(rc))
     1386            {
     1387                pClient->pvHGBuffer = NULL;
     1388                pClient->bufpool = crBufferPoolInit(16);
     1389                return (HVBOXCRHGSMI_CLIENT) pClient;
     1390            }
     1391        }
     1392    }
     1393
     1394    return NULL;
     1395}
     1396
     1397DECLCALLBACK(void) _crVBoxHGSMIClientDestroy(HVBOXCRHGSMI_CLIENT hClient)
     1398{
     1399    Assert(0);
     1400
     1401    /* @todo */
     1402}
     1403
     1404bool _crVBoxHGSMIInit()
     1405{
     1406    int bHasHGSMI = -1;
     1407
     1408    if (bHasHGSMI < 0)
     1409    {
     1410        int rc;
     1411        VBOXCRHGSMI_CALLBACKS Callbacks;
     1412        Callbacks.pfnClientCreate = _crVBoxHGSMIClientCreate;
     1413        Callbacks.pfnClientDestroy = _crVBoxHGSMIClientDestroy;
     1414        rc = VBoxCrHgsmiInit(&Callbacks);
     1415        AssertRC(rc);
     1416        if (RT_SUCCESS(rc))
     1417            bHasHGSMI = 1;
     1418        else
     1419            bHasHGSMI = 0;
     1420    }
     1421
     1422    Assert(bHasHGSMI);
     1423
     1424    return bHasHGSMI;
     1425}
     1426
     1427void _crVBoxHGSMITearDown()
     1428{
     1429    VBoxCrHgsmiTerm();
     1430}
     1431
     1432static void *_crVBoxHGSMIDoAlloc(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient)
     1433{
     1434    PVBOXUHGSMI_BUFFER buf;
     1435    CRVBOXHGCMBUFFER *pData = NULL;
     1436    uint32_t cbSize = conn->buffer_size;
     1437    int rc;
     1438
     1439    buf = _crVBoxHGSMIBufAlloc(pClient, CRVBOXHGSMI_BUF_SIZE(cbSize));
     1440    Assert(buf);
     1441    if (buf)
     1442    {
     1443        VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags;
     1444        buf->pvUserData = pClient;
     1445        fFlags.Value = 0;
     1446        fFlags.bDiscard = 1;
     1447        rc = buf->pfnLock(buf, 0, CRVBOXHGSMI_BUF_LOCK_SIZE(cbSize), fFlags, (void**)&pData);
     1448        if (RT_SUCCESS(rc))
     1449        {
     1450            pData->magic = CR_VBOXHGCM_BUFFER_MAGIC;
     1451            pData->kind = CR_VBOXHGCM_UHGSMI_BUFFER;
     1452            pData->pBuffer = buf;
     1453        }
     1454        else
     1455        {
     1456            crWarning("Failed to Lock the buffer, rc(%d)\n", rc);
     1457        }
     1458        return CRVBOXHGSMI_BUF_DATA(pData);
     1459    }
     1460
     1461    /* fall back */
     1462    return _crVBoxHGCMAlloc(conn);
     1463}
     1464
     1465static void _crVBoxHGSMIFree(CRConnection *conn, void *buf)
     1466{
     1467    CRVBOXHGCMBUFFER *hgcm_buffer = (CRVBOXHGCMBUFFER *) buf - 1;
     1468
     1469    CRASSERT(hgcm_buffer->magic == CR_VBOXHGCM_BUFFER_MAGIC);
     1470
     1471    if (hgcm_buffer->kind == CR_VBOXHGCM_UHGSMI_BUFFER)
     1472    {
     1473        PVBOXUHGSMI_BUFFER pBuf = _crVBoxHGSMIBufFromHdr(hgcm_buffer);
     1474        PCRVBOXHGSMI_CLIENT pClient = (PCRVBOXHGSMI_CLIENT)pBuf->pvUserData;
     1475        pBuf->pfnUnlock(pBuf);
     1476        _crVBoxHGSMIBufFree(pClient, pBuf);
     1477    }
     1478    else
     1479    {
     1480        _crVBoxHGCMFree(conn, buf);
     1481    }
     1482}
     1483
     1484static void *crVBoxHGSMIAlloc(CRConnection *conn)
     1485{
     1486    PCRVBOXHGSMI_CLIENT pClient;
     1487    void *pvBuf;
     1488
     1489    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
     1490
     1491    pClient = _crVBoxHGSMIClientGet(conn);
     1492    if (pClient)
     1493    {
     1494        pvBuf = _crVBoxHGSMIDoAlloc(conn, pClient);
     1495        Assert(pvBuf);
     1496    }
     1497    else
     1498    {
     1499        pvBuf = _crVBoxHGCMAlloc(conn);
     1500    }
     1501
     1502    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     1503
     1504    return pvBuf;
     1505}
     1506
     1507static void crVBoxHGSMIFree(CRConnection *conn, void *buf)
     1508{
     1509    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
     1510    _crVBoxHGSMIFree(conn, buf);
     1511    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     1512}
     1513
     1514static void _crVBoxHGSMIPollHost(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient)
     1515{
     1516    CRVBOXHGSMIREAD *parms = (CRVBOXHGSMIREAD *)_crVBoxHGSMICmdBufferLock(pClient, sizeof (*parms));
     1517    int rc;
     1518    VBOXUHGSMI_BUFFER_SUBMIT aSubmit[2];
     1519    PVBOXUHGSMI_BUFFER pRecvBuffer;
     1520    uint32_t cbBuffer;
     1521
     1522    Assert(parms);
     1523
     1524    parms->hdr.result      = VERR_WRONG_ORDER;
     1525    parms->hdr.u32ClientID = conn->u32ClientID;
     1526    parms->hdr.u32Function = SHCRGL_GUEST_FN_READ;
     1527//    parms->hdr.u32Reserved = 0;
     1528
     1529    CRASSERT(!conn->pBuffer); //make sure there's no data to process
     1530    parms->iBuffer = 1;
     1531    parms->cbBuffer = 0;
     1532
     1533    _crVBoxHGSMICmdBufferUnlock(pClient);
     1534
     1535    pRecvBuffer = _crVBoxHGSMIRecvBufGet(pClient);
     1536    Assert(pRecvBuffer);
     1537    if (!pRecvBuffer)
     1538        return;
     1539
     1540    _crVBoxHGSMIFillCmd(&aSubmit[0], pClient, sizeof (*parms));
     1541
     1542    aSubmit[1].pBuf = pRecvBuffer;
     1543    aSubmit[1].offData = 0;
     1544    aSubmit[1].cbData = pRecvBuffer->cbBuffer;
     1545    aSubmit[1].fFlags.Value = 0;
     1546    aSubmit[1].fFlags.bHostWriteOnly = 1;
     1547
     1548    rc = pClient->pHgsmi->pfnBufferSubmitAsynch(pClient->pHgsmi, aSubmit, 2);
     1549    AssertRC(rc);
     1550    if (RT_FAILURE(rc))
     1551    {
     1552        crWarning("pfnBufferSubmitAsynch failed with %d \n", rc);
     1553        return;
     1554    }
     1555
     1556    _crVBoxHGSMIWaitCmd(pClient);
     1557
     1558    parms = (CRVBOXHGSMIREAD *)_crVBoxHGSMICmdBufferLockRo(pClient, sizeof (*parms));
     1559    Assert(parms);
     1560    if (!parms)
     1561    {
     1562        crWarning("_crVBoxHGSMICmdBufferLockRo failed\n");
     1563        return;
     1564    }
     1565
     1566    if (RT_SUCCESS(parms->hdr.result))
     1567        cbBuffer = parms->cbBuffer;
     1568    else
     1569        cbBuffer = 0;
     1570
     1571    _crVBoxHGSMICmdBufferUnlock(pClient);
     1572
     1573    if (cbBuffer)
     1574    {
     1575        void *pvData = _crVBoxHGSMIRecvBufData(pClient, cbBuffer);
     1576        Assert(pvData);
     1577        if (pvData)
     1578        {
     1579            conn->pBuffer  = pvData;
     1580            conn->cbBuffer = cbBuffer;
     1581        }
     1582    }
     1583}
     1584
     1585static void _crVBoxHGSMIReadExact(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient)
     1586{
     1587    _crVBoxHGSMIPollHost(conn, pClient);
     1588
     1589    if (conn->cbBuffer)
     1590        _crVBoxHGCMReceiveMessage(conn);
     1591}
     1592
     1593/* Same as crVBoxHGCMWriteExact, but combined with read of writeback data.
     1594 * This halves the number of HGCM calls we do,
     1595 * most likely crVBoxHGCMPollHost shouldn't be called at all now.
     1596 */
     1597static void
     1598_crVBoxHGSMIWriteReadExact(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient, void *buf, uint32_t offBuffer, unsigned int len, bool bIsBuffer)
     1599{
     1600    CRVBOXHGSMIWRITEREAD *parms = (CRVBOXHGSMIWRITEREAD*)_crVBoxHGSMICmdBufferLock(pClient, sizeof (*parms));
     1601    int rc;
     1602    VBOXUHGSMI_BUFFER_SUBMIT aSubmit[3];
     1603    PVBOXUHGSMI_BUFFER pBuf = NULL;
     1604    VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags;
     1605//    uint32_t cbBuffer;
     1606
     1607    parms->hdr.result      = VERR_WRONG_ORDER;
     1608    parms->hdr.u32ClientID = conn->u32ClientID;
     1609    parms->hdr.u32Function = SHCRGL_GUEST_FN_WRITE_READ;
     1610//    parms->hdr.u32Reserved = 0;
     1611
     1612    parms->iBuffer = 1;
     1613
     1614    CRASSERT(!conn->pBuffer); //make sure there's no data to process
     1615    parms->iWriteback = 2;
     1616    parms->cbWriteback = 0;
     1617
     1618    _crVBoxHGSMICmdBufferUnlock(pClient);
     1619
     1620    if (!bIsBuffer)
     1621    {
     1622        void *pvBuf;
     1623        pBuf = _crVBoxHGSMIBufAlloc(pClient, len);
     1624        Assert(pBuf);
     1625        if (!pBuf)
     1626        {
     1627            /* fallback */
     1628            crVBoxHGCMWriteReadExact(conn, buf, len, CR_VBOXHGCM_USERALLOCATED);
     1629            return;
     1630        }
     1631
     1632        Assert(!offBuffer);
     1633
     1634        offBuffer = 0;
     1635        fFlags.Value = 0;
     1636        fFlags.bDiscard = 1;
     1637        fFlags.bWriteOnly = 1;
     1638        rc = pBuf->pfnLock(pBuf, 0, len, fFlags, &pvBuf);
     1639        AssertRC(rc);
     1640        if (RT_SUCCESS(rc))
     1641        {
     1642            memcpy(pvBuf, buf, len);
     1643            rc = pBuf->pfnUnlock(pBuf);
     1644            AssertRC(rc);
     1645            CRASSERT(RT_SUCCESS(rc));
     1646        }
     1647        else
     1648        {
     1649            _crVBoxHGSMIBufFree(pClient, pBuf);
     1650            /* fallback */
     1651            crVBoxHGCMWriteReadExact(conn, buf, len, CR_VBOXHGCM_USERALLOCATED);
     1652            return;
     1653        }
     1654    }
     1655    else
     1656    {
     1657        pBuf = (PVBOXUHGSMI_BUFFER)buf;
     1658    }
     1659
     1660    do
     1661    {
     1662        PVBOXUHGSMI_BUFFER pRecvBuffer = _crVBoxHGSMIRecvBufGet(pClient);
     1663        Assert(pRecvBuffer);
     1664        if (!pRecvBuffer)
     1665        {
     1666            break;
     1667        }
     1668
     1669        _crVBoxHGSMIFillCmd(&aSubmit[0], pClient, sizeof (*parms));
     1670
     1671        aSubmit[1].pBuf = pBuf;
     1672        aSubmit[1].offData = offBuffer;
     1673        aSubmit[1].cbData = len;
     1674        aSubmit[1].fFlags.Value = 0;
     1675        aSubmit[1].fFlags.bHostReadOnly = 1;
     1676
     1677        aSubmit[2].pBuf = pRecvBuffer;
     1678        aSubmit[2].offData = 0;
     1679        aSubmit[2].cbData = pRecvBuffer->cbBuffer;
     1680        aSubmit[2].fFlags.Value = 0;
     1681
     1682        rc = pClient->pHgsmi->pfnBufferSubmitAsynch(pClient->pHgsmi, aSubmit, 3);
     1683        AssertRC(rc);
     1684        if (RT_FAILURE(rc))
     1685        {
     1686            crWarning("pfnBufferSubmitAsynch failed with %d \n", rc);
     1687            break;
     1688        }
     1689
     1690        _crVBoxHGSMIWaitCmd(pClient);
     1691
     1692        parms = (CRVBOXHGSMIWRITEREAD *)_crVBoxHGSMICmdBufferLockRo(pClient, sizeof (*parms));
     1693        Assert(parms);
     1694        if (parms)
     1695        {
     1696            uint32_t cbWriteback = parms->cbWriteback;
     1697            rc = parms->hdr.result;
     1698            _crVBoxHGSMICmdBufferUnlock(pClient);
     1699#ifdef DEBUG
     1700            parms = NULL;
     1701#endif
     1702            if (RT_SUCCESS(rc))
     1703            {
     1704                if (cbWriteback)
     1705                {
     1706                    void *pvData = _crVBoxHGSMIRecvBufData(pClient, cbWriteback);
     1707                    Assert(pvData);
     1708                    if (pvData)
     1709                    {
     1710                        conn->pBuffer  = pvData;
     1711                        conn->cbBuffer = cbWriteback;
     1712                        _crVBoxHGCMReceiveMessage(conn);
     1713                    }
     1714                }
     1715            }
     1716            else if (VERR_BUFFER_OVERFLOW == rc)
     1717            {
     1718                PVBOXUHGSMI_BUFFER pOldBuf = pClient->pHGBuffer;
     1719                Assert(!pClient->pvHGBuffer);
     1720                CRASSERT(cbWriteback>pClient->pHGBuffer->cbBuffer);
     1721                crDebug("Reallocating host buffer from %d to %d bytes", conn->cbHostBufferAllocated, cbWriteback);
     1722
     1723                rc = pClient->pHgsmi->pfnBufferCreate(pClient->pHgsmi, CRVBOXHGSMI_PAGE_ALIGN(cbWriteback),
     1724                                VBOXUHGSMI_SYNCHOBJECT_TYPE_NONE, NULL, &pClient->pHGBuffer);
     1725                AssertRC(rc);
     1726                CRASSERT(RT_SUCCESS(rc));
     1727                if (RT_SUCCESS(rc))
     1728                {
     1729                    rc = pOldBuf->pfnDestroy(pOldBuf);
     1730                    CRASSERT(RT_SUCCESS(rc));
     1731
     1732                    _crVBoxHGSMIReadExact(conn, pClient/*, cbWriteback*/);
     1733                }
     1734                else
     1735                {
     1736                    crFree(conn->pHostBuffer);
     1737                    conn->cbHostBufferAllocated = cbWriteback;
     1738                    conn->pHostBuffer = crAlloc(conn->cbHostBufferAllocated);
     1739                    crVBoxHGCMReadExact(conn, NULL, cbWriteback);
     1740                }
     1741            }
     1742            else
     1743            {
     1744                crWarning("SHCRGL_GUEST_FN_WRITE_READ (%i) failed with %x \n", len, rc);
     1745            }
     1746        }
     1747        else
     1748        {
     1749            crWarning("_crVBoxHGSMICmdBufferLockRo failed\n");
     1750            break;
     1751        }
     1752    } while (0);
     1753
     1754    if (!bIsBuffer)
     1755        _crVBoxHGSMIBufFree(pClient, pBuf);
     1756
     1757    return;
     1758}
     1759
     1760static void _crVBoxHGSMIWriteExact(CRConnection *conn, PCRVBOXHGSMI_CLIENT pClient, PVBOXUHGSMI_BUFFER pBuf, uint32_t offStart, unsigned int len)
     1761{
     1762    int rc;
     1763    int32_t callRes;
     1764    VBOXUHGSMI_BUFFER_SUBMIT aSubmit[2];
     1765
     1766#ifdef IN_GUEST
     1767    if (conn->u32InjectClientID)
     1768    {
     1769        CRVBOXHGSMIINJECT *parms = (CRVBOXHGSMIINJECT *)_crVBoxHGSMICmdBufferLock(pClient, sizeof (*parms));
     1770        Assert(parms);
     1771        if (!parms)
     1772        {
     1773            return;
     1774        }
     1775
     1776        parms->hdr.result      = VERR_WRONG_ORDER;
     1777        parms->hdr.u32ClientID = conn->u32ClientID;
     1778        parms->hdr.u32Function = SHCRGL_GUEST_FN_INJECT;
     1779//        parms->hdr.u32Reserved = 0;
     1780
     1781        parms->u32ClientID = conn->u32InjectClientID;
     1782
     1783        parms->iBuffer = 1;
     1784        _crVBoxHGSMICmdBufferUnlock(pClient);
     1785
     1786        _crVBoxHGSMIFillCmd(&aSubmit[0], pClient, sizeof (*parms));
     1787
     1788        aSubmit[1].pBuf = pBuf;
     1789        aSubmit[1].offData = offStart;
     1790        aSubmit[1].cbData = len;
     1791        aSubmit[1].fFlags.Value = 0;
     1792        aSubmit[1].fFlags.bHostReadOnly = 1;
     1793
     1794        rc = pClient->pHgsmi->pfnBufferSubmitAsynch(pClient->pHgsmi, aSubmit, 2);
     1795        AssertRC(rc);
     1796        if (RT_SUCCESS(rc))
     1797        {
     1798            _crVBoxHGSMIWaitCmd(pClient);
     1799                /* @todo: do we need to wait for completion actually?
     1800                 * NOTE: in case we do not need completion,
     1801                 * we MUST specify bDoNotSignalCompletion flag for the command buffer */
     1802//                CRVBOXHGSMI_BUF_WAIT(pClient->pCmdBuffer);
     1803
     1804            callRes = _crVBoxHGSMICmdBufferGetRc(pClient);
     1805        }
     1806    }
     1807    else
     1808#endif
     1809    {
     1810        CRVBOXHGSMIWRITE * parms = (CRVBOXHGSMIWRITE *)_crVBoxHGSMICmdBufferLock(pClient, sizeof (*parms));;
     1811
     1812        parms->hdr.result      = VERR_WRONG_ORDER;
     1813        parms->hdr.u32ClientID = conn->u32ClientID;
     1814        parms->hdr.u32Function = SHCRGL_GUEST_FN_WRITE;
     1815//        parms->hdr.u32Reserved = 0;
     1816
     1817        parms->iBuffer = 1;
     1818        _crVBoxHGSMICmdBufferUnlock(pClient);
     1819
     1820        _crVBoxHGSMIFillCmd(&aSubmit[0], pClient, sizeof (*parms));
     1821
     1822        aSubmit[1].pBuf = pBuf;
     1823        aSubmit[1].offData = offStart;
     1824        aSubmit[1].cbData = len;
     1825        aSubmit[1].fFlags.Value = 0;
     1826        aSubmit[1].fFlags.bHostReadOnly = 1;
     1827
     1828        rc = pClient->pHgsmi->pfnBufferSubmitAsynch(pClient->pHgsmi, aSubmit, 2);
     1829        AssertRC(rc);
     1830        if (RT_SUCCESS(rc))
     1831        {
     1832            _crVBoxHGSMIWaitCmd(pClient);
     1833                /* @todo: do we need to wait for completion actually?
     1834                 * NOTE: in case we do not need completion,
     1835                 * we MUST specify bDoNotSignalCompletion flag for the command buffer */
     1836//                CRVBOXHGSMI_BUF_WAIT(pClient->pCmdBuffer);
     1837
     1838            callRes = _crVBoxHGSMICmdBufferGetRc(pClient);
     1839        }
     1840    }
     1841
     1842    if (RT_FAILURE(rc) || RT_FAILURE(callRes))
     1843    {
     1844        crWarning("SHCRGL_GUEST_FN_WRITE failed with %x %x\n", rc, callRes);
     1845    }
     1846}
     1847
     1848static void crVBoxHGSMISend(CRConnection *conn, void **bufp,
     1849                           const void *start, unsigned int len)
     1850{
     1851    PCRVBOXHGSMI_CLIENT pClient;
     1852    PVBOXUHGSMI_BUFFER pBuf;
     1853    CRVBOXHGCMBUFFER *hgcm_buffer;
     1854
     1855    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
     1856
     1857    if (!bufp) /* We're sending a user-allocated buffer. */
     1858    {
     1859        pClient = _crVBoxHGSMIClientGet(conn);
     1860        if (pClient)
     1861        {
     1862#ifndef IN_GUEST
     1863                //@todo remove temp buffer allocation in unpacker
     1864                /* we're at the host side, so just store data until guest polls us */
     1865                _crVBoxHGCMWriteBytes(conn, start, len);
     1866#else
     1867            CRASSERT(!conn->u32InjectClientID);
     1868            crDebug("SHCRGL: sending userbuf with %d bytes\n", len);
     1869            _crVBoxHGSMIWriteReadExact(conn, pClient, (void*)start, 0, len, false);
     1870#endif
     1871            VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     1872            return;
     1873        }
     1874
     1875        /* fallback */
     1876        crVBoxHGCMSend(conn, bufp, start, len);
     1877        VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     1878        return;
     1879    }
     1880
     1881    hgcm_buffer = (CRVBOXHGCMBUFFER *) *bufp - 1;
     1882    Assert(hgcm_buffer->magic == CR_VBOXHGCM_BUFFER_MAGIC);
     1883    if (hgcm_buffer->kind != CR_VBOXHGCM_UHGSMI_BUFFER)
     1884    {
     1885        /* fallback */
     1886        crVBoxHGCMSend(conn, bufp, start, len);
     1887        VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     1888        return;
     1889    }
     1890
     1891    /* The region [start .. start + len + 1] lies within a buffer that
     1892     * was allocated with crVBoxHGCMAlloc() and can be put into the free
     1893     * buffer pool when we're done sending it.
     1894     */
     1895
     1896    pBuf = _crVBoxHGSMIBufFromHdr(hgcm_buffer);
     1897    Assert(pBuf);
     1898    if (!pBuf)
     1899    {
     1900        crVBoxHGCMSend(conn, bufp, start, len);
     1901        VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     1902        return;
     1903    }
     1904
     1905    pClient = (PCRVBOXHGSMI_CLIENT)pBuf->pvUserData;
     1906
     1907    /* Length would be passed as part of HGCM pointer description
     1908     * No need to prepend it to the buffer
     1909     */
     1910#ifdef IN_GUEST
     1911    if (conn->u32InjectClientID)
     1912    {
     1913        _crVBoxHGSMIWriteExact(conn, pClient, pBuf, CRVBOXHGSMI_BUF_OFFSET(start, *bufp) + CRVBOXHGSMI_BUF_HDR_SIZE(), len);
     1914    }
     1915    else
     1916#endif
     1917    {
     1918        _crVBoxHGSMIWriteReadExact(conn, pClient, pBuf, CRVBOXHGSMI_BUF_OFFSET(start, *bufp) + CRVBOXHGSMI_BUF_HDR_SIZE(), len, true);
     1919    }
     1920
     1921    /* Reclaim this pointer for reuse */
     1922    _crVBoxHGSMIBufFree(pClient, pBuf);
     1923    /* Since the buffer's now in the 'free' buffer pool, the caller can't
     1924     * use it any more.  Setting bufp to NULL will make sure the caller
     1925     * doesn't try to re-use the buffer.
     1926     */
     1927    *bufp = NULL;
     1928
     1929    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     1930}
     1931
     1932static void crVBoxHGSMIWriteExact(CRConnection *conn, const void *buf, unsigned int len)
     1933{
     1934    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
     1935    Assert(0);
     1936
     1937    CRASSERT(0);
     1938//    PCRVBOXHGSMI_CLIENT pClient;
     1939//    PVBOXUHGSMI_BUFFER pBuf = _crVBoxHGSMIBufFromMemPtr(buf);
     1940//    if (!pBuf)
     1941//        return;
     1942//    pClient = (PCRVBOXHGSMI_CLIENT)pBuf->pvUserData;
     1943//    _crVBoxHGSMIWriteExact(conn, pClient, pBuf, 0, len);
     1944//    _crVBoxHGSMIBufFree(pClient, pBuf);
     1945    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     1946}
     1947
     1948static void crVBoxHGSMISingleRecv(CRConnection *conn, void *buf, unsigned int len)
     1949{
     1950//    PCRVBOXHGSMI_CLIENT pClient;
     1951//    PVBOXUHGSMI_BUFFER pBuf;
     1952    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
     1953//    pBuf = _crVBoxHGSMIBufFromMemPtr(buf);
     1954//    Assert(pBuf);
     1955    Assert(0);
     1956    CRASSERT(0);
     1957//    if (!pBuf)
     1958//    {
     1959//        VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     1960//        return;
     1961//    }
     1962//    pClient = (PCRVBOXHGSMI_CLIENT)pBuf->pvUserData;
     1963//    _crVBoxHGSMIReadExact(conn, pClient);
     1964    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     1965}
     1966
     1967static void crVBoxHGSMIReceiveMessage(CRConnection *conn)
     1968{
     1969    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
     1970
     1971    Assert(0);
     1972
     1973    _crVBoxHGCMReceiveMessage(conn);
     1974    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     1975}
     1976
     1977/*
     1978 * Called on host side only, to "accept" client connection
     1979 */
     1980static void crVBoxHGSMIAccept( CRConnection *conn, const char *hostname, unsigned short port )
     1981{
     1982    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
     1983    Assert(0);
     1984
     1985    CRASSERT(conn && conn->pHostBuffer);
     1986#ifdef IN_GUEST
     1987    CRASSERT(FALSE);
     1988#endif
     1989    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     1990}
     1991
     1992static int crVBoxHGSMIDoConnect( CRConnection *conn )
     1993{
     1994    return crVBoxHGCMDoConnect(conn);
     1995}
     1996
     1997static void crVBoxHGSMIDoDisconnect( CRConnection *conn )
     1998{
     1999    crVBoxHGCMDoDisconnect(conn);
     2000}
     2001
     2002static void crVBoxHGSMIInstantReclaim(CRConnection *conn, CRMessage *mess)
     2003{
     2004    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
     2005    Assert(0);
     2006
     2007    _crVBoxHGSMIFree(conn, mess);
     2008    CRASSERT(FALSE);
     2009
     2010    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     2011}
     2012
     2013static void crVBoxHGSMIHandleNewMessage( CRConnection *conn, CRMessage *msg, unsigned int len )
     2014{
     2015    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
     2016    Assert(0);
     2017
     2018    CRASSERT(FALSE);
     2019    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     2020}
     2021#endif
     2022
    11432023void crVBoxHGCMInit(CRNetReceiveFuncList *rfl, CRNetCloseFuncList *cfl, unsigned int mtu)
    11442024{
     
    11552035
    11562036    g_crvboxhgcm.initialized = 1;
     2037
     2038#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
     2039    g_crvboxhgcm.bHgsmiOn = _crVBoxHGSMIInit();
     2040#endif
    11572041
    11582042    g_crvboxhgcm.num_conns = 0;
     
    12412125    g_crvboxhgcm.conns = NULL;
    12422126
     2127#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
     2128    if (g_crvboxhgcm.bHgsmiOn)
     2129    {
     2130        _crVBoxHGSMITearDown();
     2131    }
     2132#endif
     2133
    12432134#ifdef RT_OS_WINDOWS
    12442135    if (g_crvboxhgcm.pDirectDraw)
     
    12582149    CRASSERT(g_crvboxhgcm.initialized);
    12592150
    1260     conn->type = CR_VBOXHGCM;
    1261     conn->Alloc = crVBoxHGCMAlloc;
    1262     conn->Send = crVBoxHGCMSend;
    1263     conn->SendExact = crVBoxHGCMWriteExact;
    1264     conn->Recv = crVBoxHGCMSingleRecv;
    1265     conn->RecvMsg = crVBoxHGCMReceiveMessage;
    1266     conn->Free = crVBoxHGCMFree;
    1267     conn->Accept = crVBoxHGCMAccept;
    1268     conn->Connect = crVBoxHGCMDoConnect;
    1269     conn->Disconnect = crVBoxHGCMDoDisconnect;
    1270     conn->InstantReclaim = crVBoxHGCMInstantReclaim;
    1271     conn->HandleNewMessage = crVBoxHGCMHandleNewMessage;
     2151#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
     2152    if (g_crvboxhgcm.bHgsmiOn)
     2153    {
     2154        conn->type = CR_VBOXHGCM;
     2155        conn->Alloc = crVBoxHGSMIAlloc;
     2156        conn->Send = crVBoxHGSMISend;
     2157        conn->SendExact = crVBoxHGSMIWriteExact;
     2158        conn->Recv = crVBoxHGSMISingleRecv;
     2159        conn->RecvMsg = crVBoxHGSMIReceiveMessage;
     2160        conn->Free = crVBoxHGSMIFree;
     2161        conn->Accept = crVBoxHGSMIAccept;
     2162        conn->Connect = crVBoxHGSMIDoConnect;
     2163        conn->Disconnect = crVBoxHGSMIDoDisconnect;
     2164        conn->InstantReclaim = crVBoxHGSMIInstantReclaim;
     2165        conn->HandleNewMessage = crVBoxHGSMIHandleNewMessage;
     2166    }
     2167    else
     2168#endif
     2169    {
     2170        conn->type = CR_VBOXHGCM;
     2171        conn->Alloc = crVBoxHGCMAlloc;
     2172        conn->Send = crVBoxHGCMSend;
     2173        conn->SendExact = crVBoxHGCMWriteExact;
     2174        conn->Recv = crVBoxHGCMSingleRecv;
     2175        conn->RecvMsg = crVBoxHGCMReceiveMessage;
     2176        conn->Free = crVBoxHGCMFree;
     2177        conn->Accept = crVBoxHGCMAccept;
     2178        conn->Connect = crVBoxHGCMDoConnect;
     2179        conn->Disconnect = crVBoxHGCMDoDisconnect;
     2180        conn->InstantReclaim = crVBoxHGCMInstantReclaim;
     2181        conn->HandleNewMessage = crVBoxHGCMHandleNewMessage;
     2182    }
    12722183    conn->index = g_crvboxhgcm.num_conns;
    12732184    conn->sizeof_buffer_header = sizeof(CRVBOXHGCMBUFFER);
     
    13212232        if (!conn->pBuffer)
    13222233        {
    1323             crVBoxHGCMPollHost(conn);
     2234#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
     2235            PCRVBOXHGSMI_CLIENT pClient;
     2236            if (g_crvboxhgcm.bHgsmiOn && !!(pClient = _crVBoxHGSMIClientGet(conn)))
     2237            {
     2238                _crVBoxHGSMIPollHost(conn, pClient);
     2239            }
     2240            else
     2241#endif
     2242            {
     2243                crVBoxHGCMPollHost(conn);
     2244            }
    13242245        }
    13252246    }
Note: See TracChangeset for help on using the changeset viewer.

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