Changeset 27383 in vbox for trunk/src/VBox/Devices/Graphics
- Timestamp:
- Mar 15, 2010 9:47:46 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 58836
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp
r27340 r27383 86 86 RTTHREAD hWorkerThread; 87 87 PHGSMIINSTANCE pHgsmi; 88 PVGASTATE pVGAState; 88 89 VBOXVDMAPIPE_CMD_POOL CmdPool; 89 90 } VBOXVDMAHOST, *PVBOXVDMAHOST; 91 92 /* to simplify things and to avoid extra backend if modifications we assume the VBOXVDMA_RECTL is the same as VBVACMDHDR */ 93 AssertCompile(sizeof(VBOXVDMA_RECTL) == sizeof(VBVACMDHDR)); 94 AssertCompile(RT_SIZEOFMEMB(VBOXVDMA_RECTL, left) == RT_SIZEOFMEMB(VBVACMDHDR, x)); 95 AssertCompile(RT_SIZEOFMEMB(VBOXVDMA_RECTL, top) == RT_SIZEOFMEMB(VBVACMDHDR, y)); 96 AssertCompile(RT_SIZEOFMEMB(VBOXVDMA_RECTL, width) == RT_SIZEOFMEMB(VBVACMDHDR, w)); 97 AssertCompile(RT_SIZEOFMEMB(VBOXVDMA_RECTL, height) == RT_SIZEOFMEMB(VBVACMDHDR, h)); 98 AssertCompile(RT_OFFSETOF(VBOXVDMA_RECTL, left) == RT_OFFSETOF(VBVACMDHDR, x)); 99 AssertCompile(RT_OFFSETOF(VBOXVDMA_RECTL, top) == RT_OFFSETOF(VBVACMDHDR, y)); 100 AssertCompile(RT_OFFSETOF(VBOXVDMA_RECTL, width) == RT_OFFSETOF(VBVACMDHDR, w)); 101 AssertCompile(RT_OFFSETOF(VBOXVDMA_RECTL, height) == RT_OFFSETOF(VBVACMDHDR, h)); 102 103 static int vboxVDMANotifyPrimaryUpdate (PVGASTATE pVGAState, unsigned uScreenId, const VBOXVDMA_RECTL * pRectl) 104 { 105 pVGAState->pDrv->pfnVBVAUpdateBegin (pVGAState->pDrv, uScreenId); 106 107 /* Updates the rectangle and sends the command to the VRDP server. */ 108 pVGAState->pDrv->pfnVBVAUpdateProcess (pVGAState->pDrv, uScreenId, 109 (const PVBVACMDHDR)pRectl /* <- see above AssertCompile's and comments */, 110 sizeof (VBOXVDMA_RECTL)); 111 112 pVGAState->pDrv->pfnVBVAUpdateEnd (pVGAState->pDrv, uScreenId, pRectl->left, pRectl->top, 113 pRectl->width, pRectl->height); 114 115 return VINF_SUCCESS; 116 } 117 118 static int vboxVDMACmdExecBltPerform(PVBOXVDMAHOST pVdma, 119 uint8_t *pvDstSurf, const uint8_t *pvSrcSurf, 120 const PVBOXVDMA_SURF_DESC pDstDesc, const PVBOXVDMA_SURF_DESC pSrcDesc, 121 const VBOXVDMA_RECTL * pDstRectl, const VBOXVDMA_RECTL * pSrcRectl) 122 { 123 /* we do not support color conversion */ 124 Assert(pDstDesc->format == pSrcDesc->format); 125 /* we do not support stretching */ 126 Assert(pDstRectl->height == pSrcRectl->height); 127 Assert(pDstRectl->width == pSrcRectl->width); 128 if (pDstDesc->format != pSrcDesc->format) 129 return VERR_INVALID_FUNCTION; 130 if (pDstDesc->width == pDstRectl->width 131 && pSrcDesc->width == pSrcRectl->width 132 && pSrcDesc->width == pDstDesc->width) 133 { 134 Assert(!pDstRectl->left); 135 Assert(!pSrcRectl->left); 136 uint32_t cbOff = pDstDesc->pitch * pDstRectl->top; 137 uint32_t cbSize = pDstDesc->pitch * pDstRectl->height; 138 memcpy(pvDstSurf + cbOff, pvSrcSurf + cbOff, cbSize); 139 } 140 else 141 { 142 uint32_t offDstStart = pDstDesc->pitch * pDstRectl->top + pDstRectl->left; 143 uint32_t cbDstLine = pDstDesc->bpp * pDstRectl->width; 144 cbDstLine = !(cbDstLine & 7) ? cbDstLine >> 3 : (cbDstLine >> 3) + 1; 145 Assert(cbDstLine <= pDstDesc->pitch); 146 uint32_t cbDstSkip = pDstDesc->pitch - cbDstLine; 147 uint8_t * pvDstStart = pvDstSurf + offDstStart; 148 149 uint32_t offSrcStart = pSrcDesc->pitch * pSrcRectl->top + pSrcRectl->left; 150 uint32_t cbSrcLine = pSrcDesc->bpp * pSrcRectl->width; 151 cbSrcLine = !(cbSrcLine & 7) ? cbSrcLine >> 3 : (cbSrcLine >> 3) + 1; 152 Assert(cbSrcLine <= pSrcDesc->pitch); 153 uint32_t cbSrcSkip = pSrcDesc->pitch - cbSrcLine; 154 const uint8_t * pvSrcStart = pvSrcSurf + offSrcStart; 155 156 Assert(cbDstLine == cbSrcLine); 157 158 for (uint32_t i = 0; ; ++i) 159 { 160 memcpy (pvDstStart, pvSrcStart, cbDstLine); 161 if (i == pDstRectl->height) 162 break; 163 pvDstStart += cbDstSkip; 164 pvSrcStart += cbSrcSkip; 165 } 166 } 167 return VINF_SUCCESS; 168 } 169 170 /* 171 * @return on success the number of bytes the command contained, otherwise - VERR_xxx error code 172 */ 173 static int vboxVDMACmdExecBlt(PVBOXVDMAHOST pVdma, const PVBOXVDMACMD_DMA_PRESENT_BLT pBlt, uint32_t cbBuffer) 174 { 175 const uint32_t cbBlt = VBOXVDMACMD_BODY_FIELD_OFFSET(uint32_t, VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects[pBlt->cDstSubRects]); 176 Assert(cbBlt <= cbBuffer); 177 if (cbBuffer < cbBlt) 178 return VERR_INVALID_FUNCTION; 179 180 /* we do not support stretching for now */ 181 Assert(pBlt->srcRectl.width == pBlt->dstRectl.width); 182 Assert(pBlt->srcRectl.height == pBlt->dstRectl.height); 183 if (pBlt->srcRectl.width != pBlt->dstRectl.width) 184 return VERR_INVALID_FUNCTION; 185 if (pBlt->srcRectl.height != pBlt->dstRectl.height) 186 return VERR_INVALID_FUNCTION; 187 Assert(pBlt->cDstSubRects); 188 189 uint8_t * pvRam = pVdma->pVGAState->vram_ptrR3; 190 191 if (pBlt->cDstSubRects) 192 { 193 VBOXVDMA_RECTL dstRectl, srcRectl; 194 const VBOXVDMA_RECTL *pDstRectl, *pSrcRectl; 195 for (uint32_t i = 0; i < pBlt->cDstSubRects; ++i) 196 { 197 pDstRectl = &pBlt->aDstSubRects[i]; 198 if (pBlt->dstRectl.left || pBlt->dstRectl.top) 199 { 200 dstRectl.left = pDstRectl->left + pBlt->dstRectl.left; 201 dstRectl.top = pDstRectl->top + pBlt->dstRectl.top; 202 dstRectl.width = pDstRectl->width; 203 dstRectl.height = pDstRectl->height; 204 pDstRectl = &dstRectl; 205 } 206 207 pSrcRectl = &pBlt->aDstSubRects[i]; 208 if (pBlt->srcRectl.left || pBlt->srcRectl.top) 209 { 210 srcRectl.left = pSrcRectl->left + pBlt->srcRectl.left; 211 srcRectl.top = pSrcRectl->top + pBlt->srcRectl.top; 212 srcRectl.width = pSrcRectl->width; 213 srcRectl.height = pSrcRectl->height; 214 pSrcRectl = &srcRectl; 215 } 216 217 int rc = vboxVDMACmdExecBltPerform(pVdma, pvRam + pBlt->offDst, pvRam + pBlt->offSrc, 218 &pBlt->dstDesc, &pBlt->srcDesc, 219 pDstRectl, 220 pSrcRectl); 221 AssertRC(rc); 222 if (!RT_SUCCESS(rc)) 223 return rc; 224 } 225 } 226 else 227 { 228 int rc = vboxVDMACmdExecBltPerform(pVdma, pvRam + pBlt->offDst, pvRam + pBlt->offSrc, 229 &pBlt->dstDesc, &pBlt->srcDesc, 230 &pBlt->dstRectl, 231 &pBlt->srcRectl); 232 AssertRC(rc); 233 if (!RT_SUCCESS(rc)) 234 return rc; 235 } 236 237 int iView = 0; 238 /* @todo: fixme: check if update is needed and get iView */ 239 vboxVDMANotifyPrimaryUpdate (pVdma->pVGAState, iView, &pBlt->dstRectl); 240 241 return cbBlt; 242 } 243 244 static int vboxVDMACmdExec(PVBOXVDMAHOST pVdma, const uint8_t *pvBuffer, uint32_t cbBuffer) 245 { 246 do 247 { 248 Assert(pvBuffer); 249 Assert(cbBuffer >= VBOXVDMACMD_HEADER_SIZE()); 250 251 if (!pvBuffer) 252 return VERR_INVALID_PARAMETER; 253 if (cbBuffer < VBOXVDMACMD_HEADER_SIZE()) 254 return VERR_INVALID_PARAMETER; 255 256 PVBOXVDMACMD pCmd = (PVBOXVDMACMD)pvBuffer; 257 uint32_t cbCmd = 0; 258 switch (pCmd->enmType) 259 { 260 case VBOXVDMACMD_TYPE_DMA_PRESENT_BLT: 261 { 262 const PVBOXVDMACMD_DMA_PRESENT_BLT pBlt = VBOXVDMACMD_BODY(pCmd, VBOXVDMACMD_DMA_PRESENT_BLT); 263 int cbBlt = vboxVDMACmdExecBlt(pVdma, pBlt, cbBuffer); 264 Assert(cbBlt >= 0); 265 Assert((uint32_t)cbBlt <= cbBuffer); 266 if (cbBlt >= 0) 267 { 268 if (cbBlt == cbBuffer) 269 return VINF_SUCCESS; 270 else 271 { 272 cbBuffer -= (uint32_t)cbBlt; 273 pvBuffer -= cbBlt; 274 } 275 } 276 else 277 return cbBlt; /* error */ 278 break; 279 } 280 default: 281 AssertBreakpoint(); 282 return VERR_INVALID_FUNCTION; 283 } 284 } while (1); 285 286 /* we should not be here */ 287 AssertBreakpoint(); 288 return VERR_INVALID_STATE; 289 } 90 290 91 291 int vboxVDMAPipeConstruct(PVBOXVDMAPIPE pPipe) … … 317 517 } 318 518 319 void vboxVDMACommandProcess(PVBOXVDMAHOST pVdma, PVBOXVDMACBUF_DR pCmd)519 static void vboxVDMACommandProcess(PVBOXVDMAHOST pVdma, PVBOXVDMACBUF_DR pCmd) 320 520 { 321 521 PHGSMIINSTANCE pHgsmi = pVdma->pHgsmi; 322 pCmd->rc = VINF_SUCCESS; 323 int rc = VBoxSHGSMICommandComplete (pHgsmi, pCmd); 324 AssertRC(rc); 325 } 326 327 void vboxVDMAControlProcess(PVBOXVDMAHOST pVdma, PVBOXVDMA_CTL pCmd) 522 const uint8_t * pvBuf; 523 PGMPAGEMAPLOCK Lock; 524 int rc; 525 bool bReleaseLocked = false; 526 527 do 528 { 529 PPDMDEVINS pDevIns = pVdma->pVGAState->pDevInsR3; 530 531 if (pCmd->fFlags & VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR) 532 pvBuf = VBOXVDMACBUF_DR_TAIL(pCmd, const uint8_t); 533 else if (pCmd->fFlags & VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET) 534 { 535 uint8_t * pvRam = pVdma->pVGAState->vram_ptrR3; 536 pvBuf = pvRam + pCmd->Location.offVramBuf; 537 } 538 else 539 { 540 RTGCPHYS phPage = pCmd->Location.phBuf & ~0xfffULL; 541 uint32_t offset = pCmd->Location.phBuf & 0xfff; 542 Assert(offset + pCmd->cbBuf <= 0x1000); 543 if (offset + pCmd->cbBuf > 0x1000) 544 { 545 /* @todo: more advanced mechanism of command buffer proc is actually needed */ 546 rc = VERR_INVALID_PARAMETER; 547 break; 548 } 549 550 const void * pvPageBuf; 551 rc = PDMDevHlpPhysGCPhys2CCPtrReadOnly(pDevIns, phPage, 0, &pvPageBuf, &Lock); 552 AssertRC(rc); 553 if (!RT_SUCCESS(rc)) 554 { 555 /* @todo: if (rc == VERR_PGM_PHYS_PAGE_RESERVED) -> fall back on using PGMPhysRead ?? */ 556 break; 557 } 558 559 pvBuf = (const uint8_t *)pvPageBuf; 560 pvBuf += offset; 561 562 bReleaseLocked = true; 563 } 564 565 rc = vboxVDMACmdExec(pVdma, pvBuf, pCmd->cbBuf); 566 AssertRC(rc); 567 568 if (bReleaseLocked) 569 PDMDevHlpPhysReleasePageMappingLock(pDevIns, &Lock); 570 } while (0); 571 572 pCmd->rc = rc; 573 574 rc = VBoxSHGSMICommandComplete (pHgsmi, pCmd); 575 AssertRC(rc); 576 } 577 578 static void vboxVDMAControlProcess(PVBOXVDMAHOST pVdma, PVBOXVDMA_CTL pCmd) 328 579 { 329 580 PHGSMIINSTANCE pHgsmi = pVdma->pHgsmi; … … 340 591 } VBOXVDMACMD_PROCESS_CONTEXT, *PVBOXVDMACMD_PROCESS_CONTEXT; 341 592 342 DECLCALLBACK(bool) vboxVDMACommandProcessCb(PVBOXVDMAPIPE pPipe, void *pvCallback)593 static DECLCALLBACK(bool) vboxVDMACommandProcessCb(PVBOXVDMAPIPE pPipe, void *pvCallback) 343 594 { 344 595 PVBOXVDMACMD_PROCESS_CONTEXT pContext = (PVBOXVDMACMD_PROCESS_CONTEXT)pvCallback; … … 359 610 } 360 611 361 DECLCALLBACK(int) vboxVDMAWorkerThread(RTTHREAD ThreadSelf, void *pvUser)612 static DECLCALLBACK(int) vboxVDMAWorkerThread(RTTHREAD ThreadSelf, void *pvUser) 362 613 { 363 614 PVBOXVDMAHOST pVdma = (PVBOXVDMAHOST)pvUser; … … 421 672 hgsmiListInit(&pVdma->PendingList); 422 673 pVdma->pHgsmi = pVGAState->pHGSMI; 423 674 pVdma->pVGAState = pVGAState; 424 675 rc = vboxVDMAPipeConstruct(&pVdma->Pipe); 425 676 AssertRC(rc);
Note:
See TracChangeset
for help on using the changeset viewer.