VirtualBox

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

crOpenGL: seamles mode support impl; bugfizes & cleanup

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c

    r45066 r45132  
    2424    GLint spuWindow;
    2525    VBOXVR_TEXTURE Tex = {0};
    26 
    27     int rc = CrVrScrCompositorInit(&mural->Compositor);
     26    RTRECT Rect;
     27    int rc;
     28
     29    crMemset(mural, 0, sizeof (*mural));
     30
     31    rc = CrVrScrCompositorInit(&mural->Compositor);
    2832    if (!RT_SUCCESS(rc))
    2933    {
    3034        crWarning("CrVrScrCompositorInit failed, rc %d", rc);
    3135        return -1;
     36    }
     37
     38    if (cr_server.fRootVrOn)
     39    {
     40        rc = CrVrScrCompositorInit(&mural->RootVrCompositor);
     41        if (!RT_SUCCESS(rc))
     42        {
     43            crWarning("CrVrScrCompositorInit failed, rc %d", rc);
     44            return -1;
     45        }
    3246    }
    3347
     
    3852    if (spuWindow < 0) {
    3953        CrVrScrCompositorTerm(&mural->Compositor);
     54        if (cr_server.fRootVrOn)
     55            CrVrScrCompositorTerm(&mural->RootVrCompositor);
    4056        return spuWindow;
    4157    }
     
    4965    Tex.hwid = 0;
    5066    CrVrScrCompositorEntryInit(&mural->CEntry, &Tex);
     67
     68    if (cr_server.fRootVrOn)
     69    {
     70        CrVrScrCompositorEntryInit(&mural->RootVrCEntry, &Tex);
     71        mural->fRootVrOn = GL_TRUE;
     72    }
    5173
    5274    defaultMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, 0);
     
    83105
    84106    crServerSetupOutputRedirect(mural);
     107
     108    Rect.xLeft = 0;
     109    Rect.xRight = mural->width;
     110    Rect.yTop = 0;
     111    Rect.yBottom = mural->height;
     112    rc = CrVrScrCompositorEntryRegionsSet(&mural->Compositor, &mural->CEntry, NULL, 1, &Rect, NULL);
     113    if (!RT_SUCCESS(rc))
     114    {
     115        crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
     116        return -1;
     117    }
     118
     119    if (mural->fRootVrOn)
     120    {
     121        uint32_t cRects;
     122        const RTRECT *pRects;
     123        int rc = crServerMuralSynchRootVr(mural, &cRects, &pRects);
     124        if (RT_SUCCESS(rc))
     125        {
     126            if (cRects != 1
     127                    || pRects[0].xLeft != 0 || pRects[0].yTop != 0
     128                    || pRects[0].xRight != mural->width || pRects[0].yBottom != mural->height)
     129            {
     130                /* do visible rects only ig they differ from the default */
     131                cr_server.head_spu->dispatch_table.WindowVisibleRegion(mural->spuWindow, cRects, pRects);
     132
     133                if (mural->pvOutputRedirectInstance)
     134                {
     135                    /* @todo the code assumes that RTRECT == four GLInts. */
     136                    cr_server.outputRedirect.CRORVisibleRegion(mural->pvOutputRedirectInstance,
     137                                                               cRects, pRects);
     138                }
     139            }
     140        }
     141    }
    85142
    86143    return windowID;
     
    165222}
    166223
     224static bool crServerVBoxTranslateIntersectRect(CRMuralInfo *mural, const RTRECT *pSrcRect, PRTRECT pDstRect)
     225{
     226    int32_t xLeft = RT_MAX(mural->gX, pSrcRect->xRight);
     227    int32_t yTop = RT_MAX(mural->gY, pSrcRect->yBottom);
     228    int32_t xRight = RT_MIN(mural->gX + mural->width, pSrcRect->xLeft);
     229    int32_t yBottom = RT_MIN(mural->gY + mural->height, pSrcRect->yTop);
     230
     231    if (xLeft < xRight && yTop < yBottom)
     232    {
     233        pDstRect->xLeft = xLeft;
     234        pDstRect->yTop = yTop;
     235        pDstRect->xRight = xRight;
     236        pDstRect->yBottom = yBottom;
     237        return true;
     238    }
     239
     240    return false;
     241}
     242
     243static void crServerVBoxRootVrTranslateForMural(CRMuralInfo *mural)
     244{
     245    int32_t dx = cr_server.RootVrCurPoint.x - mural->gX;
     246    int32_t dy = cr_server.RootVrCurPoint.y - mural->gY;
     247
     248    VBoxVrListTranslate(&cr_server.RootVr, dx, dy);
     249}
     250
    167251static int crServerRemoveClientWindow(CRClient *pClient, GLint window)
    168252{
     
    316400    CrVrScrCompositorTerm(&mural->Compositor);
    317401
     402    if (mural->fRootVrOn)
     403        CrVrScrCompositorTerm(&mural->RootVrCompositor);
     404
    318405    crHashtableDelete(cr_server.muralTable, window, crFree);
    319406}
    320407
     408int crServerMuralSynchRootVr(CRMuralInfo *mural, uint32_t *pcRects, const RTRECT **ppRects)
     409{
     410    int rc;
     411
     412    rc = CrVrScrCompositorEntryRegionsGet(&mural->Compositor, &mural->CEntry, pcRects, NULL, ppRects);
     413    if (!RT_SUCCESS(rc))
     414    {
     415        crWarning("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc);
     416        return rc;
     417    }
     418
     419    rc = CrVrScrCompositorEntryRegionsSet(&mural->RootVrCompositor, &mural->RootVrCEntry, NULL, *pcRects, *ppRects, NULL);
     420    if (!RT_SUCCESS(rc))
     421    {
     422        crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
     423        return rc;
     424    }
     425
     426    crServerVBoxRootVrTranslateForMural(mural);
     427    rc = CrVrScrCompositorEntryListIntersect(&mural->RootVrCompositor, &mural->RootVrCEntry, &cr_server.RootVr, NULL);
     428    if (!RT_SUCCESS(rc))
     429    {
     430        crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
     431        return rc;
     432    }
     433
     434    rc = CrVrScrCompositorEntryRegionsGet(&mural->RootVrCompositor, &mural->RootVrCEntry, pcRects, NULL, ppRects);
     435    if (!RT_SUCCESS(rc))
     436    {
     437        crWarning("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc);
     438        return rc;
     439    }
     440
     441    return VINF_SUCCESS;
     442}
     443
    321444void crServerMuralSize(CRMuralInfo *mural, GLint width, GLint height)
    322445{
    323446    if (mural->width != width || mural->height != height)
    324447    {
     448        uint32_t cRects;
     449        const RTRECT *pRects;
    325450        RTRECT Rect;
    326451        VBOXVR_TEXTURE Tex;
     452        int rc = VINF_SUCCESS;
    327453        Tex.width = width;
    328454        Tex.height = height;
     
    346472        /* the compositor lock is not needed actually since we have prevented renderspu from using the compositor */
    347473        /* CrVrScrCompositorLock(&mural->Compositor); */
    348         CrVrScrCompositorEntryRemove(&mural->Compositor, &mural->CEntry);
     474        rc = CrVrScrCompositorEntryRemove(&mural->Compositor, &mural->CEntry);
     475        if (!RT_SUCCESS(rc))
     476        {
     477            crWarning("CrVrScrCompositorEntryRemove failed, rc %d", rc);
     478            return;
     479        }
    349480        CrVrScrCompositorEntryInit(&mural->CEntry, &Tex);
    350481        /* initially set regions to all visible since this is what some guest assume
     
    354485        Rect.yTop = 0;
    355486        Rect.yBottom = height;
    356         CrVrScrCompositorEntryRegionsSet(&mural->Compositor, &mural->CEntry, NULL, 1, &Rect);
     487        rc = CrVrScrCompositorEntryRegionsSet(&mural->Compositor, &mural->CEntry, NULL, 1, &Rect, NULL);
     488        if (!RT_SUCCESS(rc))
     489        {
     490            crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
     491            return;
     492        }
    357493        /* CrVrScrCompositorUnlock(&mural->Compositor); */
    358494        mural->width = width;
     
    365501        }
    366502
     503        if (mural->fRootVrOn)
     504        {
     505            rc = CrVrScrCompositorEntryRemove(&mural->RootVrCompositor, &mural->RootVrCEntry);
     506            if (!RT_SUCCESS(rc))
     507            {
     508                crWarning("CrVrScrCompositorEntryRemove failed, rc %d", rc);
     509                return;
     510            }
     511            CrVrScrCompositorEntryInit(&mural->RootVrCEntry, &Tex);
     512            /* initially set regions to all visible since this is what some guest assume
     513             * and will not post any more visible regions command */
     514            Rect.xLeft = 0;
     515            Rect.xRight = width;
     516            Rect.yTop = 0;
     517            Rect.yBottom = height;
     518            rc = CrVrScrCompositorEntryRegionsSet(&mural->RootVrCompositor, &mural->RootVrCEntry, NULL, 1, &Rect, NULL);
     519            if (!RT_SUCCESS(rc))
     520            {
     521                crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
     522                return;
     523            }
     524
     525            crServerVBoxRootVrTranslateForMural(mural);
     526            rc = CrVrScrCompositorEntryListIntersect(&mural->RootVrCompositor, &mural->RootVrCEntry, &cr_server.RootVr, NULL);
     527            if (!RT_SUCCESS(rc))
     528            {
     529                crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
     530                return;
     531            }
     532
     533            rc = CrVrScrCompositorEntryRegionsGet(&mural->RootVrCompositor, &mural->RootVrCEntry, &cRects, NULL, &pRects);
     534            if (!RT_SUCCESS(rc))
     535            {
     536                crWarning("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc);
     537                return;
     538            }
     539        }
     540        else
     541        {
     542            rc = CrVrScrCompositorEntryRegionsGet(&mural->Compositor, &mural->CEntry, &cRects, NULL, &pRects);
     543            if (!RT_SUCCESS(rc))
     544            {
     545                crWarning("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc);
     546                return;
     547            }
     548        }
     549
    367550        crServerCheckMuralGeometry(mural);
    368551
    369552        cr_server.head_spu->dispatch_table.WindowSize(mural->spuWindow, width, height);
     553
     554        cr_server.head_spu->dispatch_table.WindowVisibleRegion(mural->spuWindow, cRects, pRects);
     555
     556        if (mural->pvOutputRedirectInstance)
     557        {
     558            /* @todo the code assumes that RTRECT == four GLInts. */
     559            cr_server.outputRedirect.CRORVisibleRegion(mural->pvOutputRedirectInstance,
     560                                                       cRects, (RTRECT *)pRects);
     561        }
    370562
    371563        /* 3. (so far not needed for resize, but in case it is in the future) re-set the compositor (see above comment) */
     
    404596{
    405597    CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
    406     RTPOINT Pos;
     598    GLboolean fForcePresent = GL_FALSE;
    407599    /*  crDebug("CRServer: Window %d pos %d, %d", window, x, y);*/
    408600    if (!mural) {
     
    427619        /* 2. do necessary modifications (see above comment) */
    428620        /* NOTE: we can do it even if mural->fUseFBO == CR_SERVER_REDIR_NONE to make sure the compositor data is always up to date */
    429         Pos.x = x;
    430         Pos.y = y;
    431 
    432         /* the compositor lock is not needed actually since we have prevented renderspu from using the compositor */
    433         /* CrVrScrCompositorLock(&mural->Compositor); */
    434         /* no need to set position because the position is relative to window */
    435         /*CrVrScrCompositorEntryPosSet(&mural->Compositor, &mural->CEntry, &Pos);*/
    436         /*CrVrScrCompositorUnlock(&mural->Compositor);*/
    437 
    438         mural->gX = x;
    439         mural->gY = y;
     621
     622        if (mural->gX != x || mural->gY != y)
     623        {
     624            if (mural->fRootVrOn)
     625            {
     626                fForcePresent = crServerVBoxCompositionPresentNeeded(mural);
     627            }
     628
     629            mural->gX = x;
     630            mural->gY = y;
     631
     632            /* the compositor lock is not needed actually since we have prevented renderspu from using the compositor */
     633            /* CrVrScrCompositorLock(&mural->Compositor); */
     634            /* no need to set position because the position is relative to window */
     635            /*CrVrScrCompositorEntryPosSet(&mural->Compositor, &mural->CEntry, &Pos);*/
     636            /*CrVrScrCompositorUnlock(&mural->Compositor);*/
     637
     638            if (mural->fRootVrOn)
     639            {
     640                uint32_t cRects;
     641                const RTRECT *pRects;
     642                int rc = crServerMuralSynchRootVr(mural, &cRects, &pRects);
     643
     644                if (RT_SUCCESS(rc))
     645                {
     646                    cr_server.head_spu->dispatch_table.WindowVisibleRegion(mural->spuWindow, cRects, pRects);
     647
     648                    if (mural->pvOutputRedirectInstance)
     649                    {
     650                        /* @todo the code assumes that RTRECT == four GLInts. */
     651                        cr_server.outputRedirect.CRORVisibleRegion(mural->pvOutputRedirectInstance,
     652                                                                   cRects, pRects);
     653                    }
     654                }
     655                else
     656                {
     657                    crWarning("crServerMuralSynchRootVr failed, rc %d", rc);
     658                }
     659            }
     660        }
    440661
    441662        crServerCheckMuralGeometry(mural);
    442663
    443664        /* 3. re-set the compositor (see above comment) */
    444         crServerVBoxCompositionReenable(mural, GL_FALSE);
     665        crServerVBoxCompositionReenable(mural, fForcePresent);
    445666    }
    446667}
    447668
    448669void SERVER_DISPATCH_APIENTRY
    449 crServerDispatchWindowVisibleRegion( GLint window, GLint cRects, GLint *pRects )
     670crServerDispatchWindowVisibleRegion( GLint window, GLint cRects, const GLint *pRects )
    450671{
    451672    CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
    452673    GLboolean fForcePresent = crServerVBoxCompositionPresentNeeded(mural);
     674    bool fRegionsChanged = false;
     675    int rc = VINF_SUCCESS;
    453676    if (!mural) {
    454677#if EXTRA_WARN
     
    470693
    471694    /* 2. do necessary modifications (see above comment) */
     695    if (mural->pVisibleRects)
     696    {
     697        crFree(mural->pVisibleRects);
     698        mural->pVisibleRects = NULL;
     699    }
     700
     701    mural->cVisibleRects = cRects;
     702    mural->bReceivedRects = GL_TRUE;
     703    if (cRects)
     704    {
     705        mural->pVisibleRects = (GLint*) crAlloc(4*sizeof(GLint)*cRects);
     706        if (!mural->pVisibleRects)
     707        {
     708            crError("Out of memory in crServerDispatchWindowVisibleRegion");
     709        }
     710        crMemcpy(mural->pVisibleRects, pRects, 4*sizeof(GLint)*cRects);
     711    }
     712
    472713    /* NOTE: we can do it even if mural->fUseFBO = CR_SERVER_REDIR_NONE to make sure the compositor data is always up to date */
    473714    /* the compositor lock is not needed actually since we have prevented renderspu from using the compositor */
    474715    /* CrVrScrCompositorLock(&mural->Compositor); */
    475     CrVrScrCompositorEntryRegionsSet(&mural->Compositor, &mural->CEntry, NULL, cRects, (const RTRECT *)pRects);
     716    rc = CrVrScrCompositorEntryRegionsSet(&mural->Compositor, &mural->CEntry, NULL, cRects, (const RTRECT *)pRects, &fRegionsChanged);
    476717    /*CrVrScrCompositorUnlock(&mural->Compositor);*/
    477 
    478     if (mural->pVisibleRects)
    479     {
    480         crFree(mural->pVisibleRects);
    481         mural->pVisibleRects = NULL;
    482     }
    483 
    484     mural->cVisibleRects = cRects;
    485     mural->bReceivedRects = GL_TRUE;
    486     if (cRects)
    487     {
    488         mural->pVisibleRects = (GLint*) crAlloc(4*sizeof(GLint)*cRects);
    489         if (!mural->pVisibleRects)
    490         {
    491             crError("Out of memory in crServerDispatchWindowVisibleRegion");
    492         }
    493         crMemcpy(mural->pVisibleRects, pRects, 4*sizeof(GLint)*cRects);
    494     }
    495 
    496     cr_server.head_spu->dispatch_table.WindowVisibleRegion(mural->spuWindow, cRects, pRects);
    497 
    498     if (mural->pvOutputRedirectInstance)
    499     {
    500         /* @todo the code assumes that RTRECT == four GLInts. */
    501         cr_server.outputRedirect.CRORVisibleRegion(mural->pvOutputRedirectInstance,
    502                                                    cRects, (RTRECT *)pRects);
     718    if (!RT_SUCCESS(rc))
     719    {
     720        crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
     721        return;
     722    }
     723
     724    if (fRegionsChanged)
     725    {
     726        if (mural->fRootVrOn)
     727        {
     728            rc = CrVrScrCompositorEntryRegionsSet(&mural->RootVrCompositor, &mural->RootVrCEntry, NULL, cRects, (const RTRECT *)pRects, NULL);
     729            if (!RT_SUCCESS(rc))
     730            {
     731                crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
     732                return;
     733            }
     734
     735            crServerVBoxRootVrTranslateForMural(mural);
     736            rc = CrVrScrCompositorEntryListIntersect(&mural->RootVrCompositor, &mural->RootVrCEntry, &cr_server.RootVr, NULL);
     737            if (!RT_SUCCESS(rc))
     738            {
     739                crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
     740                return;
     741            }
     742
     743            rc = CrVrScrCompositorEntryRegionsGet(&mural->RootVrCompositor, &mural->RootVrCEntry, &cRects, NULL, (const RTRECT **)&pRects);
     744            if (!RT_SUCCESS(rc))
     745            {
     746                crWarning("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc);
     747                return;
     748            }
     749        }
     750        else
     751        {
     752            rc = CrVrScrCompositorEntryRegionsGet(&mural->Compositor, &mural->CEntry, &cRects, NULL, (const RTRECT **)&pRects);
     753            if (!RT_SUCCESS(rc))
     754            {
     755                crWarning("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc);
     756                return;
     757            }
     758        }
     759
     760        cr_server.head_spu->dispatch_table.WindowVisibleRegion(mural->spuWindow, cRects, pRects);
     761
     762        if (mural->pvOutputRedirectInstance)
     763        {
     764            /* @todo the code assumes that RTRECT == four GLInts. */
     765            cr_server.outputRedirect.CRORVisibleRegion(mural->pvOutputRedirectInstance,
     766                                                       cRects, (RTRECT *)pRects);
     767        }
    503768    }
    504769
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