VirtualBox

Ignore:
Timestamp:
Feb 18, 2013 5:02:47 PM (12 years ago)
Author:
vboxsync
Message:

crOpenGL: OSX backend rework; oddscreen rendering generalization

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/OpenGL/util/vreg.cpp

    r44596 r44740  
    2020#include <iprt/err.h>
    2121#include <iprt/assert.h>
     22#include <iprt/asm.h>
    2223
    2324#ifndef IN_RING0
     
    2829#endif
    2930
    30 typedef struct VBOXVR_REG
    31 {
    32     RTLISTNODE ListEntry;
    33     RTRECT Rect;
    34 } VBOXVR_REG, *PVBOXVR_REG;
    35 
    36 #define PVBOXVR_REG_FROM_ENTRY(_pEntry) ((PVBOXVR_REG)(((uint8_t*)(_pEntry)) - RT_OFFSETOF(VBOXVR_REG, ListEntry)))
    37 
    3831#ifdef DEBUG_misha
    3932//# define VBOXVDBG_VR_LAL_DISABLE
     
    4134
    4235#ifndef VBOXVDBG_VR_LAL_DISABLE
     36static volatile int32_t g_cVBoxVrInits = 0;
    4337static RTMEMCACHE g_VBoxVrLookasideList;
    4438#endif
     
    8276VBOXVREGDECL(int) VBoxVrInit()
    8377{
     78    int32_t cNewRefs = ASMAtomicIncS32(&g_cVBoxVrInits);
     79    Assert(cNewRefs >= 1);
     80    Assert(cNewRefs == 1); /* <- debugging */
     81    if (cNewRefs > 1)
     82        return VINF_SUCCESS;
     83
    8484#ifndef VBOXVDBG_VR_LAL_DISABLE
    8585    int rc = RTMemCacheCreate(&g_VBoxVrLookasideList, sizeof (VBOXVR_REG),
     
    103103VBOXVREGDECL(void) VBoxVrTerm()
    104104{
     105    int32_t cNewRefs = ASMAtomicDecS32(&g_cVBoxVrInits);
     106    Assert(cNewRefs >= 0);
     107    if (cNewRefs > 0)
     108        return;
     109
    105110#ifndef VBOXVDBG_VR_LAL_DISABLE
    106111    RTMemCacheDestroy(g_VBoxVrLookasideList);
     
    798803{
    799804    PVBOXVR_COMPOSITOR_ENTRY pEntry, pEntryNext;
    800     RTListForEachSafe(&pCompositor->List, pEntry, pEntryNext, VBOXVR_COMPOSITOR_ENTRY, Node);
     805    RTListForEachSafe(&pCompositor->List, pEntry, pEntryNext, VBOXVR_COMPOSITOR_ENTRY, Node)
    801806    {
    802807        VBoxVrCompositorEntryRemove(pCompositor, pEntry);
     
    935940        else if (fEntryChanged)
    936941            fFlags = VBOXVR_COMPOSITOR_CF_ENTRIES_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_COMPOSITED_REGIONS_CHANGED;
     942        if (!fEntryInList)
     943            fFlags |= VBOXVR_COMPOSITOR_CF_ENTRY_ADDED;
    937944
    938945        *pfChangeFlags = fFlags;
     
    10731080{
    10741081    PVBOXVR_COMPOSITOR_ENTRY pEntry, pEntryNext;
    1075     RTListForEachSafe(&pCompositor->List, pEntry, pEntryNext, VBOXVR_COMPOSITOR_ENTRY, Node);
     1082    RTListForEachSafe(&pCompositor->List, pEntry, pEntryNext, VBOXVR_COMPOSITOR_ENTRY, Node)
    10761083    {
    10771084        if (!pfnVisitor(pCompositor, pEntry, pvVisitor))
     
    10791086    }
    10801087}
     1088
     1089
     1090
     1091#define VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED UINT32_MAX
     1092
     1093static int crVrScrCompositorRectsAssignBuffer(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t cRects)
     1094{
     1095    Assert(cRects);
     1096
     1097    if (pCompositor->cRectsBuffer >= cRects)
     1098    {
     1099        pCompositor->cRects = cRects;
     1100        return VINF_SUCCESS;
     1101    }
     1102
     1103    if (pCompositor->cRectsBuffer)
     1104    {
     1105        Assert(pCompositor->paSrcRects);
     1106        RTMemFree(pCompositor->paSrcRects);
     1107        Assert(pCompositor->paDstRects);
     1108        RTMemFree(pCompositor->paDstRects);
     1109    }
     1110
     1111    pCompositor->paSrcRects = (PRTRECT)RTMemAlloc(sizeof (*pCompositor->paSrcRects) * cRects);
     1112    if (pCompositor->paSrcRects)
     1113    {
     1114        pCompositor->paDstRects = (PRTRECT)RTMemAlloc(sizeof (*pCompositor->paDstRects) * cRects);
     1115        if (pCompositor->paDstRects)
     1116        {
     1117            pCompositor->cRects = cRects;
     1118            pCompositor->cRectsBuffer = cRects;
     1119            return VINF_SUCCESS;
     1120        }
     1121        else
     1122        {
     1123            crWarning("RTMemAlloc failed!");
     1124            RTMemFree(pCompositor->paSrcRects);
     1125            pCompositor->paSrcRects = NULL;
     1126        }
     1127    }
     1128    else
     1129    {
     1130        crWarning("RTMemAlloc failed!");
     1131        pCompositor->paDstRects = NULL;
     1132    }
     1133
     1134    pCompositor->cRects = VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED;
     1135    pCompositor->cRectsBuffer = 0;
     1136
     1137    return VERR_NO_MEMORY;
     1138}
     1139
     1140static void crVrScrCompositorRectsInvalidate(PVBOXVR_SCR_COMPOSITOR pCompositor)
     1141{
     1142    pCompositor->cRects = VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED;
     1143}
     1144
     1145static DECLCALLBACK(bool) crVrScrCompositorRectsCounterCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, void *pvVisitor)
     1146{
     1147    uint32_t* pCounter = (uint32_t*)pvVisitor;
     1148    Assert(VBoxVrListRectsCount(&pEntry->Vr));
     1149    *pCounter += VBoxVrListRectsCount(&pEntry->Vr);
     1150    return true;
     1151}
     1152
     1153typedef struct VBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER
     1154{
     1155    PRTRECT paSrcRects;
     1156    PRTRECT paDstRects;
     1157    uint32_t cRects;
     1158} VBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER, *PVBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER;
     1159
     1160static DECLCALLBACK(bool) crVrScrCompositorRectsAssignerCb(PVBOXVR_COMPOSITOR pCCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
     1161{
     1162    PVBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER pData = (PVBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER)pvVisitor;
     1163    PVBOXVR_SCR_COMPOSITOR pCompositor = VBOXVR_SCR_COMPOSITOR_FROM_COMPOSITOR(pCCompositor);
     1164    PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry = VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pCEntry);
     1165    pEntry->paSrcRects = pData->paSrcRects;
     1166    pEntry->paDstRects = pData->paDstRects;
     1167    uint32_t cRects = VBoxVrListRectsCount(&pCEntry->Vr);
     1168    Assert(cRects);
     1169    Assert(cRects >= pData->cRects);
     1170    int rc = VBoxVrListRectsGet(&pCEntry->Vr, cRects, pEntry->paDstRects);
     1171    AssertRC(rc);
     1172    if (pCompositor->StretchX >= 1. && pCompositor->StretchY >= 1. /* <- stretching can not zero some rects */
     1173            && !pEntry->Pos.x && !pEntry->Pos.y)
     1174    {
     1175        memcpy(pEntry->paSrcRects, pEntry->paDstRects, cRects * sizeof (*pEntry->paSrcRects));
     1176    }
     1177    else
     1178    {
     1179        for (uint32_t i = 0; i < cRects; ++i)
     1180        {
     1181            pEntry->paSrcRects[i].xLeft = (int32_t)((pEntry->paDstRects[i].xLeft - pEntry->Pos.x) * pCompositor->StretchX);
     1182            pEntry->paSrcRects[i].yTop = (int32_t)((pEntry->paDstRects[i].yTop - pEntry->Pos.y) * pCompositor->StretchY);
     1183            pEntry->paSrcRects[i].xRight = (int32_t)((pEntry->paDstRects[i].xRight - pEntry->Pos.x) * pCompositor->StretchX);
     1184            pEntry->paSrcRects[i].yBottom = (int32_t)((pEntry->paDstRects[i].yBottom - pEntry->Pos.y) * pCompositor->StretchY);
     1185        }
     1186
     1187        bool canZeroX = (pCompositor->StretchX < 1);
     1188        bool canZeroY = (pCompositor->StretchY < 1);
     1189        if (canZeroX && canZeroY)
     1190        {
     1191            /* filter out zero rectangles*/
     1192            uint32_t iOrig, iNew;
     1193            for (iOrig = 0, iNew = 0; iOrig < cRects; ++iOrig)
     1194            {
     1195                PRTRECT pOrigRect = &pEntry->paSrcRects[iOrig];
     1196                if (pOrigRect->xLeft == pOrigRect->xRight
     1197                        || pOrigRect->yTop == pOrigRect->yBottom)
     1198                    continue;
     1199
     1200                if (iNew != iOrig)
     1201                {
     1202                    PRTRECT pNewRect = &pEntry->paSrcRects[iNew];
     1203                    *pNewRect = *pOrigRect;
     1204                }
     1205
     1206                ++iNew;
     1207            }
     1208
     1209            Assert(iNew <= iOrig);
     1210
     1211            uint32_t cDiff = iOrig - iNew;
     1212
     1213            if (cDiff)
     1214            {
     1215                pCompositor->cRects -= cDiff;
     1216                cRects -= cDiff;
     1217            }
     1218        }
     1219    }
     1220
     1221    pEntry->cRects = cRects;
     1222    pData->paDstRects += cRects;
     1223    pData->paSrcRects += cRects;
     1224    pData->cRects -= cRects;
     1225    return true;
     1226}
     1227
     1228static int crVrScrCompositorRectsCheckInit(PVBOXVR_SCR_COMPOSITOR pCompositor)
     1229{
     1230    if (pCompositor->cRects != VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED)
     1231        return VINF_SUCCESS;
     1232
     1233    uint32_t cRects = 0;
     1234    VBoxVrCompositorVisit(&pCompositor->Compositor, crVrScrCompositorRectsCounterCb, &cRects);
     1235
     1236    if (!cRects)
     1237    {
     1238        pCompositor->cRects = 0;
     1239        return VINF_SUCCESS;
     1240    }
     1241
     1242    int rc = crVrScrCompositorRectsAssignBuffer(pCompositor, cRects);
     1243    if (!RT_SUCCESS(rc))
     1244        return rc;
     1245
     1246    VBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER AssignerData;
     1247    AssignerData.paSrcRects = pCompositor->paSrcRects;
     1248    AssignerData.paDstRects = pCompositor->paDstRects;
     1249    AssignerData.cRects = pCompositor->cRects;
     1250    VBoxVrCompositorVisit(&pCompositor->Compositor, crVrScrCompositorRectsAssignerCb, &AssignerData);
     1251    Assert(!AssignerData.cRects);
     1252    return VINF_SUCCESS;
     1253}
     1254
     1255
     1256static int crVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
     1257{
     1258    uint32_t fChangedFlags = 0;
     1259    int rc = VBoxVrCompositorEntryRegionsAdd(&pCompositor->Compositor, &pEntry->Ce, cRegions, paRegions, &fChangedFlags);
     1260    if (!RT_SUCCESS(rc))
     1261    {
     1262        crWarning("VBoxVrCompositorEntryRegionsAdd failed, rc %d", rc);
     1263        return rc;
     1264    }
     1265
     1266    if (fChangedFlags & VBOXVR_COMPOSITOR_CF_COMPOSITED_REGIONS_CHANGED)
     1267    {
     1268        crVrScrCompositorRectsInvalidate(pCompositor);
     1269    }
     1270
     1271    CrVrScrCompositorEntrySetChanged(pEntry, true);
     1272
     1273    if (pfChanged)
     1274        *pfChanged = !!fChangedFlags;
     1275    return VINF_SUCCESS;
     1276}
     1277
     1278static int crVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
     1279{
     1280    bool fChanged;
     1281    int rc = VBoxVrCompositorEntryRegionsSet(&pCompositor->Compositor, &pEntry->Ce, cRegions, paRegions, &fChanged);
     1282    if (!RT_SUCCESS(rc))
     1283    {
     1284        crWarning("VBoxVrCompositorEntryRegionsSet failed, rc %d", rc);
     1285        return rc;
     1286    }
     1287
     1288    if (fChanged)
     1289    {
     1290        crVrScrCompositorRectsInvalidate(pCompositor);
     1291    }
     1292
     1293    CrVrScrCompositorEntrySetChanged(pEntry, true);
     1294
     1295    if (pfChanged)
     1296        *pfChanged = fChanged;
     1297    return VINF_SUCCESS;
     1298}
     1299
     1300static int crVrScrCompositorEntryPositionSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, bool *pfChanged)
     1301{
     1302    if (pEntry && (pEntry->Pos.x != pPos->x || pEntry->Pos.y != pPos->y))
     1303    {
     1304        int rc = VBoxVrCompositorEntryRegionsTranslate(&pCompositor->Compositor, &pEntry->Ce, pPos->x - pEntry->Pos.x, pPos->y - pEntry->Pos.y, pfChanged);
     1305        if (!RT_SUCCESS(rc))
     1306        {
     1307            crWarning("VBoxVrCompositorEntryRegionsTranslate failed rc %d", rc);
     1308            return rc;
     1309        }
     1310
     1311        if (VBoxVrCompositorEntryIsInList(&pEntry->Ce))
     1312        {
     1313            crVrScrCompositorRectsInvalidate(pCompositor);
     1314        }
     1315
     1316        pEntry->Pos = *pPos;
     1317        CrVrScrCompositorEntrySetChanged(pEntry, true);
     1318    }
     1319    return VINF_SUCCESS;
     1320}
     1321
     1322VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
     1323{
     1324    int rc;
     1325    if (pPos)
     1326    {
     1327        rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, pPos, NULL);
     1328        if (!RT_SUCCESS(rc))
     1329        {
     1330            crWarning("RegionsAdd: crVrScrCompositorEntryPositionSet failed rc %d", rc);
     1331            return rc;
     1332        }
     1333    }
     1334
     1335    rc = crVrScrCompositorEntryRegionsAdd(pCompositor, pEntry, cRegions, paRegions, NULL);
     1336    if (!RT_SUCCESS(rc))
     1337    {
     1338        crWarning("crVrScrCompositorEntryRegionsAdd failed, rc %d", rc);
     1339        return rc;
     1340    }
     1341
     1342    return VINF_SUCCESS;
     1343}
     1344
     1345VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
     1346{
     1347    int rc = CrVrScrCompositorEntryRemove(pCompositor, pEntry);
     1348    if (!RT_SUCCESS(rc))
     1349    {
     1350        crWarning("RegionsSet: CrVrScrCompositorEntryRemove failed rc %d", rc);
     1351        return rc;
     1352    }
     1353
     1354    if (pPos)
     1355    {
     1356        rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, pPos, NULL);
     1357        if (!RT_SUCCESS(rc))
     1358        {
     1359            crWarning("RegionsSet: crVrScrCompositorEntryPositionSet failed rc %d", rc);
     1360            return rc;
     1361        }
     1362    }
     1363
     1364    rc = crVrScrCompositorEntryRegionsSet(pCompositor, pEntry, cRegions, paRegions, NULL);
     1365    if (!RT_SUCCESS(rc))
     1366    {
     1367        crWarning("crVrScrCompositorEntryRegionsSet failed, rc %d", rc);
     1368        return rc;
     1369    }
     1370
     1371    return VINF_SUCCESS;
     1372}
     1373
     1374VBOXVREGDECL(int) CrVrScrCompositorEntryPosSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos)
     1375{
     1376    int rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, pPos, NULL);
     1377    if (!RT_SUCCESS(rc))
     1378    {
     1379        crWarning("RegionsSet: crVrScrCompositorEntryPositionSet failed rc %d", rc);
     1380        return rc;
     1381    }
     1382    return VINF_SUCCESS;
     1383}
     1384
     1385/* regions are valid until the next CrVrScrCompositor call */
     1386VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsGet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions)
     1387{
     1388    int rc = crVrScrCompositorRectsCheckInit(pCompositor);
     1389    if (!RT_SUCCESS(rc))
     1390    {
     1391        crWarning("crVrScrCompositorRectsCheckInit failed, rc %d", rc);
     1392        return rc;
     1393    }
     1394
     1395    Assert(pCompositor->cRects != VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED);
     1396
     1397    *pcRegions = pEntry->cRects;
     1398    if (ppaSrcRegions)
     1399        *ppaSrcRegions = pEntry->paSrcRects;
     1400    if (ppaDstRegions)
     1401        *ppaDstRegions = pEntry->paDstRects;
     1402
     1403    return VINF_SUCCESS;
     1404}
     1405
     1406VBOXVREGDECL(int) CrVrScrCompositorEntryRemove(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
     1407{
     1408    if (!VBoxVrCompositorEntryRemove(&pCompositor->Compositor, &pEntry->Ce))
     1409        return VINF_SUCCESS;
     1410
     1411    crVrScrCompositorRectsInvalidate(pCompositor);
     1412    return VINF_SUCCESS;
     1413}
     1414
     1415VBOXVREGDECL(int) CrVrScrCompositorInit(PVBOXVR_SCR_COMPOSITOR pCompositor)
     1416{
     1417    memset(pCompositor, 0, sizeof (*pCompositor));
     1418    VBoxVrCompositorInit(&pCompositor->Compositor, NULL);
     1419    pCompositor->StretchX = 1.0;
     1420    pCompositor->StretchY = 1.0;
     1421    return VINF_SUCCESS;
     1422}
     1423
     1424VBOXVREGDECL(void) CrVrScrCompositorTerm(PVBOXVR_SCR_COMPOSITOR pCompositor)
     1425{
     1426    VBoxVrCompositorTerm(&pCompositor->Compositor);
     1427    if (pCompositor->paDstRects)
     1428        RTMemFree(pCompositor->paDstRects);
     1429    if (pCompositor->paSrcRects)
     1430        RTMemFree(pCompositor->paSrcRects);
     1431}
     1432
     1433
     1434static DECLCALLBACK(bool) crVrScrCompositorEntrySetAllChangedCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
     1435{
     1436    PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry = VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pCEntry);
     1437    CrVrScrCompositorEntrySetChanged(pEntry, !!pvVisitor);
     1438    return true;
     1439}
     1440
     1441VBOXVREGDECL(void) CrVrScrCompositorEntrySetAllChanged(PVBOXVR_SCR_COMPOSITOR pCompositor, bool fChanged)
     1442{
     1443    VBoxVrCompositorVisit(&pCompositor->Compositor, crVrScrCompositorEntrySetAllChangedCb, (void*)fChanged);
     1444}
     1445
     1446VBOXVREGDECL(void) CrVrScrCompositorSetStretching(PVBOXVR_SCR_COMPOSITOR pCompositor, float StretchX, float StretchY)
     1447{
     1448    pCompositor->StretchX = StretchX;
     1449    pCompositor->StretchY = StretchY;
     1450    crVrScrCompositorRectsInvalidate(pCompositor);
     1451    CrVrScrCompositorEntrySetAllChanged(pCompositor, true);
     1452}
     1453
     1454/* regions are valid until the next CrVrScrCompositor call */
     1455VBOXVREGDECL(int) CrVrScrCompositorRegionsGet(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions)
     1456{
     1457    int rc = crVrScrCompositorRectsCheckInit(pCompositor);
     1458    if (!RT_SUCCESS(rc))
     1459    {
     1460        crWarning("crVrScrCompositorRectsCheckInit failed, rc %d", rc);
     1461        return rc;
     1462    }
     1463
     1464    Assert(pCompositor->cRects != VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED);
     1465
     1466    *pcRegions = pCompositor->cRects;
     1467    if (ppaSrcRegions)
     1468        *ppaSrcRegions = pCompositor->paSrcRects;
     1469    if (ppaDstRegions)
     1470        *ppaDstRegions = pCompositor->paDstRects;
     1471
     1472    return VINF_SUCCESS;
     1473}
     1474
     1475typedef struct VBOXVR_SCR_COMPOSITOR_VISITOR_CB
     1476{
     1477    PFNVBOXVRSCRCOMPOSITOR_VISITOR pfnVisitor;
     1478    void *pvVisitor;
     1479} VBOXVR_SCR_COMPOSITOR_VISITOR_CB, *PVBOXVR_SCR_COMPOSITOR_VISITOR_CB;
     1480
     1481static DECLCALLBACK(bool) crVrScrCompositorVisitCb(PVBOXVR_COMPOSITOR pCCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
     1482{
     1483    PVBOXVR_SCR_COMPOSITOR_VISITOR_CB pData = (PVBOXVR_SCR_COMPOSITOR_VISITOR_CB)pvVisitor;
     1484    PVBOXVR_SCR_COMPOSITOR pCompositor = VBOXVR_SCR_COMPOSITOR_FROM_COMPOSITOR(pCCompositor);
     1485    PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry = VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pCEntry);
     1486    return pData->pfnVisitor(pCompositor, pEntry, pData->pvVisitor);
     1487}
     1488
     1489VBOXVREGDECL(void) CrVrScrCompositorVisit(PVBOXVR_SCR_COMPOSITOR pCompositor, PFNVBOXVRSCRCOMPOSITOR_VISITOR pfnVisitor, void *pvVisitor)
     1490{
     1491    VBOXVR_SCR_COMPOSITOR_VISITOR_CB Data;
     1492    Data.pfnVisitor = pfnVisitor;
     1493    Data.pvVisitor = pvVisitor;
     1494    VBoxVrCompositorVisit(&pCompositor->Compositor, crVrScrCompositorVisitCb, &Data);
     1495}
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