Changeset 72352 in vbox for trunk/src/VBox/Devices/VMMDev
- Timestamp:
- May 26, 2018 12:37:50 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 122809
- Location:
- trunk/src/VBox/Devices/VMMDev
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/VMMDev/VMMDev.cpp
r71891 r72352 83 83 /* Enable dev_vmm Log3 statements to get IRQ-related logging. */ 84 84 #define LOG_GROUP LOG_GROUP_DEV_VMM 85 #include <VBox Video.h> /* For VBVA definitions. */85 #include <VBox/AssertGuest.h> 86 86 #include <VBox/VMMDev.h> 87 87 #include <VBox/vmm/mm.h> … … 1311 1311 } 1312 1312 1313 if (pThis->displayChangeData.fGuestSentChangeEventAck) 1314 { 1315 pReq->xres = pDispRequest->lastReadDisplayChangeRequest.xres; 1316 pReq->yres = pDispRequest->lastReadDisplayChangeRequest.yres; 1317 pReq->bpp = pDispRequest->lastReadDisplayChangeRequest.bpp; 1318 } 1319 else 1320 { 1321 /* This is not a response to a VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, just 1322 * read the last valid video mode hint. This happens when the guest X server 1323 * determines the initial mode. */ 1324 pReq->xres = pDispRequest->displayChangeRequest.xres; 1325 pReq->yres = pDispRequest->displayChangeRequest.yres; 1326 pReq->bpp = pDispRequest->displayChangeRequest.bpp; 1327 } 1313 /* If not a response to a VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, just 1314 * read the last valid video mode hint. This happens when the guest X server 1315 * determines the initial mode. */ 1316 VMMDevDisplayDef const *pDisplayDef = pThis->displayChangeData.fGuestSentChangeEventAck ? 1317 &pDispRequest->lastReadDisplayChangeRequest : 1318 &pDispRequest->displayChangeRequest; 1319 pReq->xres = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_CX) ? pDisplayDef->cx : 0; 1320 pReq->yres = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_CY) ? pDisplayDef->cy : 0; 1321 pReq->bpp = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_BPP) ? pDisplayDef->cBitsPerPixel : 0; 1322 1328 1323 Log(("VMMDev: returning display change request xres = %d, yres = %d, bpp = %d\n", pReq->xres, pReq->yres, pReq->bpp)); 1329 1324 … … 1396 1391 } 1397 1392 1398 if (pThis->displayChangeData.fGuestSentChangeEventAck) 1399 { 1400 pReq->xres = pDispRequest->lastReadDisplayChangeRequest.xres; 1401 pReq->yres = pDispRequest->lastReadDisplayChangeRequest.yres; 1402 pReq->bpp = pDispRequest->lastReadDisplayChangeRequest.bpp; 1403 pReq->display = pDispRequest->lastReadDisplayChangeRequest.display; 1404 } 1405 else 1406 { 1407 /* This is not a response to a VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, just 1408 * read the last valid video mode hint. This happens when the guest X server 1409 * determines the initial video mode. */ 1410 pReq->xres = pDispRequest->displayChangeRequest.xres; 1411 pReq->yres = pDispRequest->displayChangeRequest.yres; 1412 pReq->bpp = pDispRequest->displayChangeRequest.bpp; 1413 pReq->display = pDispRequest->displayChangeRequest.display; 1414 } 1393 /* If not a response to a VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, just 1394 * read the last valid video mode hint. This happens when the guest X server 1395 * determines the initial mode. */ 1396 VMMDevDisplayDef const *pDisplayDef = pThis->displayChangeData.fGuestSentChangeEventAck ? 1397 &pDispRequest->lastReadDisplayChangeRequest : 1398 &pDispRequest->displayChangeRequest; 1399 pReq->xres = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_CX) ? pDisplayDef->cx : 0; 1400 pReq->yres = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_CY) ? pDisplayDef->cy : 0; 1401 pReq->bpp = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_BPP) ? pDisplayDef->cBitsPerPixel : 0; 1402 pReq->display = pDisplayDef->idDisplay; 1403 1415 1404 Log(("VMMDev: returning display change request xres = %d, yres = %d, bpp = %d at %d\n", 1416 1405 pReq->xres, pReq->yres, pReq->bpp, pReq->display)); … … 1487 1476 } 1488 1477 1489 if (pThis->displayChangeData.fGuestSentChangeEventAck) 1490 { 1491 pReq->xres = pDispRequest->lastReadDisplayChangeRequest.xres; 1492 pReq->yres = pDispRequest->lastReadDisplayChangeRequest.yres; 1493 pReq->bpp = pDispRequest->lastReadDisplayChangeRequest.bpp; 1494 pReq->display = pDispRequest->lastReadDisplayChangeRequest.display; 1495 pReq->cxOrigin = pDispRequest->lastReadDisplayChangeRequest.xOrigin; 1496 pReq->cyOrigin = pDispRequest->lastReadDisplayChangeRequest.yOrigin; 1497 pReq->fEnabled = pDispRequest->lastReadDisplayChangeRequest.fEnabled; 1498 pReq->fChangeOrigin = pDispRequest->lastReadDisplayChangeRequest.fChangeOrigin; 1499 } 1500 else 1501 { 1502 /* This is not a response to a VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, just 1503 * read the last valid video mode hint. This happens when the guest X server 1504 * determines the initial video mode. */ 1505 pReq->xres = pDispRequest->displayChangeRequest.xres; 1506 pReq->yres = pDispRequest->displayChangeRequest.yres; 1507 pReq->bpp = pDispRequest->displayChangeRequest.bpp; 1508 pReq->display = pDispRequest->displayChangeRequest.display; 1509 pReq->cxOrigin = pDispRequest->displayChangeRequest.xOrigin; 1510 pReq->cyOrigin = pDispRequest->displayChangeRequest.yOrigin; 1511 pReq->fEnabled = pDispRequest->displayChangeRequest.fEnabled; 1512 pReq->fChangeOrigin = pDispRequest->displayChangeRequest.fChangeOrigin; 1513 1514 } 1478 /* If not a response to a VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, just 1479 * read the last valid video mode hint. This happens when the guest X server 1480 * determines the initial mode. */ 1481 VMMDevDisplayDef const *pDisplayDef = pThis->displayChangeData.fGuestSentChangeEventAck ? 1482 &pDispRequest->lastReadDisplayChangeRequest : 1483 &pDispRequest->displayChangeRequest; 1484 pReq->xres = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_CX) ? pDisplayDef->cx : 0; 1485 pReq->yres = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_CY) ? pDisplayDef->cy : 0; 1486 pReq->bpp = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_BPP) ? pDisplayDef->cBitsPerPixel : 0; 1487 pReq->display = pDisplayDef->idDisplay; 1488 pReq->cxOrigin = pDisplayDef->xOrigin; 1489 pReq->cyOrigin = pDisplayDef->yOrigin; 1490 pReq->fEnabled = !RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_DISABLED); 1491 pReq->fChangeOrigin = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_ORIGIN); 1492 1515 1493 Log(("VMMDevEx: returning display change request xres = %d, yres = %d, bpp = %d id %d xPos = %d, yPos = %d & Enabled=%d\n", 1516 1494 pReq->xres, pReq->yres, pReq->bpp, pReq->display, pReq->cxOrigin, pReq->cyOrigin, pReq->fEnabled)); 1495 1496 return VINF_SUCCESS; 1497 } 1498 1499 1500 /** 1501 * Handles VMMDevReq_GetDisplayChangeRequestMulti. 1502 * 1503 * @returns VBox status code that the guest should see. 1504 * @param pThis The VMMDev instance data. 1505 * @param pReqHdr The header of the request to handle. 1506 */ 1507 static int vmmdevReqHandler_GetDisplayChangeRequestMulti(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr) 1508 { 1509 VMMDevDisplayChangeRequestMulti *pReq = (VMMDevDisplayChangeRequestMulti *)pReqHdr; 1510 unsigned i; 1511 1512 ASSERT_GUEST_MSG_RETURN(pReq->header.size >= sizeof(*pReq), 1513 ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER); 1514 RT_UNTRUSTED_VALIDATED_FENCE(); 1515 1516 uint32_t const cDisplays = pReq->cDisplays; 1517 ASSERT_GUEST_MSG_RETURN(cDisplays > 0 && cDisplays <= RT_ELEMENTS(pThis->displayChangeData.aRequests), 1518 ("cDisplays %u\n", cDisplays), VERR_INVALID_PARAMETER); 1519 RT_UNTRUSTED_VALIDATED_FENCE(); 1520 1521 ASSERT_GUEST_MSG_RETURN(pReq->header.size >= sizeof(*pReq) + (cDisplays - 1) * sizeof(VMMDevDisplayDef), 1522 ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER); 1523 RT_UNTRUSTED_VALIDATED_FENCE(); 1524 1525 if (pReq->eventAck == VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST) 1526 { 1527 /* Remember which resolution the client has queried, subsequent reads 1528 * will return the same values. */ 1529 for (i = 0; i < RT_ELEMENTS(pThis->displayChangeData.aRequests); ++i) 1530 { 1531 DISPLAYCHANGEREQUEST *pDCR = &pThis->displayChangeData.aRequests[i]; 1532 1533 pDCR->lastReadDisplayChangeRequest = pDCR->displayChangeRequest; 1534 pDCR->fPending = false; 1535 } 1536 } 1537 1538 /* Fill the guest request with monitor layout data. */ 1539 for (i = 0; i < cDisplays; ++i) 1540 { 1541 /* If not a response to a VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, just 1542 * read the last valid video mode hint. This happens when the guest X server 1543 * determines the initial mode. */ 1544 DISPLAYCHANGEREQUEST const *pDCR = &pThis->displayChangeData.aRequests[i]; 1545 VMMDevDisplayDef const *pDisplayDef = pThis->displayChangeData.fGuestSentChangeEventAck ? 1546 &pDCR->lastReadDisplayChangeRequest : 1547 &pDCR->displayChangeRequest; 1548 pReq->aDisplays[i] = *pDisplayDef; 1549 } 1550 1551 Log(("VMMDev: returning multimonitor display change request cDisplays %d\n", cDisplays)); 1517 1552 1518 1553 return VINF_SUCCESS; … … 2570 2605 case VMMDevReq_GetDisplayChangeRequestEx: 2571 2606 pReqHdr->rc = vmmdevReqHandler_GetDisplayChangeRequestEx(pThis, pReqHdr); 2607 break; 2608 2609 case VMMDevReq_GetDisplayChangeRequestMulti: 2610 pReqHdr->rc = vmmdevReqHandler_GetDisplayChangeRequestMulti(pThis, pReqHdr); 2572 2611 break; 2573 2612 … … 3182 3221 } 3183 3222 3223 static bool vmmdevIsMonitorDefEqual(VMMDevDisplayDef const *pNew, VMMDevDisplayDef const *pOld) 3224 { 3225 bool fEqual = pNew->idDisplay == pOld->idDisplay; 3226 3227 fEqual = fEqual && ( !RT_BOOL(pNew->fDisplayFlags & VMMDEV_DISPLAY_ORIGIN) /* No change. */ 3228 || ( RT_BOOL(pOld->fDisplayFlags & VMMDEV_DISPLAY_ORIGIN) /* Old value exists and */ 3229 && pNew->xOrigin == pOld->xOrigin /* the old is equal to the new. */ 3230 && pNew->yOrigin == pOld->yOrigin)); 3231 3232 fEqual = fEqual && ( !RT_BOOL(pNew->fDisplayFlags & VMMDEV_DISPLAY_CX) 3233 || ( RT_BOOL(pOld->fDisplayFlags & VMMDEV_DISPLAY_CX) 3234 && pNew->cx == pOld->cx)); 3235 3236 fEqual = fEqual && ( !RT_BOOL(pNew->fDisplayFlags & VMMDEV_DISPLAY_CY) 3237 || ( RT_BOOL(pOld->fDisplayFlags & VMMDEV_DISPLAY_CY) 3238 && pNew->cy == pOld->cy)); 3239 3240 fEqual = fEqual && ( !RT_BOOL(pNew->fDisplayFlags & VMMDEV_DISPLAY_BPP) 3241 || ( RT_BOOL(pOld->fDisplayFlags & VMMDEV_DISPLAY_BPP) 3242 && pNew->cBitsPerPixel == pOld->cBitsPerPixel)); 3243 3244 fEqual = fEqual && ( RT_BOOL(pNew->fDisplayFlags & VMMDEV_DISPLAY_DISABLED) 3245 == RT_BOOL(pOld->fDisplayFlags & VMMDEV_DISPLAY_DISABLED)); 3246 3247 fEqual = fEqual && ( RT_BOOL(pNew->fDisplayFlags & VMMDEV_DISPLAY_PRIMARY) 3248 == RT_BOOL(pOld->fDisplayFlags & VMMDEV_DISPLAY_PRIMARY)); 3249 3250 return fEqual; 3251 } 3252 3184 3253 /** 3185 3254 * @interface_method_impl{PDMIVMMDEVPORT,pfnRequestDisplayChange} 3186 3255 */ 3187 3256 static DECLCALLBACK(int) 3188 vmmdevIPort_RequestDisplayChange(PPDMIVMMDEVPORT pInterface, uint32_t cx, uint32_t cy, uint32_t cBits, uint32_t idxDisplay, 3189 int32_t xOrigin, int32_t yOrigin, bool fEnabled, bool fChangeOrigin) 3190 { 3257 vmmdevIPort_RequestDisplayChange(PPDMIVMMDEVPORT pInterface, uint32_t cDisplays, VMMDevDisplayDef const *paDisplays, bool fForce) 3258 { 3259 int rc = VINF_SUCCESS; 3260 3191 3261 PVMMDEV pThis = RT_FROM_MEMBER(pInterface, VMMDEV, IPort); 3192 3193 if (idxDisplay >= RT_ELEMENTS(pThis->displayChangeData.aRequests)) 3194 return VERR_INVALID_PARAMETER; 3262 bool fNotifyGuest = false; 3195 3263 3196 3264 PDMCritSectEnter(&pThis->CritSect, VERR_IGNORED); 3197 3265 3198 DISPLAYCHANGEREQUEST *pRequest = &pThis->displayChangeData.aRequests[idxDisplay]; 3199 3200 /* Verify that the new resolution is different and that guest does not yet know about it. */ 3201 bool fSameResolution = (!cx || pRequest->lastReadDisplayChangeRequest.xres == cx) 3202 && (!cy || pRequest->lastReadDisplayChangeRequest.yres == cy) 3203 && (!cBits || pRequest->lastReadDisplayChangeRequest.bpp == cBits) 3204 && pRequest->lastReadDisplayChangeRequest.xOrigin == xOrigin 3205 && pRequest->lastReadDisplayChangeRequest.yOrigin == yOrigin 3206 && pRequest->lastReadDisplayChangeRequest.fEnabled == fEnabled 3207 && pRequest->lastReadDisplayChangeRequest.display == idxDisplay; 3208 3209 if (!cx && !cy && !cBits) 3210 { 3211 /* Special case of reset video mode. */ 3212 fSameResolution = false; 3213 } 3214 3215 Log3(("vmmdevIPort_RequestDisplayChange: same=%d. new: cx=%d, cy=%d, cBits=%d, idxDisplay=%d.\ 3216 old: cx=%d, cy=%d, cBits=%d, idxDisplay=%d. \n \ 3217 ,OriginX = %d , OriginY=%d, Enabled=%d, ChangeOrigin=%d\n", 3218 fSameResolution, cx, cy, cBits, idxDisplay, pRequest->lastReadDisplayChangeRequest.xres, 3219 pRequest->lastReadDisplayChangeRequest.yres, pRequest->lastReadDisplayChangeRequest.bpp, 3220 pRequest->lastReadDisplayChangeRequest.display, 3221 xOrigin, yOrigin, fEnabled, fChangeOrigin)); 3222 3223 /* we could validate the information here but hey, the guest can do that as well! */ 3224 pRequest->displayChangeRequest.xres = cx; 3225 pRequest->displayChangeRequest.yres = cy; 3226 pRequest->displayChangeRequest.bpp = cBits; 3227 pRequest->displayChangeRequest.display = idxDisplay; 3228 pRequest->displayChangeRequest.xOrigin = xOrigin; 3229 pRequest->displayChangeRequest.yOrigin = yOrigin; 3230 pRequest->displayChangeRequest.fEnabled = fEnabled; 3231 pRequest->displayChangeRequest.fChangeOrigin = fChangeOrigin; 3232 3233 pRequest->fPending = !fSameResolution; 3234 3235 if (!fSameResolution) 3236 { 3237 LogRel(("VMMDev: SetVideoModeHint: Got a video mode hint (%dx%dx%d)@(%dx%d),(%d;%d) at %d\n", 3238 cx, cy, cBits, xOrigin, yOrigin, fEnabled, fChangeOrigin, idxDisplay)); 3239 3240 /* IRQ so the guest knows what's going on */ 3241 VMMDevNotifyGuest(pThis, VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST); 3266 uint32_t i; 3267 for (i = 0; i < cDisplays; ++i) 3268 { 3269 VMMDevDisplayDef const *p = &paDisplays[i]; 3270 3271 /* Either one display definition is provided or the display id must be equal to the array index. */ 3272 AssertBreakStmt(cDisplays == 1 || p->idDisplay == i, rc = VERR_INVALID_PARAMETER); 3273 AssertBreakStmt(p->idDisplay < RT_ELEMENTS(pThis->displayChangeData.aRequests), rc = VERR_INVALID_PARAMETER); 3274 3275 DISPLAYCHANGEREQUEST *pRequest = &pThis->displayChangeData.aRequests[p->idDisplay]; 3276 3277 VMMDevDisplayDef const *pLastRead = &pRequest->lastReadDisplayChangeRequest; 3278 3279 /* Verify that the new resolution is different and that guest does not yet know about it. */ 3280 bool const fDifferentResolution = fForce || !vmmdevIsMonitorDefEqual(p, pLastRead); 3281 3282 LogFunc(("same=%d. New: %dx%d, cBits=%d, id=%d. Old: %dx%d, cBits=%d, id=%d. @%d,%d, Enabled=%d, ChangeOrigin=%d\n", 3283 !fDifferentResolution, p->cx, p->cy, p->cBitsPerPixel, p->idDisplay, 3284 pLastRead->cx, pLastRead->cy, pLastRead->cBitsPerPixel, pLastRead->idDisplay, 3285 p->xOrigin, p->yOrigin, 3286 !RT_BOOL(p->fDisplayFlags & VMMDEV_DISPLAY_DISABLED), 3287 RT_BOOL(p->fDisplayFlags & VMMDEV_DISPLAY_ORIGIN))); 3288 3289 /* We could validate the information here but hey, the guest can do that as well! */ 3290 pRequest->displayChangeRequest = *p; 3291 pRequest->fPending = fDifferentResolution; 3292 3293 fNotifyGuest = fNotifyGuest || fDifferentResolution; 3294 } 3295 3296 if (RT_SUCCESS(rc)) 3297 { 3298 if (fNotifyGuest) 3299 { 3300 for (i = 0; i < RT_ELEMENTS(pThis->displayChangeData.aRequests); ++i) 3301 { 3302 DISPLAYCHANGEREQUEST *pRequest = &pThis->displayChangeData.aRequests[i]; 3303 if (pRequest->fPending) 3304 { 3305 VMMDevDisplayDef const *p = &pRequest->displayChangeRequest; 3306 LogRel(("VMMDev: SetVideoModeHint: Got a video mode hint (%dx%dx%d)@(%dx%d),(%d;%d) at %d\n", 3307 p->cx, p->cy, p->cBitsPerPixel, p->xOrigin, p->yOrigin, 3308 !RT_BOOL(p->fDisplayFlags & VMMDEV_DISPLAY_DISABLED), 3309 RT_BOOL(p->fDisplayFlags & VMMDEV_DISPLAY_ORIGIN), i)); 3310 } 3311 } 3312 3313 /* IRQ so the guest knows what's going on */ 3314 VMMDevNotifyGuest(pThis, VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST); 3315 } 3242 3316 } 3243 3317 3244 3318 PDMCritSectLeave(&pThis->CritSect); 3245 return VINF_SUCCESS;3319 return rc; 3246 3320 } 3247 3321 -
trunk/src/VBox/Devices/VMMDev/VMMDevState.h
r71891 r72352 19 19 #define ___VMMDev_VMMDevState_h 20 20 21 #include <VBoxVideo.h> /* For VBVA definitions. */ 21 22 #include <VBox/VMMDev.h> 22 23 #include <VBox/vmm/pdmdev.h> … … 31 32 #define VMMDEV_WITH_ALT_TIMESYNC 32 33 33 typedef struct DISPLAYCHANGEINFO34 {35 uint32_t xres;36 uint32_t yres;37 uint32_t bpp;38 uint32_t display;39 int32_t xOrigin;40 int32_t yOrigin;41 bool fEnabled;42 bool fChangeOrigin;43 } DISPLAYCHANGEINFO;44 45 34 typedef struct DISPLAYCHANGEREQUEST 46 35 { 47 36 bool fPending; 48 37 bool afAlignment[3]; 49 DISPLAYCHANGEINFOdisplayChangeRequest;50 DISPLAYCHANGEINFOlastReadDisplayChangeRequest;38 VMMDevDisplayDef displayChangeRequest; 39 VMMDevDisplayDef lastReadDisplayChangeRequest; 51 40 } DISPLAYCHANGEREQUEST; 52 41 … … 60 49 bool afAlignment[3]; 61 50 62 DISPLAYCHANGEREQUEST aRequests[ 64]; /// @todo maxMonitors51 DISPLAYCHANGEREQUEST aRequests[VBOX_VIDEO_MAX_SCREENS]; 63 52 } DISPLAYCHANGEDATA; 64 53
Note:
See TracChangeset
for help on using the changeset viewer.