Bug 1409018 - Defer RegisterRefreshAndMoveHandlers call; r=pehrsons
authorDan Minor <dminor@mozilla.com>
Tue, 05 Jun 2018 08:13:01 -0400
changeset 479580 1a8d462805f02ed0314c6da98e37000ccdd04592
parent 479579 a7bd9bd361a3da29ab46cc4bbedc34270d23fd5a
child 479581 0708df4d3b7a8c38dd32f52d3199e5a27a0758f2
push id1757
push userffxbld-merge
push dateFri, 24 Aug 2018 17:02:43 +0000
treeherdermozilla-release@736023aebdb1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspehrsons
bugs1409018
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1409018 - Defer RegisterRefreshAndMoveHandlers call; r=pehrsons This defers the call to register the refresh and move handlers to the CaptureFrame() call so that they will be registered on the ScreenCapture thread. This also calls CFRunLoopInMode to process any pending sources in the run loop corresponding to the ScreenCapture thread so that the refresh and move notifications are received. MozReview-Commit-ID: G4aEchnGuUz
media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_mac.mm
--- a/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_mac.mm
+++ b/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_mac.mm
@@ -358,16 +358,23 @@ class ScreenCapturerMac : public Desktop
   CGLSetFullScreenFunc cgl_set_full_screen_ = nullptr;
 
   CGWindowID excluded_window_ = 0;
 
   // A self-owned object that will destroy itself after ScreenCapturerMac and
   // all display streams have been destroyed..
   DisplayStreamManager* display_stream_manager_;
 
+  // Used to force CaptureFrame to update it's screen configuration
+  // and reregister event handlers. This ensure that this
+  // occurs on the ScreenCapture thread. Read and written from
+  // both the VideoCapture thread and ScreenCapture thread.
+  // Protected by desktop_config_monitor_.
+  bool update_screen_configuration_ = false;
+
   RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerMac);
 };
 
 // DesktopFrame wrapper that flips wrapped frame upside down by inverting
 // stride.
 class InvertedDesktopFrame : public DesktopFrame {
  public:
   InvertedDesktopFrame(std::unique_ptr<DesktopFrame> frame)
@@ -398,23 +405,32 @@ ScreenCapturerMac::ScreenCapturerMac(
 ScreenCapturerMac::~ScreenCapturerMac() {
   ReleaseBuffers();
   display_stream_manager_->PrepareForSelfDestruction();
   dlclose(app_services_library_);
   dlclose(opengl_library_);
 }
 
 bool ScreenCapturerMac::Init() {
+// MOZILLA: Calling RegisterRefreshAndMoveHandlers here causes us
+// to register on the VideoCapture thread rather than the ScreenCapture
+// thread which will result in us never receiving any notifications.
+// See Bug 1468509.
+/*
   desktop_config_monitor_->Lock();
   desktop_config_ = desktop_config_monitor_->desktop_configuration();
   desktop_config_monitor_->Unlock();
   if (!RegisterRefreshAndMoveHandlers()) {
     return false;
   }
   ScreenConfigurationChanged();
+*/
+  desktop_config_monitor_->Lock();
+  update_screen_configuration_ = true;
+  desktop_config_monitor_->Unlock();
   return true;
 }
 
 void ScreenCapturerMac::ReleaseBuffers() {
   if (cgl_context_) {
     pixel_buffer_object_.Release();
     CGLDestroyContext(cgl_context_);
     cgl_context_ = nullptr;
@@ -425,16 +441,19 @@ void ScreenCapturerMac::ReleaseBuffers()
   queue_.Reset();
 }
 
 void ScreenCapturerMac::Start(Callback* callback) {
   assert(!callback_);
   assert(callback);
 
   callback_ = callback;
+  desktop_config_monitor_->Lock();
+  update_screen_configuration_ = true;
+  desktop_config_monitor_->Unlock();
 }
 
 void ScreenCapturerMac::Stop() {
   if (power_assertion_id_display_ != kIOPMNullAssertionID) {
     IOPMAssertionRelease(power_assertion_id_display_);
     power_assertion_id_display_ = kIOPMNullAssertionID;
   }
   if (power_assertion_id_user_ != kIOPMNullAssertionID) {
@@ -443,23 +462,27 @@ void ScreenCapturerMac::Stop() {
   }
 
   callback_ = NULL;
 }
 
 void ScreenCapturerMac::CaptureFrame() {
   int64_t capture_start_time_nanos = rtc::TimeNanos();
 
+  // Spin RunLoop for 1/100th of a second, handling at most one source
+  CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.01, true);
+
   queue_.MoveToNextFrame();
   RTC_DCHECK(!queue_.current_frame() || !queue_.current_frame()->IsShared());
 
   desktop_config_monitor_->Lock();
   MacDesktopConfiguration new_config =
       desktop_config_monitor_->desktop_configuration();
-  if (!desktop_config_.Equals(new_config)) {
+  if (update_screen_configuration_ || !desktop_config_.Equals(new_config)) {
+    update_screen_configuration_ = false;
     desktop_config_ = new_config;
     // If the display configuraiton has changed then refresh capturer data
     // structures. Occasionally, the refresh and move handlers are lost when
     // the screen mode changes, so re-register them here.
     UnregisterRefreshAndMoveHandlers();
     RegisterRefreshAndMoveHandlers();
     ScreenConfigurationChanged();
   }