Changeset 51603 in vbox
- Timestamp:
- Jun 11, 2014 11:59:20 AM (11 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/DisplayImpl.h
r51553 r51603 37 37 struct VIDEORECCONTEXT; 38 38 39 enum40 {41 ResizeStatus_Void,42 ResizeStatus_InProgress,43 ResizeStatus_UpdateDisplayData44 };45 46 39 typedef struct _DISPLAYFBINFO 47 40 { … … 66 59 uint16_t flags; 67 60 68 /** For saving the rectangles arrived during fb resize is in progress. */69 PRTRECT mpSavedVisibleRegion;70 uint32_t mcSavedVisibleRegion;71 72 61 VBOXVIDEOINFOHOSTEVENTS *pHostEvents; 73 74 volatile uint32_t u32ResizeStatus;75 62 76 63 /** The framebuffer has default format and must be updates immediately. */ … … 86 73 } dirtyRect; 87 74 88 struct89 {90 bool fPending;91 ULONG pixelFormat;92 void *pvVRAM;93 uint32_t bpp;94 uint32_t cbLine;95 uint32_t w;96 uint32_t h;97 uint16_t flags;98 } pendingResize;99 100 75 #ifdef VBOX_WITH_HGSMI 101 76 bool fVBVAEnabled; 102 77 bool fVBVAForceResize; 103 78 bool fRenderThreadMode; 104 uint32_t cVBVASkipUpdate;105 struct106 {107 int32_t xLeft;108 int32_t yTop;109 int32_t xRight;110 int32_t yBottom;111 } vbvaSkippedRect;112 79 PVBVAHOSTFLAGS pVBVAHostFlags; 113 80 #endif /* VBOX_WITH_HGSMI */ … … 324 291 325 292 bool mfSourceBitmapEnabled; 293 bool volatile fVGAResizing; 326 294 327 295 /* arguments of the last handleDisplayResize() call */ … … 372 340 int vbvaLock(void); 373 341 void vbvaUnlock(void); 374 375 RTCRITSECT mSaveSeamlessRectLock;376 int SaveSeamlessRectLock(void);377 void SaveSeamlessRectUnLock(void);378 342 379 343 public: -
trunk/src/VBox/Main/src-client/DisplayImpl.cpp
r51553 r51603 135 135 136 136 int rc = RTCritSectInit(&mVBVALock); 137 AssertRC(rc);138 139 rc = RTCritSectInit(&mSaveSeamlessRectLock);140 137 AssertRC(rc); 141 138 … … 178 175 RTCritSectDelete (&mVBVALock); 179 176 RT_ZERO(mVBVALock); 180 }181 182 if (RTCritSectIsInitialized(&mSaveSeamlessRectLock))183 {184 RTCritSectDelete(&mSaveSeamlessRectLock);185 RT_ZERO(mSaveSeamlessRectLock);186 177 } 187 178 … … 599 590 600 591 mfSourceBitmapEnabled = true; 592 fVGAResizing = false; 601 593 602 594 ULONG ul; … … 628 620 maFramebuffers[ul].pHostEvents = NULL; 629 621 630 maFramebuffers[ul].u32ResizeStatus = ResizeStatus_Void;631 632 622 maFramebuffers[ul].fDefaultFormat = false; 633 623 634 maFramebuffers[ul].mcSavedVisibleRegion = 0;635 maFramebuffers[ul].mpSavedVisibleRegion = NULL;636 637 624 RT_ZERO(maFramebuffers[ul].dirtyRect); 638 RT_ZERO(maFramebuffers[ul].pendingResize);639 625 #ifdef VBOX_WITH_HGSMI 640 626 maFramebuffers[ul].fVBVAEnabled = false; 641 627 maFramebuffers[ul].fVBVAForceResize = false; 642 628 maFramebuffers[ul].fRenderThreadMode = false; 643 maFramebuffers[ul].cVBVASkipUpdate = 0;644 RT_ZERO(maFramebuffers[ul].vbvaSkippedRect);645 629 maFramebuffers[ul].pVBVAHostFlags = NULL; 646 630 #endif /* VBOX_WITH_HGSMI */ … … 850 834 ///////////////////////////////////////////////////////////////////////////// 851 835 852 /**853 * @thread EMT854 */855 static int callFramebufferResize (IFramebuffer *pFramebuffer, unsigned uScreenId,856 ULONG pixelFormat, void *pvVRAM,857 uint32_t bpp, uint32_t cbLine,858 uint32_t w, uint32_t h)859 {860 Assert (pFramebuffer);861 862 NOREF(pixelFormat);863 NOREF(pvVRAM);864 NOREF(bpp);865 NOREF(cbLine);866 867 /* Call the framebuffer to try and set required pixelFormat. */868 HRESULT hr = pFramebuffer->NotifyChange(uScreenId, 0, 0, w, h); /* @todo origin */869 870 Log(("pFramebuffer->NotifyChange hr %08x\n", hr));871 872 return VINF_SUCCESS;873 }874 875 836 int Display::notifyCroglResize(const PVBVAINFOVIEW pView, const PVBVAINFOSCREEN pScreen, void *pvVRAM) 876 837 { … … 937 898 uScreenId, pvVRAM, w, h, bpp, cbLine, flags)); 938 899 939 /* If there is no framebuffer, this call is not interesting. */940 900 if (uScreenId >= mcMonitors) 941 901 { … … 975 935 maFramebuffers[uScreenId].pSourceBitmap.setNull(); 976 936 977 ULONG pixelFormat;978 979 switch (bpp)980 {981 case 32:982 case 24:983 case 16:984 pixelFormat = FramebufferPixelFormat_FOURCC_RGB;985 break;986 default:987 pixelFormat = FramebufferPixelFormat_Opaque;988 bpp = cbLine = 0;989 break;990 }991 992 /* Atomically set the resize status before calling the framebuffer. The new InProgress status will993 * disable access to the VGA device by the EMT thread.994 */995 bool f = ASMAtomicCmpXchgU32 (&maFramebuffers[uScreenId].u32ResizeStatus,996 ResizeStatus_InProgress, ResizeStatus_Void);997 if (!f)998 {999 /* This could be a result of the screenshot taking call Display::TakeScreenShot:1000 * if the framebuffer is processing the resize request and GUI calls the TakeScreenShot1001 * and the guest has reprogrammed the virtual VGA devices again so a new resize is required.1002 *1003 * Save the resize information and return the pending status code.1004 *1005 * Note: the resize information is only accessed on EMT so no serialization is required.1006 */1007 LogRel(("Display::handleDisplayResize(): Warning: resize postponed.\n"));1008 1009 maFramebuffers[uScreenId].pendingResize.fPending = true;1010 maFramebuffers[uScreenId].pendingResize.pixelFormat = pixelFormat;1011 maFramebuffers[uScreenId].pendingResize.pvVRAM = pvVRAM;1012 maFramebuffers[uScreenId].pendingResize.bpp = bpp;1013 maFramebuffers[uScreenId].pendingResize.cbLine = cbLine;1014 maFramebuffers[uScreenId].pendingResize.w = w;1015 maFramebuffers[uScreenId].pendingResize.h = h;1016 maFramebuffers[uScreenId].pendingResize.flags = flags;1017 1018 return VINF_VGA_RESIZE_IN_PROGRESS;1019 }1020 1021 937 if (!maFramebuffers[uScreenId].pFramebuffer.isNull()) 1022 938 { 1023 callFramebufferResize(maFramebuffers[uScreenId].pFramebuffer, uScreenId, 1024 pixelFormat, pvVRAM, bpp, cbLine, w, h); 1025 } 1026 1027 /* Set the status so the 'handleResizeCompleted' would work. */ 1028 f = ASMAtomicCmpXchgU32 (&maFramebuffers[uScreenId].u32ResizeStatus, 1029 ResizeStatus_UpdateDisplayData, ResizeStatus_InProgress); 1030 AssertRelease(f);NOREF(f); 1031 1032 AssertRelease(!maFramebuffers[uScreenId].pendingResize.fPending); 1033 1034 /* The method also unlocks the framebuffer. */ 939 HRESULT hr = maFramebuffers[uScreenId].pFramebuffer->NotifyChange(uScreenId, 0, 0, w, h); /* @todo origin */ 940 LogFunc(("NotifyChange hr %08X\n", hr)); 941 NOREF(hr); 942 } 943 1035 944 handleResizeCompletedEMT(uScreenId, TRUE); 1036 945 … … 1057 966 DISPLAYFBINFO *pFBInfo = &maFramebuffers[uScreenId]; 1058 967 1059 /* Try to into non resizing state. */1060 bool f = ASMAtomicCmpXchgU32 (&pFBInfo->u32ResizeStatus, ResizeStatus_Void, ResizeStatus_UpdateDisplayData);1061 1062 if (f == false)1063 {1064 /* This is not the display that has completed resizing. */1065 AssertFailed();1066 break;1067 }1068 1069 /* Check whether a resize is pending for this framebuffer. */1070 if (pFBInfo->pendingResize.fPending)1071 {1072 /* Reset the condition, call the display resize with saved data and continue.1073 *1074 * Note: handleDisplayResize can call handleResizeCompletedEMT back,1075 * but infinite recursion is not possible, because when the handleResizeCompletedEMT1076 * is called, the pFBInfo->pendingResize.fPending is equal to false.1077 */1078 pFBInfo->pendingResize.fPending = false;1079 handleDisplayResize (uScreenId, pFBInfo->pendingResize.bpp, pFBInfo->pendingResize.pvVRAM,1080 pFBInfo->pendingResize.cbLine, pFBInfo->pendingResize.w, pFBInfo->pendingResize.h,1081 pFBInfo->pendingResize.flags);1082 break;1083 }1084 1085 968 /* Inform VRDP server about the change of display parameters. 1086 969 * Must be done before calling NotifyUpdate below. … … 1109 992 } 1110 993 LogRelFlow(("[%d]: default format %d\n", uScreenId, pFBInfo->fDefaultFormat)); 1111 1112 /* Handle the case if there are some saved visible region that needs to be1113 * applied after the resize of the framebuffer is completed1114 */1115 SaveSeamlessRectLock();1116 PRTRECT pSavedVisibleRegion = pFBInfo->mpSavedVisibleRegion;1117 uint32_t cSavedVisibleRegion = pFBInfo->mcSavedVisibleRegion;1118 pFBInfo->mpSavedVisibleRegion = NULL;1119 pFBInfo->mcSavedVisibleRegion = 0;1120 SaveSeamlessRectUnLock();1121 1122 if (pSavedVisibleRegion)1123 {1124 handleSetVisibleRegion(cSavedVisibleRegion, pSavedVisibleRegion);1125 RTMemFree(pSavedVisibleRegion);1126 }1127 994 1128 995 #ifdef DEBUG_sunlover … … 1286 1153 * Inform the server here only if VBVA is disabled. 1287 1154 */ 1288 if (maFramebuffers[uScreenId].u32ResizeStatus == ResizeStatus_Void) 1289 mParent->consoleVRDPServer()->SendUpdateBitmap(uScreenId, x, y, w, h); 1155 mParent->consoleVRDPServer()->SendUpdateBitmap(uScreenId, x, y, w, h); 1290 1156 } 1291 1157 } … … 1386 1252 if (!pFBInfo->pFramebuffer.isNull()) 1387 1253 { 1388 if (pFBInfo->u32ResizeStatus != ResizeStatus_Void)1389 {1390 /* handle the case where new rectangles are received from the GA1391 * when framebuffer resizing is in progress.1392 * Just save the rectangles to be applied for later time when FB resizing is complete1393 * (from handleResizeCompletedEMT).1394 * This is done to prevent a race condition where a new rectangles are received1395 * from the GA after a resize event and framebuffer resizing is still in progress1396 * As a result the coordinates of the framebuffer are still1397 * not updated and hence there is no intersection with the new rectangles passed1398 * for the new region (THis is checked in the above if condition ). With 0 intersection,1399 * cRectVisibleRegions = 0 is returned to the GUI and if GUI has invalidated its1400 * earlier region then it draws nothihing and seamless mode doesn't display the1401 * guest desktop.1402 */1403 SaveSeamlessRectLock();1404 RTMemFree(pFBInfo->mpSavedVisibleRegion);1405 1406 pFBInfo->mpSavedVisibleRegion = (RTRECT *)RTMemAlloc( RT_MAX(cRect, 1)1407 * sizeof (RTRECT));1408 if (pFBInfo->mpSavedVisibleRegion)1409 {1410 memcpy(pFBInfo->mpSavedVisibleRegion, pRect, cRect * sizeof(RTRECT));1411 pFBInfo->mcSavedVisibleRegion = cRect;1412 }1413 else1414 {1415 pFBInfo->mcSavedVisibleRegion = 0;1416 }1417 SaveSeamlessRectUnLock();1418 continue;1419 }1420 1254 /* Prepare a new array of rectangles which intersect with the framebuffer. 1421 1255 */ … … 1717 1551 } 1718 1552 1719 int Display::SaveSeamlessRectLock(void)1720 {1721 return RTCritSectEnter(&mSaveSeamlessRectLock);1722 }1723 1724 void Display::SaveSeamlessRectUnLock(void)1725 {1726 RTCritSectLeave(&mSaveSeamlessRectLock);1727 }1728 1729 1553 1730 1554 /** … … 1800 1624 1801 1625 /* Update entire display. */ 1802 if (maFramebuffers[VBOX_VIDEO_PRIMARY_SCREEN].u32ResizeStatus == ResizeStatus_Void) 1803 mpDrv->pUpPort->pfnUpdateDisplayAll(mpDrv->pUpPort); 1626 mpDrv->pUpPort->pfnUpdateDisplayAll(mpDrv->pUpPort); 1804 1627 1805 1628 /* Everything OK. VBVA status can be changed. */ … … 2266 2089 DISPLAYFBINFO *pFBInfo = &maFramebuffers[uScreenId]; 2267 2090 2268 if (pFBInfo->u32ResizeStatus == ResizeStatus_Void) 2269 { 2270 /* Handle the command. 2271 * 2272 * Guest is responsible for updating the guest video memory. 2273 * The Windows guest does all drawing using Eng*. 2274 * 2275 * For local output, only dirty rectangle information is used 2276 * to update changed areas. 2277 * 2278 * Dirty rectangles are accumulated to exclude overlapping updates and 2279 * group small updates to a larger one. 2280 */ 2281 2282 /* Accumulate the update. */ 2283 vbvaRgnDirtyRect (&rgn, uScreenId, phdr); 2284 2285 /* Forward the command to VRDP server. */ 2286 mParent->consoleVRDPServer()->SendUpdate (uScreenId, phdr, cbCmd); 2287 2288 *phdr = hdrSaved; 2289 } 2091 /* Handle the command. 2092 * 2093 * Guest is responsible for updating the guest video memory. 2094 * The Windows guest does all drawing using Eng*. 2095 * 2096 * For local output, only dirty rectangle information is used 2097 * to update changed areas. 2098 * 2099 * Dirty rectangles are accumulated to exclude overlapping updates and 2100 * group small updates to a larger one. 2101 */ 2102 2103 /* Accumulate the update. */ 2104 vbvaRgnDirtyRect (&rgn, uScreenId, phdr); 2105 2106 /* Forward the command to VRDP server. */ 2107 mParent->consoleVRDPServer()->SendUpdate (uScreenId, phdr, cbCmd); 2108 2109 *phdr = hdrSaved; 2290 2110 } 2291 2111 … … 2295 2115 for (uScreenId = 0; uScreenId < mcMonitors; uScreenId++) 2296 2116 { 2297 if (maFramebuffers[uScreenId].u32ResizeStatus == ResizeStatus_Void) 2298 { 2299 /* Draw the framebuffer. */ 2300 vbvaRgnUpdateFramebuffer (&rgn, uScreenId); 2301 } 2117 /* Draw the framebuffer. */ 2118 vbvaRgnUpdateFramebuffer (&rgn, uScreenId); 2302 2119 } 2303 2120 } … … 3257 3074 if (aScreenId == VBOX_VIDEO_PRIMARY_SCREEN) 3258 3075 { 3259 if (pFBInfo->u32ResizeStatus == ResizeStatus_Void) 3260 { 3261 rc = pDisplay->mpDrv->pUpPort->pfnDisplayBlt(pDisplay->mpDrv->pUpPort, address, x, y, width, height); 3262 } 3076 rc = pDisplay->mpDrv->pUpPort->pfnDisplayBlt(pDisplay->mpDrv->pUpPort, address, x, y, width, height); 3263 3077 } 3264 3078 else if (aScreenId < pDisplay->mcMonitors) … … 3355 3169 } 3356 3170 3357 if ( RT_SUCCESS(rc) 3358 && pDisplay->maFramebuffers[aScreenId].u32ResizeStatus == ResizeStatus_Void) 3171 if (RT_SUCCESS(rc)) 3359 3172 pDisplay->mParent->consoleVRDPServer()->SendUpdateBitmap(aScreenId, x, y, width, height); 3360 3173 … … 3439 3252 else 3440 3253 { 3441 if ( !pFBInfo->fDisabled 3442 && pFBInfo->u32ResizeStatus == ResizeStatus_Void) 3254 if (!pFBInfo->fDisabled) 3443 3255 { 3444 3256 /* Render complete VRAM screen to the framebuffer. … … 3681 3493 { 3682 3494 /* @todo make sure that the bitmap contains the latest image? */ 3495 Console::SafeVMPtrQuiet ptrVM(mParent); 3496 if (ptrVM.isOk()) 3497 { 3498 // VMR3ReqCallWaitU(ptrVM.rawUVM(), VMCPUID_ANY, (PFNRT)Display::InvalidateAndUpdateEMT, 3499 // 3, this, aScreenId, false); 3500 } 3683 3501 } 3684 3502 } … … 3785 3603 { 3786 3604 PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface); 3605 Display *pThis = pDrv->pDisplay; 3787 3606 3788 3607 LogRelFlowFunc(("bpp %d, pvVRAM %p, cbLine %d, cx %d, cy %d\n", 3789 3608 bpp, pvVRAM, cbLine, cx, cy)); 3790 3609 3791 return pDrv->pDisplay->handleDisplayResize(VBOX_VIDEO_PRIMARY_SCREEN, bpp, pvVRAM, cbLine, cx, cy, VBVA_SCREEN_F_ACTIVE); 3610 bool f = ASMAtomicCmpXchgBool(&pThis->fVGAResizing, true, false); 3611 if (!f) 3612 { 3613 /* This is a result of recursive call when the source bitmap is being updated 3614 * during a VGA resize. Tell the VGA device to ignore the call. 3615 * 3616 * @todo It is a workaround, actually pfnUpdateDisplayAll must 3617 * fail on resize. 3618 */ 3619 LogRel(("displayResizeCallback: already processing\n")); 3620 return VINF_VGA_RESIZE_IN_PROGRESS; 3621 } 3622 3623 int rc = pThis->handleDisplayResize(VBOX_VIDEO_PRIMARY_SCREEN, bpp, pvVRAM, cbLine, cx, cy, VBVA_SCREEN_F_ACTIVE); 3624 3625 /* Restore the flag. */ 3626 f = ASMAtomicCmpXchgBool(&pThis->fVGAResizing, false, true); 3627 AssertRelease(f); 3628 3629 return rc; 3792 3630 } 3793 3631 … … 3835 3673 3836 3674 Display *pDisplay = pDrv->pDisplay; 3837 bool fNoUpdate = false; /* Do not update the display if any of the framebuffers is being resized. */3838 3675 unsigned uScreenId; 3839 3676 3840 for (uScreenId = 0; uScreenId < pDisplay->mcMonitors; uScreenId++) 3841 { 3842 DISPLAYFBINFO *pFBInfo = &pDisplay->maFramebuffers[uScreenId]; 3843 3844 /* Check the resize status. The status can be checked normally because 3845 * the status affects only the EMT. 3677 int rc = pDisplay->videoAccelRefreshProcess(); 3678 if (rc != VINF_TRY_AGAIN) /* Means 'do nothing' here. */ 3679 { 3680 if (rc == VWRN_INVALID_STATE) 3681 { 3682 /* No VBVA do a display update. */ 3683 DISPLAYFBINFO *pFBInfo = &pDisplay->maFramebuffers[VBOX_VIDEO_PRIMARY_SCREEN]; 3684 pDisplay->vbvaLock(); 3685 pDrv->pUpPort->pfnUpdateDisplay(pDrv->pUpPort); 3686 pDisplay->vbvaUnlock(); 3687 } 3688 3689 /* Inform the VRDP server that the current display update sequence is 3690 * completed. At this moment the framebuffer memory contains a definite 3691 * image, that is synchronized with the orders already sent to VRDP client. 3692 * The server can now process redraw requests from clients or initial 3693 * fullscreen updates for new clients. 3846 3694 */ 3847 uint32_t u32ResizeStatus = pFBInfo->u32ResizeStatus; 3848 3849 if (u32ResizeStatus == ResizeStatus_UpdateDisplayData) 3850 { 3851 LogRelFlowFunc(("ResizeStatus_UpdateDisplayData %d\n", uScreenId)); 3852 fNoUpdate = true; /* Always set it here, because pfnUpdateDisplayAll can cause a new resize. */ 3853 /* The framebuffer was resized and display data need to be updated. */ 3854 pDisplay->handleResizeCompletedEMT(uScreenId, FALSE); 3855 if (pFBInfo->u32ResizeStatus != ResizeStatus_Void) 3856 { 3857 /* The resize status could be not Void here because a pending resize is issued. */ 3858 continue; 3859 } 3860 3861 /* Repaint the display because VM continued to run during the framebuffer resize. */ 3862 pDisplay->InvalidateAndUpdateEMT(pDisplay, uScreenId, false); 3863 3864 /* Continue with normal processing because the status here is ResizeStatus_Void. */ 3865 } 3866 else if (u32ResizeStatus == ResizeStatus_InProgress) 3867 { 3868 /* The framebuffer is being resized. Do not call the VGA device back. Immediately return. */ 3869 LogRelFlowFunc(("ResizeStatus_InProcess\n")); 3870 fNoUpdate = true; 3871 continue; 3872 } 3873 } 3874 3875 if (!fNoUpdate) 3876 { 3877 int rc = pDisplay->videoAccelRefreshProcess(); 3878 if (rc != VINF_TRY_AGAIN) /* Means 'do nothing' here. */ 3879 { 3880 if (rc == VWRN_INVALID_STATE) 3881 { 3882 /* No VBVA do a display update. */ 3883 DISPLAYFBINFO *pFBInfo = &pDisplay->maFramebuffers[VBOX_VIDEO_PRIMARY_SCREEN]; 3884 if (pFBInfo->u32ResizeStatus == ResizeStatus_Void) 3885 { 3886 pDisplay->vbvaLock(); 3887 pDrv->pUpPort->pfnUpdateDisplay(pDrv->pUpPort); 3888 pDisplay->vbvaUnlock(); 3889 } 3890 } 3891 3892 /* Inform the VRDP server that the current display update sequence is 3893 * completed. At this moment the framebuffer memory contains a definite 3894 * image, that is synchronized with the orders already sent to VRDP client. 3895 * The server can now process redraw requests from clients or initial 3896 * fullscreen updates for new clients. 3897 */ 3898 for (uScreenId = 0; uScreenId < pDisplay->mcMonitors; uScreenId++) 3899 { 3900 DISPLAYFBINFO *pFBInfo = &pDisplay->maFramebuffers[uScreenId]; 3901 3902 if (pFBInfo->u32ResizeStatus == ResizeStatus_Void) 3903 { 3904 Assert (pDisplay->mParent && pDisplay->mParent->consoleVRDPServer()); 3905 pDisplay->mParent->consoleVRDPServer()->SendUpdate (uScreenId, NULL, 0); 3906 } 3907 } 3695 for (uScreenId = 0; uScreenId < pDisplay->mcMonitors; uScreenId++) 3696 { 3697 DISPLAYFBINFO *pFBInfo = &pDisplay->maFramebuffers[uScreenId]; 3698 3699 Assert (pDisplay->mParent && pDisplay->mParent->consoleVRDPServer()); 3700 pDisplay->mParent->consoleVRDPServer()->SendUpdate (uScreenId, NULL, 0); 3908 3701 } 3909 3702 } … … 3957 3750 3958 3751 if ( !pFBInfo->pFramebuffer.isNull() 3959 && !pFBInfo->fDisabled 3960 && pFBInfo->u32ResizeStatus == ResizeStatus_Void) 3752 && !pFBInfo->fDisabled) 3961 3753 { 3962 3754 int rc = VERR_NOT_SUPPORTED; … … 4697 4489 ASMAtomicDecU32(&pThis->mu32UpdateVBVAFlags); 4698 4490 } 4699 4700 if (RT_LIKELY(pFBInfo->u32ResizeStatus == ResizeStatus_Void))4701 {4702 if (RT_UNLIKELY(pFBInfo->cVBVASkipUpdate != 0))4703 {4704 /* Some updates were skipped. Note: displayVBVAUpdate* callbacks are called4705 * under display device lock, so thread safe.4706 */4707 pFBInfo->cVBVASkipUpdate = 0;4708 pThis->handleDisplayUpdate(uScreenId, pFBInfo->vbvaSkippedRect.xLeft - pFBInfo->xOrigin,4709 pFBInfo->vbvaSkippedRect.yTop - pFBInfo->yOrigin,4710 pFBInfo->vbvaSkippedRect.xRight - pFBInfo->vbvaSkippedRect.xLeft,4711 pFBInfo->vbvaSkippedRect.yBottom - pFBInfo->vbvaSkippedRect.yTop);4712 }4713 }4714 else4715 {4716 /* The framebuffer is being resized. */4717 pFBInfo->cVBVASkipUpdate++;4718 }4719 4491 } 4720 4492 … … 4728 4500 DISPLAYFBINFO *pFBInfo = &pThis->maFramebuffers[uScreenId]; 4729 4501 4730 if (RT_LIKELY(pFBInfo->cVBVASkipUpdate == 0)) 4731 { 4732 if (pFBInfo->fDefaultFormat) 4733 { 4734 /* Make sure that framebuffer contains the same image as the guest VRAM. */ 4735 if ( uScreenId == VBOX_VIDEO_PRIMARY_SCREEN 4736 && !pFBInfo->fDisabled) 4502 if (pFBInfo->fDefaultFormat) 4503 { 4504 /* Make sure that framebuffer contains the same image as the guest VRAM. */ 4505 if ( uScreenId == VBOX_VIDEO_PRIMARY_SCREEN 4506 && !pFBInfo->fDisabled) 4507 { 4508 pDrv->pUpPort->pfnUpdateDisplayRect (pDrv->pUpPort, pCmd->x, pCmd->y, pCmd->w, pCmd->h); 4509 } 4510 else if ( !pFBInfo->pSourceBitmap.isNull() 4511 && !pFBInfo->fDisabled) 4512 { 4513 /* Render VRAM content to the framebuffer. */ 4514 BYTE *pAddress = NULL; 4515 ULONG ulWidth = 0; 4516 ULONG ulHeight = 0; 4517 ULONG ulBitsPerPixel = 0; 4518 ULONG ulBytesPerLine = 0; 4519 ULONG ulPixelFormat = 0; 4520 4521 HRESULT hrc = pFBInfo->pSourceBitmap->QueryBitmapInfo(&pAddress, 4522 &ulWidth, 4523 &ulHeight, 4524 &ulBitsPerPixel, 4525 &ulBytesPerLine, 4526 &ulPixelFormat); 4527 if (SUCCEEDED(hrc)) 4737 4528 { 4738 pDrv->pUpPort->pfnUpdateDisplayRect (pDrv->pUpPort, pCmd->x, pCmd->y, pCmd->w, pCmd->h); 4529 uint32_t width = pCmd->w; 4530 uint32_t height = pCmd->h; 4531 4532 const uint8_t *pu8Src = pFBInfo->pu8FramebufferVRAM; 4533 int32_t xSrc = pCmd->x - pFBInfo->xOrigin; 4534 int32_t ySrc = pCmd->y - pFBInfo->yOrigin; 4535 uint32_t u32SrcWidth = pFBInfo->w; 4536 uint32_t u32SrcHeight = pFBInfo->h; 4537 uint32_t u32SrcLineSize = pFBInfo->u32LineSize; 4538 uint32_t u32SrcBitsPerPixel = pFBInfo->u16BitsPerPixel; 4539 4540 uint8_t *pu8Dst = pAddress; 4541 int32_t xDst = xSrc; 4542 int32_t yDst = ySrc; 4543 uint32_t u32DstWidth = u32SrcWidth; 4544 uint32_t u32DstHeight = u32SrcHeight; 4545 uint32_t u32DstLineSize = u32DstWidth * 4; 4546 uint32_t u32DstBitsPerPixel = 32; 4547 4548 pDrv->pUpPort->pfnCopyRect(pDrv->pUpPort, 4549 width, height, 4550 pu8Src, 4551 xSrc, ySrc, 4552 u32SrcWidth, u32SrcHeight, 4553 u32SrcLineSize, u32SrcBitsPerPixel, 4554 pu8Dst, 4555 xDst, yDst, 4556 u32DstWidth, u32DstHeight, 4557 u32DstLineSize, u32DstBitsPerPixel); 4739 4558 } 4740 else if ( !pFBInfo->pSourceBitmap.isNull() 4741 && !pFBInfo->fDisabled) 4742 { 4743 /* Render VRAM content to the framebuffer. */ 4744 BYTE *pAddress = NULL; 4745 ULONG ulWidth = 0; 4746 ULONG ulHeight = 0; 4747 ULONG ulBitsPerPixel = 0; 4748 ULONG ulBytesPerLine = 0; 4749 ULONG ulPixelFormat = 0; 4750 4751 HRESULT hrc = pFBInfo->pSourceBitmap->QueryBitmapInfo(&pAddress, 4752 &ulWidth, 4753 &ulHeight, 4754 &ulBitsPerPixel, 4755 &ulBytesPerLine, 4756 &ulPixelFormat); 4757 if (SUCCEEDED(hrc)) 4758 { 4759 uint32_t width = pCmd->w; 4760 uint32_t height = pCmd->h; 4761 4762 const uint8_t *pu8Src = pFBInfo->pu8FramebufferVRAM; 4763 int32_t xSrc = pCmd->x - pFBInfo->xOrigin; 4764 int32_t ySrc = pCmd->y - pFBInfo->yOrigin; 4765 uint32_t u32SrcWidth = pFBInfo->w; 4766 uint32_t u32SrcHeight = pFBInfo->h; 4767 uint32_t u32SrcLineSize = pFBInfo->u32LineSize; 4768 uint32_t u32SrcBitsPerPixel = pFBInfo->u16BitsPerPixel; 4769 4770 uint8_t *pu8Dst = pAddress; 4771 int32_t xDst = xSrc; 4772 int32_t yDst = ySrc; 4773 uint32_t u32DstWidth = u32SrcWidth; 4774 uint32_t u32DstHeight = u32SrcHeight; 4775 uint32_t u32DstLineSize = u32DstWidth * 4; 4776 uint32_t u32DstBitsPerPixel = 32; 4777 4778 pDrv->pUpPort->pfnCopyRect(pDrv->pUpPort, 4779 width, height, 4780 pu8Src, 4781 xSrc, ySrc, 4782 u32SrcWidth, u32SrcHeight, 4783 u32SrcLineSize, u32SrcBitsPerPixel, 4784 pu8Dst, 4785 xDst, yDst, 4786 u32DstWidth, u32DstHeight, 4787 u32DstLineSize, u32DstBitsPerPixel); 4788 } 4789 } 4790 } 4791 4792 VBVACMDHDR hdrSaved = *pCmd; 4793 4794 VBVACMDHDR *pHdrUnconst = (VBVACMDHDR *)pCmd; 4795 4796 pHdrUnconst->x -= (int16_t)pFBInfo->xOrigin; 4797 pHdrUnconst->y -= (int16_t)pFBInfo->yOrigin; 4798 4799 /* @todo new SendUpdate entry which can get a separate cmd header or coords. */ 4800 pThis->mParent->consoleVRDPServer()->SendUpdate (uScreenId, pCmd, (uint32_t)cbCmd); 4801 4802 *pHdrUnconst = hdrSaved; 4803 } 4559 } 4560 } 4561 4562 VBVACMDHDR hdrSaved = *pCmd; 4563 4564 VBVACMDHDR *pHdrUnconst = (VBVACMDHDR *)pCmd; 4565 4566 pHdrUnconst->x -= (int16_t)pFBInfo->xOrigin; 4567 pHdrUnconst->y -= (int16_t)pFBInfo->yOrigin; 4568 4569 /* @todo new SendUpdate entry which can get a separate cmd header or coords. */ 4570 pThis->mParent->consoleVRDPServer()->SendUpdate (uScreenId, pCmd, (uint32_t)cbCmd); 4571 4572 *pHdrUnconst = hdrSaved; 4804 4573 } 4805 4574 … … 4818 4587 * cx, cy); 4819 4588 */ 4820 if (RT_LIKELY(pFBInfo->cVBVASkipUpdate == 0)) 4821 { 4822 pThis->handleDisplayUpdate(uScreenId, x - pFBInfo->xOrigin, y - pFBInfo->yOrigin, cx, cy); 4823 } 4824 else 4825 { 4826 /* Save the updated rectangle. */ 4827 int32_t xRight = x + cx; 4828 int32_t yBottom = y + cy; 4829 4830 if (pFBInfo->cVBVASkipUpdate == 1) 4831 { 4832 pFBInfo->vbvaSkippedRect.xLeft = x; 4833 pFBInfo->vbvaSkippedRect.yTop = y; 4834 pFBInfo->vbvaSkippedRect.xRight = xRight; 4835 pFBInfo->vbvaSkippedRect.yBottom = yBottom; 4836 } 4837 else 4838 { 4839 if (pFBInfo->vbvaSkippedRect.xLeft > x) 4840 { 4841 pFBInfo->vbvaSkippedRect.xLeft = x; 4842 } 4843 if (pFBInfo->vbvaSkippedRect.yTop > y) 4844 { 4845 pFBInfo->vbvaSkippedRect.yTop = y; 4846 } 4847 if (pFBInfo->vbvaSkippedRect.xRight < xRight) 4848 { 4849 pFBInfo->vbvaSkippedRect.xRight = xRight; 4850 } 4851 if (pFBInfo->vbvaSkippedRect.yBottom < yBottom) 4852 { 4853 pFBInfo->vbvaSkippedRect.yBottom = yBottom; 4854 } 4855 } 4856 } 4589 pThis->handleDisplayUpdate(uScreenId, x - pFBInfo->xOrigin, y - pFBInfo->yOrigin, cx, cy); 4857 4590 } 4858 4591 … … 4883 4616 " pFBInfo->flags 0x%04X\n" 4884 4617 " pFBInfo->pHostEvents %p\n" 4885 " pFBInfo->u32ResizeStatus %d\n"4886 4618 " pFBInfo->fDefaultFormat %d\n" 4887 4619 " dirtyRect %d-%d %d-%d\n" 4888 " pFBInfo->pendingResize.fPending %d\n"4889 " pFBInfo->pendingResize.pixelFormat %d\n"4890 " pFBInfo->pendingResize.pvVRAM %p\n"4891 " pFBInfo->pendingResize.bpp %d\n"4892 " pFBInfo->pendingResize.cbLine 0x%08X\n"4893 " pFBInfo->pendingResize.w,h %dx%d\n"4894 " pFBInfo->pendingResize.flags 0x%04X\n"4895 4620 " pFBInfo->fVBVAEnabled %d\n" 4896 4621 " pFBInfo->fVBVAForceResize %d\n" 4897 " pFBInfo->cVBVASkipUpdate %d\n"4898 " pFBInfo->vbvaSkippedRect %d-%d %d-%d\n"4899 4622 " pFBInfo->pVBVAHostFlags %p\n" 4900 4623 "", … … 4926 4649 pFBInfo->flags, 4927 4650 pFBInfo->pHostEvents, 4928 pFBInfo->u32ResizeStatus,4929 4651 pFBInfo->fDefaultFormat, 4930 4652 pFBInfo->dirtyRect.xLeft, … … 4932 4654 pFBInfo->dirtyRect.yTop, 4933 4655 pFBInfo->dirtyRect.yBottom, 4934 pFBInfo->pendingResize.fPending,4935 pFBInfo->pendingResize.pixelFormat,4936 pFBInfo->pendingResize.pvVRAM,4937 pFBInfo->pendingResize.bpp,4938 pFBInfo->pendingResize.cbLine,4939 pFBInfo->pendingResize.w,4940 pFBInfo->pendingResize.h,4941 pFBInfo->pendingResize.flags,4942 4656 pFBInfo->fVBVAEnabled, 4943 4657 pFBInfo->fVBVAForceResize, 4944 pFBInfo->cVBVASkipUpdate,4945 pFBInfo->vbvaSkippedRect.xLeft,4946 pFBInfo->vbvaSkippedRect.yTop,4947 pFBInfo->vbvaSkippedRect.xRight,4948 pFBInfo->vbvaSkippedRect.yBottom,4949 4658 pFBInfo->pVBVAHostFlags 4950 4659 ));
Note:
See TracChangeset
for help on using the changeset viewer.