VirtualBox

Changeset 45132 in vbox for trunk/src/VBox/GuestHost/OpenGL


Ignore:
Timestamp:
Mar 21, 2013 4:11:28 PM (12 years ago)
Author:
vboxsync
Message:

crOpenGL: seamles mode support impl; bugfizes & cleanup

Location:
trunk/src/VBox/GuestHost/OpenGL
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/OpenGL/glapi_parser/APIspec.txt

    r44938 r45132  
    83678367param       window      GLint
    83688368param       cRects      GLint
    8369 param       pRects      GLint *
     8369param       pRects      const GLint *
    83708370category    Chromium
    83718371props       nolist
     
    83798379param       yPos        GLint
    83808380param       cRects      GLint
    8381 param       pRects      GLint *
     8381param       pRects      const GLint *
    83828382category    Chromium
    83838383props       nolist
  • trunk/src/VBox/GuestHost/OpenGL/include/chromium.h

    r45041 r45132  
    772772extern void APIENTRY crWindowSize(GLint window, GLint w, GLint h);
    773773extern void APIENTRY crWindowPosition(GLint window, GLint x, GLint y);
    774 extern void APIENTRY crWindowVisibleRegion( GLint window, GLint cRects, void *pRects );
     774extern void APIENTRY crWindowVisibleRegion( GLint window, GLint cRects, const void *pRects );
    775775extern void APIENTRY crWindowShow( GLint window, GLint flag );
    776 extern void APIENTRY crVBoxTexPresent(GLuint texture, GLuint cfg, GLint xPos, GLint yPos, GLint cRects, GLint *pRects);
     776extern void APIENTRY crVBoxTexPresent(GLuint texture, GLuint cfg, GLint xPos, GLint yPos, GLint cRects, const GLint *pRects);
    777777
    778778typedef int (CR_APIENTRY *CR_PROC)();
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_blitter.h

    r45009 r45132  
    5454struct CR_BLITTER;
    5555
    56 typedef DECLCALLBACK(int) FNCRBLT_BLITTER(struct CR_BLITTER *pBlitter, VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRect, const PRTRECTSIZE pDstSize, const RTRECT *paDstRect, uint32_t cRects, uint32_t fFlags);
     56typedef DECLCALLBACK(int) FNCRBLT_BLITTER(struct CR_BLITTER *pBlitter, VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRect, const RTRECTSIZE *pDstSize, const RTRECT *paDstRect, uint32_t cRects, uint32_t fFlags);
    5757typedef FNCRBLT_BLITTER *PFNCRBLT_BLITTER;
    5858
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h

    r45066 r45132  
    125125    GLuint idPBO;
    126126
     127    GLboolean fRootVrOn;
     128
    127129    VBOXVR_SCR_COMPOSITOR_ENTRY CEntry;
    128130    VBOXVR_SCR_COMPOSITOR Compositor;
     131
     132    /* if root Visible regions are set, these two contain actual regions being passed to render spu */
     133    VBOXVR_SCR_COMPOSITOR_ENTRY RootVrCEntry;
     134    VBOXVR_SCR_COMPOSITOR RootVrCompositor;
    129135
    130136    /* bitfield representing contexts the mural has been ever current with
     
    220226void CrDpResize(PCR_DISPLAY pDisplay, uint32_t width, uint32_t height,
    221227        uint32_t stretchedWidth, uint32_t stretchedHeight);
    222 void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, const PVBOXVR_TEXTURE pTextureData);
     228void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, const VBOXVR_TEXTURE *pTextureData);
    223229void CrDpEntryCleanup(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry);
    224230int CrDpEntryRegionsSet(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions);
     
    303309    /* visBits -> dummy mural association */
    304310    CRHashTable *dummyMuralTable;
     311
     312    GLboolean fRootVrOn;
     313    VBOXVR_LIST RootVr;
     314    /* we need to translate Root Vr to each window coords, this one cpecifies the current translation point
     315     * note that since window attributes modifications is performed in HGCM thread only and thus is serialized,
     316     * we deal with the global RootVr data directly */
     317    RTPOINT RootVrCurPoint;
    305318
    306319    /** configuration options */
     
    400413extern DECLEXPORT(int32_t) crVBoxServerMapScreen(int sIndex, int32_t x, int32_t y, uint32_t w, uint32_t h, uint64_t winID);
    401414
    402 extern DECLEXPORT(int32_t) crVBoxServerSetRootVisibleRegion(GLint cRects, GLint *pRects);
     415extern DECLEXPORT(int32_t) crVBoxServerSetRootVisibleRegion(GLint cRects, const RTRECT *pRects);
    403416
    404417extern DECLEXPORT(void) crVBoxServerSetPresentFBOCB(PFNCRSERVERPRESENTFBO pfnPresentFBO);
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_vreg.h

    r45053 r45132  
    4747}
    4848
     49DECLINLINE(void) VBoxRectIntersect(PRTRECT pRect1, const RTRECT * pRect2)
     50{
     51    Assert(pRect1);
     52    Assert(pRect2);
     53    pRect1->xLeft = RT_MAX(pRect1->xLeft, pRect2->xLeft);
     54    pRect1->yTop = RT_MAX(pRect1->yTop, pRect2->yTop);
     55    pRect1->xRight = RT_MIN(pRect1->xRight, pRect2->xRight);
     56    pRect1->yBottom = RT_MIN(pRect1->yBottom, pRect2->yBottom);
     57}
     58
     59DECLINLINE(void) VBoxRectIntersected(const RTRECT *pRect1, const RTRECT * pRect2, RTRECT *pResult)
     60{
     61    *pResult = *pRect1;
     62    VBoxRectIntersect(pResult, pRect2);
     63}
     64
     65
    4966DECLINLINE(void) VBoxRectTranslate(RTRECT * pRect, int32_t x, int32_t y)
    5067{
     
    93110}
    94111
    95 DECLINLINE(uint32_t) VBoxVrListRectsCount(PVBOXVR_LIST pList)
     112DECLINLINE(uint32_t) VBoxVrListRectsCount(const VBOXVR_LIST *pList)
    96113{
    97114    return pList->cEntries;
    98115}
    99116
    100 DECLINLINE(bool) VBoxVrListIsEmpty(const PVBOXVR_LIST pList)
     117DECLINLINE(bool) VBoxVrListIsEmpty(const VBOXVR_LIST *pList)
    101118{
    102119    return !VBoxVrListRectsCount(pList);
     
    115132VBOXVREGDECL(int) VBoxVrListCmp(PVBOXVR_LIST pList1, PVBOXVR_LIST pList2);
    116133
     134VBOXVREGDECL(int) VBoxVrListRectsSet(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged);
    117135VBOXVREGDECL(int) VBoxVrListRectsAdd(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged);
    118136VBOXVREGDECL(int) VBoxVrListRectsSubst(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged);
    119137VBOXVREGDECL(int) VBoxVrListRectsGet(PVBOXVR_LIST pList, uint32_t cRects, RTRECT * aRects);
     138
     139/* NOTE: with the current implementation the VBoxVrListIntersect is faster than VBoxVrListRectsIntersect,
     140 * i.e. VBoxVrListRectsIntersect is actually a convenience function that create a temporary list and calls VBoxVrListIntersect internally */
     141VBOXVREGDECL(int) VBoxVrListRectsIntersect(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged);
     142VBOXVREGDECL(int) VBoxVrListIntersect(PVBOXVR_LIST pList, const VBOXVR_LIST *pList2, bool *pfChanged);
    120143
    121144VBOXVREGDECL(int) VBoxVrInit();
     
    177200VBOXVREGDECL(void) VBoxVrCompositorTerm(PVBOXVR_COMPOSITOR pCompositor);
    178201VBOXVREGDECL(void) VBoxVrCompositorEntryInit(PVBOXVR_COMPOSITOR_ENTRY pEntry);
    179 DECLINLINE(bool) VBoxVrCompositorEntryIsInList(const PVBOXVR_COMPOSITOR_ENTRY pEntry)
     202DECLINLINE(bool) VBoxVrCompositorEntryIsInList(const VBOXVR_COMPOSITOR_ENTRY *pEntry)
    180203{
    181204    return !VBoxVrListIsEmpty(&pEntry->Vr);
    182205}
    183206
    184 #define VBOXVR_COMPOSITOR_CF_ENTRIES_REGIONS_CHANGED    0x00000001
    185 #define VBOXVR_COMPOSITOR_CF_COMPOSITED_REGIONS_CHANGED 0x00000002
    186 #define VBOXVR_COMPOSITOR_CF_ENTRY_ADDED                0x00000004
     207/* compositor regions changed
     208 * always comes with VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED */
     209#define VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED             0x00000001
     210/* only current entry regions changed */
     211#define VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED       0x00000002
     212/* the given entry has replaced some other entry, while overal regions did NOT change.
     213 * always comes with VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED */
     214#define VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED              0x00000004
    187215
    188216
     
    191219VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsSubst(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged);
    192220VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsSet(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged);
     221VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsIntersect(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged);
     222VBOXVREGDECL(int) VBoxVrCompositorEntryListIntersect(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, const VBOXVR_LIST *pList2, bool *pfChanged);
     223VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsIntersectAll(PVBOXVR_COMPOSITOR pCompositor, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged);
     224VBOXVREGDECL(int) VBoxVrCompositorEntryListIntersectAll(PVBOXVR_COMPOSITOR pCompositor, const VBOXVR_LIST *pList2, bool *pfChanged);
    193225VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsTranslate(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, int32_t x, int32_t y, bool *pfChanged);
    194226VBOXVREGDECL(void) VBoxVrCompositorVisit(PVBOXVR_COMPOSITOR pCompositor, PFNVBOXVRCOMPOSITOR_VISITOR pfnVisitor, void *pvVisitor);
    195227
    196 DECLINLINE(bool) VBoxVrCompositorIsEmpty(const PVBOXVR_COMPOSITOR pCompositor)
     228DECLINLINE(bool) VBoxVrCompositorIsEmpty(const VBOXVR_COMPOSITOR *pCompositor)
    197229{
    198230    return RTListIsEmpty(&pCompositor->List);
     
    261293typedef FNVBOXVRSCRCOMPOSITOR_VISITOR *PFNVBOXVRSCRCOMPOSITOR_VISITOR;
    262294
    263 DECLINLINE(void) CrVrScrCompositorEntryInit(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const PVBOXVR_TEXTURE pTex)
     295DECLINLINE(void) CrVrScrCompositorEntryInit(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const VBOXVR_TEXTURE *pTex)
    264296{
    265297    VBoxVrCompositorEntryInit(&pEntry->Ce);
     
    268300}
    269301
    270 DECLINLINE(bool) CrVrScrCompositorEntryIsUsed(const PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
     302DECLINLINE(bool) CrVrScrCompositorEntryIsUsed(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
    271303{
    272304    return VBoxVrCompositorEntryIsInList(&pEntry->Ce);
     
    284316}
    285317
    286 DECLINLINE(bool) CrVrScrCompositorEntryIsChanged(const PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
     318DECLINLINE(void) CrVrScrCompositorEntryTexUpdate(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const VBOXVR_TEXTURE *pTex)
     319{
     320    pEntry->Tex = *pTex;
     321    CrVrScrCompositorEntrySetChanged(pEntry, true);
     322}
     323
     324DECLINLINE(const VBOXVR_TEXTURE *) CrVrScrCompositorEntryTexGet(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
     325{
     326    return &pEntry->Tex;
     327}
     328
     329DECLINLINE(bool) CrVrScrCompositorEntryIsChanged(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
    287330{
    288331    return !!pEntry->fChanged;
    289332}
    290333
    291 DECLINLINE(bool) CrVrScrCompositorIsEmpty(const PVBOXVR_SCR_COMPOSITOR pCompositor)
     334DECLINLINE(bool) CrVrScrCompositorIsEmpty(const VBOXVR_SCR_COMPOSITOR *pCompositor)
    292335{
    293336    return VBoxVrCompositorIsEmpty(&pCompositor->Compositor);
     
    296339VBOXVREGDECL(void) CrVrScrCompositorVisit(PVBOXVR_SCR_COMPOSITOR pCompositor, PFNVBOXVRSCRCOMPOSITOR_VISITOR pfnVisitor, void *pvVisitor);
    297340VBOXVREGDECL(void) CrVrScrCompositorEntrySetAllChanged(PVBOXVR_SCR_COMPOSITOR pCompositor, bool fChanged);
    298 DECLINLINE(bool) CrVrScrCompositorEntryIsInList(const PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
     341DECLINLINE(bool) CrVrScrCompositorEntryIsInList(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
    299342{
    300343    return VBoxVrCompositorEntryIsInList(&pEntry->Ce);
    301344}
    302 VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions);
    303 VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions);
     345VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, uint32_t *pfChangeFlags);
     346VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged);
     347VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const VBOXVR_LIST *pList2, bool *pfChanged);
     348VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged);
     349VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged);
     350VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pList2, bool *pfChanged);
    304351VBOXVREGDECL(int) CrVrScrCompositorEntryPosSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos);
    305352
  • trunk/src/VBox/GuestHost/OpenGL/packer/pack_visibleregion.c

    r44529 r45132  
    2323#endif
    2424
    25 void PACK_APIENTRY crPackWindowVisibleRegion( CR_PACKER_CONTEXT_ARGDECL GLint window, GLint cRects, GLint * pRects )
     25void PACK_APIENTRY crPackWindowVisibleRegion( CR_PACKER_CONTEXT_ARGDECL GLint window, GLint cRects, const GLint * pRects )
    2626{
    2727    GLint i, size, cnt;
     
    5050}
    5151
    52 void PACK_APIENTRY crPackWindowVisibleRegionSWAP( CR_PACKER_CONTEXT_ARGDECL  GLint window, GLint cRects, GLint * pRects )
     52void PACK_APIENTRY crPackWindowVisibleRegionSWAP( CR_PACKER_CONTEXT_ARGDECL  GLint window, GLint cRects, const GLint * pRects )
    5353{
    5454    crError( "crPackWindowVisibleRegionSWAP unimplemented and shouldn't be called" );
  • trunk/src/VBox/GuestHost/OpenGL/util/blitter.cpp

    r45042 r45132  
    8181#define CRBLT_FILTER_FROM_FLAGS(_f) (((_f) & CRBLT_F_LINEAR) ? GL_LINEAR : GL_NEAREST)
    8282
    83 static DECLCALLBACK(int) crBltBlitTexBufImplFbo(PCR_BLITTER pBlitter, VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRect, const PRTRECTSIZE pDstSize, const RTRECT *paDstRect, uint32_t cRects, uint32_t fFlags)
     83static DECLCALLBACK(int) crBltBlitTexBufImplFbo(PCR_BLITTER pBlitter, VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRect, const RTRECTSIZE *pDstSize, const RTRECT *paDstRect, uint32_t cRects, uint32_t fFlags)
    8484{
    8585    GLenum filter = CRBLT_FILTER_FROM_FLAGS(fFlags);
     
    269269}
    270270
    271 static void crBltCheckSetupViewport(PCR_BLITTER pBlitter, const PRTRECTSIZE pDstSize, bool fFBODraw)
     271static void crBltCheckSetupViewport(PCR_BLITTER pBlitter, const RTRECTSIZE *pDstSize, bool fFBODraw)
    272272{
    273273    if (!pBlitter->Flags.LastWasFBODraw != !fFBODraw
     
    308308}
    309309
    310 static DECLCALLBACK(int) crBltBlitTexBufImplDraw2D(PCR_BLITTER pBlitter, VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRect, const PRTRECTSIZE pDstSize, const RTRECT *paDstRect, uint32_t cRects, uint32_t fFlags)
     310static DECLCALLBACK(int) crBltBlitTexBufImplDraw2D(PCR_BLITTER pBlitter, VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRect, const RTRECTSIZE *pDstSize, const RTRECT *paDstRect, uint32_t cRects, uint32_t fFlags)
    311311{
    312312    GLuint normalX, normalY;
     
    515515}
    516516
    517 static void crBltBlitTexBuf(PCR_BLITTER pBlitter, VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRects, GLenum enmDstBuff, const PRTRECTSIZE pDstSize, const RTRECT *paDstRects, uint32_t cRects, uint32_t fFlags)
     517static void crBltBlitTexBuf(PCR_BLITTER pBlitter, VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRects, GLenum enmDstBuff, const RTRECTSIZE *pDstSize, const RTRECT *paDstRects, uint32_t cRects, uint32_t fFlags)
    518518{
    519519    pBlitter->pDispatch->DrawBuffer(enmDstBuff);
  • trunk/src/VBox/GuestHost/OpenGL/util/vreg.cpp

    r45044 r45132  
    113113}
    114114
    115 typedef DECLCALLBACK(int) FNVBOXVR_CB_COMPARATOR(const PVBOXVR_REG pReg1, const PVBOXVR_REG pReg2);
     115typedef DECLCALLBACK(int) FNVBOXVR_CB_COMPARATOR(const VBOXVR_REG *pReg1, const VBOXVR_REG *pReg2);
    116116typedef FNVBOXVR_CB_COMPARATOR *PFNVBOXVR_CB_COMPARATOR;
    117117
     
    162162    RTListNodeRemove(&pReg->ListEntry);
    163163    --pList->cEntries;
     164    vboxVrDbgListVerify(pList);
    164165}
    165166
     
    292293}
    293294
     295/* @returns Entry to be used for continuing the rectangles iterations being made currently on the callback call.
     296 *          ListHead is returned to break the current iteration
     297 * @param ppNext specifies next reg entry to be used for iteration. the default is pReg1->ListEntry.pNext */
    294298typedef DECLCALLBACK(PRTLISTNODE) FNVBOXVR_CB_INTERSECTED_VISITOR(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, const RTRECT * pRect2, void *pvContext, PRTLISTNODE *ppNext);
    295299typedef FNVBOXVR_CB_INTERSECTED_VISITOR *PFNVBOXVR_CB_INTERSECTED_VISITOR;
     
    310314            if (VBoxRectIsZero(pRect2))
    311315                continue;
    312             if (pReg1->Rect.yBottom <= pRect2->yTop)
     316
     317            if (!VBoxRectIsIntersect(&pReg1->Rect, pRect2))
    313318                continue;
    314             else if (pRect2->yBottom <= pReg1->Rect.yTop)
    315                 continue;
    316             /* y coords intersect */
    317             else if (pReg1->Rect.xRight <= pRect2->xLeft)
    318                 continue;
    319             else if (pRect2->xRight <= pReg1->Rect.xLeft)
    320                 continue;
    321             /* x coords intersect */
    322319
    323320            /* the visitor can modify the list 1, apply necessary adjustments after it */
    324             PRTLISTNODE pEntry1 = pfnVisitor (pList1, pReg1, pRect2, pvVisitor, &pNext1);
     321            pEntry1 = pfnVisitor (pList1, pReg1, pRect2, pvVisitor, &pNext1);
    325322            if (pEntry1 == &pList1->ListHead)
    326323                break;
    327         }
    328     }
    329 }
    330 
     324            else
     325                pReg1 = PVBOXVR_REG_FROM_ENTRY(pEntry1);
     326        }
     327    }
     328}
     329
     330/* @returns Entry to be iterated next. ListHead is returned to break the iteration
     331 *
     332 */
     333typedef DECLCALLBACK(PRTLISTNODE) FNVBOXVR_CB_NONINTERSECTED_VISITOR(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, void *pvContext);
     334typedef FNVBOXVR_CB_NONINTERSECTED_VISITOR *PFNVBOXVR_CB_NONINTERSECTED_VISITOR;
     335
     336static void vboxVrListVisitNonintersected(PVBOXVR_LIST pList1, uint32_t cRects, const RTRECT *aRects, PFNVBOXVR_CB_NONINTERSECTED_VISITOR pfnVisitor, void* pvVisitor)
     337{
     338    PRTLISTNODE pEntry1 = pList1->ListHead.pNext;
     339    PRTLISTNODE pNext1;
     340    uint32_t iFirst2 = 0;
     341
     342    for (; pEntry1 != &pList1->ListHead; pEntry1 = pNext1)
     343    {
     344        PVBOXVR_REG pReg1 = PVBOXVR_REG_FROM_ENTRY(pEntry1);
     345        uint32_t i = iFirst2;
     346        for (; i < cRects; ++i)
     347        {
     348            const RTRECT *pRect2 = &aRects[i];
     349            if (VBoxRectIsZero(pRect2))
     350                continue;
     351
     352            if (VBoxRectIsIntersect(&pReg1->Rect, pRect2))
     353                break;
     354        }
     355
     356        if (i == cRects)
     357            pNext1 = pfnVisitor(pList1, pReg1, pvVisitor);
     358        else
     359            pNext1 = pEntry1->pNext;
     360    }
     361}
    331362
    332363static void vboxVrListJoinRectsHV(PVBOXVR_LIST pList, bool fHorizontal)
     
    508539static int vboxVrListSubstNoJoin(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
    509540{
     541    *pfChanged = false;
     542
    510543    if (VBoxVrListIsEmpty(pList))
    511544        return VINF_SUCCESS;
     
    514547    Data.rc = VINF_SUCCESS;
    515548    Data.fChanged = false;
    516 
    517     *pfChanged = false;
    518549
    519550    vboxVrListVisitIntersected(pList, cRects, aRects, vboxVrListSubstNoJoinCb, &Data);
     
    600631}
    601632
     633static DECLCALLBACK(PRTLISTNODE) vboxVrListIntersectNoJoinNonintersectedCb(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, void *pvContext)
     634{
     635    VBOXVR_CBDATA_SUBST *pData = (VBOXVR_CBDATA_SUBST*)pvContext;
     636
     637    PRTLISTNODE pNext = pReg1->ListEntry.pNext;
     638
     639    vboxVrDbgListVerify(pList1);
     640
     641    vboxVrListRegRemove(pList1, pReg1);
     642    vboxVrRegTerm(pReg1);
     643
     644    vboxVrDbgListVerify(pList1);
     645
     646    pData->fChanged = true;
     647
     648    return pNext;
     649}
     650
     651static DECLCALLBACK(PRTLISTNODE) vboxVrListIntersectNoJoinIntersectedCb(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, const RTRECT *pRect2, void *pvContext, PRTLISTNODE *ppNext)
     652{
     653    PVBOXVR_CBDATA_SUBST pData = (PVBOXVR_CBDATA_SUBST)pvContext;
     654    pData->fChanged = true;
     655
     656    vboxVrDbgListVerify(pList1);
     657
     658    PRTLISTNODE pMemberEntry = pReg1->ListEntry.pNext;
     659
     660    Assert(VBoxRectIsIntersect(&pReg1->Rect, pRect2));
     661    Assert(!VBoxRectIsZero(pRect2));
     662
     663    vboxVrListRegRemove(pList1, pReg1);
     664    VBoxRectIntersect(&pReg1->Rect, pRect2);
     665    Assert(!VBoxRectIsZero(&pReg1->Rect));
     666
     667    vboxVrListRegAddOrder(pList1, pMemberEntry, pReg1);
     668
     669    vboxVrDbgListVerify(pList1);
     670
     671    return &pReg1->ListEntry;
     672}
     673
     674static int vboxVrListIntersectNoJoin(PVBOXVR_LIST pList, const VBOXVR_LIST *pList2, bool *pfChanged)
     675{
     676    bool fChanged = false;
     677    *pfChanged = false;
     678
     679    if (VBoxVrListIsEmpty(pList))
     680        return VINF_SUCCESS;
     681
     682    if (VBoxVrListIsEmpty(pList2))
     683    {
     684        if (pfChanged)
     685            *pfChanged = true;
     686
     687        VBoxVrListClear(pList);
     688        return VINF_SUCCESS;
     689    }
     690
     691    PRTLISTNODE pNext1;
     692
     693    for (PRTLISTNODE pEntry1 = pList->ListHead.pNext; pEntry1 != &pList->ListHead; pEntry1 = pNext1)
     694    {
     695        pNext1 = pEntry1->pNext;
     696        PVBOXVR_REG pReg1 = PVBOXVR_REG_FROM_ENTRY(pEntry1);
     697        RTRECT RegRect1 = pReg1->Rect;
     698        PRTLISTNODE pMemberEntry = pReg1->ListEntry.pNext;
     699
     700        for (const RTLISTNODE *pEntry2 = pList2->ListHead.pNext; pEntry2 != &pList2->ListHead; pEntry2 = pEntry2->pNext)
     701        {
     702            const VBOXVR_REG *pReg2 = PVBOXVR_REG_FROM_ENTRY(pEntry2);
     703            const RTRECT *pRect2 = &pReg2->Rect;
     704
     705            if (!VBoxRectIsIntersect(&RegRect1, pRect2))
     706                continue;
     707
     708            if (pReg1)
     709            {
     710                if (!VBoxRectCmp(&pReg1->Rect, pRect2))
     711                {
     712                    /* no change, and we can break the iteration here */
     713
     714                    /* zero up the pReg1 to mark it as intersected (see the code after this inner loop) */
     715                    pReg1 = NULL;
     716                    break;
     717                }
     718                /* @todo: this can have false-alarming sometimes if the separated rects will then be joind into the original rect,
     719                 * so far this should not be a problem for VReg clients, so keep it this way for now  */
     720                fChanged = true;
     721
     722                /* re-use the reg entry */
     723                vboxVrListRegRemove(pList, pReg1);
     724                VBoxRectIntersect(&pReg1->Rect, pRect2);
     725                Assert(!VBoxRectIsZero(&pReg1->Rect));
     726
     727                vboxVrListRegAddOrder(pList, pMemberEntry, pReg1);
     728                pReg1 = NULL;
     729            }
     730            else
     731            {
     732                Assert(fChanged); /* <- should be set by the if branch above */
     733                PVBOXVR_REG pReg = vboxVrRegCreate();
     734                if (!pReg)
     735                {
     736                    WARN(("vboxVrRegCreate failed!"));
     737                    return VERR_NO_MEMORY;
     738                }
     739                VBoxRectIntersected(&RegRect1, pRect2, &pReg->Rect);
     740                Assert(!VBoxRectIsZero(&pReg->Rect));
     741                vboxVrListRegAddOrder(pList, pList->ListHead.pNext, pReg);
     742            }
     743        }
     744
     745        if (pReg1)
     746        {
     747            /* the region has no intersections, remove it */
     748            vboxVrListRegRemove(pList, pReg1);
     749            vboxVrRegTerm(pReg1);
     750            fChanged = true;
     751        }
     752    }
     753
     754    *pfChanged = fChanged;
     755    return VINF_SUCCESS;
     756}
     757
     758VBOXVREGDECL(int) VBoxVrListIntersect(PVBOXVR_LIST pList, const VBOXVR_LIST *pList2, bool *pfChanged)
     759{
     760    if (pfChanged)
     761        *pfChanged = false;
     762
     763    int rc = vboxVrListIntersectNoJoin(pList, pList2, pfChanged);
     764    if (!RT_SUCCESS(rc))
     765    {
     766        WARN(("vboxVrListSubstNoJoin failed!"));
     767        return rc;
     768    }
     769
     770    if (*pfChanged)
     771    {
     772        vboxVrListJoinRects(pList);
     773    }
     774
     775    return rc;
     776}
     777
     778VBOXVREGDECL(int) VBoxVrListRectsIntersect(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
     779{
     780    if (pfChanged)
     781        *pfChanged = false;
     782
     783    if (VBoxVrListIsEmpty(pList))
     784        return VINF_SUCCESS;
     785
     786    if (!cRects)
     787    {
     788        if (pfChanged)
     789            *pfChanged = true;
     790
     791        VBoxVrListClear(pList);
     792        return VINF_SUCCESS;
     793    }
     794
     795    /* we perform intersection using lists because the algorythm axpects the rects to be non-intersected,
     796     * which list guaranties to us */
     797
     798    VBOXVR_LIST TmpList;
     799    VBoxVrListInit(&TmpList);
     800
     801    int rc = VBoxVrListRectsAdd(&TmpList, cRects, aRects, NULL);
     802    if (RT_SUCCESS(rc))
     803    {
     804        rc = VBoxVrListIntersect(pList, &TmpList, pfChanged);
     805        if (!RT_SUCCESS(rc))
     806        {
     807            WARN(("VBoxVrListIntersect failed! rc %d", rc));
     808        }
     809    }
     810    else
     811    {
     812        WARN(("VBoxVrListRectsAdd failed, rc %d", rc));
     813    }
     814    VBoxVrListClear(&TmpList);
     815
     816    return rc;
     817}
     818
    602819VBOXVREGDECL(int) VBoxVrListRectsSubst(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
    603820{
     
    631848}
    632849
     850VBOXVREGDECL(int) VBoxVrListRectsSet(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
     851{
     852    if (pfChanged)
     853        *pfChanged = false;
     854
     855    if (!cRects && VBoxVrListIsEmpty(pList))
     856    {
     857        return VINF_SUCCESS;
     858    }
     859
     860    /* @todo: fChanged will have false alarming here, fix if needed */
     861    VBoxVrListClear(pList);
     862
     863    int rc = VBoxVrListRectsAdd(pList, cRects, aRects, NULL);
     864    if (!RT_SUCCESS(rc))
     865    {
     866        WARN(("VBoxVrListRectsSet failed rc %d", rc));
     867        return rc;
     868    }
     869
     870    if (pfChanged)
     871        *pfChanged = true;
     872
     873    return VINF_SUCCESS;
     874}
     875
    633876VBOXVREGDECL(int) VBoxVrListRectsAdd(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
    634877{
    635878    uint32_t cCovered = 0;
     879
     880    if (pfChanged)
     881        *pfChanged = false;
    636882
    637883#if 0
     
    673919
    674920    if (cCovered == cRects)
    675     {
    676         *pfChanged = false;
    677921        return VINF_SUCCESS;
    678     }
    679922
    680923    /* rects are not covered, need to go the slow way */
     
    7661009        vboxVrListJoinRects(pList);
    7671010
    768     *pfChanged = fChanged;
     1011    if (pfChanged)
     1012        *pfChanged = fChanged;
    7691013
    7701014    return VINF_SUCCESS;
     
    8711115VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsAdd(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT *paRects, uint32_t *pfChangeFlags)
    8721116{
    873     bool fOthersChanged = false, fCurChanged = false, fEntryChanged = false, fEntryInList = false, fEntryReplaces = false;
     1117    bool fOthersChanged = false, fCurChanged = false, fEntryChanged = false, fEntryWasInList = false, fEntryReplaced = false;
    8741118    PVBOXVR_COMPOSITOR_ENTRY pCur;
    8751119    int rc = VINF_SUCCESS;
     
    8841128    if (pEntry)
    8851129    {
    886         fEntryInList = VBoxVrCompositorEntryIsInList(pEntry);
     1130        fEntryWasInList = VBoxVrCompositorEntryIsInList(pEntry);
    8871131        rc = VBoxVrListRectsAdd(&pEntry->Vr, cRects, paRects, &fEntryChanged);
    8881132        if (RT_SUCCESS(rc))
     
    9101154        if (pCur == pEntry)
    9111155        {
    912             Assert(fEntryInList);
     1156            Assert(fEntryWasInList);
    9131157        }
    9141158        else
     
    9181162                VBoxVrListClear(&pCur->Vr);
    9191163                vboxVrCompositorEntryRemove(pCompositor, pCur, pEntry);
    920                 fEntryReplaces = true;
     1164                fEntryReplaced = true;
     1165                break;
    9211166            }
    9221167            else
     
    9361181    AssertRC(rc);
    9371182
    938     if (pEntry && !fEntryInList)
     1183    if (pEntry && !fEntryWasInList)
    9391184    {
    9401185        Assert(!VBoxVrListIsEmpty(&pEntry->Vr));
     
    9461191        uint32_t fFlags = 0;
    9471192        if (fOthersChanged)
    948             fFlags = VBOXVR_COMPOSITOR_CF_ENTRIES_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_COMPOSITED_REGIONS_CHANGED;
    949         else if (fEntryReplaces)
     1193            fFlags = VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED;
     1194        else if (fEntryReplaced)
    9501195        {
    9511196            Assert(fEntryChanged);
    952             fFlags = VBOXVR_COMPOSITOR_CF_ENTRIES_REGIONS_CHANGED;
     1197            fFlags = VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED;
    9531198        }
    9541199        else if (fEntryChanged)
    955             fFlags = VBOXVR_COMPOSITOR_CF_ENTRIES_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_COMPOSITED_REGIONS_CHANGED;
    956         if (!fEntryInList)
    957             fFlags |= VBOXVR_COMPOSITOR_CF_ENTRY_ADDED;
     1200            fFlags = VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED;
     1201
     1202        if (!fEntryWasInList)
     1203            Assert(fEntryChanged);
    9581204
    9591205        *pfChangeFlags = fFlags;
     
    10191265        *pfChanged = fChanged;
    10201266    return VINF_SUCCESS;
     1267}
     1268
     1269VBOXVREGDECL(int) VBoxVrCompositorEntryListIntersect(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, const VBOXVR_LIST *pList2, bool *pfChanged)
     1270{
     1271    int rc = VINF_SUCCESS;
     1272    bool fChanged = false;
     1273    if (VBoxVrCompositorEntryIsInList(pEntry))
     1274    {
     1275        rc = VBoxVrListIntersect(&pEntry->Vr, pList2, &fChanged);
     1276        if (RT_SUCCESS(rc))
     1277        {
     1278            if (VBoxVrListIsEmpty(&pEntry->Vr))
     1279            {
     1280                Assert(fChanged);
     1281                vboxVrCompositorEntryRemove(pCompositor, pEntry, NULL);
     1282            }
     1283        }
     1284        else
     1285        {
     1286            WARN(("VBoxVrListRectsIntersect failed, rc %d", rc));
     1287        }
     1288    }
     1289
     1290    if (pfChanged)
     1291        *pfChanged = fChanged;
     1292
     1293    return rc;
     1294}
     1295
     1296VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsIntersect(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT *paRects, bool *pfChanged)
     1297{
     1298    int rc = VINF_SUCCESS;
     1299    bool fChanged = false;
     1300    if (VBoxVrCompositorEntryIsInList(pEntry))
     1301    {
     1302        rc = VBoxVrListRectsIntersect(&pEntry->Vr, cRects, paRects, &fChanged);
     1303        if (RT_SUCCESS(rc))
     1304        {
     1305            if (VBoxVrListIsEmpty(&pEntry->Vr))
     1306            {
     1307                Assert(fChanged);
     1308                vboxVrCompositorEntryRemove(pCompositor, pEntry, NULL);
     1309            }
     1310        }
     1311        else
     1312        {
     1313            WARN(("VBoxVrListRectsIntersect failed, rc %d", rc));
     1314        }
     1315    }
     1316
     1317    if (pfChanged)
     1318        *pfChanged = fChanged;
     1319
     1320    return rc;
     1321}
     1322
     1323VBOXVREGDECL(int) VBoxVrCompositorEntryListIntersectAll(PVBOXVR_COMPOSITOR pCompositor, const VBOXVR_LIST *pList2, bool *pfChanged)
     1324{
     1325    VBOXVR_COMPOSITOR_ITERATOR Iter;
     1326    VBoxVrCompositorIterInit(pCompositor, &Iter);
     1327    PVBOXVR_COMPOSITOR_ENTRY pEntry;
     1328    int rc = VINF_SUCCESS;
     1329    bool fChanged = false;
     1330
     1331    while ((pEntry = VBoxVrCompositorIterNext(&Iter)) != NULL)
     1332    {
     1333        bool fTmpChanged = false;
     1334        int tmpRc = VBoxVrCompositorEntryListIntersect(pCompositor, pEntry, pList2, &fTmpChanged);
     1335        if (RT_SUCCESS(tmpRc))
     1336        {
     1337            fChanged |= fChanged;
     1338        }
     1339        else
     1340        {
     1341            crWarning("VBoxVrCompositorEntryRegionsIntersect failed, rc %d", tmpRc);
     1342            rc = tmpRc;
     1343        }
     1344    }
     1345
     1346    if (pfChanged)
     1347        *pfChanged = fChanged;
     1348
     1349    return rc;
     1350}
     1351
     1352VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsIntersectAll(PVBOXVR_COMPOSITOR pCompositor, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
     1353{
     1354    VBOXVR_COMPOSITOR_ITERATOR Iter;
     1355    VBoxVrCompositorIterInit(pCompositor, &Iter);
     1356    PVBOXVR_COMPOSITOR_ENTRY pEntry;
     1357    int rc = VINF_SUCCESS;
     1358    bool fChanged = false;
     1359
     1360    while ((pEntry = VBoxVrCompositorIterNext(&Iter)) != NULL)
     1361    {
     1362        bool fTmpChanged = false;
     1363        int tmpRc = VBoxVrCompositorEntryRegionsIntersect(pCompositor, pEntry, cRegions, paRegions, &fTmpChanged);
     1364        if (RT_SUCCESS(tmpRc))
     1365        {
     1366            fChanged |= fChanged;
     1367        }
     1368        else
     1369        {
     1370            crWarning("VBoxVrCompositorEntryRegionsIntersect failed, rc %d", tmpRc);
     1371            rc = tmpRc;
     1372        }
     1373    }
     1374
     1375    if (pfChanged)
     1376        *pfChanged = fChanged;
     1377
     1378    return rc;
    10211379}
    10221380
     
    12681626
    12691627
    1270 static int crVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
     1628static int crVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, uint32_t *pfChangedFlags)
    12711629{
    12721630    uint32_t fChangedFlags = 0;
     
    12781636    }
    12791637
    1280     if (fChangedFlags & VBOXVR_COMPOSITOR_CF_COMPOSITED_REGIONS_CHANGED)
     1638    if (fChangedFlags & VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED)
    12811639    {
    12821640        crVrScrCompositorRectsInvalidate(pCompositor);
    12831641    }
    12841642
    1285     CrVrScrCompositorEntrySetChanged(pEntry, true);
    1286 
    1287     if (pfChanged)
    1288         *pfChanged = !!fChangedFlags;
     1643    if (fChangedFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED)
     1644    {
     1645        CrVrScrCompositorEntrySetChanged(pEntry, true);
     1646    }
     1647
     1648    if (pfChangedFlags)
     1649        *pfChangedFlags = fChangedFlags;
    12891650    return VINF_SUCCESS;
    12901651}
     
    13341695}
    13351696
    1336 VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
     1697VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, uint32_t *pfChangeFlags)
    13371698{
    13381699    int rc;
     1700    uint32_t fChangeFlags = 0;
     1701    bool fPosChanged = false;
    13391702    if (pPos)
    13401703    {
    1341         rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, pPos, NULL);
     1704        rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, pPos, &fPosChanged);
    13421705        if (!RT_SUCCESS(rc))
    13431706        {
     
    13471710    }
    13481711
    1349     rc = crVrScrCompositorEntryRegionsAdd(pCompositor, pEntry, cRegions, paRegions, NULL);
     1712    rc = crVrScrCompositorEntryRegionsAdd(pCompositor, pEntry, cRegions, paRegions, &fChangeFlags);
    13501713    if (!RT_SUCCESS(rc))
    13511714    {
     
    13541717    }
    13551718
     1719    if (pfChangeFlags)
     1720    {
     1721        if (fPosChanged)
     1722        {
     1723            /* means entry was in list and was moved, so regions changed */
     1724            *pfChangeFlags = VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED;
     1725        }
     1726        else
     1727            *pfChangeFlags = fChangeFlags;
     1728    }
     1729
    13561730    return VINF_SUCCESS;
    13571731}
    13581732
    1359 VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
    1360 {
     1733VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
     1734{
     1735    bool fChanged = false, fPosChanged = false;
    13611736    int rc = CrVrScrCompositorEntryRemove(pCompositor, pEntry);
    13621737    if (!RT_SUCCESS(rc))
     
    13681743    if (pPos)
    13691744    {
    1370         rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, pPos, NULL);
     1745        rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, pPos, &fPosChanged);
    13711746        if (!RT_SUCCESS(rc))
    13721747        {
     
    13761751    }
    13771752
    1378     rc = crVrScrCompositorEntryRegionsSet(pCompositor, pEntry, cRegions, paRegions, NULL);
     1753    rc = crVrScrCompositorEntryRegionsSet(pCompositor, pEntry, cRegions, paRegions, &fChanged);
    13791754    if (!RT_SUCCESS(rc))
    13801755    {
     
    13831758    }
    13841759
     1760    if (pfChanged)
     1761        *pfChanged = fPosChanged || fChanged;
     1762
    13851763    return VINF_SUCCESS;
     1764}
     1765
     1766VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const VBOXVR_LIST *pList2, bool *pfChanged)
     1767{
     1768    bool fChanged = false;
     1769    int rc = VBoxVrCompositorEntryListIntersect(&pCompositor->Compositor, &pEntry->Ce, pList2, &fChanged);
     1770    if (!RT_SUCCESS(rc))
     1771    {
     1772        crWarning("RegionsIntersect: VBoxVrCompositorEntryRegionsIntersect failed rc %d", rc);
     1773        return rc;
     1774    }
     1775
     1776    if (fChanged)
     1777    {
     1778        CrVrScrCompositorEntrySetChanged(pEntry, true);
     1779        crVrScrCompositorRectsInvalidate(pCompositor);
     1780    }
     1781
     1782    if (pfChanged)
     1783        *pfChanged = fChanged;
     1784
     1785    return VINF_SUCCESS;
     1786}
     1787
     1788VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
     1789{
     1790    bool fChanged = false;
     1791    int rc = VBoxVrCompositorEntryRegionsIntersect(&pCompositor->Compositor, &pEntry->Ce, cRegions, paRegions, &fChanged);
     1792    if (!RT_SUCCESS(rc))
     1793    {
     1794        crWarning("RegionsIntersect: VBoxVrCompositorEntryRegionsIntersect failed rc %d", rc);
     1795        return rc;
     1796    }
     1797
     1798    if (fChanged)
     1799    {
     1800        CrVrScrCompositorEntrySetChanged(pEntry, true);
     1801        crVrScrCompositorRectsInvalidate(pCompositor);
     1802    }
     1803
     1804    if (pfChanged)
     1805        *pfChanged = fChanged;
     1806
     1807    return VINF_SUCCESS;
     1808}
     1809
     1810VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pList2, bool *pfChanged)
     1811{
     1812    VBOXVR_SCR_COMPOSITOR_ITERATOR Iter;
     1813    CrVrScrCompositorIterInit(pCompositor, &Iter);
     1814    PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
     1815    int rc = VINF_SUCCESS;
     1816    bool fChanged = false;
     1817
     1818    while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL)
     1819    {
     1820        bool fTmpChanged = false;
     1821        int tmpRc = CrVrScrCompositorEntryListIntersect(pCompositor, pEntry, pList2, &fTmpChanged);
     1822        if (RT_SUCCESS(tmpRc))
     1823        {
     1824            fChanged |= fTmpChanged;
     1825        }
     1826        else
     1827        {
     1828            crWarning("CrVrScrCompositorEntryRegionsIntersect failed, rc %d", tmpRc);
     1829            rc = tmpRc;
     1830        }
     1831    }
     1832
     1833    if (pfChanged)
     1834        *pfChanged = fChanged;
     1835
     1836    return rc;
     1837}
     1838
     1839VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
     1840{
     1841    VBOXVR_SCR_COMPOSITOR_ITERATOR Iter;
     1842    CrVrScrCompositorIterInit(pCompositor, &Iter);
     1843    PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
     1844    int rc = VINF_SUCCESS;
     1845    bool fChanged = false;
     1846
     1847    while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL)
     1848    {
     1849        bool fTmpChanged = false;
     1850        int tmpRc = CrVrScrCompositorEntryRegionsIntersect(pCompositor, pEntry, cRegions, paRegions, &fTmpChanged);
     1851        if (RT_SUCCESS(tmpRc))
     1852        {
     1853            fChanged |= fTmpChanged;
     1854        }
     1855        else
     1856        {
     1857            crWarning("CrVrScrCompositorEntryRegionsIntersect failed, rc %d", tmpRc);
     1858            rc = tmpRc;
     1859        }
     1860    }
     1861
     1862    if (pfChanged)
     1863        *pfChanged = fChanged;
     1864
     1865    return rc;
    13861866}
    13871867
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