VirtualBox

Changeset 28534 in vbox


Ignore:
Timestamp:
Apr 20, 2010 6:30:11 PM (15 years ago)
Author:
vboxsync
Message:

crOpenGL: add visible region support for host offscreen rendering

Location:
trunk/src/VBox
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h

    r27889 r28534  
    6161    GLboolean bVisible;      /*guest window is visible*/
    6262    GLboolean bUseFBO;       /*redirect to FBO instead of real host window*/
     63
     64    GLint  cVisibleRects;    /*count of visible rects*/
     65    GLint *pVisibleRects;    /*visible rects left, top, right, bottom*/
    6366
    6467    GLuint idFBO, idColorTex, idDepthStencilRB;
  • trunk/src/VBox/GuestHost/OpenGL/include/state/cr_statetypes.h

    r15532 r28534  
    3737
    3838typedef struct {
    39         GLint x1, x2, y1, y2;
     39        GLint x1, y1, x2, y2;
    4040} CRrecti;
    4141
  • trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp

    r28215 r28534  
    6969
    7070static const char* gszVBoxOGLSSMMagic = "***OpenGL state data***";
    71 #define SHCROGL_SSM_VERSION 17
     71#define SHCROGL_SSM_VERSION 18
    7272
    7373static DECLCALLBACK(int) svcUnload (void *)
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c

    r27889 r28534  
    552552    rc = SSMR3PutMem(pSSM, pMI, sizeof(*pMI));
    553553    CRASSERT(rc == VINF_SUCCESS);
     554
     555    if (pMI->pVisibleRects)
     556    {
     557        rc = SSMR3PutMem(pSSM, pMI->pVisibleRects, 4*sizeof(GLint)*pMI->cVisibleRects);
     558    }
    554559}
    555560
     
    852857        AssertRCReturn(rc, rc);
    853858
     859        if (muralInfo.pVisibleRects)
     860        {
     861            muralInfo.pVisibleRects = crAlloc(4*sizeof(GLint)*muralInfo.cVisibleRects);
     862            if (!muralInfo.pVisibleRects)
     863            {
     864                return VERR_NO_MEMORY;
     865            }
     866
     867            rc = SSMR3GetMem(pSSM, muralInfo.pVisibleRects, 4*sizeof(GLint)*muralInfo.cVisibleRects);
     868            AssertRCReturn(rc, rc);
     869        }
     870
    854871        /* Restore windows geometry info */
    855872        crServerDispatchWindowSize(key, muralInfo.width, muralInfo.height);
    856873        crServerDispatchWindowPosition(key, muralInfo.gX, muralInfo.gY);
     874        crServerDispatchWindowVisibleRegion(key, muralInfo.cVisibleRects, muralInfo.pVisibleRects);
     875
     876        if (muralInfo.pVisibleRects)
     877        {
     878            crFree(muralInfo.pVisibleRects);
     879        }
    857880    }
    858881
     
    10701093DECLEXPORT(int32_t) crVBoxServerMapScreen(int sIndex, int32_t x, int32_t y, uint32_t w, uint32_t h, uint64_t winID)
    10711094{
     1095    crDebug("crVBoxServerMapScreen(%i) [%i,%i:%u,%u]", sIndex, x, y, w, h);
     1096
    10721097    if (sIndex<0 || sIndex>=cr_server.screenCount)
    10731098        return VERR_INVALID_PARAMETER;
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c

    r28521 r28534  
    262262#define MAX(a, b) ((a) > (b) ? (a) : (b))
    263263
     264static GLboolean crServerIntersectRect(CRrecti *a, CRrecti *b, CRrecti *rect)
     265{
     266    CRASSERT(a && b && rect);
     267
     268    rect->x1 = MAX(a->x1, b->x1);
     269    rect->x2 = MIN(a->x2, b->x2);
     270    rect->y1 = MAX(a->y1, b->y1);
     271    rect->y2 = MIN(a->y2, b->y2);
     272
     273    return (rect->x2>rect->x1) && (rect->y2>rect->y1);
     274}
     275
    264276static GLboolean crServerIntersectScreen(CRMuralInfo *mural, int sId, CRrecti *rect)
    265277{
     
    272284}
    273285
     286static void crServerCopySubImage(char *pDst, char* pSrc, CRrecti *pRect, int srcWidth, int srcHeight)
     287{
     288    int i;
     289    int dstrowsize = 4*(pRect->x2-pRect->x1);
     290    int srcrowsize = 4*srcWidth;
     291    int height = pRect->y2-pRect->y1;
     292
     293    pSrc += 4*pRect->x1 + srcrowsize*(srcHeight-1-pRect->y1);
     294
     295    for (i=0; i<height; ++i)
     296    {
     297        crMemcpy(pDst, pSrc, dstrowsize);
     298
     299        pSrc -= srcrowsize;
     300        pDst += dstrowsize;
     301    }
     302}
     303
     304static void crServerTransformRect(CRrecti *pDst, CRrecti *pSrc, int dx, int dy)
     305{
     306    pDst->x1 = pSrc->x1+dx;
     307    pDst->x2 = pSrc->x2+dx;
     308    pDst->y1 = pSrc->y1+dy;
     309    pDst->y2 = pSrc->y2+dy;
     310}
     311
    274312void crServerPresentFBO(CRMuralInfo *mural)
    275313{
    276     char *pixels, *tmppixels, *pSrc, *pDst;
     314    char *pixels, *tmppixels;
    277315    GLuint uid;
    278     int i, j, rowsize, rowstride, height;
    279     CRrecti rect;
     316    int i, j;
     317    CRrecti rect, rectwr, sectr;
    280318    CRContext *ctx = crStateGetCurrent();
    281319
    282320    CRASSERT(cr_server.pfnPresentFBO);
     321
     322    if (!mural->bVisible)
     323    {
     324        return;
     325    }
    283326
    284327    pixels = crAlloc(4*mural->fboWidth*mural->fboHeight);
     
    298341        if (crServerIntersectScreen(mural, i, &rect))
    299342        {
    300             rowsize = 4*(rect.x2-rect.x1);
    301             tmppixels = crAlloc(rowsize*(rect.y2-rect.y1));
    302            
     343            tmppixels = crAlloc(4*(rect.x2-rect.x1)*(rect.y2-rect.y1));
    303344            if (!tmppixels)
    304345            {
     
    307348                return;
    308349            }
    309             rowstride = 4*mural->fboWidth;
    310             height = rect.y2-rect.y1;
    311 
    312             pSrc = pixels + 4*(rect.x1-mural->gX) + rowstride*(rect.y2-mural->gY-1);
    313             pDst = tmppixels;
    314 
    315             for (j=0; j<height; ++j)
    316             {
    317                 crMemcpy(pDst, pSrc, rowsize);
    318 
    319                 pSrc -= rowstride;
    320                 pDst += rowsize;
    321             }
    322 
    323             cr_server.pfnPresentFBO(tmppixels, i, rect.x1-cr_server.screen[i].x, rect.y1-cr_server.screen[i].y, rect.x2-rect.x1, height);
     350
     351            /* rect in window relative coords */
     352            crServerTransformRect(&rectwr, &rect, -mural->gX, -mural->gY);
     353
     354            if (!mural->pVisibleRects)
     355            {
     356                crServerCopySubImage(tmppixels, pixels, &rectwr, mural->fboWidth, mural->fboHeight);
     357                cr_server.pfnPresentFBO(tmppixels, i, rect.x1-cr_server.screen[i].x, rect.y1-cr_server.screen[i].y, rect.x2-rect.x1, rect.y2-rect.y1);
     358            }
     359            else
     360            {
     361                for (j=0; j<mural->cVisibleRects; ++j)
     362                {
     363                    if (crServerIntersectRect(&rectwr, (CRrecti*) &mural->pVisibleRects[4*j], &sectr))
     364                    {
     365                        crServerCopySubImage(tmppixels, pixels, &sectr, mural->fboWidth, mural->fboHeight);
     366                        cr_server.pfnPresentFBO(tmppixels, i,
     367                                                sectr.x1+mural->gX-cr_server.screen[i].x,
     368                                                sectr.y1+mural->gY-cr_server.screen[i].y,
     369                                                sectr.x2-sectr.x1, sectr.y2-sectr.y1);
     370                    }
     371                }
     372            }
    324373
    325374            crFree(tmppixels);
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c

    r27889 r28534  
    8484        mural->bUseFBO = GL_FALSE;
    8585
     86        mural->cVisibleRects = 0;
     87        mural->pVisibleRects = NULL;
     88
    8689        /* generate ID for this new window/mural (special-case for file conns) */
    8790        if (cr_server.curClient && cr_server.curClient->conn->type == CR_FILE)
     
    182185
    183186    crHashtableDelete(cr_server.pWindowCreateInfoTable, window, crServerCreateInfoDeleteCB);
     187
     188    if (mural->pVisibleRects)
     189    {
     190        crFree(mural->pVisibleRects);
     191    }
    184192    crHashtableDelete(cr_server.muralTable, window, crFree);
    185193}
     
    237245         return;
    238246    }
     247
     248    if (mural->pVisibleRects)
     249    {
     250        crFree(mural->pVisibleRects);
     251        mural->pVisibleRects = NULL;
     252    }
     253
     254    mural->cVisibleRects = cRects;
     255    if (cRects)
     256    {
     257        mural->pVisibleRects = (GLint*) crAlloc(4*sizeof(GLint)*cRects);
     258        if (!mural->pVisibleRects)
     259        {
     260            crError("Out of memory in crServerDispatchWindowVisibleRegion");
     261        }
     262        crMemcpy(mural->pVisibleRects, pRects, 4*sizeof(GLint)*cRects);
     263    }
     264
    239265    cr_server.head_spu->dispatch_table.WindowVisibleRegion(mural->spuWindow, cRects, pRects);
    240266}
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