Changeset 50957 in vbox for trunk/src/VBox/HostServices/SharedOpenGL/crserverlib
- Timestamp:
- Apr 2, 2014 8:26:07 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 93111
- Location:
- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
r50937 r50957 466 466 void CrFbTexDataInit(CR_TEXDATA* pFbTex, const VBOXVR_TEXTURE *pTex, PFNCRTEXDATA_RELEASED pfnTextureReleased); 467 467 468 int8_t crVBoxServerCrCmdBltProcess(const VBOXCMDVBVA_ HDR *pCmd, uint32_t cbCmd);468 int8_t crVBoxServerCrCmdBltProcess(const VBOXCMDVBVA_BLT_HDR *pCmd, uint32_t cbCmd); 469 469 int8_t crVBoxServerCrCmdFlipProcess(const VBOXCMDVBVA_FLIP *pFlip); 470 470 -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
r50937 r50957 3514 3514 return crVBoxServerCrCmdFlipProcess(pFlip); 3515 3515 } 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); 3519 3525 } 3520 3526 default: -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp
r50948 r50957 397 397 } 398 398 399 static 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 399 410 static void crFbImgFromFb(HCR_FRAMEBUFFER hFb, CR_BLITTER_IMG *pImg) 400 411 { … … 402 413 void *pvVram = CrFbGetVRAM(hFb); 403 414 crFbImgFromScreenVram(pScreen, pvVram, pImg); 415 } 416 417 static 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; 404 462 } 405 463 … … 1077 1135 1078 1136 return pFbTex; 1137 } 1138 1139 static 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; 1079 1149 } 1080 1150 … … 4637 4707 } 4638 4708 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")); 4709 static 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 4732 static 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 4796 static 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)); 4650 4836 return -1; 4651 4837 } 4652 4838 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 4852 static 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 4921 static 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 5020 static 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 5102 static 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 5127 static 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 5160 int8_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)) 4664 5170 { 4665 WARN(("RTMemAlloc failed!")); 4666 g_CrPresenter.cbTmpBuf = 0; 5171 WARN(("VBOXCMDVBVA_OPF_BLT_TYPE_PRIMARY: invalid command size")); 4667 5172 return -1; 4668 5173 } 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)) 4680 5180 { 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")); 4784 5182 return -1; 4785 5183 } 4786 } 4787 else4788 {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)) 4792 5190 { 4793 uint32_t texId = pBlt->alloc.u.id; 4794 WARN(("not implemented")); 5191 WARN(("VBOXCMDVBVA_OPF_BLT_TYPE_PRIMARY_GENERIC_A8R8G8B8: invalid command size")); 4795 5192 return -1; 4796 5193 } 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)) 4798 5200 { 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; 4829 5203 } 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 } 4839 5221 } 4840 5222 … … 4842 5224 { 4843 5225 uint32_t hostId; 4844 if (pFlip->Hdr.u8Flags & VBOXCMDVBVA_OPF_ALLOC_SRCID) 5226 if (pFlip->Hdr.u8Flags & VBOXCMDVBVA_OPF_OPERAND1_ISID) 5227 { 4845 5228 hostId = pFlip->src.u.id; 5229 if (!hostId) 5230 { 5231 WARN(("hostId is NULL")); 5232 return -1; 5233 } 5234 } 4846 5235 else 4847 5236 {
Note:
See TracChangeset
for help on using the changeset viewer.