Moves the display reconfiguration callback into a separate class,
so that it can be shared with the cursor monitor when single monitor capturing is added (https://webrtc-codereview.appspot.com/4679005/). This Cl should have no functionality change. BUG=2253 R=henrike@webrtc.org, sergeyu@chromium.org Review URL: https://webrtc-codereview.appspot.com/7599004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5461 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
808b99b111
commit
cf1b51b6fb
@ -36,6 +36,8 @@
|
|||||||
"differ_block.h",
|
"differ_block.h",
|
||||||
"mac/desktop_configuration.h",
|
"mac/desktop_configuration.h",
|
||||||
"mac/desktop_configuration.mm",
|
"mac/desktop_configuration.mm",
|
||||||
|
"mac/desktop_configuration_monitor.h",
|
||||||
|
"mac/desktop_configuration_monitor.cc",
|
||||||
"mac/scoped_pixel_buffer_object.cc",
|
"mac/scoped_pixel_buffer_object.cc",
|
||||||
"mac/scoped_pixel_buffer_object.h",
|
"mac/scoped_pixel_buffer_object.h",
|
||||||
"mouse_cursor.cc",
|
"mouse_cursor.cc",
|
||||||
|
@ -28,6 +28,9 @@ DesktopCaptureOptions DesktopCaptureOptions::CreateDefault() {
|
|||||||
DesktopCaptureOptions result;
|
DesktopCaptureOptions result;
|
||||||
#if defined(USE_X11)
|
#if defined(USE_X11)
|
||||||
result.set_x_display(SharedXDisplay::CreateDefault());
|
result.set_x_display(SharedXDisplay::CreateDefault());
|
||||||
|
#endif
|
||||||
|
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
|
||||||
|
result.set_configuration_monitor(new DesktopConfigurationMonitor());
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,16 @@
|
|||||||
#define WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_OPTIONS_H_
|
#define WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_OPTIONS_H_
|
||||||
|
|
||||||
#include "webrtc/system_wrappers/interface/constructor_magic.h"
|
#include "webrtc/system_wrappers/interface/constructor_magic.h"
|
||||||
|
#include "webrtc/system_wrappers/interface/scoped_refptr.h"
|
||||||
|
|
||||||
#if defined(USE_X11)
|
#if defined(USE_X11)
|
||||||
#include "webrtc/modules/desktop_capture/x11/shared_x_display.h"
|
#include "webrtc/modules/desktop_capture/x11/shared_x_display.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
|
||||||
|
#include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
// An object that stores initialization parameters for screen and window
|
// An object that stores initialization parameters for screen and window
|
||||||
@ -38,6 +43,15 @@ class DesktopCaptureOptions {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
|
||||||
|
DesktopConfigurationMonitor* configuration_monitor() const {
|
||||||
|
return configuration_monitor_;
|
||||||
|
}
|
||||||
|
void set_configuration_monitor(scoped_refptr<DesktopConfigurationMonitor> m) {
|
||||||
|
configuration_monitor_ = m;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Flag indicating that the capturer should use screen change notifications.
|
// Flag indicating that the capturer should use screen change notifications.
|
||||||
// Enables/disables use of XDAMAGE in the X11 capturer.
|
// Enables/disables use of XDAMAGE in the X11 capturer.
|
||||||
bool use_update_notifications() const { return use_update_notifications_; }
|
bool use_update_notifications() const { return use_update_notifications_; }
|
||||||
@ -56,6 +70,10 @@ class DesktopCaptureOptions {
|
|||||||
#if defined(USE_X11)
|
#if defined(USE_X11)
|
||||||
scoped_refptr<SharedXDisplay> x_display_;
|
scoped_refptr<SharedXDisplay> x_display_;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
|
||||||
|
scoped_refptr<DesktopConfigurationMonitor> configuration_monitor_;
|
||||||
|
#endif
|
||||||
bool use_update_notifications_;
|
bool use_update_notifications_;
|
||||||
bool disable_effects_;
|
bool disable_effects_;
|
||||||
};
|
};
|
||||||
|
@ -52,6 +52,9 @@ struct MacDesktopConfiguration {
|
|||||||
// increase as you move up the screen) or Carbon-style "top-down" coordinates.
|
// increase as you move up the screen) or Carbon-style "top-down" coordinates.
|
||||||
static MacDesktopConfiguration GetCurrent(Origin origin);
|
static MacDesktopConfiguration GetCurrent(Origin origin);
|
||||||
|
|
||||||
|
// Returns true if the given desktop configuration equals this one.
|
||||||
|
bool Equals(const MacDesktopConfiguration& other);
|
||||||
|
|
||||||
// Bounds of the desktop in Density-Independent Pixels (DIPs).
|
// Bounds of the desktop in Density-Independent Pixels (DIPs).
|
||||||
DesktopRect bounds;
|
DesktopRect bounds;
|
||||||
|
|
||||||
|
@ -143,4 +143,22 @@ MacDesktopConfiguration MacDesktopConfiguration::GetCurrent(Origin origin) {
|
|||||||
return desktop_config;
|
return desktop_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// For convenience of comparing MacDisplayConfigurations in
|
||||||
|
// MacDesktopConfiguration::Equals.
|
||||||
|
bool operator==(const MacDisplayConfiguration& left,
|
||||||
|
const MacDisplayConfiguration& right) {
|
||||||
|
return left.id == right.id &&
|
||||||
|
left.bounds.equals(right.bounds) &&
|
||||||
|
left.pixel_bounds.equals(right.pixel_bounds) &&
|
||||||
|
left.dip_to_pixel_scale == right.dip_to_pixel_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacDesktopConfiguration::Equals(const MacDesktopConfiguration& other) {
|
||||||
|
return bounds.equals(other.bounds) &&
|
||||||
|
pixel_bounds.equals(other.pixel_bounds) &&
|
||||||
|
dip_to_pixel_scale == other.dip_to_pixel_scale &&
|
||||||
|
displays == other.displays;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h"
|
||||||
|
|
||||||
|
#include "webrtc/modules/desktop_capture/mac/desktop_configuration.h"
|
||||||
|
#include "webrtc/system_wrappers/interface/event_wrapper.h"
|
||||||
|
#include "webrtc/system_wrappers/interface/logging.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
// The amount of time allowed for displays to reconfigure.
|
||||||
|
static const int64_t kDisplayConfigurationEventTimeoutMs = 10 * 1000;
|
||||||
|
|
||||||
|
DesktopConfigurationMonitor::DesktopConfigurationMonitor()
|
||||||
|
: ref_count_(0),
|
||||||
|
display_configuration_capture_event_(EventWrapper::Create()) {
|
||||||
|
CGError err = CGDisplayRegisterReconfigurationCallback(
|
||||||
|
DesktopConfigurationMonitor::DisplaysReconfiguredCallback, this);
|
||||||
|
if (err != kCGErrorSuccess) {
|
||||||
|
LOG(LS_ERROR) << "CGDisplayRegisterReconfigurationCallback " << err;
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
display_configuration_capture_event_->Set();
|
||||||
|
|
||||||
|
desktop_configuration_ = MacDesktopConfiguration::GetCurrent(
|
||||||
|
MacDesktopConfiguration::TopLeftOrigin);
|
||||||
|
}
|
||||||
|
|
||||||
|
DesktopConfigurationMonitor::~DesktopConfigurationMonitor() {
|
||||||
|
CGError err = CGDisplayRemoveReconfigurationCallback(
|
||||||
|
DesktopConfigurationMonitor::DisplaysReconfiguredCallback, this);
|
||||||
|
if (err != kCGErrorSuccess)
|
||||||
|
LOG(LS_ERROR) << "CGDisplayRemoveReconfigurationCallback " << err;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopConfigurationMonitor::Lock() {
|
||||||
|
if (!display_configuration_capture_event_->Wait(
|
||||||
|
kDisplayConfigurationEventTimeoutMs)) {
|
||||||
|
LOG_F(LS_ERROR) << "Event wait timed out.";
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopConfigurationMonitor::Unlock() {
|
||||||
|
display_configuration_capture_event_->Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void DesktopConfigurationMonitor::DisplaysReconfiguredCallback(
|
||||||
|
CGDirectDisplayID display,
|
||||||
|
CGDisplayChangeSummaryFlags flags,
|
||||||
|
void *user_parameter) {
|
||||||
|
DesktopConfigurationMonitor* monitor =
|
||||||
|
reinterpret_cast<DesktopConfigurationMonitor*>(user_parameter);
|
||||||
|
monitor->DisplaysReconfigured(display, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopConfigurationMonitor::DisplaysReconfigured(
|
||||||
|
CGDirectDisplayID display,
|
||||||
|
CGDisplayChangeSummaryFlags flags) {
|
||||||
|
if (flags & kCGDisplayBeginConfigurationFlag) {
|
||||||
|
if (reconfiguring_displays_.empty()) {
|
||||||
|
// If this is the first display to start reconfiguring then wait on
|
||||||
|
// |display_configuration_capture_event_| to block the capture thread
|
||||||
|
// from accessing display memory until the reconfiguration completes.
|
||||||
|
if (!display_configuration_capture_event_->Wait(
|
||||||
|
kDisplayConfigurationEventTimeoutMs)) {
|
||||||
|
LOG_F(LS_ERROR) << "Event wait timed out.";
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reconfiguring_displays_.insert(display);
|
||||||
|
} else {
|
||||||
|
reconfiguring_displays_.erase(display);
|
||||||
|
if (reconfiguring_displays_.empty()) {
|
||||||
|
desktop_configuration_ = MacDesktopConfiguration::GetCurrent(
|
||||||
|
MacDesktopConfiguration::TopLeftOrigin);
|
||||||
|
display_configuration_capture_event_->Set();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_MAC_DESKTOP_CONFIGURATION_MONITOR_H_
|
||||||
|
#define WEBRTC_MODULES_DESKTOP_CAPTURE_MAC_DESKTOP_CONFIGURATION_MONITOR_H_
|
||||||
|
|
||||||
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "webrtc/modules/desktop_capture/mac/desktop_configuration.h"
|
||||||
|
#include "webrtc/system_wrappers/interface/atomic32.h"
|
||||||
|
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
class EventWrapper;
|
||||||
|
|
||||||
|
// The class provides functions to synchronize capturing and display
|
||||||
|
// reconfiguring across threads, and the up-to-date MacDesktopConfiguration.
|
||||||
|
class DesktopConfigurationMonitor {
|
||||||
|
public:
|
||||||
|
DesktopConfigurationMonitor();
|
||||||
|
// Acquires a lock on the current configuration.
|
||||||
|
void Lock();
|
||||||
|
// Releases the lock previously acquired.
|
||||||
|
void Unlock();
|
||||||
|
// Returns the current desktop configuration. Should only be called when the
|
||||||
|
// lock has been acquired.
|
||||||
|
const MacDesktopConfiguration& desktop_configuration() {
|
||||||
|
return desktop_configuration_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddRef() { ++ref_count_; }
|
||||||
|
void Release() {
|
||||||
|
if (--ref_count_ == 0)
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void DisplaysReconfiguredCallback(CGDirectDisplayID display,
|
||||||
|
CGDisplayChangeSummaryFlags flags,
|
||||||
|
void *user_parameter);
|
||||||
|
~DesktopConfigurationMonitor();
|
||||||
|
|
||||||
|
void DisplaysReconfigured(CGDirectDisplayID display,
|
||||||
|
CGDisplayChangeSummaryFlags flags);
|
||||||
|
|
||||||
|
Atomic32 ref_count_;
|
||||||
|
std::set<CGDirectDisplayID> reconfiguring_displays_;
|
||||||
|
MacDesktopConfiguration desktop_configuration_;
|
||||||
|
scoped_ptr<EventWrapper> display_configuration_capture_event_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(DesktopConfigurationMonitor);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_MAC_DESKTOP_CONFIGURATION_MONITOR_H_
|
@ -26,11 +26,11 @@
|
|||||||
#include "webrtc/modules/desktop_capture/desktop_geometry.h"
|
#include "webrtc/modules/desktop_capture/desktop_geometry.h"
|
||||||
#include "webrtc/modules/desktop_capture/desktop_region.h"
|
#include "webrtc/modules/desktop_capture/desktop_region.h"
|
||||||
#include "webrtc/modules/desktop_capture/mac/desktop_configuration.h"
|
#include "webrtc/modules/desktop_capture/mac/desktop_configuration.h"
|
||||||
|
#include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h"
|
||||||
#include "webrtc/modules/desktop_capture/mac/scoped_pixel_buffer_object.h"
|
#include "webrtc/modules/desktop_capture/mac/scoped_pixel_buffer_object.h"
|
||||||
#include "webrtc/modules/desktop_capture/mouse_cursor_shape.h"
|
#include "webrtc/modules/desktop_capture/mouse_cursor_shape.h"
|
||||||
#include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h"
|
#include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h"
|
||||||
#include "webrtc/modules/desktop_capture/screen_capturer_helper.h"
|
#include "webrtc/modules/desktop_capture/screen_capturer_helper.h"
|
||||||
#include "webrtc/system_wrappers/interface/event_wrapper.h"
|
|
||||||
#include "webrtc/system_wrappers/interface/logging.h"
|
#include "webrtc/system_wrappers/interface/logging.h"
|
||||||
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
|
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
|
||||||
#include "webrtc/system_wrappers/interface/tick_util.h"
|
#include "webrtc/system_wrappers/interface/tick_util.h"
|
||||||
@ -120,13 +120,11 @@ bool IsOSLionOrLater() {
|
|||||||
return darwin_version >= 11;
|
return darwin_version >= 11;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The amount of time allowed for displays to reconfigure.
|
|
||||||
const int64_t kDisplayConfigurationEventTimeoutMs = 10 * 1000;
|
|
||||||
|
|
||||||
// A class to perform video frame capturing for mac.
|
// A class to perform video frame capturing for mac.
|
||||||
class ScreenCapturerMac : public ScreenCapturer {
|
class ScreenCapturerMac : public ScreenCapturer {
|
||||||
public:
|
public:
|
||||||
ScreenCapturerMac();
|
explicit ScreenCapturerMac(
|
||||||
|
scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor);
|
||||||
virtual ~ScreenCapturerMac();
|
virtual ~ScreenCapturerMac();
|
||||||
|
|
||||||
bool Init();
|
bool Init();
|
||||||
@ -160,8 +158,6 @@ class ScreenCapturerMac : public ScreenCapturer {
|
|||||||
void ScreenUpdateMove(CGScreenUpdateMoveDelta delta,
|
void ScreenUpdateMove(CGScreenUpdateMoveDelta delta,
|
||||||
size_t count,
|
size_t count,
|
||||||
const CGRect *rect_array);
|
const CGRect *rect_array);
|
||||||
void DisplaysReconfigured(CGDirectDisplayID display,
|
|
||||||
CGDisplayChangeSummaryFlags flags);
|
|
||||||
static void ScreenRefreshCallback(CGRectCount count,
|
static void ScreenRefreshCallback(CGRectCount count,
|
||||||
const CGRect *rect_array,
|
const CGRect *rect_array,
|
||||||
void *user_parameter);
|
void *user_parameter);
|
||||||
@ -169,10 +165,6 @@ class ScreenCapturerMac : public ScreenCapturer {
|
|||||||
size_t count,
|
size_t count,
|
||||||
const CGRect *rect_array,
|
const CGRect *rect_array,
|
||||||
void *user_parameter);
|
void *user_parameter);
|
||||||
static void DisplaysReconfiguredCallback(CGDirectDisplayID display,
|
|
||||||
CGDisplayChangeSummaryFlags flags,
|
|
||||||
void *user_parameter);
|
|
||||||
|
|
||||||
void ReleaseBuffers();
|
void ReleaseBuffers();
|
||||||
|
|
||||||
Callback* callback_;
|
Callback* callback_;
|
||||||
@ -184,9 +176,6 @@ class ScreenCapturerMac : public ScreenCapturer {
|
|||||||
// Queue of the frames buffers.
|
// Queue of the frames buffers.
|
||||||
ScreenCaptureFrameQueue queue_;
|
ScreenCaptureFrameQueue queue_;
|
||||||
|
|
||||||
// Current display configuration.
|
|
||||||
MacDesktopConfiguration desktop_config_;
|
|
||||||
|
|
||||||
// A thread-safe list of invalid rectangles, and the size of the most
|
// A thread-safe list of invalid rectangles, and the size of the most
|
||||||
// recently captured screen.
|
// recently captured screen.
|
||||||
ScreenCapturerHelper helper_;
|
ScreenCapturerHelper helper_;
|
||||||
@ -197,13 +186,12 @@ class ScreenCapturerMac : public ScreenCapturer {
|
|||||||
// Contains an invalid region from the previous capture.
|
// Contains an invalid region from the previous capture.
|
||||||
DesktopRegion last_invalid_region_;
|
DesktopRegion last_invalid_region_;
|
||||||
|
|
||||||
// Used to ensure that frame captures do not take place while displays
|
// Monitoring display reconfiguration.
|
||||||
// are being reconfigured.
|
scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor_;
|
||||||
scoped_ptr<EventWrapper> display_configuration_capture_event_;
|
|
||||||
|
|
||||||
// Records the Ids of attached displays which are being reconfigured.
|
// The desktop configuration obtained from desktop_config_monitor_ the last
|
||||||
// Accessed on the thread on which we are notified of display events.
|
// time of capturing.
|
||||||
std::set<CGDirectDisplayID> reconfiguring_displays_;
|
MacDesktopConfiguration desktop_config_;
|
||||||
|
|
||||||
// Power management assertion to prevent the screen from sleeping.
|
// Power management assertion to prevent the screen from sleeping.
|
||||||
IOPMAssertionID power_assertion_id_display_;
|
IOPMAssertionID power_assertion_id_display_;
|
||||||
@ -258,11 +246,12 @@ DesktopFrame* CreateFrame(
|
|||||||
return frame.release();
|
return frame.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenCapturerMac::ScreenCapturerMac()
|
ScreenCapturerMac::ScreenCapturerMac(
|
||||||
|
scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor)
|
||||||
: callback_(NULL),
|
: callback_(NULL),
|
||||||
mouse_shape_observer_(NULL),
|
mouse_shape_observer_(NULL),
|
||||||
cgl_context_(NULL),
|
cgl_context_(NULL),
|
||||||
display_configuration_capture_event_(EventWrapper::Create()),
|
desktop_config_monitor_(desktop_config_monitor),
|
||||||
power_assertion_id_display_(kIOPMNullAssertionID),
|
power_assertion_id_display_(kIOPMNullAssertionID),
|
||||||
power_assertion_id_user_(kIOPMNullAssertionID),
|
power_assertion_id_user_(kIOPMNullAssertionID),
|
||||||
app_services_library_(NULL),
|
app_services_library_(NULL),
|
||||||
@ -271,7 +260,6 @@ ScreenCapturerMac::ScreenCapturerMac()
|
|||||||
cg_display_bits_per_pixel_(NULL),
|
cg_display_bits_per_pixel_(NULL),
|
||||||
opengl_library_(NULL),
|
opengl_library_(NULL),
|
||||||
cgl_set_full_screen_(NULL) {
|
cgl_set_full_screen_(NULL) {
|
||||||
display_configuration_capture_event_->Set();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenCapturerMac::~ScreenCapturerMac() {
|
ScreenCapturerMac::~ScreenCapturerMac() {
|
||||||
@ -286,11 +274,6 @@ ScreenCapturerMac::~ScreenCapturerMac() {
|
|||||||
|
|
||||||
ReleaseBuffers();
|
ReleaseBuffers();
|
||||||
UnregisterRefreshAndMoveHandlers();
|
UnregisterRefreshAndMoveHandlers();
|
||||||
CGError err = CGDisplayRemoveReconfigurationCallback(
|
|
||||||
ScreenCapturerMac::DisplaysReconfiguredCallback, this);
|
|
||||||
if (err != kCGErrorSuccess)
|
|
||||||
LOG(LS_ERROR) << "CGDisplayRemoveReconfigurationCallback " << err;
|
|
||||||
|
|
||||||
dlclose(app_services_library_);
|
dlclose(app_services_library_);
|
||||||
dlclose(opengl_library_);
|
dlclose(opengl_library_);
|
||||||
}
|
}
|
||||||
@ -299,14 +282,6 @@ bool ScreenCapturerMac::Init() {
|
|||||||
if (!RegisterRefreshAndMoveHandlers()) {
|
if (!RegisterRefreshAndMoveHandlers()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGError err = CGDisplayRegisterReconfigurationCallback(
|
|
||||||
ScreenCapturerMac::DisplaysReconfiguredCallback, this);
|
|
||||||
if (err != kCGErrorSuccess) {
|
|
||||||
LOG(LS_ERROR) << "CGDisplayRegisterReconfigurationCallback " << err;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScreenConfigurationChanged();
|
ScreenConfigurationChanged();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -351,14 +326,17 @@ void ScreenCapturerMac::Capture(
|
|||||||
|
|
||||||
queue_.MoveToNextFrame();
|
queue_.MoveToNextFrame();
|
||||||
|
|
||||||
// Wait until the display configuration is stable. If one or more displays
|
desktop_config_monitor_->Lock();
|
||||||
// are reconfiguring then |display_configuration_capture_event_| will not be
|
MacDesktopConfiguration new_config =
|
||||||
// set until the reconfiguration completes.
|
desktop_config_monitor_->desktop_configuration();
|
||||||
// TODO(wez): Replace this with an early-exit (See crbug.com/104542).
|
if (!desktop_config_.Equals(new_config)) {
|
||||||
if (!display_configuration_capture_event_->Wait(
|
desktop_config_ = new_config;
|
||||||
kDisplayConfigurationEventTimeoutMs)) {
|
// If the display configuraiton has changed then refresh capturer data
|
||||||
LOG_F(LS_ERROR) << "Event wait timed out.";
|
// structures. Occasionally, the refresh and move handlers are lost when
|
||||||
abort();
|
// the screen mode changes, so re-register them here.
|
||||||
|
UnregisterRefreshAndMoveHandlers();
|
||||||
|
RegisterRefreshAndMoveHandlers();
|
||||||
|
ScreenConfigurationChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
DesktopRegion region;
|
DesktopRegion region;
|
||||||
@ -400,7 +378,7 @@ void ScreenCapturerMac::Capture(
|
|||||||
|
|
||||||
// Signal that we are done capturing data from the display framebuffer,
|
// Signal that we are done capturing data from the display framebuffer,
|
||||||
// and accessing display structures.
|
// and accessing display structures.
|
||||||
display_configuration_capture_event_->Set();
|
desktop_config_monitor_->Unlock();
|
||||||
|
|
||||||
// Capture the current cursor shape and notify |callback_| if it has changed.
|
// Capture the current cursor shape and notify |callback_| if it has changed.
|
||||||
CaptureCursor();
|
CaptureCursor();
|
||||||
@ -693,14 +671,8 @@ void ScreenCapturerMac::ScreenConfigurationChanged() {
|
|||||||
// Clear the dirty region, in case the display is down-sizing.
|
// Clear the dirty region, in case the display is down-sizing.
|
||||||
helper_.ClearInvalidRegion();
|
helper_.ClearInvalidRegion();
|
||||||
|
|
||||||
// Refresh the cached desktop configuration.
|
|
||||||
desktop_config_ = MacDesktopConfiguration::GetCurrent(
|
|
||||||
MacDesktopConfiguration::TopLeftOrigin);
|
|
||||||
|
|
||||||
// Re-mark the entire desktop as dirty.
|
// Re-mark the entire desktop as dirty.
|
||||||
helper_.InvalidateScreen(
|
helper_.InvalidateScreen(desktop_config_.pixel_bounds.size());
|
||||||
DesktopSize(desktop_config_.pixel_bounds.width(),
|
|
||||||
desktop_config_.pixel_bounds.height()));
|
|
||||||
|
|
||||||
// Make sure the frame buffers will be reallocated.
|
// Make sure the frame buffers will be reallocated.
|
||||||
queue_.Reset();
|
queue_.Reset();
|
||||||
@ -847,39 +819,6 @@ void ScreenCapturerMac::ScreenUpdateMove(CGScreenUpdateMoveDelta delta,
|
|||||||
ScreenRefresh(count, refresh_rects);
|
ScreenRefresh(count, refresh_rects);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenCapturerMac::DisplaysReconfigured(
|
|
||||||
CGDirectDisplayID display,
|
|
||||||
CGDisplayChangeSummaryFlags flags) {
|
|
||||||
if (flags & kCGDisplayBeginConfigurationFlag) {
|
|
||||||
if (reconfiguring_displays_.empty()) {
|
|
||||||
// If this is the first display to start reconfiguring then wait on
|
|
||||||
// |display_configuration_capture_event_| to block the capture thread
|
|
||||||
// from accessing display memory until the reconfiguration completes.
|
|
||||||
if (!display_configuration_capture_event_->Wait(
|
|
||||||
kDisplayConfigurationEventTimeoutMs)) {
|
|
||||||
LOG_F(LS_ERROR) << "Event wait timed out.";
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reconfiguring_displays_.insert(display);
|
|
||||||
} else {
|
|
||||||
reconfiguring_displays_.erase(display);
|
|
||||||
|
|
||||||
if (reconfiguring_displays_.empty()) {
|
|
||||||
// If no other displays are reconfiguring then refresh capturer data
|
|
||||||
// structures and un-block the capturer thread. Occasionally, the
|
|
||||||
// refresh and move handlers are lost when the screen mode changes,
|
|
||||||
// so re-register them here (the same does not appear to be true for
|
|
||||||
// the reconfiguration handler itself).
|
|
||||||
UnregisterRefreshAndMoveHandlers();
|
|
||||||
RegisterRefreshAndMoveHandlers();
|
|
||||||
ScreenConfigurationChanged();
|
|
||||||
display_configuration_capture_event_->Set();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScreenCapturerMac::ScreenRefreshCallback(CGRectCount count,
|
void ScreenCapturerMac::ScreenRefreshCallback(CGRectCount count,
|
||||||
const CGRect* rect_array,
|
const CGRect* rect_array,
|
||||||
void* user_parameter) {
|
void* user_parameter) {
|
||||||
@ -900,20 +839,15 @@ void ScreenCapturerMac::ScreenUpdateMoveCallback(
|
|||||||
capturer->ScreenUpdateMove(delta, count, rect_array);
|
capturer->ScreenUpdateMove(delta, count, rect_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenCapturerMac::DisplaysReconfiguredCallback(
|
|
||||||
CGDirectDisplayID display,
|
|
||||||
CGDisplayChangeSummaryFlags flags,
|
|
||||||
void* user_parameter) {
|
|
||||||
ScreenCapturerMac* capturer =
|
|
||||||
reinterpret_cast<ScreenCapturerMac*>(user_parameter);
|
|
||||||
capturer->DisplaysReconfigured(display, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ScreenCapturer* ScreenCapturer::Create(const DesktopCaptureOptions& options) {
|
ScreenCapturer* ScreenCapturer::Create(const DesktopCaptureOptions& options) {
|
||||||
scoped_ptr<ScreenCapturerMac> capturer(new ScreenCapturerMac());
|
if (!options.configuration_monitor())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
scoped_ptr<ScreenCapturerMac> capturer(
|
||||||
|
new ScreenCapturerMac(options.configuration_monitor()));
|
||||||
if (!capturer->Init())
|
if (!capturer->Init())
|
||||||
capturer.reset();
|
capturer.reset();
|
||||||
return capturer.release();
|
return capturer.release();
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#ifndef SYSTEM_WRAPPERS_INTERFACE_SCOPED_REFPTR_H_
|
#ifndef SYSTEM_WRAPPERS_INTERFACE_SCOPED_REFPTR_H_
|
||||||
#define SYSTEM_WRAPPERS_INTERFACE_SCOPED_REFPTR_H_
|
#define SYSTEM_WRAPPERS_INTERFACE_SCOPED_REFPTR_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
// Extracted from Chromium's src/base/memory/ref_counted.h.
|
// Extracted from Chromium's src/base/memory/ref_counted.h.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user