VirtualBox

Ignore:
Timestamp:
Apr 2, 2014 8:26:07 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
93111
Message:

wddm/crOpenGL/DevVGA: blitting enhancements and cleanup + bugfixes

Location:
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h

    r50937 r50957  
    466466void CrFbTexDataInit(CR_TEXDATA* pFbTex, const VBOXVR_TEXTURE *pTex, PFNCRTEXDATA_RELEASED pfnTextureReleased);
    467467
    468 int8_t crVBoxServerCrCmdBltProcess(const VBOXCMDVBVA_HDR *pCmd, uint32_t cbCmd);
     468int8_t crVBoxServerCrCmdBltProcess(const VBOXCMDVBVA_BLT_HDR *pCmd, uint32_t cbCmd);
    469469int8_t crVBoxServerCrCmdFlipProcess(const VBOXCMDVBVA_FLIP *pFlip);
    470470
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c

    r50937 r50957  
    35143514            return crVBoxServerCrCmdFlipProcess(pFlip);
    35153515        }
    3516         case VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID:
    3517         {
    3518             return crVBoxServerCrCmdBltProcess(pCmd, cbCmd);
     3516        case VBOXCMDVBVA_OPTYPE_BLT:
     3517        {
     3518            if (cbCmd < sizeof (VBOXCMDVBVA_BLT_HDR))
     3519            {
     3520                WARN(("invalid buffer size"));
     3521                return -1;
     3522            }
     3523
     3524            return crVBoxServerCrCmdBltProcess((const VBOXCMDVBVA_BLT_HDR*)pCmd, cbCmd);
    35193525        }
    35203526        default:
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp

    r50948 r50957  
    397397}
    398398
     399static void crFbImgFromDimVramBGRA(void *pvVram, uint32_t width, uint32_t height, CR_BLITTER_IMG *pImg)
     400{
     401    pImg->pvData = pvVram;
     402    pImg->cbData = width * height * 4;
     403    pImg->enmFormat = GL_BGRA;
     404    pImg->width = width;
     405    pImg->height = height;
     406    pImg->bpp = 32;
     407    pImg->pitch = width * 4;
     408}
     409
    399410static void crFbImgFromFb(HCR_FRAMEBUFFER hFb, CR_BLITTER_IMG *pImg)
    400411{
     
    402413    void *pvVram = CrFbGetVRAM(hFb);
    403414    crFbImgFromScreenVram(pScreen, pvVram, pImg);
     415}
     416
     417static int crFbTexDataGetContents(CR_TEXDATA *pTex, const RTRECT *pSrcRect, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
     418{
     419    PCR_BLITTER pEnteredBlitter = NULL;
     420    uint32_t width = 0, height = 0;
     421    RTPOINT ScaledEntryPoint = {0};
     422
     423    int32_t srcWidth = pSrcRect->xRight - pSrcRect->xLeft;
     424    int32_t srcHeight = pSrcRect->yBottom - pSrcRect->yTop;
     425    int32_t dstWidth = pDstRect->xRight - pDstRect->xLeft;
     426    int32_t dstHeight = pDstRect->yBottom - pDstRect->yTop;
     427
     428    RTPOINT DstPoint = {pDstRect->xLeft, pDstRect->yTop};
     429    float strX = ((float)dstWidth) / srcWidth;
     430    float strY = ((float)dstHeight) / srcHeight;
     431    bool fScale = (dstWidth != srcWidth || dstHeight != srcHeight);
     432
     433    const RTPOINT ZeroPoint = {0, 0};
     434
     435    const VBOXVR_TEXTURE *pVrTex = CrTdTexGet(pTex);
     436
     437    width = CR_FLOAT_RCAST(uint32_t, strX * pVrTex->width);
     438    height = CR_FLOAT_RCAST(uint32_t, strY * pVrTex->height);
     439    ScaledEntryPoint.x = pDstRect->xLeft;
     440    ScaledEntryPoint.y = pDstRect->yTop;
     441    const CR_BLITTER_IMG *pSrcImg;
     442    int rc = CrTdBltDataAcquireScaled(pTex, GL_BGRA, false, width, height, &pSrcImg);
     443    if (!RT_SUCCESS(rc))
     444    {
     445        WARN(("CrTdBltDataAcquire failed rc %d", rc));
     446        return rc;
     447    }
     448
     449    for (uint32_t i = 0; i < cRects; ++i)
     450    {
     451        RTRECT Intersection;
     452        VBoxRectIntersected(pDstRect, &pRects[i], &Intersection);
     453        if (VBoxRectIsZero(&Intersection))
     454            continue;
     455
     456        crFbBltImg(pSrcImg, &ScaledEntryPoint, false, &Intersection, &ZeroPoint, pImg);
     457    }
     458
     459    CrTdBltDataReleaseScaled(pTex, pSrcImg);
     460
     461    return VINF_SUCCESS;
    404462}
    405463
     
    10771135
    10781136    return pFbTex;
     1137}
     1138
     1139static CR_TEXDATA* CrFbTexDataAcquire(GLuint idTexture)
     1140{
     1141    CR_FBTEX* pTex = crFbTexAcquire(idTexture);
     1142    if (!pTex)
     1143    {
     1144        WARN(("crFbTexAcquire failed for %d", idTexture));
     1145        return NULL;
     1146    }
     1147
     1148    return &pTex->Tex;
    10791149}
    10801150
     
    46374707}
    46384708
    4639 int8_t crVBoxServerCrCmdBltProcess(const VBOXCMDVBVA_HDR *pCmd, uint32_t cbCmd)
    4640 {
    4641     uint8_t u8Flags = pCmd->u8Flags;
    4642     if (u8Flags & (VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY | VBOXCMDVBVA_OPF_ALLOC_SRCPRIMARY))
    4643     {
    4644         VBOXCMDVBVA_BLT_PRIMARY *pBlt = (VBOXCMDVBVA_BLT_PRIMARY*)pCmd;
    4645         uint8_t u8PrimaryID = pBlt->Hdr.u.u8PrimaryID;
    4646         HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(u8PrimaryID);
    4647         if (!hFb)
    4648         {
    4649             WARN(("request to present on disabled framebuffer, ignore"));
     4709static RTRECT * crVBoxServerCrCmdBltRecsUnpack(const VBOXCMDVBVA_RECT *pPRects, uint32_t cRects)
     4710{
     4711    if (g_CrPresenter.cbTmpBuf < cRects * sizeof (RTRECT))
     4712    {
     4713        if (g_CrPresenter.pvTmpBuf)
     4714            RTMemFree(g_CrPresenter.pvTmpBuf);
     4715
     4716        g_CrPresenter.cbTmpBuf = (cRects + 10) * sizeof (RTRECT);
     4717        g_CrPresenter.pvTmpBuf = RTMemAlloc(g_CrPresenter.cbTmpBuf);
     4718        if (!g_CrPresenter.pvTmpBuf)
     4719        {
     4720            WARN(("RTMemAlloc failed!"));
     4721            g_CrPresenter.cbTmpBuf = 0;
     4722            return NULL;
     4723        }
     4724    }
     4725
     4726    RTRECT *pRects = (RTRECT *)g_CrPresenter.pvTmpBuf;
     4727    crVBoxPRectUnpacks(pPRects, pRects, cRects);
     4728
     4729    return pRects;
     4730}
     4731
     4732static void crVBoxServerCrCmdBltPrimaryUpdate(const RTRECT *pRects, uint32_t cRects, uint32_t u32PrimaryID)
     4733{
     4734    if (!cRects)
     4735        return;
     4736
     4737    bool fDirtyEmpty = true;
     4738    RTRECT dirtyRect;
     4739    cr_server.CrCmdClientInfo.pfnCltScrUpdateBegin(cr_server.CrCmdClientInfo.hCltScr, u32PrimaryID);
     4740
     4741    VBVACMDHDR hdr;
     4742    for (uint32_t i = 0; i < cRects; ++i)
     4743    {
     4744        hdr.x = pRects[i].xLeft;
     4745        hdr.y = pRects[i].yTop;
     4746        hdr.w = hdr.x + pRects[i].xRight;
     4747        hdr.h = hdr.y + pRects[i].yBottom;
     4748
     4749        cr_server.CrCmdClientInfo.pfnCltScrUpdateProcess(cr_server.CrCmdClientInfo.hCltScr, u32PrimaryID, &hdr, sizeof (hdr));
     4750
     4751        if (fDirtyEmpty)
     4752        {
     4753            /* This is the first rectangle to be added. */
     4754            dirtyRect.xLeft   = pRects[i].xLeft;
     4755            dirtyRect.yTop    = pRects[i].yTop;
     4756            dirtyRect.xRight  = pRects[i].xRight;
     4757            dirtyRect.yBottom = pRects[i].yBottom;
     4758            fDirtyEmpty       = false;
     4759        }
     4760        else
     4761        {
     4762            /* Adjust region coordinates. */
     4763            if (dirtyRect.xLeft > pRects[i].xLeft)
     4764            {
     4765                dirtyRect.xLeft = pRects[i].xLeft;
     4766            }
     4767
     4768            if (dirtyRect.yTop > pRects[i].yTop)
     4769            {
     4770                dirtyRect.yTop = pRects[i].yTop;
     4771            }
     4772
     4773            if (dirtyRect.xRight < pRects[i].xRight)
     4774            {
     4775                dirtyRect.xRight = pRects[i].xRight;
     4776            }
     4777
     4778            if (dirtyRect.yBottom < pRects[i].yBottom)
     4779            {
     4780                dirtyRect.yBottom = pRects[i].yBottom;
     4781            }
     4782        }
     4783    }
     4784
     4785    if (dirtyRect.xRight - dirtyRect.xLeft)
     4786    {
     4787        cr_server.CrCmdClientInfo.pfnCltScrUpdateEnd(cr_server.CrCmdClientInfo.hCltScr, u32PrimaryID, dirtyRect.xLeft, dirtyRect.yTop,
     4788                                           dirtyRect.xRight - dirtyRect.xLeft, dirtyRect.yBottom - dirtyRect.yTop);
     4789    }
     4790    else
     4791    {
     4792        cr_server.CrCmdClientInfo.pfnCltScrUpdateEnd(cr_server.CrCmdClientInfo.hCltScr, u32PrimaryID, 0, 0, 0, 0);
     4793    }
     4794}
     4795
     4796static int8_t crVBoxServerCrCmdBltPrimaryVramGenericProcess(uint32_t u32PrimaryID, VBOXCMDVBVAOFFSET offVRAM, uint32_t width, uint32_t height, uint32_t xPos, uint32_t yPos, const RTRECT *pRects, uint32_t cRects, bool fToPrimary)
     4797{
     4798    CR_BLITTER_IMG Img;
     4799    uint32_t cbBuff = width * height * 4;
     4800    if (offVRAM >= g_cbVRam
     4801            || offVRAM + cbBuff >= g_cbVRam)
     4802    {
     4803        WARN(("invalid param"));
     4804        return -1;
     4805    }
     4806
     4807    uint8_t *pu8Buf = g_pvVRamBase + offVRAM;
     4808    RTRECT SrcRect, DstRect;
     4809
     4810    SrcRect.xLeft = 0;
     4811    SrcRect.yTop = 0;
     4812    SrcRect.xRight = width;
     4813    SrcRect.yBottom = height;
     4814
     4815    DstRect.xLeft = xPos;
     4816    DstRect.yTop = yPos;
     4817    DstRect.xRight = DstRect.xLeft + width;
     4818    DstRect.yBottom = DstRect.yTop + height;
     4819
     4820    crFbImgFromDimVramBGRA(pu8Buf, width, height, &Img);
     4821
     4822    HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(u32PrimaryID);
     4823    if (!hFb)
     4824    {
     4825        WARN(("request to present on disabled framebuffer"));
     4826        return -1;
     4827    }
     4828
     4829    if (!fToPrimary)
     4830    {
     4831
     4832        int rc = CrFbBltGetContents(hFb, &SrcRect, &DstRect, cRects, pRects, &Img);
     4833        if (!RT_SUCCESS(rc))
     4834        {
     4835            WARN(("CrFbBltGetContents failed %d", rc));
    46504836            return -1;
    46514837        }
    46524838
    4653         const VBOXCMDVBVA_RECT *pPRects = pBlt->aRects;
    4654         uint32_t cRects = (cbCmd - RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, aRects)) / sizeof (VBOXCMDVBVA_RECT);
    4655         RTRECT *pRects;
    4656         if (g_CrPresenter.cbTmpBuf < cRects * sizeof (RTRECT))
    4657         {
    4658             if (g_CrPresenter.pvTmpBuf)
    4659                 RTMemFree(g_CrPresenter.pvTmpBuf);
    4660 
    4661             g_CrPresenter.cbTmpBuf = (cRects + 10) * sizeof (RTRECT);
    4662             g_CrPresenter.pvTmpBuf = RTMemAlloc(g_CrPresenter.cbTmpBuf);
    4663             if (!g_CrPresenter.pvTmpBuf)
     4839        return 0;
     4840    }
     4841
     4842    int rc = CrFbBltPutContentsNe(hFb, &SrcRect, &DstRect, cRects, pRects, &Img);
     4843    if (!RT_SUCCESS(rc))
     4844    {
     4845        WARN(("CrFbBltPutContentsNe failed %d", rc));
     4846        return -1;
     4847    }
     4848
     4849    return 0;
     4850}
     4851
     4852static int8_t crVBoxServerCrCmdBltPrimaryProcess(const VBOXCMDVBVA_BLT_PRIMARY *pCmd, uint32_t cbCmd)
     4853{
     4854    uint32_t u32PrimaryID = (uint32_t)pCmd->Hdr.Hdr.u.u8PrimaryID;
     4855    HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(u32PrimaryID);
     4856    if (!hFb)
     4857    {
     4858        WARN(("request to present on disabled framebuffer, ignore"));
     4859        return 0;
     4860    }
     4861
     4862    uint32_t cRects;
     4863    const VBOXCMDVBVA_RECT *pPRects = pCmd->aRects;
     4864    if ((cbCmd - RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, aRects)) % sizeof (VBOXCMDVBVA_RECT))
     4865    {
     4866        WARN(("invalid argument size"));
     4867        return -1;
     4868    }
     4869
     4870    cRects = (cbCmd - RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, aRects)) / sizeof (VBOXCMDVBVA_RECT);
     4871
     4872    RTRECT *pRects = crVBoxServerCrCmdBltRecsUnpack(pPRects, cRects);
     4873    if (!pRects)
     4874    {
     4875        WARN(("crVBoxServerCrCmdBltRecsUnpack failed"));
     4876        return -1;
     4877    }
     4878
     4879    uint8_t u8Flags = pCmd->Hdr.Hdr.u8Flags;
     4880
     4881    if (u8Flags & VBOXCMDVBVA_OPF_OPERAND2_ISID)
     4882    {
     4883        uint32_t texId = pCmd->alloc.u.id;
     4884        if (!texId)
     4885        {
     4886            WARN(("texId is NULL!\n"));
     4887            return -1;
     4888        }
     4889
     4890        if (u8Flags & VBOXCMDVBVA_OPF_BLT_DIR_IN_2)
     4891        {
     4892            WARN(("blit from primary to texture not implemented"));
     4893            return -1;
     4894        }
     4895
     4896        crServerDispatchVBoxTexPresent(texId, u32PrimaryID, pCmd->Hdr.Pos.x, pCmd->Hdr.Pos.y, cRects, (const GLint*)pRects);
     4897    }
     4898    else
     4899    {
     4900        const VBVAINFOSCREEN *pScreen = CrFbGetScreenInfo(hFb);
     4901        uint32_t width = pScreen->u32Width, height = pScreen->u32Height;
     4902        VBOXCMDVBVAOFFSET offVRAM = pCmd->alloc.u.offVRAM;
     4903
     4904        bool fToPrymary = !(u8Flags & VBOXCMDVBVA_OPF_BLT_DIR_IN_2);
     4905        int8_t i8Result = crVBoxServerCrCmdBltPrimaryVramGenericProcess(u32PrimaryID, offVRAM, width, height, pCmd->Hdr.Pos.x, pCmd->Hdr.Pos.y, pRects, cRects, fToPrymary);
     4906        if (i8Result < 0)
     4907        {
     4908            WARN(("crVBoxServerCrCmdBltPrimaryVramGenericProcess failed"));
     4909            return i8Result;
     4910        }
     4911
     4912        if (!fToPrymary)
     4913            return 0;
     4914    }
     4915
     4916    crVBoxServerCrCmdBltPrimaryUpdate(pRects, cRects, u32PrimaryID);
     4917
     4918    return 0;
     4919}
     4920
     4921static int8_t crVBoxServerCrCmdBltOffIdProcess(const VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID *pCmd, uint32_t cbCmd)
     4922{
     4923    uint32_t cRects;
     4924    const VBOXCMDVBVA_RECT *pPRects = pCmd->aRects;
     4925    if ((cbCmd - RT_OFFSETOF(VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID, aRects)) % sizeof (VBOXCMDVBVA_RECT))
     4926    {
     4927        WARN(("invalid argument size"));
     4928        return -1;
     4929    }
     4930
     4931    cRects = (cbCmd - RT_OFFSETOF(VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID, aRects)) / sizeof (VBOXCMDVBVA_RECT);
     4932
     4933    RTRECT *pRects = crVBoxServerCrCmdBltRecsUnpack(pPRects, cRects);
     4934    if (!pRects)
     4935    {
     4936        WARN(("crVBoxServerCrCmdBltRecsUnpack failed"));
     4937        return -1;
     4938    }
     4939
     4940    uint8_t u8Flags = pCmd->Hdr.Hdr.u8Flags;
     4941    uint32_t hostId = pCmd->id;
     4942
     4943    Assert(u8Flags & VBOXCMDVBVA_OPF_OPERAND2_ISID);
     4944
     4945    if (!hostId)
     4946    {
     4947        WARN(("zero host id"));
     4948        return -1;
     4949    }
     4950
     4951    if (u8Flags & VBOXCMDVBVA_OPF_OPERAND1_ISID)
     4952    {
     4953        WARN(("blit from texture to texture not implemented"));
     4954        return -1;
     4955    }
     4956
     4957    if (u8Flags & VBOXCMDVBVA_OPF_BLT_DIR_IN_2)
     4958    {
     4959        WARN(("blit to texture not implemented"));
     4960        return -1;
     4961    }
     4962
     4963    CR_TEXDATA* pTex = CrFbTexDataAcquire(hostId);
     4964    if (!pTex)
     4965    {
     4966        WARN(("pTex failed for %d", hostId));
     4967        return -1;
     4968    }
     4969
     4970    const VBOXVR_TEXTURE *pVrTex = CrTdTexGet(pTex);
     4971    RTRECT SrcRect, DstRect;
     4972    uint32_t width = pVrTex->width;
     4973    uint32_t height = pVrTex->height;
     4974
     4975    SrcRect.xLeft = 0;
     4976    SrcRect.yTop = 0;
     4977    SrcRect.xRight = width;
     4978    SrcRect.yBottom = height;
     4979
     4980    DstRect.xLeft = pCmd->Hdr.Pos.x;
     4981    DstRect.yTop = pCmd->Hdr.Pos.y;
     4982    DstRect.xRight = DstRect.xLeft + width;
     4983    DstRect.yBottom = DstRect.yTop + height;
     4984
     4985    VBOXCMDVBVAOFFSET offVRAM = pCmd->alloc.u.offVRAM;
     4986    uint32_t cbBuff = width * height * 4;
     4987    if (offVRAM >= g_cbVRam
     4988            || offVRAM + cbBuff >= g_cbVRam)
     4989    {
     4990        WARN(("invalid param"));
     4991        return -1;
     4992    }
     4993
     4994    int rc = CrTdBltEnter(pTex);
     4995    if (!RT_SUCCESS(rc))
     4996    {
     4997        WARN(("CrTdBltEnter failed %d", rc));
     4998        return -1;
     4999    }
     5000
     5001    uint8_t *pu8Buf = g_pvVRamBase + offVRAM;
     5002    CR_BLITTER_IMG Img;
     5003    crFbImgFromDimVramBGRA(pu8Buf, width, height, &Img);
     5004
     5005    rc = crFbTexDataGetContents(pTex, &SrcRect, &DstRect, cRects, pRects, &Img);
     5006
     5007    CrTdBltLeave(pTex);
     5008
     5009    CrTdRelease(pTex);
     5010
     5011    if (!RT_SUCCESS(rc))
     5012    {
     5013        WARN(("crFbTexDataGetContents failed %d", rc));
     5014        return -1;
     5015    }
     5016
     5017    return 0;
     5018}
     5019
     5020static int8_t crVBoxServerCrCmdBltPrimaryGenericBGRAProcess(const VBOXCMDVBVA_BLT_PRIMARY_GENERIC_A8R8G8B8 *pCmd, uint32_t cbCmd)
     5021{
     5022    uint32_t u32PrimaryID = pCmd->Hdr.Hdr.u.u8PrimaryID;
     5023    HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(u32PrimaryID);
     5024    if (!hFb)
     5025    {
     5026        WARN(("request to present on disabled framebuffer, ignore"));
     5027        return 0;
     5028    }
     5029
     5030    uint32_t cRects;
     5031    const VBOXCMDVBVA_RECT *pPRects = pCmd->aRects;
     5032    if ((cbCmd - RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY_GENERIC_A8R8G8B8, aRects)) % sizeof (VBOXCMDVBVA_RECT))
     5033    {
     5034        WARN(("invalid argument size"));
     5035        return -1;
     5036    }
     5037
     5038    cRects = (cbCmd - RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY_GENERIC_A8R8G8B8, aRects)) / sizeof (VBOXCMDVBVA_RECT);
     5039
     5040    RTRECT *pRects = crVBoxServerCrCmdBltRecsUnpack(pPRects, cRects);
     5041    if (!pRects)
     5042    {
     5043        WARN(("crVBoxServerCrCmdBltRecsUnpack failed"));
     5044        return -1;
     5045    }
     5046
     5047    uint8_t u8Flags = pCmd->Hdr.Hdr.u8Flags;
     5048
     5049    if (u8Flags & VBOXCMDVBVA_OPF_OPERAND2_ISID)
     5050    {
     5051        WARN(("blit tex-primary generic is somewhat unexpected"));
     5052
     5053        uint32_t texId = pCmd->alloc.Info.u.id;
     5054        if (!texId)
     5055        {
     5056            WARN(("texId is NULL!\n"));
     5057            return -1;
     5058        }
     5059
     5060        if (u8Flags & VBOXCMDVBVA_OPF_BLT_DIR_IN_2)
     5061        {
     5062            WARN(("blit from primary to texture not implemented"));
     5063            return -1;
     5064        }
     5065
     5066        crServerDispatchVBoxTexPresent(texId, u32PrimaryID, pCmd->Hdr.Pos.x, pCmd->Hdr.Pos.y, cRects, (const GLint*)pRects);
     5067    }
     5068    else
     5069    {
     5070        bool fToPrymary = !(u8Flags & VBOXCMDVBVA_OPF_BLT_DIR_IN_2);
     5071        uint32_t width, height;
     5072        if (fToPrymary)
     5073        {
     5074            width = pCmd->alloc.width;
     5075            height = pCmd->alloc.height;
     5076        }
     5077        else
     5078        {
     5079            const VBVAINFOSCREEN *pScreen = CrFbGetScreenInfo(hFb);
     5080            width = pScreen->u32Width;
     5081            height = pScreen->u32Height;
     5082        }
     5083
     5084        VBOXCMDVBVAOFFSET offVRAM = pCmd->alloc.Info.u.offVRAM;
     5085
     5086        int8_t i8Result = crVBoxServerCrCmdBltPrimaryVramGenericProcess(u32PrimaryID, offVRAM, width, height, pCmd->Hdr.Pos.x, pCmd->Hdr.Pos.y, pRects, cRects, fToPrymary);
     5087        if (i8Result < 0)
     5088        {
     5089            WARN(("crVBoxServerCrCmdBltPrimaryVramGenericProcess failed"));
     5090            return i8Result;
     5091        }
     5092
     5093        if (!fToPrymary)
     5094            return 0;
     5095    }
     5096
     5097    crVBoxServerCrCmdBltPrimaryUpdate(pRects, cRects, u32PrimaryID);
     5098
     5099    return 0;
     5100}
     5101
     5102static int8_t crVBoxServerCrCmdBltGenericBGRAProcess(const VBOXCMDVBVA_BLT_GENERIC_A8R8G8B8 *pCmd, uint32_t cbCmd)
     5103{
     5104    uint32_t cRects;
     5105    const VBOXCMDVBVA_RECT *pPRects = pCmd->aRects;
     5106    if ((cbCmd - RT_OFFSETOF(VBOXCMDVBVA_BLT_GENERIC_A8R8G8B8, aRects)) % sizeof (VBOXCMDVBVA_RECT))
     5107    {
     5108        WARN(("invalid argument size"));
     5109        return -1;
     5110    }
     5111
     5112    cRects = (cbCmd - RT_OFFSETOF(VBOXCMDVBVA_BLT_GENERIC_A8R8G8B8, aRects)) / sizeof (VBOXCMDVBVA_RECT);
     5113
     5114    RTRECT *pRects = crVBoxServerCrCmdBltRecsUnpack(pPRects, cRects);
     5115    if (!pRects)
     5116    {
     5117        WARN(("crVBoxServerCrCmdBltRecsUnpack failed"));
     5118        return -1;
     5119    }
     5120
     5121    uint8_t u8Flags = pCmd->Hdr.Hdr.u8Flags;
     5122
     5123    WARN(("crVBoxServerCrCmdBltGenericBGRAProcess: not supported"));
     5124    return -1;
     5125}
     5126
     5127static int8_t crVBoxServerCrCmdBltPrimaryPrimaryProcess(const VBOXCMDVBVA_BLT_PRIMARY *pCmd, uint32_t cbCmd)
     5128{
     5129    uint8_t u8PrimaryID = pCmd->Hdr.Hdr.u.u8PrimaryID;
     5130    HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(u8PrimaryID);
     5131    if (!hFb)
     5132    {
     5133        WARN(("request to present on disabled framebuffer, ignore"));
     5134        return -1;
     5135    }
     5136
     5137    uint32_t cRects;
     5138    const VBOXCMDVBVA_RECT *pPRects = pCmd->aRects;
     5139    if ((cbCmd - RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, aRects)) % sizeof (VBOXCMDVBVA_RECT))
     5140    {
     5141        WARN(("invalid argument size"));
     5142        return -1;
     5143    }
     5144
     5145    cRects = (cbCmd - RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, aRects)) / sizeof (VBOXCMDVBVA_RECT);
     5146
     5147    RTRECT *pRects = crVBoxServerCrCmdBltRecsUnpack(pPRects, cRects);
     5148    if (!pRects)
     5149    {
     5150        WARN(("crVBoxServerCrCmdBltRecsUnpack failed"));
     5151        return -1;
     5152    }
     5153
     5154    uint8_t u8Flags = pCmd->Hdr.Hdr.u8Flags;
     5155
     5156    WARN(("crVBoxServerCrCmdBltPrimaryPrimaryProcess: not supported"));
     5157    return -1;
     5158}
     5159
     5160int8_t crVBoxServerCrCmdBltProcess(const VBOXCMDVBVA_BLT_HDR *pCmd, uint32_t cbCmd)
     5161{
     5162    uint8_t u8Flags = pCmd->Hdr.u8Flags;
     5163    uint8_t u8Cmd = (VBOXCMDVBVA_OPF_BLT_TYPE_MASK & u8Flags);
     5164
     5165    switch (u8Cmd)
     5166    {
     5167        case VBOXCMDVBVA_OPF_BLT_TYPE_PRIMARY:
     5168        {
     5169            if (cbCmd < sizeof (VBOXCMDVBVA_BLT_PRIMARY))
    46645170            {
    4665                 WARN(("RTMemAlloc failed!"));
    4666                 g_CrPresenter.cbTmpBuf = 0;
     5171                WARN(("VBOXCMDVBVA_OPF_BLT_TYPE_PRIMARY: invalid command size"));
    46675172                return -1;
    46685173            }
    4669         }
    4670 
    4671         pRects = (RTRECT *)g_CrPresenter.pvTmpBuf;
    4672 
    4673         crVBoxPRectUnpacks(pPRects, pRects, cRects);
    4674 
    4675         Assert(!((cbCmd - RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, aRects)) % sizeof (VBOXCMDVBVA_RECT)));
    4676 
    4677         if (u8Flags & VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY)
    4678         {
    4679             if (!(u8Flags & VBOXCMDVBVA_OPF_ALLOC_SRCPRIMARY))
     5174
     5175            return crVBoxServerCrCmdBltPrimaryProcess((const VBOXCMDVBVA_BLT_PRIMARY*)pCmd, cbCmd);
     5176        }
     5177        case VBOXCMDVBVA_OPF_BLT_TYPE_OFFPRIMSZFMT_OR_ID:
     5178        {
     5179            if (cbCmd < sizeof (VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID))
    46805180            {
    4681                 /* blit to primary from non-primary */
    4682                 if (u8Flags & VBOXCMDVBVA_OPF_ALLOC_SRCID)
    4683                 {
    4684                     /* TexPresent */
    4685                     uint32_t texId = pBlt->alloc.u.id;
    4686                     if (!texId)
    4687                     {
    4688                         WARN(("texId is NULL!\n"));
    4689                         return -1;
    4690                     }
    4691 
    4692                     crServerDispatchVBoxTexPresent(texId, u8PrimaryID, pBlt->Pos.x, pBlt->Pos.y, cRects, (const GLint*)pRects);
    4693                 }
    4694                 else
    4695                 {
    4696                     VBOXCMDVBVAOFFSET offVRAM = pBlt->alloc.u.offVRAM;
    4697                     const VBVAINFOSCREEN *pScreen = CrFbGetScreenInfo(hFb);
    4698                     uint32_t cbScreen = pScreen->u32LineSize * pScreen->u32Height;
    4699                     if (offVRAM >= g_cbVRam
    4700                             || offVRAM + cbScreen >= g_cbVRam)
    4701                     {
    4702                         WARN(("invalid param"));
    4703                         return -1;
    4704                     }
    4705 
    4706                     uint8_t *pu8Buf = g_pvVRamBase + offVRAM;
    4707                     const RTRECT *pCompRect = CrVrScrCompositorRectGet(&hFb->Compositor);
    4708                     CR_BLITTER_IMG Img;
    4709                     crFbImgFromScreenVram(pScreen, pu8Buf, &Img);
    4710                     int rc = CrFbBltPutContentsNe(hFb, pCompRect, pCompRect, cRects, pRects, &Img);
    4711                     if (!RT_SUCCESS(rc))
    4712                     {
    4713                         WARN(("CrFbBltPutContentsNe failed %d", rc));
    4714                         return -1;
    4715                     }
    4716 
    4717                     if (cRects)
    4718                     {
    4719                         bool fDirtyEmpty = true;
    4720                         RTRECT dirtyRect;
    4721                         cr_server.CrCmdClientInfo.pfnCltScrUpdateBegin(cr_server.CrCmdClientInfo.hCltScr, u8PrimaryID);
    4722 
    4723                         VBVACMDHDR hdr;
    4724                         for (uint32_t i = 0; i < cRects; ++i)
    4725                         {
    4726                             hdr.x = pRects[i].xLeft;
    4727                             hdr.y = pRects[i].yTop;
    4728                             hdr.w = hdr.x + pRects[i].xRight;
    4729                             hdr.h = hdr.y + pRects[i].yBottom;
    4730 
    4731                             cr_server.CrCmdClientInfo.pfnCltScrUpdateProcess(cr_server.CrCmdClientInfo.hCltScr, u8PrimaryID, &hdr, sizeof (hdr));
    4732 
    4733                             if (fDirtyEmpty)
    4734                             {
    4735                                 /* This is the first rectangle to be added. */
    4736                                 dirtyRect.xLeft   = pRects[i].xLeft;
    4737                                 dirtyRect.yTop    = pRects[i].yTop;
    4738                                 dirtyRect.xRight  = pRects[i].xRight;
    4739                                 dirtyRect.yBottom = pRects[i].yBottom;
    4740                                 fDirtyEmpty       = false;
    4741                             }
    4742                             else
    4743                             {
    4744                                 /* Adjust region coordinates. */
    4745                                 if (dirtyRect.xLeft > pRects[i].xLeft)
    4746                                 {
    4747                                     dirtyRect.xLeft = pRects[i].xLeft;
    4748                                 }
    4749 
    4750                                 if (dirtyRect.yTop > pRects[i].yTop)
    4751                                 {
    4752                                     dirtyRect.yTop = pRects[i].yTop;
    4753                                 }
    4754 
    4755                                 if (dirtyRect.xRight < pRects[i].xRight)
    4756                                 {
    4757                                     dirtyRect.xRight = pRects[i].xRight;
    4758                                 }
    4759 
    4760                                 if (dirtyRect.yBottom < pRects[i].yBottom)
    4761                                 {
    4762                                     dirtyRect.yBottom = pRects[i].yBottom;
    4763                                 }
    4764                             }
    4765                         }
    4766 
    4767                         if (dirtyRect.xRight - dirtyRect.xLeft)
    4768                         {
    4769                             cr_server.CrCmdClientInfo.pfnCltScrUpdateEnd(cr_server.CrCmdClientInfo.hCltScr, u8PrimaryID, dirtyRect.xLeft, dirtyRect.yTop,
    4770                                                                dirtyRect.xRight - dirtyRect.xLeft, dirtyRect.yBottom - dirtyRect.yTop);
    4771                         }
    4772                         else
    4773                         {
    4774                             cr_server.CrCmdClientInfo.pfnCltScrUpdateEnd(cr_server.CrCmdClientInfo.hCltScr, u8PrimaryID, 0, 0, 0, 0);
    4775                         }
    4776                     }
    4777                 }
    4778                 return 0;
    4779             }
    4780             else
    4781             {
    4782                 /* blit from one primary to another primary, wow */
    4783                 WARN(("not implemented"));
     5181                WARN(("VBOXCMDVBVA_OPF_BLT_TYPE_OFFPRIMSZFMT_OR_ID: invalid command size"));
    47845182                return -1;
    47855183            }
    4786         }
    4787         else
    4788         {
    4789             Assert(u8Flags & VBOXCMDVBVA_OPF_ALLOC_SRCPRIMARY);
    4790             /* blit from primary to non-primary */
    4791             if (u8Flags & VBOXCMDVBVA_OPF_ALLOC_DSTID)
     5184
     5185            return crVBoxServerCrCmdBltOffIdProcess((const VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID *)pCmd, cbCmd);
     5186        }
     5187        case VBOXCMDVBVA_OPF_BLT_TYPE_PRIMARY_GENERIC_A8R8G8B8:
     5188        {
     5189            if (cbCmd < sizeof (VBOXCMDVBVA_BLT_PRIMARY_GENERIC_A8R8G8B8))
    47925190            {
    4793                 uint32_t texId = pBlt->alloc.u.id;
    4794                 WARN(("not implemented"));
     5191                WARN(("VBOXCMDVBVA_OPF_BLT_TYPE_PRIMARY_GENERIC_A8R8G8B8: invalid command size"));
    47955192                return -1;
    47965193            }
    4797             else
     5194
     5195            return crVBoxServerCrCmdBltPrimaryGenericBGRAProcess((const VBOXCMDVBVA_BLT_PRIMARY_GENERIC_A8R8G8B8 *)pCmd, cbCmd);
     5196        }
     5197        case VBOXCMDVBVA_OPF_BLT_TYPE_GENERIC_A8R8G8B8:
     5198        {
     5199            if (cbCmd < sizeof (VBOXCMDVBVA_BLT_GENERIC_A8R8G8B8))
    47985200            {
    4799                 VBOXCMDVBVAOFFSET offVRAM = pBlt->alloc.u.offVRAM;
    4800                 const VBVAINFOSCREEN *pScreen = CrFbGetScreenInfo(hFb);
    4801                 uint32_t cbScreen = pScreen->u32LineSize * pScreen->u32Height;
    4802                 if (offVRAM >= g_cbVRam
    4803                         || offVRAM + cbScreen >= g_cbVRam)
    4804                 {
    4805                     WARN(("invalid param"));
    4806                     return -1;
    4807                 }
    4808 
    4809                 uint8_t *pu8Buf = g_pvVRamBase + offVRAM;
    4810 
    4811                 RTRECT SrcRect;
    4812                 SrcRect.xLeft = 0;
    4813                 SrcRect.yTop = 0;
    4814                 SrcRect.xRight = pScreen->u32Width;
    4815                 SrcRect.yBottom = pScreen->u32Height;
    4816                 RTRECT DstRect;
    4817                 DstRect.xLeft = pBlt->Pos.x;
    4818                 DstRect.yTop = pBlt->Pos.y;
    4819                 DstRect.xRight = DstRect.xLeft + pScreen->u32Width;
    4820                 DstRect.yBottom = DstRect.yTop + pScreen->u32Height;
    4821                 CR_BLITTER_IMG Img;
    4822                 crFbImgFromScreenVram(pScreen, pu8Buf, &Img);
    4823                 int rc = CrFbBltGetContents(hFb, &SrcRect, &DstRect, cRects, pRects, &Img);
    4824                 if (!RT_SUCCESS(rc))
    4825                 {
    4826                     WARN(("CrFbBltGetContents failed %d", rc));
    4827                     return -1;
    4828                 }
     5201                WARN(("VBOXCMDVBVA_OPF_BLT_TYPE_GENERIC_A8R8G8B8: invalid command size"));
     5202                return -1;
    48295203            }
    4830         }
    4831     }
    4832     else
    4833     {
    4834         WARN(("not implemented"));
    4835         return -1;
    4836     }
    4837 
    4838     return 0;
     5204
     5205            return crVBoxServerCrCmdBltGenericBGRAProcess((const VBOXCMDVBVA_BLT_GENERIC_A8R8G8B8 *)pCmd, cbCmd);
     5206        }
     5207        case VBOXCMDVBVA_OPF_BLT_TYPE_PRIMARY_PRIMARY:
     5208        {
     5209            if (cbCmd < sizeof (VBOXCMDVBVA_BLT_PRIMARY))
     5210            {
     5211                WARN(("VBOXCMDVBVA_OPF_BLT_TYPE_PRIMARY_PRIMARY: invalid command size"));
     5212                return -1;
     5213            }
     5214
     5215            return crVBoxServerCrCmdBltPrimaryPrimaryProcess((const VBOXCMDVBVA_BLT_PRIMARY *)pCmd, cbCmd);
     5216        }
     5217        default:
     5218            WARN(("unsupported command"));
     5219            return -1;
     5220    }
    48395221}
    48405222
     
    48425224{
    48435225    uint32_t hostId;
    4844     if (pFlip->Hdr.u8Flags & VBOXCMDVBVA_OPF_ALLOC_SRCID)
     5226    if (pFlip->Hdr.u8Flags & VBOXCMDVBVA_OPF_OPERAND1_ISID)
     5227    {
    48455228        hostId = pFlip->src.u.id;
     5229        if (!hostId)
     5230        {
     5231            WARN(("hostId is NULL"));
     5232            return -1;
     5233        }
     5234    }
    48465235    else
    48475236    {
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette