Changeset 102453 in vbox for trunk/src/VBox/Additions/x11/VBoxClient
- Timestamp:
- Dec 4, 2023 3:31:48 PM (16 months ago)
- svn:sync-xref-src-repo-rev:
- 160596
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/VBoxClient/display-drm.cpp
r98103 r102453 111 111 #include <iprt/asm.h> 112 112 #include <iprt/localipc.h> 113 #include <iprt/timer.h> 113 114 114 115 #include <unistd.h> … … 151 152 /** Maximum number of simultaneous IPC client connections. */ 152 153 #define DRM_IPC_SERVER_CONNECTIONS_MAX (16) 154 /** Interval between attempts to send resize events to DRM stack. */ 155 #define DRM_RESIZE_INTERVAL_MS (250) 153 156 154 157 /** IPC client connections counter. */ … … 210 213 static RTCRITSECT g_monitorPositionsCritSect; 211 214 215 /** Resize events suppression. 216 * 217 * We tend to suppress incoming resizing events from host. Instead of 218 * applying them immediately to Linux DRM stack, we keep them and apply 219 * in recurring timer callback. This structure collects all the necessary 220 * components to implement events suppression. */ 221 static struct VBOX_DRM_SUPPRESSION 222 { 223 /** Protection for concurrent access from host events loop and 224 * suppression timer contexts. */ 225 RTCRITSECT critSect; 226 227 /** Recurring timer which is used in order to push resize events 228 * into DRM stack. */ 229 PRTTIMER pResizeSuppressionTimer; 230 231 /** Resize parameters from the last host event: coordinates. */ 232 VMMDevDisplayDef aDisplaysIn[VBOX_DRMIPC_MONITORS_MAX]; 233 234 /** Resize parameters from the last host event: number of displays. */ 235 uint32_t cDisplaysIn; 236 237 /** Flag to indicate that new events were suppressed since last 238 * time when we sent data to DRM stack. */ 239 bool fHaveSuppressedEvents; 240 } g_vboxDrmSuppression; 241 212 242 /** Counter of how often our daemon has been re-spawned. */ 213 243 unsigned g_cRespawn = 0; … … 621 651 } 622 652 653 /** 654 * Suppress incoming resize events from host. 655 * 656 * This function will put last resize event data into suppression 657 * cache. This data will later be picked up by timer callback and 658 * pushed into DRM stack. 659 * 660 * @returns IPRT status code. 661 * @param paDisplaysIn Display resize data. 662 * @param cDisplaysIn Number of displays. 663 */ 664 static int vbDrmResizeSuppress(VMMDevDisplayDef *paDisplaysIn, uint32_t cDisplaysIn) 665 { 666 int rc; 667 668 Assert((sizeof(VMMDevDisplayDef) * cDisplaysIn) <= sizeof(g_vboxDrmSuppression.aDisplaysIn)); 669 670 rc = RTCritSectEnter(&g_vboxDrmSuppression.critSect); 671 if (RT_FAILURE(rc)) 672 { 673 VBClLogError("unable to lock suppression data cache, rc=%Rrc\n", rc); 674 return rc; 675 } 676 677 memcpy(g_vboxDrmSuppression.aDisplaysIn, paDisplaysIn, sizeof(VMMDevDisplayDef) * cDisplaysIn); 678 g_vboxDrmSuppression.cDisplaysIn = cDisplaysIn; 679 g_vboxDrmSuppression.fHaveSuppressedEvents = true; 680 681 int rc2 = RTCritSectLeave(&g_vboxDrmSuppression.critSect); 682 if (RT_FAILURE(rc2)) 683 VBClLogError("unable to unlock suppression data cache, rc=%Rrc\n", rc); 684 685 if (RT_SUCCESS(rc)) 686 rc = rc2; 687 688 return rc; 689 } 690 691 /** Recurring timer callback to push display resize events into DRM stack. 692 * 693 * @param pTimer IPRT timer structure (unused). 694 * @param pvUser User data (unused). 695 * @param iTick Timer tick data (unused). 696 */ 697 static DECLCALLBACK(void) vbDrmResizeSuppressionTimerCb(PRTTIMER pTimer, void *pvUser, uint64_t iTick) 698 { 699 int rc; 700 701 RT_NOREF(pTimer, pvUser, iTick); 702 703 rc = RTCritSectEnter(&g_vboxDrmSuppression.critSect); 704 if (RT_FAILURE(rc)) 705 { 706 VBClLogError("unable to lock suppression data cache, rc=%Rrc\n", rc); 707 return; 708 } 709 710 if (g_vboxDrmSuppression.fHaveSuppressedEvents) 711 { 712 rc = vbDrmPushScreenLayout(g_vboxDrmSuppression.aDisplaysIn, g_vboxDrmSuppression.cDisplaysIn, false, true); 713 if (RT_FAILURE(rc)) 714 VBClLogError("Failed to push display change as requested by host, rc=%Rrc\n", rc); 715 716 g_vboxDrmSuppression.fHaveSuppressedEvents = false; 717 } 718 719 int rc2 = RTCritSectLeave(&g_vboxDrmSuppression.critSect); 720 if (RT_FAILURE(rc2)) 721 VBClLogError("unable to unlock suppression data cache, rc=%Rrc\n", rc); 722 } 723 724 /** 725 * Initialize DRM events suppression data. 726 * 727 * @returns IPRT status code. 728 * @param pSuppression Pointer to suppression data. 729 */ 730 static int vbDrmSuppressionInit(struct VBOX_DRM_SUPPRESSION *pSuppression) 731 { 732 int rc; 733 734 RT_BZERO(pSuppression, sizeof(*pSuppression)); 735 736 rc = RTCritSectInit(&pSuppression->critSect); 737 if (RT_SUCCESS(rc)) 738 { 739 rc = RTTimerCreate(&pSuppression->pResizeSuppressionTimer, DRM_RESIZE_INTERVAL_MS, vbDrmResizeSuppressionTimerCb, NULL); 740 if (RT_SUCCESS(rc)) 741 VBClLogInfo("starting deferred resize events delivery\n"); 742 else 743 VBClLogError("unable to enable deferred resize events delivery: no timer, rc=%Rrc\n", rc); 744 } 745 else 746 VBClLogError("unable to enable deferred resize events delivery: no critsect, rc=%Rrc\n", rc); 747 748 return rc; 749 } 750 751 /** 752 * Destroy DRM events suppression data. 753 * 754 * @returns IPRT status code. 755 * @param pSuppression Pointer to suppression data. 756 */ 757 static int vbDrmSuppressionDestroy(struct VBOX_DRM_SUPPRESSION *pSuppression) 758 { 759 int rc; 760 761 rc = RTTimerDestroy(pSuppression->pResizeSuppressionTimer); 762 if (RT_SUCCESS(rc)) 763 { 764 rc = RTCritSectDelete(&pSuppression->critSect); 765 if (RT_FAILURE(rc)) 766 VBClLogError("unable to destroy suppression critsect, rc=%Rrc\n", rc); 767 } 768 else 769 VBClLogError("unable to destroy suppression timer, rc=%Rrc\n", rc); 770 771 return rc; 772 } 773 623 774 /** Worker thread for resize task. */ 624 775 static DECLCALLBACK(int) vbDrmResizeWorker(RTTHREAD ThreadSelf, void *pvUser) … … 648 799 if (RT_SUCCESS(rc)) 649 800 { 650 rc = vbDrm PushScreenLayout(aDisplaysIn, cDisplaysIn, false, true);801 rc = vbDrmResizeSuppress(aDisplaysIn, cDisplaysIn); 651 802 if (RT_FAILURE(rc)) 652 803 VBClLogError("Failed to push display change as requested by host, rc=%Rrc\n", rc); … … 1119 1270 } 1120 1271 1121 /* Set flag for the thread which serves incom ming IPC connections. */1272 /* Set flag for the thread which serves incoming IPC connections. */ 1122 1273 ASMAtomicWriteBool(&g_fDrmIpcRestricted, fRestrict); 1123 1274 } … … 1299 1450 } 1300 1451 1452 rc = vbDrmSuppressionInit(&g_vboxDrmSuppression); 1453 if (RT_FAILURE(rc)) 1454 return RTEXITCODE_FAILURE; 1455 1301 1456 /* Instantiate IPC server for VBoxClient service communication. */ 1302 1457 rc = RTLocalIpcServerCreate(&hIpcServer, VBOX_DRMIPC_SERVER_NAME, 0); … … 1351 1506 VBClLogError("unable to stop IPC server, rc=%Rrc\n", rc); 1352 1507 1508 rc2 = vbDrmSuppressionDestroy(&g_vboxDrmSuppression); 1509 if (RT_FAILURE(rc2)) 1510 VBClLogError("unable to destroy suppression data, rc=%Rrc\n", rc2); 1511 1353 1512 rc2 = RTCritSectDelete(&g_monitorPositionsCritSect); 1354 1513 if (RT_FAILURE(rc2))
Note:
See TracChangeset
for help on using the changeset viewer.