vreg.cpp revision 7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync * Visible Regions processing API implementation
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync * Copyright (C) 2012 Oracle Corporation
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * available from http://www.virtualbox.org. This file is free software;
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
154e1d5579ca6c8bee571a8d1ced5d76a0234030vboxsync#define vboxVrRegLaFree(_c, _e) RTMemCacheFree((_c), (_e))
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsyncDECLINLINE(int) vboxVrLaCreate(RTMEMCACHE *pCache, size_t cbElement)
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync 0, /* size_t cbAlignment */
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync 0 /* uint32_t fFlags*/
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync# if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync# define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap
cb13ee8e628d04a773894bf4f9e8047d74f2ee21vboxsync# define _InterlockedExchangeAdd _InterlockedExchangeAdd_StupidDDKVsCompilerCrap
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync# define _InterlockedCompareExchange _InterlockedCompareExchange_StupidDDKVsCompilerCrap
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync# define _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap
40af749e457b7d704c869ea986a042f0d4b6e09avboxsync# define _interlockedbittestandset _interlockedbittestandset_StupidDDKVsCompilerCrap
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync# define _interlockedbittestandreset _interlockedbittestandreset_StupidDDKVsCompilerCrap
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync# define _interlockedbittestandset64 _interlockedbittestandset64_StupidDDKVsCompilerCrap
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync# define _interlockedbittestandreset64 _interlockedbittestandreset64_StupidDDKVsCompilerCrap
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync#define vboxVrRegLaAlloc(_c) ExAllocateFromLookasideListEx(&(_c))
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync#define vboxVrRegLaFree(_c, _e) ExFreeToLookasideListEx(&(_c), (_e))
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsyncDECLINLINE(int) vboxVrLaCreate(LOOKASIDE_LIST_EX *pCache, size_t cbElement)
40af749e457b7d704c869ea986a042f0d4b6e09avboxsync NTSTATUS Status = ExInitializeLookasideListEx(pCache,
cb13ee8e628d04a773894bf4f9e8047d74f2ee21vboxsync 0, /* ULONG Flags */
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync 0 /* USHORT Depth - reserved, must be null */
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync WARN(("ExInitializeLookasideListEx failed, Status (0x%x)", Status));
07db1daf0ffed7a0fe1224c296fc1e7ac40d7681vboxsync#define vboxVrLaDestroy(_c) ExDeleteLookasideListEx(&(_c))
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsync//# define VBOXVDBG_VR_LAL_DISABLE
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsync PVBOXVR_REG pReg = (PVBOXVR_REG)vboxVrRegLaAlloc(g_VBoxVrLookasideList);
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsync return (PVBOXVR_REG)RTMemAlloc(sizeof (VBOXVR_REG));
062b8a43e237d9e2edde03b5837d44506e35eb47vboxsyncVBOXVREGDECL(void) VBoxVrListClear(PVBOXVR_LIST pList)
6cb96ab7d4ba4dab39ef47e8d7c3dcfbf7582959vboxsync RTListForEachSafe(&pList->ListHead, pReg, pRegNext, VBOXVR_REG, ListEntry)
6cb96ab7d4ba4dab39ef47e8d7c3dcfbf7582959vboxsync int32_t cNewRefs = ASMAtomicIncS32(&g_cVBoxVrInits);
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsync int rc = vboxVrLaCreate(&g_VBoxVrLookasideList, sizeof (VBOXVR_REG));
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsync WARN(("ExInitializeLookasideListEx failed, rc (%d)", rc));
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsync int32_t cNewRefs = ASMAtomicDecS32(&g_cVBoxVrInits);
062b8a43e237d9e2edde03b5837d44506e35eb47vboxsynctypedef DECLCALLBACK(int) FNVBOXVR_CB_COMPARATOR(const VBOXVR_REG *pReg1, const VBOXVR_REG *pReg2);
062b8a43e237d9e2edde03b5837d44506e35eb47vboxsynctypedef FNVBOXVR_CB_COMPARATOR *PFNVBOXVR_CB_COMPARATOR;
062b8a43e237d9e2edde03b5837d44506e35eb47vboxsyncstatic DECLCALLBACK(int) vboxVrRegNonintersectedComparator(const RTRECT* pRect1, const RTRECT* pRect2)
062b8a43e237d9e2edde03b5837d44506e35eb47vboxsyncstatic void vboxVrDbgListDoVerify(PVBOXVR_LIST pList)
062b8a43e237d9e2edde03b5837d44506e35eb47vboxsync RTListForEach(&pList->ListHead, pReg1, VBOXVR_REG, ListEntry)
062b8a43e237d9e2edde03b5837d44506e35eb47vboxsync for (RTLISTNODE *pEntry2 = pReg1->ListEntry.pNext; pEntry2 != &pList->ListHead; pEntry2 = pEntry2->pNext)
062b8a43e237d9e2edde03b5837d44506e35eb47vboxsync Assert(vboxVrRegNonintersectedComparator(&pReg1->Rect, &pReg2->Rect) < 0);
062b8a43e237d9e2edde03b5837d44506e35eb47vboxsyncstatic int vboxVrListUniteIntersection(PVBOXVR_LIST pList, PVBOXVR_LIST pIntersection);
062b8a43e237d9e2edde03b5837d44506e35eb47vboxsyncDECLINLINE(void) vboxVrListRegAdd(PVBOXVR_LIST pList, PVBOXVR_REG pReg, PRTLISTNODE pPlace, bool fAfter)
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsyncDECLINLINE(void) vboxVrListRegRemove(PVBOXVR_LIST pList, PVBOXVR_REG pReg)
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsyncstatic void vboxVrListRegAddOrder(PVBOXVR_LIST pList, PRTLISTNODE pMemberEntry, PVBOXVR_REG pReg)
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsync PVBOXVR_REG pMemberReg = PVBOXVR_REG_FROM_ENTRY(pMemberEntry);
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsync if (vboxVrRegNonintersectedComparator(&pMemberReg->Rect, &pReg->Rect) < 0)
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsync vboxVrListRegAdd(pList, pReg, pMemberEntry, false);
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsync } while (1);
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsyncstatic void vboxVrListAddNonintersected(PVBOXVR_LIST pList1, PVBOXVR_LIST pList2)
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsync for (PRTLISTNODE pEntry2 = pList2->ListHead.pNext; pEntry2 != &pList2->ListHead; pEntry2 = pList2->ListHead.pNext)
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsync PVBOXVR_REG pReg2 = PVBOXVR_REG_FROM_ENTRY(pEntry2);
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsync PVBOXVR_REG pReg1 = PVBOXVR_REG_FROM_ENTRY(pEntry1);
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsync if (vboxVrRegNonintersectedComparator(&pReg1->Rect, &pReg2->Rect) < 0)
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsync } while (1);
6fea4abcc6ee0f2797ac01ef79c374d506aedc02vboxsyncstatic int vboxVrListRegIntersectSubstNoJoin(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, const RTRECT * pRect2)
if (pBottomReg)
pMemberEntry = pEntry->pNext; /* the following elements should go after the given pEntry since they are ordered already */
return VINF_SUCCESS;
/* @returns Entry to be used for continuing the rectangles iterations being made currently on the callback call.
* @param ppNext specifies next reg entry to be used for iteration. the default is pReg1->ListEntry.pNext */
typedef DECLCALLBACK(PRTLISTNODE) FNVBOXVR_CB_INTERSECTED_VISITOR(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, const RTRECT * pRect2, void *pvContext, PRTLISTNODE *ppNext);
static void vboxVrListVisitIntersected(PVBOXVR_LIST pList1, uint32_t cRects, const RTRECT *aRects, PFNVBOXVR_CB_INTERSECTED_VISITOR pfnVisitor, void* pvVisitor)
typedef DECLCALLBACK(PRTLISTNODE) FNVBOXVR_CB_NONINTERSECTED_VISITOR(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, void *pvContext);
static void vboxVrListVisitNonintersected(PVBOXVR_LIST pList1, uint32_t cRects, const RTRECT *aRects, PFNVBOXVR_CB_NONINTERSECTED_VISITOR pfnVisitor, void* pvVisitor)
for (; i < cRects; ++i)
if (i == cRects)
if (fHorizontal)
Assert(pReg1->Rect.yTop < pReg2->Rect.yTop); /* <- since pReg1 > pReg2 && pReg1->Rect.yTop != pReg2->Rect.yTop*/
typedef struct VBOXVR_CBDATA_SUBST
int rc;
bool fChanged;
static DECLCALLBACK(PRTLISTNODE) vboxVrListSubstNoJoinCb(PVBOXVR_LIST pList, PVBOXVR_REG pReg1, const RTRECT *pRect2, void *pvContext, PRTLISTNODE *ppNext)
static int vboxVrListSubstNoJoin(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
*pfChanged = false;
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifdef DEBUG
if (!pRects)
return NULL;
return pRects;
for (PRTLISTNODE pEntry1 = pList->ListHead.pNext; pEntry1 != &pList->ListHead; pEntry1 = pEntry1->pNext)
static DECLCALLBACK(PRTLISTNODE) vboxVrListIntersectNoJoinNonintersectedCb(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, void *pvContext)
return pNext;
static DECLCALLBACK(PRTLISTNODE) vboxVrListIntersectNoJoinIntersectedCb(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, const RTRECT *pRect2, void *pvContext, PRTLISTNODE *ppNext)
static int vboxVrListIntersectNoJoin(PVBOXVR_LIST pList, const VBOXVR_LIST *pList2, bool *pfChanged)
bool fChanged = false;
*pfChanged = false;
return VINF_SUCCESS;
if (pfChanged)
*pfChanged = true;
return VINF_SUCCESS;
for (const RTLISTNODE *pEntry2 = pList2->ListHead.pNext; pEntry2 != &pList2->ListHead; pEntry2 = pEntry2->pNext)
if (pReg1)
/* @todo: this can have false-alarming sometimes if the separated rects will then be joind into the original rect,
fChanged = true;
if (!pReg)
return VERR_NO_MEMORY;
if (pReg1)
fChanged = true;
return VINF_SUCCESS;
VBOXVREGDECL(int) VBoxVrListIntersect(PVBOXVR_LIST pList, const VBOXVR_LIST *pList2, bool *pfChanged)
if (pfChanged)
*pfChanged = false;
return rc;
if (*pfChanged)
return rc;
VBOXVREGDECL(int) VBoxVrListRectsIntersect(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
if (pfChanged)
*pfChanged = false;
return VINF_SUCCESS;
if (!cRects)
if (pfChanged)
*pfChanged = true;
return VINF_SUCCESS;
/* we perform intersection using lists because the algorythm axpects the rects to be non-intersected,
return rc;
VBOXVREGDECL(int) VBoxVrListRectsSubst(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
if (!pRects)
return VERR_NO_MEMORY;
goto done;
if (!*pfChanged)
goto done;
done:
return rc;
VBOXVREGDECL(int) VBoxVrListRectsSet(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
if (pfChanged)
*pfChanged = false;
return VINF_SUCCESS;
return rc;
if (pfChanged)
*pfChanged = true;
return VINF_SUCCESS;
VBOXVREGDECL(int) VBoxVrListRectsAdd(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
if (pfChanged)
*pfChanged = false;
#ifdef DEBUG
cCovered++;
for (PRTLISTNODE pEntry1 = pList->ListHead.pNext; pEntry1 != &pList->ListHead; pEntry1 = pEntry1->pNext)
cCovered++;
return VINF_SUCCESS;
bool fNeedRectreate = true;
bool fChanged = false;
if (!pReg)
if (!cListRects)
fChanged = true;
if (pListRects)
if (!pListRects)
if (fNeedRectreate)
fNeedRectreate = false;
bool fDummyChanged = false;
fNeedRectreate = true;
fChanged = true;
if (pListRects)
if (fChanged)
if (pfChanged)
return VINF_SUCCESS;
return VERR_BUFFER_OVERFLOW;
uint32_t i = 0;
for (PRTLISTNODE pEntry1 = pList->ListHead.pNext; pEntry1 != &pList->ListHead; pEntry1 = pEntry1->pNext, ++i)
return VINF_SUCCESS;
if (cTmp)
return cTmp;
if (cTmp)
return cTmp;
VBOXVREGDECL(void) VBoxVrCompositorInit(PVBOXVR_COMPOSITOR pCompositor, PFNVBOXVRCOMPOSITOR_ENTRY_REMOVED pfnEntryRemoved)
DECLINLINE(void) vboxVrCompositorEntryAdd(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry)
DECLINLINE(void) vboxVrCompositorEntryRemove(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, PVBOXVR_COMPOSITOR_ENTRY pReplacingEntry)
VBOXVREGDECL(bool) VBoxVrCompositorEntryRemove(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry)
static int vboxVrCompositorEntryRegionsSubst(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT * paRects, bool *pfChanged)
bool fChanged;
if (pfChanged)
*pfChanged = false;
return VINF_SUCCESS;
return rc;
VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsAdd(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT *paRects, uint32_t *pfChangeFlags)
bool fOthersChanged = false, fCurChanged = false, fEntryChanged = false, fEntryWasInList = false, fEntryReplaced = false;
if (!cRects)
if (pfChangeFlags)
*pfChangeFlags = 0;
return VINF_SUCCESS;
if (pEntry)
if (pfChangeFlags)
*pfChangeFlags = 0;
return VINF_SUCCESS;
return rc;
fEntryReplaced = true;
return rc;
if (pfChangeFlags)
if (fOthersChanged)
else if (fEntryReplaced)
else if (fEntryChanged)
if (!fEntryWasInList)
return VINF_SUCCESS;
VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsSubst(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT * paRects, bool *pfChanged)
if (!pEntry)
if (pfChanged)
*pfChanged = false;
return VERR_INVALID_PARAMETER;
if (pfChanged)
*pfChanged = false;
return VINF_SUCCESS;
return VINF_SUCCESS;
return rc;
VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsSet(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT *paRects, bool *pfChanged)
if (!pEntry)
if (pfChanged)
*pfChanged = false;
return VERR_INVALID_PARAMETER;
int rc;
return rc;
if (pfChanged)
return VINF_SUCCESS;
VBOXVREGDECL(int) VBoxVrCompositorEntryListIntersect(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, const VBOXVR_LIST *pList2, bool *pfChanged)
bool fChanged = false;
if (pfChanged)
return rc;
VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsIntersect(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT *paRects, bool *pfChanged)
bool fChanged = false;
if (pfChanged)
return rc;
VBOXVREGDECL(int) VBoxVrCompositorEntryListIntersectAll(PVBOXVR_COMPOSITOR pCompositor, const VBOXVR_LIST *pList2, bool *pfChanged)
bool fChanged = false;
bool fTmpChanged = false;
if (pfChanged)
return rc;
VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsIntersectAll(PVBOXVR_COMPOSITOR pCompositor, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
bool fChanged = false;
bool fTmpChanged = false;
int tmpRc = VBoxVrCompositorEntryRegionsIntersect(pCompositor, pEntry, cRegions, paRegions, &fTmpChanged);
if (pfChanged)
return rc;
VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsTranslate(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, int32_t x, int32_t y, bool *pfChanged)
if (!pEntry)
if (pfChanged)
*pfChanged = false;
return VERR_INVALID_PARAMETER;
if (pfChanged)
*pfChanged = false;
return VINF_SUCCESS;
if (!paRects)
if (!paRects)
if (pfChanged)
*pfChanged = true;
if (paRects)
return rc;
VBOXVREGDECL(void) VBoxVrCompositorVisit(PVBOXVR_COMPOSITOR pCompositor, PFNVBOXVRCOMPOSITOR_VISITOR pfnVisitor, void *pvVisitor)
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_NO_MEMORY;
static DECLCALLBACK(bool) crVrScrCompositorRectsCounterCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, void *pvVisitor)
typedef struct VBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER
static DECLCALLBACK(bool) crVrScrCompositorRectsAssignerCb(PVBOXVR_COMPOSITOR pCCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
#ifndef IN_RING0
pCompositor->StretchX >= 1. && pCompositor->StretchY >= 1. /* <- stretching can not zero some rects */
#ifndef IN_RING0
#ifndef IN_RING0
++iNew;
if (cDiff)
return VINF_SUCCESS;
if (!cRects)
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
static int crVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, uint32_t *pfChangedFlags)
int rc = VBoxVrCompositorEntryRegionsAdd(&pCompositor->Compositor, &pEntry->Ce, cRegions, paRegions, &fChangedFlags);
return rc;
if (pfChangedFlags)
return VINF_SUCCESS;
static int crVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
bool fChanged;
int rc = VBoxVrCompositorEntryRegionsSet(&pCompositor->Compositor, &pEntry->Ce, cRegions, paRegions, &fChanged);
return rc;
if (fChanged)
if (pfChanged)
return VINF_SUCCESS;
static int crVrScrCompositorEntryPositionSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, bool *pfChanged)
if (pfChanged)
*pfChanged = false;
int rc = VBoxVrCompositorEntryRegionsTranslate(&pCompositor->Compositor, &pEntry->Ce, pPos->x - pEntry->Pos.x, pPos->y - pEntry->Pos.y, pfChanged);
return rc;
if (pfChanged)
*pfChanged = true;
return VINF_SUCCESS;
static int crVrScrCompositorEntryEnsureRegionsInTex(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
return rc;
VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, uint32_t *pfChangeFlags)
int rc;
bool fPosChanged = false;
if (pPos)
return rc;
return rc;
return rc;
if (pfChangeFlags)
if (fPosChanged)
return VINF_SUCCESS;
VBOXVREGDECL(int) CrVrScrCompositorEntryTexUpdate(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const VBOXVR_TEXTURE *pTex)
bool fCompositorChanged = CrVrScrCompositorEntryIsUsed(pEntry) && (pEntry->Tex.width != pTex->width || pEntry->Tex.height != pTex->height);
if (fCompositorChanged)
return rc;
return VINF_SUCCESS;
VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
return rc;
if (pPos)
return rc;
return rc;
return rc;
if (pfChanged)
return VINF_SUCCESS;
VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const VBOXVR_LIST *pList2, bool *pfChanged)
bool fChanged = false;
int rc = VBoxVrCompositorEntryListIntersect(&pCompositor->Compositor, &pEntry->Ce, pList2, &fChanged);
return rc;
if (fChanged)
if (pfChanged)
return VINF_SUCCESS;
VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
bool fChanged = false;
int rc = VBoxVrCompositorEntryRegionsIntersect(&pCompositor->Compositor, &pEntry->Ce, cRegions, paRegions, &fChanged);
return rc;
if (fChanged)
if (pfChanged)
return VINF_SUCCESS;
VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pList2, bool *pfChanged)
bool fChanged = false;
bool fTmpChanged = false;
if (pfChanged)
return rc;
VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
bool fChanged = false;
bool fTmpChanged = false;
int tmpRc = CrVrScrCompositorEntryRegionsIntersect(pCompositor, pEntry, cRegions, paRegions, &fTmpChanged);
if (pfChanged)
return rc;
VBOXVREGDECL(int) CrVrScrCompositorEntryPosSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos)
return rc;
return VINF_SUCCESS;
VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsGet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions)
return rc;
if (ppaSrcRegions)
if (ppaDstRegions)
return VINF_SUCCESS;
VBOXVREGDECL(int) CrVrScrCompositorEntryRemove(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifndef IN_RING0
return rc;
#ifndef IN_RING0
return VINF_SUCCESS;
#ifndef IN_RING0
static DECLCALLBACK(bool) crVrScrCompositorEntrySetAllChangedCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
VBOXVREGDECL(void) CrVrScrCompositorEntrySetAllChanged(PVBOXVR_SCR_COMPOSITOR pCompositor, bool fChanged)
VBoxVrCompositorVisit(&pCompositor->Compositor, crVrScrCompositorEntrySetAllChangedCb, (void*)fChanged);
#ifndef IN_RING0
VBOXVREGDECL(void) CrVrScrCompositorSetStretching(PVBOXVR_SCR_COMPOSITOR pCompositor, float StretchX, float StretchY)
VBOXVREGDECL(int) CrVrScrCompositorRegionsGet(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions)
return rc;
if (ppaSrcRegions)
if (ppaDstRegions)
return VINF_SUCCESS;
typedef struct VBOXVR_SCR_COMPOSITOR_VISITOR_CB
void *pvVisitor;
static DECLCALLBACK(bool) crVrScrCompositorVisitCb(PVBOXVR_COMPOSITOR pCCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)