vreg.cpp revision 8be5264d31d6a6ec949ff2285764c9af57298b52
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync * Visible Regions processing API implementation
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync * Copyright (C) 2012 Oracle Corporation
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync * available from http://www.virtualbox.org. This file is free software;
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync * you can redistribute it and/or modify it under the terms of the GNU
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync * General Public License (GPL) as published by the Free Software
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync//# define VBOXVDBG_VR_LAL_DISABLE
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync PVBOXVR_REG pReg = (PVBOXVR_REG)RTMemCacheAlloc(g_VBoxVrLookasideList);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync return (PVBOXVR_REG)RTMemAlloc(sizeof (VBOXVR_REG));
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncVBOXVREGDECL(void) VBoxVrListClear(PVBOXVR_LIST pList)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync RTListForEachSafe(&pList->ListHead, pReg, pRegNext, VBOXVR_REG, ListEntry)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync int32_t cNewRefs = ASMAtomicIncS32(&g_cVBoxVrInits);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync int rc = RTMemCacheCreate(&g_VBoxVrLookasideList, sizeof (VBOXVR_REG),
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync 0, /* size_t cbAlignment */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync 0 /* uint32_t fFlags*/
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync WARN(("ExInitializeLookasideListEx failed, rc (%d)", rc));
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync int32_t cNewRefs = ASMAtomicDecS32(&g_cVBoxVrInits);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsynctypedef DECLCALLBACK(int) FNVBOXVR_CB_COMPARATOR(const PVBOXVR_REG pReg1, const PVBOXVR_REG pReg2);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsynctypedef FNVBOXVR_CB_COMPARATOR *PFNVBOXVR_CB_COMPARATOR;
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsyncstatic DECLCALLBACK(int) vboxVrRegNonintersectedComparator(const RTRECT* pRect1, const RTRECT* pRect2)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsyncstatic void vboxVrDbgListDoVerify(PVBOXVR_LIST pList)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync RTListForEach(&pList->ListHead, pReg1, VBOXVR_REG, ListEntry)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync for (RTLISTNODE *pEntry2 = pReg1->ListEntry.pNext; pEntry2 != &pList->ListHead; pEntry2 = pEntry2->pNext)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync Assert(vboxVrRegNonintersectedComparator(&pReg1->Rect, &pReg2->Rect) < 0);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsyncstatic int vboxVrListUniteIntersection(PVBOXVR_LIST pList, PVBOXVR_LIST pIntersection);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsyncDECLINLINE(void) vboxVrListRegAdd(PVBOXVR_LIST pList, PVBOXVR_REG pReg, PRTLISTNODE pPlace, bool fAfter)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsyncDECLINLINE(void) vboxVrListRegRemove(PVBOXVR_LIST pList, PVBOXVR_REG pReg)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsyncstatic void vboxVrListRegAddOrder(PVBOXVR_LIST pList, PRTLISTNODE pMemberEntry, PVBOXVR_REG pReg)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync PVBOXVR_REG pMemberReg = PVBOXVR_REG_FROM_ENTRY(pMemberEntry);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync if (vboxVrRegNonintersectedComparator(&pMemberReg->Rect, &pReg->Rect) < 0)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync vboxVrListRegAdd(pList, pReg, pMemberEntry, false);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync } while (1);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsyncstatic void vboxVrListAddNonintersected(PVBOXVR_LIST pList1, PVBOXVR_LIST pList2)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync for (PRTLISTNODE pEntry2 = pList2->ListHead.pNext; pEntry2 != &pList2->ListHead; pEntry2 = pList2->ListHead.pNext)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync PVBOXVR_REG pReg2 = PVBOXVR_REG_FROM_ENTRY(pEntry2);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync PVBOXVR_REG pReg1 = PVBOXVR_REG_FROM_ENTRY(pEntry1);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync if (vboxVrRegNonintersectedComparator(&pReg1->Rect, &pReg2->Rect) < 0)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync } while (1);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncstatic int vboxVrListRegIntersectSubstNoJoin(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, const RTRECT * pRect2)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync pRegResult->Rect.yTop = topLim == VBOXVR_INVALID_COORD ? pReg1->Rect.yTop : topLim;
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync pRegResult->Rect.yBottom = bottomLim == VBOXVR_INVALID_COORD ? pReg1->Rect.yBottom : bottomLim;
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync pRegResult->Rect.yTop = topLim == VBOXVR_INVALID_COORD ? pReg1->Rect.yTop : topLim;
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync pRegResult->Rect.yBottom = bottomLim == VBOXVR_INVALID_COORD ? pReg1->Rect.yBottom : bottomLim;
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync return VINF_SUCCESS; /* the region is covered by the pRect2 */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync pMemberEntry = pEntry->pNext; /* the following elements should go after the given pEntry since they are ordered already */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsynctypedef DECLCALLBACK(PRTLISTNODE) FNVBOXVR_CB_INTERSECTED_VISITOR(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, const RTRECT * pRect2, void *pvContext, PRTLISTNODE *ppNext);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsynctypedef FNVBOXVR_CB_INTERSECTED_VISITOR *PFNVBOXVR_CB_INTERSECTED_VISITOR;
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsyncstatic void vboxVrListVisitIntersected(PVBOXVR_LIST pList1, uint32_t cRects, const RTRECT *aRects, PFNVBOXVR_CB_INTERSECTED_VISITOR pfnVisitor, void* pvVisitor)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync for (; pEntry1 != &pList1->ListHead; pEntry1 = pNext1)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync PVBOXVR_REG pReg1 = PVBOXVR_REG_FROM_ENTRY(pEntry1);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* y coords intersect */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* x coords intersect */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* the visitor can modify the list 1, apply necessary adjustments after it */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync PRTLISTNODE pEntry1 = pfnVisitor (pList1, pReg1, pRect2, pvVisitor, &pNext1);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsyncstatic void vboxVrListJoinRectsHV(PVBOXVR_LIST pList, bool fHorizontal)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync for (PRTLISTNODE pEntry1 = pList->ListHead.pNext; pEntry1 != &pList->ListHead; pEntry1 = pNext1)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync PVBOXVR_REG pReg1 = PVBOXVR_REG_FROM_ENTRY(pEntry1);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync for (PRTLISTNODE pEntry2 = pEntry1->pNext; pEntry2 != &pList->ListHead; pEntry2 = pNext2)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync PVBOXVR_REG pReg2 = PVBOXVR_REG_FROM_ENTRY(pEntry2);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* join rectangles */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync vboxVrListRegAddOrder(pList, pReg1->ListEntry.pNext, pReg2);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* restart the pNext1 & pNext2 since regs are splitted into smaller ones in y dimension
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync * and thus can match one of the previous rects */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync else if (pReg1->Rect.yBottom < pReg2->Rect.yBottom)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync vboxVrListRegAddOrder(pList, pReg1->ListEntry.pNext, pReg2);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* restart the pNext1 & pNext2 since regs are splitted into smaller ones in y dimension
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync * and thus can match one of the previous rects */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* reset the pNext1 since it could be the pReg2 being destroyed */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* pNext2 stays the same since it is pReg2->ListEntry.pNext, which is kept intact */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync else if (pReg1->Rect.yBottom == pReg2->Rect.yBottom)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync Assert(pReg1->Rect.yTop < pReg2->Rect.yTop); /* <- since pReg1 > pReg2 && pReg1->Rect.yTop != pReg2->Rect.yTop*/
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* join rectangles */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync vboxVrListRegAddOrder(pList, pReg2->ListEntry.pNext, pReg2);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* restart the pNext1 & pNext2 since regs are splitted into smaller ones in y dimension
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync * and thus can match one of the previous rects */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* join rectangles */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync vboxVrListRegAddOrder(pList, pReg2->ListEntry.pNext, pReg2);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* restart the pNext1 & pNext2 since regs are splitted into smaller ones in y dimension
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync * and thus can match one of the previous rects */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* join rects */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* reset the pNext1 since it could be the pReg2 being destroyed */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* pNext2 stays the same since it is pReg2->ListEntry.pNext, which is kept intact */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* no more to be done for for pReg1 */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* no more to be done for for pReg1 */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* no more to be done for for pReg1 */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsyncstatic DECLCALLBACK(PRTLISTNODE) vboxVrListSubstNoJoinCb(PVBOXVR_LIST pList, PVBOXVR_REG pReg1, const RTRECT *pRect2, void *pvContext, PRTLISTNODE *ppNext)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync PVBOXVR_CBDATA_SUBST pData = (PVBOXVR_CBDATA_SUBST)pvContext;
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* store the prev to get the new pNext out of it*/
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* NOTE: the pReg1 will be invalid after the vboxVrListRegIntersectSubstNoJoin call!!! */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync int rc = vboxVrListRegIntersectSubstNoJoin(pList, pReg1, pRect2);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync WARN(("vboxVrListRegIntersectSubstNoJoin failed!"));
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncstatic int vboxVrListSubstNoJoin(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync vboxVrListVisitIntersected(pList, cRects, aRects, vboxVrListSubstNoJoinCb, &Data);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncstatic const RTRECT * vboxVrRectsOrder(uint32_t cRects, const RTRECT * aRects)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* check if rects are ordered already */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync if (vboxVrRegNonintersectedComparator(pRect1, pRect2) < 0)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync pRects = (RTRECT *)RTMemAlloc(sizeof (RTRECT) * cRects);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync int j = (int)i - 1;
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync if (vboxVrRegNonintersectedComparator(pRect1, pRect1-1) > 0)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync } while (1);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncVBOXVREGDECL(void) VBoxVrListTranslate(PVBOXVR_LIST pList, int32_t x, int32_t y)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync for (PRTLISTNODE pEntry1 = pList->ListHead.pNext; pEntry1 != &pList->ListHead; pEntry1 = pEntry1->pNext)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync PVBOXVR_REG pReg1 = PVBOXVR_REG_FROM_ENTRY(pEntry1);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncVBOXVREGDECL(int) VBoxVrListRectsSubst(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync const RTRECT * pRects = vboxVrRectsOrder(cRects, aRects);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync int rc = vboxVrListSubstNoJoin(pList, cRects, aRects, pfChanged);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncVBOXVREGDECL(int) VBoxVrListRectsAdd(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* early sort out the case when there are no new rects */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync for (PRTLISTNODE pEntry1 = pList->ListHead.pNext; pEntry1 != &pList->ListHead; pEntry1 = pEntry1->pNext)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync PVBOXVR_REG pReg1 = PVBOXVR_REG_FROM_ENTRY(pEntry1);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync /* rects are not covered, need to go the slow way */
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync bool fChanged = false;
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync vboxVrListRegAdd(pList, pReg, &pList->ListHead, false);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync vboxVrListRegAdd(&DiffList, pReg, &DiffList.ListHead, false);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync pListRects = (RTRECT *)RTMemAlloc(sizeof (RTRECT) * cAllocatedRects);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync rc = VBoxVrListRectsGet(pList, cListRects, pListRects);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync rc = vboxVrListSubstNoJoin(&DiffList, cListRects, pListRects, &fDummyChanged);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync Assert(VBoxVrListIsEmpty(&DiffList) || rc != VINF_SUCCESS);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncVBOXVREGDECL(int) VBoxVrListRectsGet(PVBOXVR_LIST pList, uint32_t cRects, RTRECT * aRects)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync for (PRTLISTNODE pEntry1 = pList->ListHead.pNext; pEntry1 != &pList->ListHead; pEntry1 = pEntry1->pNext, ++i)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync PVBOXVR_REG pReg1 = PVBOXVR_REG_FROM_ENTRY(pEntry1);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncVBOXVREGDECL(int) VBoxVrListCmp(PVBOXVR_LIST pList1, PVBOXVR_LIST pList2)
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync for (pReg1 = RTListNodeGetNext(&pList1->ListHead, VBOXVR_REG, ListEntry),
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync pReg2 = RTListNodeGetNext(&pList2->ListHead, VBOXVR_REG, ListEntry);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync !RTListNodeIsDummy(&pList1->ListHead, pReg1, VBOXVR_REG, ListEntry);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync pReg1 = RT_FROM_MEMBER(pReg1->ListEntry.pNext, VBOXVR_REG, ListEntry),
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync pReg2 = RT_FROM_MEMBER(pReg2->ListEntry.pNext, VBOXVR_REG, ListEntry))
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync Assert(!RTListNodeIsDummy(&pList2->ListHead, pReg2, VBOXVR_REG, ListEntry));
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync Assert(RTListNodeIsDummy(&pList2->ListHead, pReg2, VBOXVR_REG, ListEntry));
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncVBOXVREGDECL(void) VBoxVrCompositorInit(PVBOXVR_COMPOSITOR pCompositor, PFNVBOXVRCOMPOSITOR_ENTRY_REMOVED pfnEntryRemoved)
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncVBOXVREGDECL(void) VBoxVrCompositorTerm(PVBOXVR_COMPOSITOR pCompositor)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync RTListForEachSafe(&pCompositor->List, pEntry, pEntryNext, VBOXVR_COMPOSITOR_ENTRY, Node)
8238dbee2b0c21592e6af0fafcdb2e56cf3a791cvboxsyncDECLINLINE(void) vboxVrCompositorEntryAdd(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry)
8238dbee2b0c21592e6af0fafcdb2e56cf3a791cvboxsyncDECLINLINE(void) vboxVrCompositorEntryRemove(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, PVBOXVR_COMPOSITOR_ENTRY pReplacingEntry)
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync pCompositor->pfnEntryRemoved(pCompositor, pEntry, pReplacingEntry);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncVBOXVREGDECL(void) VBoxVrCompositorEntryInit(PVBOXVR_COMPOSITOR_ENTRY pEntry)
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncVBOXVREGDECL(bool) VBoxVrCompositorEntryRemove(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync return false;
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync vboxVrCompositorEntryRemove(pCompositor, pEntry, NULL);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync return true;
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncstatic int vboxVrCompositorEntryRegionsSubst(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT * paRects, bool *pfChanged)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync int rc = VBoxVrListRectsSubst(&pEntry->Vr, cRects, paRects, &fChanged);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync vboxVrCompositorEntryRemove(pCompositor, pEntry, NULL);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncVBOXVREGDECL(int) VBoxVrCompositorEntryRegionsAdd(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT *paRects, uint32_t *pfChangeFlags)
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync bool fOthersChanged = false, fCurChanged = false, fEntryChanged = false, fEntryInList = false, fEntryReplaces = false;
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync fEntryInList = VBoxVrCompositorEntryIsInList(pEntry);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync rc = VBoxVrListRectsAdd(&pEntry->Vr, cRects, paRects, &fEntryChanged);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync WARN(("Empty rectangles passed in, is it expected?"));
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync RTListForEach(&pCompositor->List, pCur, VBOXVR_COMPOSITOR_ENTRY, Node)
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync if (pEntry && !VBoxVrListCmp(&pCur->Vr, &pEntry->Vr))
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync vboxVrCompositorEntryRemove(pCompositor, pCur, pEntry);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync rc = vboxVrCompositorEntryRegionsSubst(pCompositor, pCur, cRects, paRects, &fCurChanged);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync WARN(("vboxVrCompositorEntryRegionsSubst failed, rc %d", rc));
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync fFlags = VBOXVR_COMPOSITOR_CF_ENTRIES_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_COMPOSITED_REGIONS_CHANGED;
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync fFlags = VBOXVR_COMPOSITOR_CF_ENTRIES_REGIONS_CHANGED;
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync fFlags = VBOXVR_COMPOSITOR_CF_ENTRIES_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_COMPOSITED_REGIONS_CHANGED;
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncVBOXVREGDECL(int) VBoxVrCompositorEntryRegionsSubst(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT * paRects, bool *pfChanged)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync WARN(("VBoxVrCompositorEntryRegionsSubst called with zero entry, unsupported!"));
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync int rc = vboxVrCompositorEntryRegionsSubst(pCompositor, pEntry, cRects, paRects, pfChanged);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncVBOXVREGDECL(int) VBoxVrCompositorEntryRegionsSet(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT *paRects, bool *pfChanged)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync WARN(("VBoxVrCompositorEntryRegionsSet called with zero entry, unsupported!"));
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync fCurChanged = VBoxVrCompositorEntryRemove(pCompositor, pEntry);
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync rc = VBoxVrCompositorEntryRegionsAdd(pCompositor, pEntry, cRects, paRects, &fChangeFlags);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync WARN(("VBoxVrCompositorEntryRegionsAdd failed, rc %d", rc));
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncVBOXVREGDECL(int) VBoxVrCompositorEntryRegionsTranslate(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, int32_t x, int32_t y, bool *pfChanged)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync WARN(("VBoxVrCompositorEntryRegionsTranslate called with zero entry, unsupported!"));
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync if ((!x && !y)
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync RTListForEach(&pCompositor->List, pCur, VBOXVR_COMPOSITOR_ENTRY, Node)
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsync paRects = (RTRECT*)RTMemAlloc(cRects * sizeof (RTRECT));
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync rc = VBoxVrListRectsGet(&pEntry->Vr, cRects, paRects);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync rc = vboxVrCompositorEntryRegionsSubst(pCompositor, pCur, cRects, paRects, NULL);
96a93b5e6bd7da64f6be955c9fd7569b80c8ae2evboxsync WARN(("vboxVrCompositorEntryRegionsSubst failed! rc %d", rc));
ddd5bf03356cc0515b0f42ed9048a6364e7eb1e2vboxsyncVBOXVREGDECL(void) VBoxVrCompositorVisit(PVBOXVR_COMPOSITOR pCompositor, PFNVBOXVRCOMPOSITOR_VISITOR pfnVisitor, void *pvVisitor)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync RTListForEachSafe(&pCompositor->List, pEntry, pEntryNext, VBOXVR_COMPOSITOR_ENTRY, Node)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync#define VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED UINT32_MAX
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncstatic int crVrScrCompositorRectsAssignBuffer(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t cRects)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync pCompositor->paSrcRects = (PRTRECT)RTMemAlloc(sizeof (*pCompositor->paSrcRects) * cRects);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync pCompositor->paDstRects = (PRTRECT)RTMemAlloc(sizeof (*pCompositor->paDstRects) * cRects);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync pCompositor->cRects = VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncstatic void crVrScrCompositorRectsInvalidate(PVBOXVR_SCR_COMPOSITOR pCompositor)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync pCompositor->cRects = VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncstatic DECLCALLBACK(bool) crVrScrCompositorRectsCounterCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, void *pvVisitor)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync return true;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync} VBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER, *PVBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncstatic DECLCALLBACK(bool) crVrScrCompositorRectsAssignerCb(PVBOXVR_COMPOSITOR pCCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync PVBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER pData = (PVBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER)pvVisitor;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync PVBOXVR_SCR_COMPOSITOR pCompositor = VBOXVR_SCR_COMPOSITOR_FROM_COMPOSITOR(pCCompositor);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry = VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pCEntry);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync uint32_t cRects = VBoxVrListRectsCount(&pCEntry->Vr);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync int rc = VBoxVrListRectsGet(&pCEntry->Vr, cRects, pEntry->paDstRects);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (pCompositor->StretchX >= 1. && pCompositor->StretchY >= 1. /* <- stretching can not zero some rects */
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync memcpy(pEntry->paSrcRects, pEntry->paDstRects, cRects * sizeof (*pEntry->paSrcRects));
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync pEntry->paSrcRects[i].xLeft = (int32_t)((pEntry->paDstRects[i].xLeft - pEntry->Pos.x) * pCompositor->StretchX);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync pEntry->paSrcRects[i].yTop = (int32_t)((pEntry->paDstRects[i].yTop - pEntry->Pos.y) * pCompositor->StretchY);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync pEntry->paSrcRects[i].xRight = (int32_t)((pEntry->paDstRects[i].xRight - pEntry->Pos.x) * pCompositor->StretchX);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync pEntry->paSrcRects[i].yBottom = (int32_t)((pEntry->paDstRects[i].yBottom - pEntry->Pos.y) * pCompositor->StretchY);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync /* filter out zero rectangles*/
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync return true;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncstatic int crVrScrCompositorRectsCheckInit(PVBOXVR_SCR_COMPOSITOR pCompositor)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (pCompositor->cRects != VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync VBoxVrCompositorVisit(&pCompositor->Compositor, crVrScrCompositorRectsCounterCb, &cRects);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync int rc = crVrScrCompositorRectsAssignBuffer(pCompositor, cRects);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync VBoxVrCompositorVisit(&pCompositor->Compositor, crVrScrCompositorRectsAssignerCb, &AssignerData);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncstatic int crVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync int rc = VBoxVrCompositorEntryRegionsAdd(&pCompositor->Compositor, &pEntry->Ce, cRegions, paRegions, &fChangedFlags);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync crWarning("VBoxVrCompositorEntryRegionsAdd failed, rc %d", rc);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (fChangedFlags & VBOXVR_COMPOSITOR_CF_COMPOSITED_REGIONS_CHANGED)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncstatic int crVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync int rc = VBoxVrCompositorEntryRegionsSet(&pCompositor->Compositor, &pEntry->Ce, cRegions, paRegions, &fChanged);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync crWarning("VBoxVrCompositorEntryRegionsSet failed, rc %d", rc);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncstatic int crVrScrCompositorEntryPositionSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, bool *pfChanged)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (pEntry && (pEntry->Pos.x != pPos->x || pEntry->Pos.y != pPos->y))
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync int rc = VBoxVrCompositorEntryRegionsTranslate(&pCompositor->Compositor, &pEntry->Ce, pPos->x - pEntry->Pos.x, pPos->y - pEntry->Pos.y, pfChanged);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync crWarning("VBoxVrCompositorEntryRegionsTranslate failed rc %d", rc);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncVBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, pPos, NULL);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync crWarning("RegionsAdd: crVrScrCompositorEntryPositionSet failed rc %d", rc);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync rc = crVrScrCompositorEntryRegionsAdd(pCompositor, pEntry, cRegions, paRegions, NULL);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync crWarning("crVrScrCompositorEntryRegionsAdd failed, rc %d", rc);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncVBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync int rc = CrVrScrCompositorEntryRemove(pCompositor, pEntry);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync crWarning("RegionsSet: CrVrScrCompositorEntryRemove failed rc %d", rc);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, pPos, NULL);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync crWarning("RegionsSet: crVrScrCompositorEntryPositionSet failed rc %d", rc);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync rc = crVrScrCompositorEntryRegionsSet(pCompositor, pEntry, cRegions, paRegions, NULL);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync crWarning("crVrScrCompositorEntryRegionsSet failed, rc %d", rc);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncVBOXVREGDECL(int) CrVrScrCompositorEntryPosSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync int rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, pPos, NULL);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync crWarning("RegionsSet: crVrScrCompositorEntryPositionSet failed rc %d", rc);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync/* regions are valid until the next CrVrScrCompositor call */
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncVBOXVREGDECL(int) CrVrScrCompositorEntryRegionsGet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync int rc = crVrScrCompositorRectsCheckInit(pCompositor);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync crWarning("crVrScrCompositorRectsCheckInit failed, rc %d", rc);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync Assert(pCompositor->cRects != VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncVBOXVREGDECL(int) CrVrScrCompositorEntryRemove(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (!VBoxVrCompositorEntryRemove(&pCompositor->Compositor, &pEntry->Ce))
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncVBOXVREGDECL(int) CrVrScrCompositorInit(PVBOXVR_SCR_COMPOSITOR pCompositor)
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync VBoxVrCompositorInit(&pCompositor->Compositor, NULL);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncVBOXVREGDECL(void) CrVrScrCompositorTerm(PVBOXVR_SCR_COMPOSITOR pCompositor)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncstatic DECLCALLBACK(bool) crVrScrCompositorEntrySetAllChangedCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry = VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pCEntry);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync CrVrScrCompositorEntrySetChanged(pEntry, !!pvVisitor);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync return true;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncVBOXVREGDECL(void) CrVrScrCompositorEntrySetAllChanged(PVBOXVR_SCR_COMPOSITOR pCompositor, bool fChanged)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync VBoxVrCompositorVisit(&pCompositor->Compositor, crVrScrCompositorEntrySetAllChangedCb, (void*)fChanged);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncVBOXVREGDECL(void) CrVrScrCompositorSetStretching(PVBOXVR_SCR_COMPOSITOR pCompositor, float StretchX, float StretchY)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync CrVrScrCompositorEntrySetAllChanged(pCompositor, true);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync/* regions are valid until the next CrVrScrCompositor call */
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncVBOXVREGDECL(int) CrVrScrCompositorRegionsGet(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync int rc = crVrScrCompositorRectsCheckInit(pCompositor);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync crWarning("crVrScrCompositorRectsCheckInit failed, rc %d", rc);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync Assert(pCompositor->cRects != VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync} VBOXVR_SCR_COMPOSITOR_VISITOR_CB, *PVBOXVR_SCR_COMPOSITOR_VISITOR_CB;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncstatic DECLCALLBACK(bool) crVrScrCompositorVisitCb(PVBOXVR_COMPOSITOR pCCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync PVBOXVR_SCR_COMPOSITOR_VISITOR_CB pData = (PVBOXVR_SCR_COMPOSITOR_VISITOR_CB)pvVisitor;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync PVBOXVR_SCR_COMPOSITOR pCompositor = VBOXVR_SCR_COMPOSITOR_FROM_COMPOSITOR(pCCompositor);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry = VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pCEntry);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync return pData->pfnVisitor(pCompositor, pEntry, pData->pvVisitor);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncVBOXVREGDECL(void) CrVrScrCompositorVisit(PVBOXVR_SCR_COMPOSITOR pCompositor, PFNVBOXVRSCRCOMPOSITOR_VISITOR pfnVisitor, void *pvVisitor)