Changeset 42217 in vbox
- Timestamp:
- Jul 18, 2012 8:41:29 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 79234
- Location:
- trunk/src/VBox/Additions/WINNT
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPCommon.h
r38739 r42217 42 42 43 43 #ifdef VBOX_WDDM_MINIPORT 44 void VBoxWddmInvalidateVideoModesInfo(PVBOXMP_DEVEXT pExt); 45 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateVideoModesInfo(PVBOXMP_DEVEXT pExt, PVBOXWDDM_RECOMMENDVIDPN pVidPnInfo); 44 void VBoxWddmInvalidateAllVideoModesInfos(PVBOXMP_DEVEXT pExt); 45 void VBoxWddmInvalidateVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId); 46 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateVideoModesInfoByMask(PVBOXMP_DEVEXT pExt, uint8_t *pScreenIdMask); 47 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateAllVideoModesInfos(PVBOXMP_DEVEXT pExt); 46 48 NTSTATUS VBoxWddmGetModesForResolution(VIDEO_MODE_INFORMATION *pAllModes, uint32_t cAllModes, int iSearchPreferredMode, 47 49 const D3DKMDT_2DREGION *pResolution, VIDEO_MODE_INFORMATION * pModes, … … 50 52 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmGetVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId); 51 53 bool VBoxWddmFillMode(VIDEO_MODE_INFORMATION *pInfo, D3DDDIFORMAT enmFormat, ULONG w, ULONG h); 54 bool VBoxWddmFillMode(VIDEO_MODE_INFORMATION *pInfo, D3DDDIFORMAT enmFormat, ULONG w, ULONG h); 55 void VBoxWddmAdjustMode(PVBOXMP_DEVEXT pExt, PVBOXWDDM_ADJUSTVIDEOMODE pMode); 56 void VBoxWddmAdjustModes(PVBOXMP_DEVEXT pExt, uint32_t cModes, PVBOXWDDM_ADJUSTVIDEOMODE aModes); 52 57 #endif 53 58 -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPVidModes.cpp
r42128 r42217 1090 1090 } 1091 1091 1092 void VBoxWddmInvalidateVideoModesInfo(PVBOXMP_DEVEXT pExt) 1093 { 1092 void VBoxWddmInvalidateVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId) 1093 { 1094 if (VidPnTargetId != D3DDDI_ID_ALL) 1095 { 1096 if (VidPnTargetId >= RT_ELEMENTS(g_aVBoxVideoModeInfos)) 1097 { 1098 WARN(("VidPnTargetId (%d) must be less than (%d)", VidPnTargetId, RT_ELEMENTS(g_aVBoxVideoModeInfos))); 1099 return; 1100 } 1101 g_aVBoxVideoModeInfos[VidPnTargetId].cModes = 0; 1102 return; 1103 } 1104 1094 1105 for (UINT i = 0; i < RT_ELEMENTS(g_aVBoxVideoModeInfos); ++i) 1095 1106 { … … 1098 1109 } 1099 1110 1100 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateVideoModesInfo(PVBOXMP_DEVEXT pExt, PVBOXWDDM_RECOMMENDVIDPN pVidPnInfo) 1101 { 1102 VBoxWddmInvalidateVideoModesInfo(pExt); 1103 1104 if (pVidPnInfo) 1105 { 1106 for (UINT i = 0; i < pVidPnInfo->cScreenInfos; ++i) 1107 { 1108 PVBOXWDDM_RECOMMENDVIDPN_SCREEN_INFO pScreenInfo = &pVidPnInfo->aScreenInfos[i]; 1109 Assert(pScreenInfo->Id < (DWORD)VBoxCommonFromDeviceExt(pExt)->cDisplays); 1110 if (pScreenInfo->Id < (DWORD)VBoxCommonFromDeviceExt(pExt)->cDisplays) 1111 { 1112 PVBOXWDDM_VIDEOMODES_INFO pInfo = &g_aVBoxVideoModeInfos[pScreenInfo->Id]; 1113 VIDEO_MODE_INFORMATION ModeInfo = {0}; 1114 D3DDDIFORMAT enmFormat; 1115 switch (pScreenInfo->BitsPerPixel) 1116 { 1117 case 32: 1118 enmFormat = D3DDDIFMT_A8R8G8B8; 1119 break; 1120 case 24: 1121 enmFormat = D3DDDIFMT_R8G8B8; 1122 break; 1123 case 16: 1124 enmFormat = D3DDDIFMT_R5G6B5; 1125 break; 1126 case 8: 1127 enmFormat = D3DDDIFMT_P8; 1128 break; 1129 default: 1130 Assert(0); 1131 enmFormat = D3DDDIFMT_UNKNOWN; 1132 break; 1133 } 1134 if (enmFormat != D3DDDIFMT_UNKNOWN) 1135 { 1136 if (VBoxWddmFillMode(pExt, pScreenInfo->Id, &ModeInfo, enmFormat, pScreenInfo->Width, pScreenInfo->Height)) 1137 { 1138 VBoxWddmBuildVideoModesInfo(pExt, pScreenInfo->Id, pInfo, &ModeInfo, 1); 1139 } 1140 else 1141 { 1142 Assert(0); 1143 } 1144 } 1145 } 1146 } 1111 void VBoxWddmInvalidateAllVideoModesInfos(PVBOXMP_DEVEXT pExt) 1112 { 1113 VBoxWddmInvalidateVideoModesInfo(pExt, D3DDDI_ID_ALL); 1114 } 1115 1116 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateVideoModesInfoByMask(PVBOXMP_DEVEXT pExt, uint8_t *pScreenIdMask) 1117 { 1118 for (int i = 0; i < VBoxCommonFromDeviceExt(pExt)->cDisplays; ++i) 1119 { 1120 if (ASMBitTest(pScreenIdMask, i)) 1121 VBoxWddmInvalidateVideoModesInfo(pExt, i); 1147 1122 } 1148 1123 … … 1150 1125 VBoxWddmGetAllVideoModesInfos(pExt); 1151 1126 return g_aVBoxVideoModeInfos; 1127 } 1128 1129 PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateAllVideoModesInfos(PVBOXMP_DEVEXT pExt) 1130 { 1131 VBoxWddmInvalidateAllVideoModesInfos(pExt); 1132 1133 /* ensure we have all the rest populated */ 1134 VBoxWddmGetAllVideoModesInfos(pExt); 1135 return g_aVBoxVideoModeInfos; 1136 } 1137 1138 void VBoxWddmAdjustMode(PVBOXMP_DEVEXT pExt, PVBOXWDDM_ADJUSTVIDEOMODE pMode) 1139 { 1140 pMode->fFlags = 0; 1141 1142 if (pMode->Mode.Id >= (UINT)VBoxCommonFromDeviceExt(pExt)->cDisplays) 1143 { 1144 WARN(("invalid screen id (%d)", pMode->Mode.Id)); 1145 pMode->fFlags = VBOXWDDM_ADJUSTVIDEOMODE_F_INVALISCREENID; 1146 return; 1147 } 1148 1149 PVBOXWDDM_TARGET pTarget = &pExt->aTargets[pMode->Mode.Id]; 1150 /* @todo: this info should go from the target actually */ 1151 PVBOXWDDM_SOURCE pSource = &pExt->aSources[pMode->Mode.Id]; 1152 if (pTarget->HeightVisible /* <- active */ 1153 && pSource->AllocData.SurfDesc.width == pMode->Mode.Width 1154 && pSource->AllocData.SurfDesc.height == pMode->Mode.Height 1155 && pSource->AllocData.SurfDesc.bpp == pMode->Mode.BitsPerPixel) 1156 { 1157 pMode->fFlags = VBOXWDDM_ADJUSTVIDEOMODE_F_CURRENT; 1158 return; 1159 } 1160 1161 UINT newWidth = pMode->Mode.Width; 1162 UINT newHeight = pMode->Mode.Height; 1163 UINT newBpp = pMode->Mode.BitsPerPixel; 1164 1165 if (!VBoxMPValidateVideoModeParams(pExt, pMode->Mode.Id, newWidth, newHeight, newBpp)) 1166 { 1167 PVBOXWDDM_SOURCE pSource = &pExt->aSources[pMode->Mode.Id]; 1168 pMode->fFlags = VBOXWDDM_ADJUSTVIDEOMODE_F_UNSUPPORTED; 1169 } 1170 1171 if (pMode->Mode.Width != newWidth 1172 || pMode->Mode.Height != newHeight 1173 || pMode->Mode.BitsPerPixel != newBpp) 1174 { 1175 pMode->fFlags |= VBOXWDDM_ADJUSTVIDEOMODE_F_ADJUSTED; 1176 pMode->Mode.Width = newWidth; 1177 pMode->Mode.Height = newHeight; 1178 pMode->Mode.BitsPerPixel = newBpp; 1179 } 1180 1181 if (pTarget->HeightVisible /* <- active */ 1182 && pSource->AllocData.SurfDesc.width == pMode->Mode.Width 1183 && pSource->AllocData.SurfDesc.height == pMode->Mode.Height 1184 && pSource->AllocData.SurfDesc.bpp == pMode->Mode.BitsPerPixel) 1185 { 1186 pMode->fFlags |= VBOXWDDM_ADJUSTVIDEOMODE_F_CURRENT; 1187 if (pMode->fFlags & VBOXWDDM_ADJUSTVIDEOMODE_F_UNSUPPORTED) 1188 { 1189 WARN(("current mode is reported as unsupported, cleaning the unsupported flag")); 1190 pMode->fFlags &= ~VBOXWDDM_ADJUSTVIDEOMODE_F_UNSUPPORTED; 1191 } 1192 } 1193 } 1194 1195 void VBoxWddmAdjustModes(PVBOXMP_DEVEXT pExt, uint32_t cModes, PVBOXWDDM_ADJUSTVIDEOMODE aModes) 1196 { 1197 for (UINT i = 0; i < cModes; ++i) 1198 { 1199 PVBOXWDDM_ADJUSTVIDEOMODE pMode = &aModes[i]; 1200 VBoxWddmAdjustMode(pExt, pMode); 1201 } 1152 1202 } 1153 1203 -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.cpp
r42158 r42217 219 219 NTSTATUS Status = STATUS_SUCCESS; 220 220 221 pVsi->VideoStandard = D3DKMDT_VSS_ VESA_DMT;221 pVsi->VideoStandard = D3DKMDT_VSS_OTHER; 222 222 pVsi->ActiveSize = *pResolution; 223 223 pVsi->VSyncFreq.Numerator = VSync * 1000; 224 224 pVsi->VSyncFreq.Denominator = 1000; 225 pVsi->TotalSize.cx = pVsi->ActiveSize.cx + VBOXVDPN_C_DISPLAY_HBLANK_SIZE;226 pVsi->TotalSize.cy = pVsi->ActiveSize.cy + VBOXVDPN_C_DISPLAY_VBLANK_SIZE;225 pVsi->TotalSize.cx = pVsi->ActiveSize.cx;// + VBOXVDPN_C_DISPLAY_HBLANK_SIZE; 226 pVsi->TotalSize.cy = pVsi->ActiveSize.cy;// + VBOXVDPN_C_DISPLAY_VBLANK_SIZE; 227 227 pVsi->PixelRate = pVsi->TotalSize.cx * pVsi->TotalSize.cy * VSync; 228 228 pVsi->HSyncFreq.Numerator = (UINT)((pVsi->PixelRate / pVsi->TotalSize.cy) * 1000); … … 527 527 D3DKMDT_2DREGION *paResolutions; 528 528 uint32_t cResolutions; 529 BOOLEAN fMatch ;529 BOOLEAN fMatched; 530 530 } VBOXVIDPNMATCHMONMODESENUM, *PVBOXVIDPNMATCHMONMODESENUM; 531 531 … … 535 535 PVBOXVIDPNMATCHMONMODESENUM pInfo = (PVBOXVIDPNMATCHMONMODESENUM)pContext; 536 536 537 Assert(pInfo->fMatch); 537 Assert(pInfo->fMatched); 538 539 BOOLEAN fFound = FALSE; 538 540 539 541 for (UINT i = 0; i < pInfo->cResolutions; ++i) 540 542 { 541 543 D3DKMDT_2DREGION *pResolution = &pInfo->paResolutions[i]; 542 if (pMonitorSMI->VideoSignalInfo.ActiveSize.cx != pResolution->cx543 || pMonitorSMI->VideoSignalInfo.ActiveSize.cy != pResolution->cy)544 { 545 pInfo->fMatch = FALSE;544 if (pMonitorSMI->VideoSignalInfo.ActiveSize.cx == pResolution->cx 545 && pMonitorSMI->VideoSignalInfo.ActiveSize.cy == pResolution->cy) 546 { 547 fFound = TRUE; 546 548 break; 547 549 } 548 550 } 549 551 552 if (!fFound) 553 pInfo->fMatched = FALSE; 554 550 555 pMonitorSMSIf->pfnReleaseModeInfo(hMonitorSMS, pMonitorSMI); 551 556 552 return pInfo->fMatch ;557 return pInfo->fMatched; 553 558 } 554 559 … … 585 590 } 586 591 587 VBOXVIDPNMATCHMONMODESENUM Info; 588 Info.paResolutions = pResolutions; 589 Info.cResolutions = cResolutions; 590 Info.fMatch = TRUE; 591 592 Status = vboxVidPnEnumMonitorSourceModes(hMonitorSMS, pMonitorSMSIf, vboxFidPnMatchMonitorModesEnum, &Info); 592 /* we care only about monitor modes covering all needed resolutions, 593 * we do NOT care if resolutions do not cover some monitor modes */ 594 SIZE_T cModes = 0; 595 Status = pMonitorSMSIf->pfnGetNumModes(hMonitorSMS, &cModes); 593 596 if (NT_SUCCESS(Status)) 594 597 { 595 *pfMatch = Info.fMatch; 596 } 598 if (cModes < cResolutions) 599 *pfMatch = FALSE; 600 else 601 { 602 VBOXVIDPNMATCHMONMODESENUM Info; 603 Info.paResolutions = pResolutions; 604 Info.cResolutions = cResolutions; 605 Info.fMatched = TRUE; 606 607 Status = vboxVidPnEnumMonitorSourceModes(hMonitorSMS, pMonitorSMSIf, vboxFidPnMatchMonitorModesEnum, &Info); 608 if (NT_SUCCESS(Status)) 609 *pfMatch = Info.fMatched; 610 } 611 } 612 else 613 WARN(("pfnGetNumModes failed, Status 0x%x", Status)); 597 614 598 615 NTSTATUS tmpStatus = pMonitorInterface->pfnReleaseMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle, hMonitorSMS); … … 1299 1316 { 1300 1317 Status = vboxVidPnPopulateTargetModeInfoFromLegacy(pNewVidPnTargetModeInfo, pResolution, i == pInfo->iPreferredResolution); 1301 Assert(Status == STATUS_SUCCESS);1302 1318 if (NT_SUCCESS(Status)) 1303 1319 { … … 1309 1325 continue; 1310 1326 } 1327 else 1328 { 1329 WARN(("pfnAddMode failed, Status 0x%x", Status)); 1330 } 1331 } 1332 else 1333 { 1334 WARN(("vboxVidPnPopulateTargetModeInfoFromLegacy failed, Status 0x%x", Status)); 1311 1335 } 1312 1336 … … 1314 1338 Assert(tmpStatus == STATUS_SUCCESS); 1315 1339 } 1340 1316 1341 /* we're here because of an error */ 1317 1342 Assert(!NT_SUCCESS(Status)); 1318 break; 1343 /* ignore mode addition failure */ 1344 Status = STATUS_SUCCESS; 1345 continue; 1319 1346 } 1320 1347 } -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp
r42170 r42217 681 681 682 682 bChanged[i] = !fMatch; 683 684 if (!fMatch) 685 { 686 Status = vboxWddmChildStatusReportReconnected(pDevExt, i); 687 if (!NT_SUCCESS(Status)) 683 } 684 685 if (!NT_SUCCESS(Status)) 686 { 687 WARN(("updating monitor modes failed, Status(0x%x)", Status)); 688 return Status; 689 } 690 691 for (i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i) 692 { 693 if (bChanged[i]) 694 { 695 NTSTATUS tmpStatus = vboxWddmChildStatusReportReconnected(pDevExt, i); 696 if (!NT_SUCCESS(tmpStatus)) 688 697 { 689 698 WARN(("vboxWddmChildStatusReportReconnected failed Status(0x%x)", Status)); … … 692 701 } 693 702 } 694 }695 696 if (!NT_SUCCESS(Status))697 {698 WARN(("updating monitor modes failed, Status(0x%x)", Status));699 return Status;700 703 } 701 704 … … 1121 1124 1122 1125 VBoxMPCmnInitCustomVideoModes(pDevExt); 1123 VBoxWddmInvalidateVideoModesInfo(pDevExt); 1126 VBoxWddmInvalidateAllVideoModesInfos(pDevExt); 1127 1128 pDevExt->fAnyX = VBoxVideoAnyWidthAllowed(); 1124 1129 #if 0 1125 1130 vboxShRcTreeInit(pDevExt); … … 4137 4142 case VBOXESC_REINITVIDEOMODES: 4138 4143 { 4139 PVBOXWDDM_VIDEOMODES_INFO pInfo = VBoxWddmUpdateVideoModesInfo(pDevExt, NULL); 4140 Status = vboxWddmChildStatusCheck(pDevExt, pInfo); 4144 if (pEscape->Flags.HardwareAccess) 4145 { 4146 WARN(("VBOXESC_REINITVIDEOMODES called with HardwareAccess flag set, failing")); 4147 Status = STATUS_INVALID_PARAMETER; 4148 break; 4149 } 4150 WARN(("VBOXESC_REINITVIDEOMODESBYMASK should be called instead")); 4151 PVBOXWDDM_VIDEOMODES_INFO pInfos = VBoxWddmUpdateAllVideoModesInfos(pDevExt); 4152 Status = vboxWddmChildStatusCheck(pDevExt, pInfos); 4141 4153 if (!NT_SUCCESS(Status)) 4142 4154 { … … 4144 4156 } 4145 4157 break; 4158 } 4159 case VBOXESC_REINITVIDEOMODESBYMASK: 4160 { 4161 BOOLEAN fCheckDisplayRecconect = (pEscapeHdr->u32CmdSpecific & VBOXWDDM_REINITVIDEOMODESBYMASK_F_RECONNECT_DISPLAYS_ON_CHANGE); 4162 if (fCheckDisplayRecconect && pEscape->Flags.HardwareAccess) 4163 { 4164 WARN(("VBOXESC_REINITVIDEOMODESBYMASK called with HardwareAccess flag set, failing")); 4165 Status = STATUS_INVALID_PARAMETER; 4166 break; 4167 } 4168 if (pEscape->PrivateDriverDataSize != sizeof (VBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK)) 4169 { 4170 WARN(("invalid private driver size %d", pEscape->PrivateDriverDataSize)); 4171 Status = STATUS_INVALID_PARAMETER; 4172 break; 4173 } 4174 PVBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK pData = (PVBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK)pEscapeHdr; 4175 PVBOXWDDM_VIDEOMODES_INFO pInfos = VBoxWddmUpdateVideoModesInfoByMask(pDevExt, pData->ScreenMask); 4176 if (fCheckDisplayRecconect) 4177 { 4178 Status = vboxWddmChildStatusCheck(pDevExt, pInfos); 4179 if (!NT_SUCCESS(Status)) 4180 { 4181 WARN(("vboxWddmChildStatusCheck failed, Status 0x%x", Status)); 4182 } 4183 } 4184 break; 4185 } 4186 case VBOXESC_ADJUSTVIDEOMODES: 4187 { 4188 if (!pEscape->Flags.HardwareAccess) 4189 { 4190 WARN(("VBOXESC_ADJUSTVIDEOMODES called without HardwareAccess flag set, failing")); 4191 Status = STATUS_INVALID_PARAMETER; 4192 break; 4193 } 4194 4195 uint32_t cModes = pEscapeHdr->u32CmdSpecific; 4196 if (cModes > VBOXWDDM_TRAILARRAY_MAXELEMENTSU32(VBOXDISPIFESCAPE_ADJUSTVIDEOMODES, aScreenInfos) 4197 || pEscape->PrivateDriverDataSize != RT_OFFSETOF(VBOXDISPIFESCAPE_ADJUSTVIDEOMODES, aScreenInfos[cModes])) 4198 { 4199 WARN(("invalid modes count passed")); 4200 Status = STATUS_INVALID_PARAMETER; 4201 break; 4202 } 4203 4204 PVBOXDISPIFESCAPE_ADJUSTVIDEOMODES pPodesInfo = (PVBOXDISPIFESCAPE_ADJUSTVIDEOMODES)pEscapeHdr; 4205 VBoxWddmAdjustModes(pDevExt, cModes, pPodesInfo->aScreenInfos); 4206 Status = STATUS_SUCCESS; 4146 4207 } 4147 4208 case VBOXESC_SHRC_ADDREF: … … 4394 4455 PVBOXWDDM_RECOMMENDVIDPN pVidPnInfo = pRecommendFunctionalVidPnArg->PrivateDriverDataSize >= sizeof (VBOXWDDM_RECOMMENDVIDPN) ? 4395 4456 (PVBOXWDDM_RECOMMENDVIDPN)pRecommendFunctionalVidPnArg->pPrivateDriverData : NULL; 4396 PVBOXWDDM_VIDEOMODES_INFO pInfos = VBoxWddmUpdate VideoModesInfo(pDevExt, NULL /*pVidPnInfo*/);4457 PVBOXWDDM_VIDEOMODES_INFO pInfos = VBoxWddmUpdateAllVideoModesInfos(pDevExt); 4397 4458 int i; 4398 4459 … … 4410 4471 Status = vboxVidPnCheckAddMonitorModes(pDevExt, i, D3DKMDT_MCO_DRIVER, pInfo->aResolutions, pInfo->cResolutions, pInfo->iPreferredResolution); 4411 4472 #endif 4412 Assert(Status == STATUS_SUCCESS);4413 4473 if (Status != STATUS_SUCCESS) 4414 4474 { 4415 LOGREL(("vboxVidPnCheckAddMonitorModes failed Status(0x%x)", Status));4475 WARN(("vboxVidPnCheckAddMonitorModes failed Status(0x%x)", Status)); 4416 4476 break; 4417 4477 } -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDispIf.cpp
r42108 r42217 23 23 #include <malloc.h> 24 24 25 #ifdef VBOX_WITH_WDDM 26 #include <iprt/asm.h> 27 #endif 28 25 29 /* display driver interface abstraction for XPDM & WDDM 26 30 * with WDDM we can not use ExtEscape to communicate with our driver … … 33 37 } 34 38 39 #ifdef VBOX_WITH_WDDM 40 static void vboxDispIfWddmTerm(PCVBOXDISPIF pIf); 41 static DWORD vboxDispIfWddmInit(PCVBOXDISPIF pIf); 42 #endif 43 35 44 DWORD VBoxDispIfTerm(PVBOXDISPIF pIf) 36 45 { 46 #ifdef VBOX_WITH_WDDM 47 if (pIf->enmMode == VBOXDISPIF_MODE_WDDM) 48 { 49 vboxDispIfWddmTerm(pIf); 50 } 51 #endif 52 37 53 pIf->enmMode = VBOXDISPIF_MODE_UNKNOWN; 38 54 return NO_ERROR; … … 123 139 Log((__FUNCTION__": can not switch to VBOXDISPIF_MODE_WDDM, because os is not Vista or upper\n")); 124 140 err = ERROR_NOT_SUPPORTED; 141 } 142 143 if (err == ERROR_SUCCESS) 144 { 145 err = vboxDispIfWddmInit(pIf); 125 146 } 126 147 … … 366 387 } 367 388 368 static BOOL vboxDispIfValidateResize(DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 389 390 #ifdef VBOX_WITH_WDDM 391 /**/ 392 typedef DECLCALLBACK(VOID) FNVBOXSCREENMONRUNNER_CB(void *pvCb); 393 typedef FNVBOXSCREENMONRUNNER_CB *PFNVBOXSCREENMONRUNNER_CB; 394 395 typedef struct VBOXSCREENMON 396 { 397 HANDLE hThread; 398 DWORD idThread; 399 HANDLE hEvent; 400 HWND hWnd; 401 PFNVBOXSCREENMONRUNNER_CB pfnCb; 402 void *pvCb; 403 } VBOXSCREENMON, *PVBOXSCREENMON; 404 405 406 static VBOXSCREENMON g_VBoxScreenMon; 407 408 409 #define VBOX_E_INSUFFICIENT_BUFFER HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) 410 #define VBOX_E_NOT_SUPPORTED HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) 411 412 413 static void vboxScreenMonOnChange() 414 { 415 PVBOXSCREENMON pMon = &g_VBoxScreenMon; 416 pMon->pfnCb(pMon->pvCb); 417 } 418 419 static LRESULT CALLBACK vboxScreenMonWndProc(HWND hwnd, 420 UINT uMsg, 421 WPARAM wParam, 422 LPARAM lParam 423 ) 424 { 425 switch(uMsg) 426 { 427 case WM_DISPLAYCHANGE: 428 { 429 vboxScreenMonOnChange(); 430 } 431 case WM_CLOSE: 432 Log((__FUNCTION__": got WM_CLOSE for hwnd(0x%x)", hwnd)); 433 return 0; 434 case WM_DESTROY: 435 Log((__FUNCTION__": got WM_DESTROY for hwnd(0x%x)", hwnd)); 436 return 0; 437 case WM_NCHITTEST: 438 Log((__FUNCTION__": got WM_NCHITTEST for hwnd(0x%x)\n", hwnd)); 439 return HTNOWHERE; 440 } 441 442 return DefWindowProc(hwnd, uMsg, wParam, lParam); 443 } 444 445 #define VBOXSCREENMONWND_NAME "VboxScreenMonWnd" 446 447 static HRESULT vboxScreenMonWndCreate(HWND *phWnd) 448 { 449 HRESULT hr = S_OK; 450 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL); 451 /* Register the Window Class. */ 452 WNDCLASS wc; 453 if (!GetClassInfo(hInstance, VBOXSCREENMONWND_NAME, &wc)) 454 { 455 wc.style = 0;//CS_OWNDC; 456 wc.lpfnWndProc = vboxScreenMonWndProc; 457 wc.cbClsExtra = 0; 458 wc.cbWndExtra = 0; 459 wc.hInstance = hInstance; 460 wc.hIcon = NULL; 461 wc.hCursor = NULL; 462 wc.hbrBackground = NULL; 463 wc.lpszMenuName = NULL; 464 wc.lpszClassName = VBOXSCREENMONWND_NAME; 465 if (!RegisterClass(&wc)) 466 { 467 DWORD winErr = GetLastError(); 468 Log((__FUNCTION__": RegisterClass failed, winErr(%d)\n", winErr)); 469 hr = E_FAIL; 470 } 471 } 472 473 if (hr == S_OK) 474 { 475 HWND hWnd = CreateWindowEx (WS_EX_TOOLWINDOW, 476 VBOXSCREENMONWND_NAME, VBOXSCREENMONWND_NAME, 477 WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED, 478 -100, -100, 479 10, 10, 480 NULL, //GetDesktopWindow() /* hWndParent */, 481 NULL /* hMenu */, 482 hInstance, 483 NULL /* lpParam */); 484 Assert(hWnd); 485 if (hWnd) 486 { 487 *phWnd = hWnd; 488 } 489 else 490 { 491 DWORD winErr = GetLastError(); 492 Log((__FUNCTION__": CreateWindowEx failed, winErr(%d)\n", winErr)); 493 hr = E_FAIL; 494 } 495 } 496 497 return hr; 498 } 499 500 static HRESULT vboxScreenMonWndDestroy(HWND hWnd) 501 { 502 BOOL bResult = DestroyWindow(hWnd); 503 if (bResult) 504 return S_OK; 505 506 DWORD winErr = GetLastError(); 507 Log((__FUNCTION__": DestroyWindow failed, winErr(%d) for hWnd(0x%x)\n", winErr, hWnd)); 508 Assert(0); 509 510 return HRESULT_FROM_WIN32(winErr); 511 } 512 513 static HRESULT vboxScreenMonWndInit() 514 { 515 PVBOXSCREENMON pMon = &g_VBoxScreenMon; 516 return vboxScreenMonWndCreate(&pMon->hWnd); 517 } 518 519 HRESULT vboxScreenMonWndTerm() 520 { 521 PVBOXSCREENMON pMon = &g_VBoxScreenMon; 522 HRESULT tmpHr = vboxScreenMonWndDestroy(pMon->hWnd); 523 Assert(tmpHr == S_OK); 524 525 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL); 526 UnregisterClass(VBOXSCREENMONWND_NAME, hInstance); 527 528 return S_OK; 529 } 530 531 #define WM_VBOXSCREENMON_INIT_QUIT (WM_APP+2) 532 533 HRESULT vboxScreenMonRun() 534 { 535 PVBOXSCREENMON pMon = &g_VBoxScreenMon; 536 MSG Msg; 537 538 HRESULT hr = S_FALSE; 539 540 PeekMessage(&Msg, 541 NULL /* HWND hWnd */, 542 WM_USER /* UINT wMsgFilterMin */, 543 WM_USER /* UINT wMsgFilterMax */, 544 PM_NOREMOVE); 545 546 BOOL bCheck = TRUE; 547 548 do 549 { 550 if (bCheck) 551 { 552 vboxScreenMonOnChange(); 553 554 bCheck = FALSE; 555 } 556 557 BOOL bResult = GetMessage(&Msg, 558 0 /*HWND hWnd*/, 559 0 /*UINT wMsgFilterMin*/, 560 0 /*UINT wMsgFilterMax*/ 561 ); 562 563 if(!bResult) /* WM_QUIT was posted */ 564 { 565 hr = S_FALSE; 566 break; 567 } 568 569 if(bResult == -1) /* error occurred */ 570 { 571 DWORD winEr = GetLastError(); 572 hr = HRESULT_FROM_WIN32(winEr); 573 Assert(0); 574 /* just ensure we never return success in this case */ 575 Assert(hr != S_OK); 576 Assert(hr != S_FALSE); 577 if (hr == S_OK || hr == S_FALSE) 578 hr = E_FAIL; 579 break; 580 } 581 582 switch (Msg.message) 583 { 584 case WM_VBOXSCREENMON_INIT_QUIT: 585 case WM_CLOSE: 586 { 587 PostQuitMessage(0); 588 break; 589 } 590 case WM_DISPLAYCHANGE: 591 bCheck = TRUE; 592 default: 593 TranslateMessage(&Msg); 594 DispatchMessage(&Msg); 595 break; 596 } 597 } while (1); 598 return 0; 599 } 600 601 static DWORD WINAPI vboxScreenMonRunnerThread(void *pvUser) 602 { 603 PVBOXSCREENMON pMon = &g_VBoxScreenMon; 604 605 BOOL bRc = SetEvent(pMon->hEvent); 606 if (!bRc) 607 { 608 DWORD winErr = GetLastError(); 609 Log((__FUNCTION__": SetEvent failed, winErr = (%d)", winErr)); 610 HRESULT tmpHr = HRESULT_FROM_WIN32(winErr); 611 Assert(0); 612 Assert(tmpHr != S_OK); 613 } 614 615 HRESULT hr = vboxScreenMonWndInit(); 616 Assert(hr == S_OK); 617 if (hr == S_OK) 618 { 619 hr = vboxScreenMonRun(); 620 Assert(hr == S_OK); 621 622 vboxScreenMonWndTerm(); 623 } 624 625 return 0; 626 } 627 628 HRESULT VBoxScreenMonInit(PFNVBOXSCREENMONRUNNER_CB pfnCb, void *pvCb) 629 { 630 HRESULT hr = E_FAIL; 631 PVBOXSCREENMON pMon = &g_VBoxScreenMon; 632 memset(pMon, 0, sizeof (*pMon)); 633 634 pMon->pfnCb = pfnCb; 635 pMon->pvCb = pvCb; 636 637 pMon->hEvent = CreateEvent(NULL, /* LPSECURITY_ATTRIBUTES lpEventAttributes*/ 638 TRUE, /* BOOL bManualReset*/ 639 FALSE, /* BOOL bInitialState */ 640 NULL /* LPCTSTR lpName */ 641 ); 642 if (pMon->hEvent) 643 { 644 pMon->hThread = CreateThread(NULL /* LPSECURITY_ATTRIBUTES lpThreadAttributes */, 645 0 /* SIZE_T dwStackSize */, 646 vboxScreenMonRunnerThread, 647 pMon, 648 0 /* DWORD dwCreationFlags */, 649 &pMon->idThread); 650 if (pMon->hThread) 651 { 652 DWORD dwResult = WaitForSingleObject(pMon->hEvent, INFINITE); 653 if (dwResult == WAIT_OBJECT_0) 654 return S_OK; 655 else 656 { 657 Log(("WaitForSingleObject failed!")); 658 hr = E_FAIL; 659 } 660 } 661 else 662 { 663 DWORD winErr = GetLastError(); 664 Log((__FUNCTION__": CreateThread failed, winErr = (%d)", winErr)); 665 hr = HRESULT_FROM_WIN32(winErr); 666 Assert(0); 667 Assert(hr != S_OK); 668 } 669 CloseHandle(pMon->hEvent); 670 } 671 else 672 { 673 DWORD winErr = GetLastError(); 674 Log((__FUNCTION__": CreateEvent failed, winErr = (%d)", winErr)); 675 hr = HRESULT_FROM_WIN32(winErr); 676 Assert(0); 677 Assert(hr != S_OK); 678 } 679 680 return hr; 681 } 682 683 VOID VBoxScreenMonTerm() 684 { 685 HRESULT hr; 686 PVBOXSCREENMON pMon = &g_VBoxScreenMon; 687 if (!pMon->hThread) 688 return; 689 690 BOOL bResult = PostThreadMessage(pMon->idThread, WM_VBOXSCREENMON_INIT_QUIT, 0, 0); 691 DWORD winErr; 692 if (bResult 693 || (winErr = GetLastError()) == ERROR_INVALID_THREAD_ID) /* <- could be that the thread is terminated */ 694 { 695 DWORD dwErr = WaitForSingleObject(pMon->hThread, INFINITE); 696 if (dwErr == WAIT_OBJECT_0) 697 { 698 hr = S_OK; 699 } 700 else 701 { 702 winErr = GetLastError(); 703 hr = HRESULT_FROM_WIN32(winErr); 704 Assert(0); 705 } 706 } 707 else 708 { 709 hr = HRESULT_FROM_WIN32(winErr); 710 Assert(0); 711 } 712 713 CloseHandle(pMon->hThread); 714 pMon->hThread = 0; 715 CloseHandle(pMon->hEvent); 716 pMon->hThread = 0; 717 } 718 /**/ 719 720 typedef struct VBOXDISPIF_WDDM_INTERNAL 721 { 722 PCVBOXDISPIF pIf; 723 724 HANDLE hResizeEvent; 725 } VBOXDISPIF_WDDM_INTERNAL, *PVBOXDISPIF_WDDM_INTERNAL; 726 727 static VBOXDISPIF_WDDM_INTERNAL g_VBoxDispIfWddm; 728 729 static BOOL vboxDispIfWddmValidateResize(DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 369 730 { 370 731 DISPLAY_DEVICE DisplayDevice; … … 463 824 } 464 825 465 #ifdef VBOX_WITH_WDDM 466 static DWORD vboxDispIfReinitVideoModes(PCVBOXDISPIF const pIf) 467 { 468 VBOXDISPIFESCAPE escape = {0}; 469 escape.escapeCode = VBOXESC_REINITVIDEOMODES; 470 DWORD err = vboxDispIfEscapeWDDM(pIf, &escape, 0, FALSE /* hw access must be false here, 826 static DWORD vboxDispIfWddmValidateFixResize(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 827 { 828 if (vboxDispIfWddmValidateResize(paDisplayDevices, paDeviceModes, cDevModes)) 829 return NO_ERROR; 830 831 DWORD winEr; 832 LONG status = DISP_CHANGE_SUCCESSFUL; 833 834 /* now try to resize in a "regular" way */ 835 /* Assign the new rectangles to displays. */ 836 for (UINT i = 0; i < cDevModes; i++) 837 { 838 /* On Vista one must specify DM_BITSPERPEL. 839 * Note that the current mode dmBitsPerPel is already in the DEVMODE structure. 840 */ 841 paDeviceModes[i].dmFields = DM_POSITION | DM_PELSHEIGHT | DM_PELSWIDTH | DM_BITSPERPEL; 842 843 Log(("VBoxTray: ResizeDisplayDevice: pfnChangeDisplaySettingsEx %x: %dx%dx%d at %d,%d\n", 844 pIf->modeData.wddm.pfnChangeDisplaySettingsEx, 845 paDeviceModes[i].dmPelsWidth, 846 paDeviceModes[i].dmPelsHeight, 847 paDeviceModes[i].dmBitsPerPel, 848 paDeviceModes[i].dmPosition.x, 849 paDeviceModes[i].dmPosition.y)); 850 851 /* the miniport might have been adjusted the display mode stuff, 852 * adjust the paDeviceModes[i] by picking the closest available one */ 853 // DEVMODE AdjustedMode = paDeviceModes[i]; 854 // vboxDispIfAdjustMode(&paDisplayDevices[i], &AdjustedMode); 855 856 LONG tmpStatus = pIf->modeData.wddm.pfnChangeDisplaySettingsEx((LPSTR)paDisplayDevices[i].DeviceName, 857 &paDeviceModes[i], NULL, CDS_NORESET | CDS_UPDATEREGISTRY, NULL); 858 Log(("VBoxTray: ResizeDisplayDevice: ChangeDisplaySettingsEx position status %d, err %d\n", tmpStatus, GetLastError ())); 859 860 if (tmpStatus != DISP_CHANGE_SUCCESSFUL) 861 { 862 status = tmpStatus; 863 } 864 } 865 866 /* A second call to ChangeDisplaySettings updates the monitor. */ 867 LONG tmpStatus = pIf->modeData.wddm.pfnChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL); 868 Log(("VBoxTray: ResizeDisplayDevice: ChangeDisplaySettings update status %d\n", status)); 869 if (tmpStatus == DISP_CHANGE_SUCCESSFUL) 870 { 871 if (status == DISP_CHANGE_SUCCESSFUL) 872 { 873 return NO_ERROR; 874 } 875 tmpStatus = status; 876 } 877 878 if (tmpStatus == DISP_CHANGE_BADMODE) 879 { 880 /* Successfully set new video mode or our driver can not set the requested mode. Stop trying. */ 881 winEr = ERROR_RETRY; 882 } 883 else 884 { 885 winEr = ERROR_GEN_FAILURE; 886 } 887 return winEr; 888 } 889 890 static DECLCALLBACK(VOID) vboxDispIfWddmScreenMonCb(void *pvCb) 891 { 892 PVBOXDISPIF_WDDM_INTERNAL pData = (PVBOXDISPIF_WDDM_INTERNAL)pvCb; 893 894 SetEvent(pData->hResizeEvent); 895 } 896 897 static DWORD vboxDispIfWddmInit(PCVBOXDISPIF pIf) 898 { 899 memset(&g_VBoxDispIfWddm, 0, sizeof (g_VBoxDispIfWddm)); 900 g_VBoxDispIfWddm.pIf = pIf; 901 g_VBoxDispIfWddm.hResizeEvent = CreateEvent(NULL, 902 FALSE, /* BOOL bManualReset */ 903 FALSE, /* BOOL bInitialState */ 904 NULL /* LPCTSTR lpName */ 905 ); 906 if (g_VBoxDispIfWddm.hResizeEvent) 907 { 908 HRESULT hr = VBoxScreenMonInit(vboxDispIfWddmScreenMonCb, &g_VBoxDispIfWddm); 909 if (SUCCEEDED(hr)) 910 { 911 /* ensure event is reset */ 912 WaitForSingleObject(g_VBoxDispIfWddm.hResizeEvent, 0); 913 return ERROR_SUCCESS; 914 } 915 CloseHandle(g_VBoxDispIfWddm.hResizeEvent); 916 } 917 return ERROR_GEN_FAILURE; 918 } 919 920 static void vboxDispIfWddmTerm(PCVBOXDISPIF pIf) 921 { 922 VBoxScreenMonTerm(); 923 CloseHandle(g_VBoxDispIfWddm.hResizeEvent); 924 memset(&g_VBoxDispIfWddm, 0, sizeof (g_VBoxDispIfWddm)); 925 } 926 927 static DWORD vboxDispIfReninitModesWDDM(PCVBOXDISPIF const pIf, uint8_t *pScreenIdMask, BOOL fReconnectDisplaysOnChange) 928 { 929 VBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK Data = {0}; 930 Data.EscapeHdr.escapeCode = VBOXESC_REINITVIDEOMODESBYMASK; 931 if (fReconnectDisplaysOnChange) 932 Data.EscapeHdr.u32CmdSpecific = VBOXWDDM_REINITVIDEOMODESBYMASK_F_RECONNECT_DISPLAYS_ON_CHANGE; 933 934 memcpy(Data.ScreenMask, pScreenIdMask, sizeof (Data.ScreenMask)); 935 936 DWORD err = vboxDispIfEscapeWDDM(pIf, &Data.EscapeHdr, sizeof (Data) - sizeof (Data.EscapeHdr), fReconnectDisplaysOnChange ? FALSE /* hw access must be false here, 471 937 * otherwise the miniport driver would fail 472 * request to prevent a deadlock */); 938 * request to prevent a deadlock */ 939 : TRUE); 473 940 if (err != NO_ERROR) 474 941 { … … 532 999 } 533 1000 534 DWORD vboxDispIfResizeModesWDDM(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 1001 static DWORD vboxDispIfAdjustModeValues(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *pDisplayDevice, DEVMODE *pDeviceMode) 1002 { 1003 VBOXDISPIFESCAPE_ADJUSTVIDEOMODES Data = {0}; 1004 Data.EscapeHdr.escapeCode = VBOXESC_REINITVIDEOMODESBYMASK; 1005 Data.EscapeHdr.u32CmdSpecific = 1; 1006 Data.aScreenInfos[0].Mode.Id = 1007 Data.aScreenInfos[0].Mode.Width = pDeviceMode->dmPelsWidth; 1008 Data.aScreenInfos[0].Mode.Height = pDeviceMode->dmPelsHeight; 1009 Data.aScreenInfos[0].Mode.BitsPerPixel = pDeviceMode->dmBitsPerPel; 1010 DWORD err = vboxDispIfEscapeWDDM(pIf, &Data.EscapeHdr, sizeof (Data) - sizeof (Data.EscapeHdr), TRUE); 1011 if (err != NO_ERROR) 1012 { 1013 Log((__FUNCTION__": VBoxDispIfEscape failed with err (%d)\n", err)); 1014 } 1015 return err; 1016 } 1017 1018 DWORD vboxDispIfResizeModesWDDM(PCVBOXDISPIF const pIf, UINT iChangedMode, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 535 1019 { 536 1020 UINT cbVidPnInfo = VBOXWDDM_RECOMMENDVIDPN_SIZE(cDevModes); … … 614 1098 } 615 1099 616 if (!fAbleToInvalidateVidPn) 617 { 618 /* fallback impl: make the driver invalidate VidPn, 1100 // for (i = 0; i < cDevModes; i++) 1101 // { 1102 // vboxDispIfAdjustMode(&paDisplayDevices[i], &paDeviceModes[i]); 1103 // } 1104 1105 if (fAbleToInvalidateVidPn) 1106 { 1107 winEr = vboxDispIfWddmValidateFixResize(pIf, paDisplayDevices, paDeviceModes, cDevModes); 1108 } 1109 else 1110 { 1111 /* fallback impl needed for display-only driver 1112 * since D3DKMTInvalidateActiveVidPn is not available for WDDM > 1.0: 1113 * make the driver invalidate VidPn, 619 1114 * which is done by emulating a monitor re-plug currently */ 620 vboxDispIfReinitVideoModes(pIf); 621 622 /* sleep 2 seconds: dirty hack to wait for the new monitor info to be picked up, 623 * @todo: implement it properly by monitoring monitor device arrival/removal */ 624 Sleep(2 * 1000); 625 } 626 627 /* ignore any prev errors and just check if resize is OK */ 628 if (!vboxDispIfValidateResize(paDisplayDevices, paDeviceModes, cDevModes)) 629 { 630 /* now try to resize in a "regular" way */ 631 /* Assign the new rectangles to displays. */ 632 for (i = 0; i < cDevModes; i++) 633 { 634 /* On Vista one must specify DM_BITSPERPEL. 635 * Note that the current mode dmBitsPerPel is already in the DEVMODE structure. 636 */ 637 paDeviceModes[i].dmFields = DM_POSITION | DM_PELSHEIGHT | DM_PELSWIDTH | DM_BITSPERPEL; 638 639 Log(("VBoxTray: ResizeDisplayDevice: pfnChangeDisplaySettingsEx %x: %dx%dx%d at %d,%d\n", 640 pIf->modeData.wddm.pfnChangeDisplaySettingsEx, 641 paDeviceModes[i].dmPelsWidth, 642 paDeviceModes[i].dmPelsHeight, 643 paDeviceModes[i].dmBitsPerPel, 644 paDeviceModes[i].dmPosition.x, 645 paDeviceModes[i].dmPosition.y)); 646 647 /* the miniport might have been adjusted the display mode stuff, 648 * adjust the paDeviceModes[i] by picking the closest available one */ 649 DEVMODE AdjustedMode = paDeviceModes[i]; 650 vboxDispIfAdjustMode(&paDisplayDevices[i], &AdjustedMode); 651 652 LONG status = pIf->modeData.wddm.pfnChangeDisplaySettingsEx((LPSTR)paDisplayDevices[i].DeviceName, 653 &AdjustedMode, NULL, CDS_NORESET | CDS_UPDATEREGISTRY, NULL); 654 Log(("VBoxTray: ResizeDisplayDevice: ChangeDisplaySettingsEx position status %d, err %d\n", status, GetLastError ())); 655 } 656 657 /* A second call to ChangeDisplaySettings updates the monitor. */ 658 LONG status = pIf->modeData.wddm.pfnChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL); 659 Log(("VBoxTray: ResizeDisplayDevice: ChangeDisplaySettings update status %d\n", status)); 660 if (status == DISP_CHANGE_SUCCESSFUL) 661 { 662 winEr = NO_ERROR; 663 } 664 else if (status == DISP_CHANGE_BADMODE) 665 { 666 /* Successfully set new video mode or our driver can not set the requested mode. Stop trying. */ 667 winEr = ERROR_RETRY; 668 } 669 else 670 { 671 winEr = ERROR_GEN_FAILURE; 672 } 673 } 674 else 675 { 676 winEr = NO_ERROR; 1115 /* ensure event is reset */ 1116 WaitForSingleObject(g_VBoxDispIfWddm.hResizeEvent, 0); 1117 1118 uint8_t ScreenMask[VBOXWDDM_SCREENMASK_SIZE] = {0}; 1119 ASMBitSet(ScreenMask, iChangedMode); 1120 vboxDispIfReninitModesWDDM(pIf, ScreenMask, TRUE); 1121 1122 for (UINT i = 0; i < 4; ++i) 1123 { 1124 WaitForSingleObject(g_VBoxDispIfWddm.hResizeEvent, 500); 1125 winEr = vboxDispIfWddmValidateFixResize(pIf, paDisplayDevices, paDeviceModes, cDevModes); 1126 if (winEr == NO_ERROR) 1127 break; 1128 } 1129 1130 Assert(winEr == NO_ERROR); 677 1131 } 678 1132 … … 681 1135 #endif /* VBOX_WITH_WDDM */ 682 1136 683 DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes)1137 DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, UINT iChangedMode, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes) 684 1138 { 685 1139 switch (pIf->enmMode) … … 691 1145 #ifdef VBOX_WITH_WDDM 692 1146 case VBOXDISPIF_MODE_WDDM: 693 return vboxDispIfResizeModesWDDM(pIf, paDisplayDevices, paDeviceModes, cDevModes); 1147 return vboxDispIfResizeModesWDDM(pIf, iChangedMode, paDisplayDevices, paDeviceModes, cDevModes); 1148 #endif 1149 default: 1150 Log((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode)); 1151 return ERROR_INVALID_PARAMETER; 1152 } 1153 } 1154 1155 DWORD VBoxDispIfReninitModes(PCVBOXDISPIF const pIf, uint8_t *pScreenIdMask, BOOL fReconnectDisplaysOnChange) 1156 { 1157 switch (pIf->enmMode) 1158 { 1159 case VBOXDISPIF_MODE_XPDM_NT4: 1160 return ERROR_NOT_SUPPORTED; 1161 case VBOXDISPIF_MODE_XPDM: 1162 return ERROR_NOT_SUPPORTED; 1163 #ifdef VBOX_WITH_WDDM 1164 case VBOXDISPIF_MODE_WDDM: 1165 return vboxDispIfReninitModesWDDM(pIf, pScreenIdMask, fReconnectDisplaysOnChange); 694 1166 #endif 695 1167 default: … … 750 1222 751 1223 if (enmMode == pIf->enmMode) 752 return VINF_ALREADY_INITIALIZED; 1224 return NO_ERROR; 1225 1226 #ifdef VBOX_WITH_WDDM 1227 if (pIf->enmMode == VBOXDISPIF_MODE_WDDM) 1228 { 1229 vboxDispIfWddmTerm(pIf); 1230 } 1231 #endif 753 1232 754 1233 DWORD err = NO_ERROR; -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDispIf.h
r42154 r42217 84 84 DWORD VBoxDispIfEscape(PCVBOXDISPIF const pIf, PVBOXDISPIFESCAPE pEscape, int cbData); 85 85 DWORD VBoxDispIfResize(PCVBOXDISPIF const pIf, ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel); 86 DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes); 86 DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, UINT iChangedMode, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes); 87 //DWORD VBoxDispIfReninitModes(PCVBOXDISPIF const pIf, uint8_t *pScreenIdMask, BOOL fReconnectDisplaysOnChange); -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp
r42098 r42217 26 26 #include <malloc.h> 27 27 #include <VBoxGuestInternal.h> 28 #ifdef VBOX_WITH_WDDM 29 #include <iprt/asm.h> 30 #endif 28 31 29 32 typedef struct _VBOXDISPLAYCONTEXT … … 407 410 } 408 411 409 DWORD err = VBoxDispIfResizeModes(&pCtx->pEnv->dispIf, paDisplayDevices, paDeviceModes, NumDevices);412 DWORD err = VBoxDispIfResizeModes(&pCtx->pEnv->dispIf, Id, paDisplayDevices, paDeviceModes, NumDevices); 410 413 if (err == NO_ERROR || err != ERROR_RETRY) 411 414 { -
trunk/src/VBox/Additions/WINNT/include/VBoxDisplay.h
r40483 r42217 35 35 # define VBOXESC_CRHGSMICTLCON_CALL 0xABCD900E 36 36 # define VBOXESC_CRHGSMICTLCON_GETCLIENTID 0xABCD900F 37 # define VBOXESC_REINITVIDEOMODESBYMASK 0xABCD9010 38 # define VBOXESC_ADJUSTVIDEOMODES 0xABCD9011 37 39 38 typedef struct 39 { 40 DWORD Id; 41 DWORD Width; 42 DWORD Height; 43 DWORD BitsPerPixel; 44 } VBOXWDDM_RECOMMENDVIDPN_SCREEN_INFO, *PVBOXWDDM_RECOMMENDVIDPN_SCREEN_INFO; 45 46 typedef struct 47 { 48 uint32_t cScreenInfos; 49 VBOXWDDM_RECOMMENDVIDPN_SCREEN_INFO aScreenInfos[1]; 50 } VBOXWDDM_RECOMMENDVIDPN, *PVBOXWDDM_RECOMMENDVIDPN; 51 52 #define VBOXWDDM_RECOMMENDVIDPN_SIZE(_c) (RT_OFFSETOF(VBOXWDDM_RECOMMENDVIDPN, aScreenInfos[_c])) 40 /* for VBOX_VIDEO_MAX_SCREENS definition */ 41 #include <VBox/Hardware/VBoxVideoVBE.h> 53 42 54 43 #endif /* #ifdef VBOX_WITH_WDDM */ … … 71 60 CTL_CODE(FILE_DEVICE_VIDEO, 0xA01, METHOD_BUFFERED, FILE_ANY_ACCESS) 72 61 62 #ifdef VBOX_WITH_WDDM 63 64 typedef struct 65 { 66 DWORD Id; 67 DWORD Width; 68 DWORD Height; 69 DWORD BitsPerPixel; 70 } VBOXWDDM_RECOMMENDVIDPN_SCREEN_INFO, *PVBOXWDDM_RECOMMENDVIDPN_SCREEN_INFO; 71 72 typedef struct 73 { 74 uint32_t cScreenInfos; 75 VBOXWDDM_RECOMMENDVIDPN_SCREEN_INFO aScreenInfos[1]; 76 } VBOXWDDM_RECOMMENDVIDPN, *PVBOXWDDM_RECOMMENDVIDPN; 77 78 #define VBOXWDDM_RECOMMENDVIDPN_SIZE(_c) (RT_OFFSETOF(VBOXWDDM_RECOMMENDVIDPN, aScreenInfos[_c])) 79 80 /* the mode was adjusted */ 81 #define VBOXWDDM_ADJUSTVIDEOMODE_F_ADJUSTED 0x00000001 82 /* the mode is the currently active one */ 83 #define VBOXWDDM_ADJUSTVIDEOMODE_F_CURRENT 0x00000002 84 /* the mode is unsupported */ 85 #define VBOXWDDM_ADJUSTVIDEOMODE_F_UNSUPPORTED 0x00000004 86 /* invalid screen id */ 87 #define VBOXWDDM_ADJUSTVIDEOMODE_F_INVALISCREENID 0x00000008 88 89 typedef struct VBOXWDDM_ADJUSTVIDEOMODE 90 { 91 uint32_t fFlags; 92 VBOXWDDM_RECOMMENDVIDPN_SCREEN_INFO Mode; 93 } VBOXWDDM_ADJUSTVIDEOMODE, *PVBOXWDDM_ADJUSTVIDEOMODE; 94 95 typedef struct VBOXDISPIFESCAPE_ADJUSTVIDEOMODES 96 { 97 VBOXDISPIFESCAPE EscapeHdr; 98 VBOXWDDM_ADJUSTVIDEOMODE aScreenInfos[1]; 99 } VBOXDISPIFESCAPE_ADJUSTVIDEOMODES, *PVBOXDISPIFESCAPE_ADJUSTVIDEOMODES; 100 101 #define VBOXWDDM_REINITVIDEOMODESBYMASK_F_RECONNECT_DISPLAYS_ON_CHANGE 0x00000001 102 103 #define VBOXWDDM_SCREENMASK_SIZE ((VBOX_VIDEO_MAX_SCREENS + 7) >> 3) 104 105 typedef struct VBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK 106 { 107 VBOXDISPIFESCAPE EscapeHdr; 108 uint8_t ScreenMask[VBOXWDDM_SCREENMASK_SIZE]; 109 } VBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK, *PVBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK; 110 111 #endif /* VBOX_WITH_WDDM */ 112 73 113 #endif /* __VBoxDisplay_h__ */
Note:
See TracChangeset
for help on using the changeset viewer.