Home | History | Annotate | Download | only in mac
      1 /*
      2  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h"
     12 
     13 #include "webrtc/modules/desktop_capture/mac/desktop_configuration.h"
     14 #include "webrtc/system_wrappers/interface/event_wrapper.h"
     15 #include "webrtc/system_wrappers/interface/logging.h"
     16 
     17 namespace webrtc {
     18 
     19 // The amount of time allowed for displays to reconfigure.
     20 static const int64_t kDisplayConfigurationEventTimeoutMs = 10 * 1000;
     21 
     22 DesktopConfigurationMonitor::DesktopConfigurationMonitor()
     23     : ref_count_(0),
     24       display_configuration_capture_event_(EventWrapper::Create()) {
     25   CGError err = CGDisplayRegisterReconfigurationCallback(
     26       DesktopConfigurationMonitor::DisplaysReconfiguredCallback, this);
     27   if (err != kCGErrorSuccess) {
     28     LOG(LS_ERROR) << "CGDisplayRegisterReconfigurationCallback " << err;
     29     abort();
     30   }
     31   display_configuration_capture_event_->Set();
     32 
     33   desktop_configuration_ = MacDesktopConfiguration::GetCurrent(
     34       MacDesktopConfiguration::TopLeftOrigin);
     35 }
     36 
     37 DesktopConfigurationMonitor::~DesktopConfigurationMonitor() {
     38   CGError err = CGDisplayRemoveReconfigurationCallback(
     39       DesktopConfigurationMonitor::DisplaysReconfiguredCallback, this);
     40   if (err != kCGErrorSuccess)
     41     LOG(LS_ERROR) << "CGDisplayRemoveReconfigurationCallback " << err;
     42 }
     43 
     44 void DesktopConfigurationMonitor::Lock() {
     45   if (!display_configuration_capture_event_->Wait(
     46               kDisplayConfigurationEventTimeoutMs)) {
     47     LOG_F(LS_ERROR) << "Event wait timed out.";
     48     abort();
     49   }
     50 }
     51 
     52 void DesktopConfigurationMonitor::Unlock() {
     53   display_configuration_capture_event_->Set();
     54 }
     55 
     56 // static
     57 void DesktopConfigurationMonitor::DisplaysReconfiguredCallback(
     58     CGDirectDisplayID display,
     59     CGDisplayChangeSummaryFlags flags,
     60     void *user_parameter) {
     61   DesktopConfigurationMonitor* monitor =
     62       reinterpret_cast<DesktopConfigurationMonitor*>(user_parameter);
     63   monitor->DisplaysReconfigured(display, flags);
     64 }
     65 
     66 void DesktopConfigurationMonitor::DisplaysReconfigured(
     67     CGDirectDisplayID display,
     68     CGDisplayChangeSummaryFlags flags) {
     69   if (flags & kCGDisplayBeginConfigurationFlag) {
     70     if (reconfiguring_displays_.empty()) {
     71       // If this is the first display to start reconfiguring then wait on
     72       // |display_configuration_capture_event_| to block the capture thread
     73       // from accessing display memory until the reconfiguration completes.
     74       if (!display_configuration_capture_event_->Wait(
     75               kDisplayConfigurationEventTimeoutMs)) {
     76         LOG_F(LS_ERROR) << "Event wait timed out.";
     77         abort();
     78       }
     79     }
     80     reconfiguring_displays_.insert(display);
     81   } else {
     82     reconfiguring_displays_.erase(display);
     83     if (reconfiguring_displays_.empty()) {
     84       desktop_configuration_ = MacDesktopConfiguration::GetCurrent(
     85           MacDesktopConfiguration::TopLeftOrigin);
     86       display_configuration_capture_event_->Set();
     87     }
     88   }
     89 }
     90 
     91 }  // namespace webrtc
     92