Implement single monitor capture on Mac.
BUG=2787, 2824
TESTED=MacBook Pro Retina with an external monitor; verified changing display configuration while capturing; add/remove monitor while capturing; verified cursor position.
R=sergeyu@chromium.org
Review URL: https://webrtc-codereview.appspot.com/7479004
git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@5471 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/modules/desktop_capture/desktop_capture.gypi b/modules/desktop_capture/desktop_capture.gypi
index 7834d21..9463257 100644
--- a/modules/desktop_capture/desktop_capture.gypi
+++ b/modules/desktop_capture/desktop_capture.gypi
@@ -38,6 +38,8 @@
"mac/desktop_configuration.mm",
"mac/desktop_configuration_monitor.h",
"mac/desktop_configuration_monitor.cc",
+ "mac/osx_version.h",
+ "mac/osx_version.cc",
"mac/scoped_pixel_buffer_object.cc",
"mac/scoped_pixel_buffer_object.h",
"mouse_cursor.cc",
diff --git a/modules/desktop_capture/desktop_capture_types.h b/modules/desktop_capture/desktop_capture_types.h
index 0ad199c..3e41796 100644
--- a/modules/desktop_capture/desktop_capture_types.h
+++ b/modules/desktop_capture/desktop_capture_types.h
@@ -26,7 +26,11 @@
const WindowId kNullWindowId = 0;
-typedef int ScreenId;
+// Type used to identify screens on the desktop. Values are platform-specific:
+// - On Windows: integer display device index.
+// - On OSX: CGDirectDisplayID cast to intptr_t.
+// - On Linux (with X11): TBD.
+typedef intptr_t ScreenId;
// The screen id corresponds to all screen combined together.
const ScreenId kFullDesktopScreenId = -1;
diff --git a/modules/desktop_capture/mac/desktop_configuration.h b/modules/desktop_capture/mac/desktop_configuration.h
index 80a155d..031d92d 100644
--- a/modules/desktop_capture/mac/desktop_configuration.h
+++ b/modules/desktop_capture/mac/desktop_configuration.h
@@ -55,6 +55,10 @@
// Returns true if the given desktop configuration equals this one.
bool Equals(const MacDesktopConfiguration& other);
+ // Returns the pointer to the display configuration with the specified id.
+ const MacDisplayConfiguration* FindDisplayConfigurationById(
+ CGDirectDisplayID id);
+
// Bounds of the desktop in Density-Independent Pixels (DIPs).
DesktopRect bounds;
diff --git a/modules/desktop_capture/mac/desktop_configuration.mm b/modules/desktop_capture/mac/desktop_configuration.mm
index 5dac409..838973e 100644
--- a/modules/desktop_capture/mac/desktop_configuration.mm
+++ b/modules/desktop_capture/mac/desktop_configuration.mm
@@ -110,15 +110,8 @@
MacDisplayConfiguration display_config =
GetConfigurationForScreen([screens objectAtIndex: i]);
- // Handling mixed-DPI is hard, so we only return displays that match the
- // "primary" display's DPI. The primary display is always the first in the
- // list returned by [NSScreen screens].
- if (i == 0) {
+ if (i == 0)
desktop_config.dip_to_pixel_scale = display_config.dip_to_pixel_scale;
- } else if (desktop_config.dip_to_pixel_scale !=
- display_config.dip_to_pixel_scale) {
- continue;
- }
// Cocoa uses bottom-up coordinates, so if the caller wants top-down then
// we need to invert the positions of secondary monitors relative to the
@@ -126,8 +119,16 @@
if (i > 0 && origin == TopLeftOrigin) {
InvertRectYOrigin(desktop_config.displays[0].bounds,
&display_config.bounds);
- InvertRectYOrigin(desktop_config.displays[0].pixel_bounds,
- &display_config.pixel_bounds);
+ // |display_bounds| is density dependent, so we need to convert the
+ // primay monitor's position into the secondary monitor's density context.
+ float scaling_factor = display_config.dip_to_pixel_scale /
+ desktop_config.displays[0].dip_to_pixel_scale;
+ DesktopRect primary_bounds = DesktopRect::MakeLTRB(
+ desktop_config.displays[0].pixel_bounds.left() * scaling_factor,
+ desktop_config.displays[0].pixel_bounds.top() * scaling_factor,
+ desktop_config.displays[0].pixel_bounds.right() * scaling_factor,
+ desktop_config.displays[0].pixel_bounds.bottom() * scaling_factor);
+ InvertRectYOrigin(primary_bounds, &display_config.pixel_bounds);
}
// Add the display to the configuration.
@@ -143,7 +144,6 @@
return desktop_config;
}
-
// For convenience of comparing MacDisplayConfigurations in
// MacDesktopConfiguration::Equals.
bool operator==(const MacDisplayConfiguration& left,
@@ -161,4 +161,16 @@
displays == other.displays;
}
+// Finds the display configuration with the specified id.
+const MacDisplayConfiguration*
+MacDesktopConfiguration::FindDisplayConfigurationById(
+ CGDirectDisplayID id) {
+ for (MacDisplayConfigurations::const_iterator it = displays.begin();
+ it != displays.end(); ++it) {
+ if (it->id == id)
+ return &(*it);
+ }
+ return NULL;
+}
+
} // namespace webrtc
diff --git a/modules/desktop_capture/mac/osx_version.cc b/modules/desktop_capture/mac/osx_version.cc
new file mode 100644
index 0000000..7466f20
--- /dev/null
+++ b/modules/desktop_capture/mac/osx_version.cc
@@ -0,0 +1,54 @@
+/*
+ * 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 <sys/utsname.h>
+
+#include "webrtc/system_wrappers/interface/logging.h"
+
+namespace webrtc {
+
+namespace {
+
+int GetDarwinVersion() {
+ struct utsname uname_info;
+ if (uname(&uname_info) != 0) {
+ LOG(LS_ERROR) << "uname failed";
+ return 0;
+ }
+
+ if (strcmp(uname_info.sysname, "Darwin") != 0)
+ return 0;
+
+ char* dot;
+ int result = strtol(uname_info.release, &dot, 10);
+ if (*dot != '.') {
+ LOG(LS_ERROR) << "Failed to parse version";
+ return 0;
+ }
+
+ return result;
+}
+
+} // namespace
+
+bool IsOSLionOrLater() {
+ static int darwin_version = GetDarwinVersion();
+
+ // Verify that the version has been parsed correctly.
+ if (darwin_version < 6) {
+ LOG_F(LS_ERROR) << "Invalid Darwin version: " << darwin_version;
+ abort();
+ }
+
+ // Darwin major version 11 corresponds to OSX 10.7.
+ return darwin_version >= 11;
+}
+
+} // namespace webrtc
diff --git a/modules/desktop_capture/mac/osx_version.h b/modules/desktop_capture/mac/osx_version.h
new file mode 100644
index 0000000..0ba49a4
--- /dev/null
+++ b/modules/desktop_capture/mac/osx_version.h
@@ -0,0 +1,16 @@
+/*
+ * 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.
+ */
+
+namespace webrtc {
+
+// Returns true if the OS version >= OSX 10.7.
+bool IsOSLionOrLater();
+
+} // namespace webrtc
diff --git a/modules/desktop_capture/mouse_cursor_monitor_mac.mm b/modules/desktop_capture/mouse_cursor_monitor_mac.mm
index 25d7e7a..e880633 100644
--- a/modules/desktop_capture/mouse_cursor_monitor_mac.mm
+++ b/modules/desktop_capture/mouse_cursor_monitor_mac.mm
@@ -17,8 +17,11 @@
#include "webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "webrtc/modules/desktop_capture/desktop_frame.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/osx_version.h"
#include "webrtc/modules/desktop_capture/mouse_cursor.h"
+#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/system_wrappers/interface/scoped_refptr.h"
@@ -27,31 +30,44 @@
class MouseCursorMonitorMac : public MouseCursorMonitor {
public:
MouseCursorMonitorMac(const DesktopCaptureOptions& options,
- CGWindowID window_id);
+ CGWindowID window_id,
+ ScreenId screen_id);
virtual ~MouseCursorMonitorMac();
virtual void Init(Callback* callback, Mode mode) OVERRIDE;
virtual void Capture() OVERRIDE;
private:
+ static void DisplaysReconfiguredCallback(CGDirectDisplayID display,
+ CGDisplayChangeSummaryFlags flags,
+ void *user_parameter);
+ void DisplaysReconfigured(CGDirectDisplayID display,
+ CGDisplayChangeSummaryFlags flags);
+
void CaptureImage();
scoped_refptr<DesktopConfigurationMonitor> configuration_monitor_;
CGWindowID window_id_;
-
+ ScreenId screen_id_;
Callback* callback_;
Mode mode_;
-
scoped_ptr<MouseCursor> last_cursor_;
};
MouseCursorMonitorMac::MouseCursorMonitorMac(
const DesktopCaptureOptions& options,
- CGWindowID window_id)
+ CGWindowID window_id,
+ ScreenId screen_id)
: configuration_monitor_(options.configuration_monitor()),
window_id_(window_id),
+ screen_id_(screen_id),
callback_(NULL),
mode_(SHAPE_AND_POSITION) {
+ assert(window_id == kCGNullWindowID || screen_id == kInvalidScreenId);
+ if (screen_id != kInvalidScreenId && !IsOSLionOrLater()) {
+ // Single screen capture is not supported on pre OS X 10.7.
+ screen_id_ = kFullDesktopScreenId;
+ }
}
MouseCursorMonitorMac::~MouseCursorMonitorMac() {}
@@ -80,6 +96,21 @@
DesktopVector position(gc_position.x, gc_position.y);
+ configuration_monitor_->Lock();
+ MacDesktopConfiguration configuration =
+ configuration_monitor_->desktop_configuration();
+ configuration_monitor_->Unlock();
+ float scale = 1.0f;
+
+ // Find the dpi to physical pixel scale for the screen where the mouse cursor
+ // is.
+ for (MacDisplayConfigurations::iterator it = configuration.displays.begin();
+ it != configuration.displays.end(); ++it) {
+ if (it->bounds.Contains(position)) {
+ scale = it->dip_to_pixel_scale;
+ break;
+ }
+ }
// If we are capturing cursor for a specific window then we need to figure out
// if the current mouse position is covered by another window and also adjust
// |position| to make it relative to the window origin.
@@ -142,10 +173,8 @@
}
}
}
-
CFRelease(window_array);
}
-
if (!found_window) {
// If we failed to get list of windows or the window wasn't in the list
// pretend that the cursor is outside the window. This can happen, e.g. if
@@ -153,17 +182,32 @@
state = OUTSIDE;
position.set(-1, -1);
}
+ } else {
+ assert(screen_id_ >= kFullDesktopScreenId);
+ if (screen_id_ != kFullDesktopScreenId) {
+ // For single screen capturing, convert the position to relative to the
+ // target screen.
+ const MacDisplayConfiguration* config =
+ configuration.FindDisplayConfigurationById(
+ static_cast<CGDirectDisplayID>(screen_id_));
+ if (config) {
+ if (!config->pixel_bounds.Contains(position))
+ state = OUTSIDE;
+ position = position.subtract(config->bounds.top_left());
+ } else {
+ // The target screen is no longer valid.
+ state = OUTSIDE;
+ position.set(-1, -1);
+ }
+ } else {
+ position.subtract(configuration.bounds.top_left());
+ }
}
-
- // Convert Density Independent Pixel to physical pixel.
- configuration_monitor_->Lock();
- float scale =
- configuration_monitor_->desktop_configuration().dip_to_pixel_scale;
- configuration_monitor_->Unlock();
-
- position = DesktopVector(round(position.x() * scale),
- round(position.y() * scale));
-
+ if (state == INSIDE) {
+ // Convert Density Independent Pixel to physical pixel.
+ position = DesktopVector(round(position.x() * scale),
+ round(position.y() * scale));
+ }
callback_->OnMouseCursorPosition(state, position);
}
@@ -221,16 +265,15 @@
callback_->OnMouseCursor(cursor.release());
}
-
MouseCursorMonitor* MouseCursorMonitor::CreateForWindow(
const DesktopCaptureOptions& options, WindowId window) {
- return new MouseCursorMonitorMac(options, window);
+ return new MouseCursorMonitorMac(options, window, kInvalidScreenId);
}
MouseCursorMonitor* MouseCursorMonitor::CreateForScreen(
const DesktopCaptureOptions& options,
ScreenId screen) {
- return new MouseCursorMonitorMac(options, kCGNullWindowID);
+ return new MouseCursorMonitorMac(options, kCGNullWindowID, screen);
}
} // namespace webrtc
diff --git a/modules/desktop_capture/screen_capturer_mac.mm b/modules/desktop_capture/screen_capturer_mac.mm
index 46118dd..100309f 100644
--- a/modules/desktop_capture/screen_capturer_mac.mm
+++ b/modules/desktop_capture/screen_capturer_mac.mm
@@ -19,7 +19,6 @@
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <OpenGL/CGLMacro.h>
#include <OpenGL/OpenGL.h>
-#include <sys/utsname.h>
#include "webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "webrtc/modules/desktop_capture/desktop_frame.h"
@@ -27,6 +26,7 @@
#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_monitor.h"
+#include "webrtc/modules/desktop_capture/mac/osx_version.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/screen_capture_frame_queue.h"
@@ -87,39 +87,6 @@
}
}
-int GetDarwinVersion() {
- struct utsname uname_info;
- if (uname(&uname_info) != 0) {
- LOG(LS_ERROR) << "uname failed";
- return 0;
- }
-
- if (strcmp(uname_info.sysname, "Darwin") != 0)
- return 0;
-
- char* dot;
- int result = strtol(uname_info.release, &dot, 10);
- if (*dot != '.') {
- LOG(LS_ERROR) << "Failed to parse version";
- return 0;
- }
-
- return result;
-}
-
-bool IsOSLionOrLater() {
- static int darwin_version = GetDarwinVersion();
-
- // Verify that the version has been parsed correctly.
- if (darwin_version < 6) {
- LOG_F(LS_ERROR) << "Invalid Darwin version: " << darwin_version;
- abort();
- }
-
- // Darwin major version 11 corresponds to OSX 10.7.
- return darwin_version >= 11;
-}
-
// A class to perform video frame capturing for mac.
class ScreenCapturerMac : public ScreenCapturer {
public:
@@ -145,7 +112,8 @@
void GlBlitSlow(const DesktopFrame& frame);
void CgBlitPreLion(const DesktopFrame& frame,
const DesktopRegion& region);
- void CgBlitPostLion(const DesktopFrame& frame,
+ // Returns false if the selected screen is no longer valid.
+ bool CgBlitPostLion(const DesktopFrame& frame,
const DesktopRegion& region);
// Called when the screen configuration is changed.
@@ -167,6 +135,8 @@
void *user_parameter);
void ReleaseBuffers();
+ DesktopFrame* CreateFrame();
+
Callback* callback_;
MouseShapeObserver* mouse_shape_observer_;
@@ -176,6 +146,19 @@
// Queue of the frames buffers.
ScreenCaptureFrameQueue queue_;
+ // Current display configuration.
+ MacDesktopConfiguration desktop_config_;
+
+ // Currently selected display, or 0 if the full desktop is selected. On OS X
+ // 10.6 and before, this is always 0.
+ CGDirectDisplayID current_display_;
+
+ // The physical pixel bounds of the current screen.
+ DesktopRect screen_pixel_bounds_;
+
+ // The dip to physical pixel scale of the current screen.
+ float dip_to_pixel_scale_;
+
// A thread-safe list of invalid rectangles, and the size of the most
// recently captured screen.
ScreenCapturerHelper helper_;
@@ -189,10 +172,6 @@
// Monitoring display reconfiguration.
scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor_;
- // The desktop configuration obtained from desktop_config_monitor_ the last
- // time of capturing.
- MacDesktopConfiguration desktop_config_;
-
// Power management assertion to prevent the screen from sleeping.
IOPMAssertionID power_assertion_id_display_;
@@ -233,24 +212,13 @@
DISALLOW_COPY_AND_ASSIGN(InvertedDesktopFrame);
};
-DesktopFrame* CreateFrame(
- const MacDesktopConfiguration& desktop_config) {
-
- DesktopSize size(desktop_config.pixel_bounds.width(),
- desktop_config.pixel_bounds.height());
- scoped_ptr<DesktopFrame> frame(new BasicDesktopFrame(size));
-
- frame->set_dpi(DesktopVector(
- kStandardDPI * desktop_config.dip_to_pixel_scale,
- kStandardDPI * desktop_config.dip_to_pixel_scale));
- return frame.release();
-}
-
ScreenCapturerMac::ScreenCapturerMac(
scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor)
: callback_(NULL),
mouse_shape_observer_(NULL),
cgl_context_(NULL),
+ current_display_(0),
+ dip_to_pixel_scale_(1.0f),
desktop_config_monitor_(desktop_config_monitor),
power_assertion_id_display_(kIOPMNullAssertionID),
power_assertion_id_user_(kIOPMNullAssertionID),
@@ -282,6 +250,9 @@
if (!RegisterRefreshAndMoveHandlers()) {
return false;
}
+ desktop_config_monitor_->Lock();
+ desktop_config_ = desktop_config_monitor_->desktop_configuration();
+ desktop_config_monitor_->Unlock();
ScreenConfigurationChanged();
return true;
}
@@ -346,7 +317,7 @@
// Note that we can't reallocate other buffers at this point, since the caller
// may still be reading from them.
if (!queue_.current_frame())
- queue_.ReplaceCurrentFrame(CreateFrame(desktop_config_));
+ queue_.ReplaceCurrentFrame(CreateFrame());
DesktopFrame* current_frame = queue_.current_frame();
@@ -354,7 +325,10 @@
if (IsOSLionOrLater()) {
// Lion requires us to use their new APIs for doing screen capture. These
// APIS currently crash on 10.6.8 if there is no monitor attached.
- CgBlitPostLion(*current_frame, region);
+ if (!CgBlitPostLion(*current_frame, region)) {
+ callback_->OnCaptureCompleted(NULL);
+ return;
+ }
} else if (cgl_context_) {
flip = true;
if (pixel_buffer_object_.get() != 0) {
@@ -397,15 +371,42 @@
bool ScreenCapturerMac::GetScreenList(ScreenList* screens) {
assert(screens->size() == 0);
- // TODO(jiayl): implement screen enumeration.
- Screen default_screen;
- default_screen.id = 0;
- screens->push_back(default_screen);
+ if (!IsOSLionOrLater()) {
+ // Single monitor cast is not supported on pre OS X 10.7.
+ Screen screen;
+ screen.id = kFullDesktopScreenId;
+ screens->push_back(screen);
+ return true;
+ }
+
+ for (MacDisplayConfigurations::iterator it = desktop_config_.displays.begin();
+ it != desktop_config_.displays.end(); ++it) {
+ Screen screen;
+ screen.id = static_cast<ScreenId>(it->id);
+ screens->push_back(screen);
+ }
return true;
}
bool ScreenCapturerMac::SelectScreen(ScreenId id) {
- // TODO(jiayl): implement screen selection.
+ if (!IsOSLionOrLater()) {
+ // Ignore the screen selection on unsupported OS.
+ assert(!current_display_);
+ return id == kFullDesktopScreenId;
+ }
+
+ if (id == kFullDesktopScreenId) {
+ current_display_ = 0;
+ } else {
+ const MacDisplayConfiguration* config =
+ desktop_config_.FindDisplayConfigurationById(
+ static_cast<CGDirectDisplayID>(id));
+ if (!config)
+ return false;
+ current_display_ = config->id;
+ }
+
+ ScreenConfigurationChanged();
return true;
}
@@ -602,7 +603,7 @@
}
}
-void ScreenCapturerMac::CgBlitPostLion(const DesktopFrame& frame,
+bool ScreenCapturerMac::CgBlitPostLion(const DesktopFrame& frame,
const DesktopRegion& region) {
// Copy the entire contents of the previous capture buffer, to capture over.
// TODO(wez): Get rid of this as per crbug.com/145064, or implement
@@ -613,13 +614,37 @@
frame.stride() * frame.size().height());
}
- for (size_t i = 0; i < desktop_config_.displays.size(); ++i) {
- const MacDisplayConfiguration& display_config = desktop_config_.displays[i];
+ MacDisplayConfigurations displays_to_capture;
+ if (current_display_) {
+ // Capturing a single screen. Note that the screen id may change when
+ // screens are added or removed.
+ const MacDisplayConfiguration* config =
+ desktop_config_.FindDisplayConfigurationById(current_display_);
+ if (config) {
+ displays_to_capture.push_back(*config);
+ } else {
+ LOG(LS_ERROR) << "The selected screen cannot be found for capturing.";
+ return false;
+ }
+ } else {
+ // Capturing the whole desktop.
+ displays_to_capture = desktop_config_.displays;
+ }
+ for (size_t i = 0; i < displays_to_capture.size(); ++i) {
+ const MacDisplayConfiguration& display_config = displays_to_capture[i];
+
+ // Capturing mixed-DPI on one surface is hard, so we only return displays
+ // that match the "primary" display's DPI. The primary display is always
+ // the first in the list.
+ if (i > 0 && display_config.dip_to_pixel_scale !=
+ displays_to_capture[0].dip_to_pixel_scale) {
+ continue;
+ }
// Determine the display's position relative to the desktop, in pixels.
DesktopRect display_bounds = display_config.pixel_bounds;
- display_bounds.Translate(-desktop_config_.pixel_bounds.left(),
- -desktop_config_.pixel_bounds.top());
+ display_bounds.Translate(-screen_pixel_bounds_.left(),
+ -screen_pixel_bounds_.top());
// Determine which parts of the blit region, if any, lay within the monitor.
DesktopRegion copy_region = region;
@@ -662,9 +687,20 @@
CFRelease(data);
CFRelease(image);
}
+ return true;
}
void ScreenCapturerMac::ScreenConfigurationChanged() {
+ if (current_display_) {
+ const MacDisplayConfiguration* config =
+ desktop_config_.FindDisplayConfigurationById(current_display_);
+ screen_pixel_bounds_ = config ? config->pixel_bounds : DesktopRect();
+ dip_to_pixel_scale_ = config ? config->dip_to_pixel_scale : 1.0f;
+ } else {
+ screen_pixel_bounds_ = desktop_config_.pixel_bounds;
+ dip_to_pixel_scale_ = desktop_config_.dip_to_pixel_scale;
+ }
+
// Release existing buffers, which will be of the wrong size.
ReleaseBuffers();
@@ -672,7 +708,7 @@
helper_.ClearInvalidRegion();
// Re-mark the entire desktop as dirty.
- helper_.InvalidateScreen(desktop_config_.pixel_bounds.size());
+ helper_.InvalidateScreen(screen_pixel_bounds_.size());
// Make sure the frame buffers will be reallocated.
queue_.Reset();
@@ -753,8 +789,8 @@
(*cgl_set_full_screen_)(cgl_context_);
CGLSetCurrentContext(cgl_context_);
- size_t buffer_size = desktop_config_.pixel_bounds.width() *
- desktop_config_.pixel_bounds.height() *
+ size_t buffer_size = screen_pixel_bounds_.width() *
+ screen_pixel_bounds_.height() *
sizeof(uint32_t);
pixel_buffer_object_.Init(cgl_context_, buffer_size);
}
@@ -786,20 +822,17 @@
void ScreenCapturerMac::ScreenRefresh(CGRectCount count,
const CGRect* rect_array) {
- if (desktop_config_.pixel_bounds.is_empty())
+ if (screen_pixel_bounds_.is_empty())
return;
DesktopRegion region;
-
+ DesktopVector translate_vector =
+ DesktopVector().subtract(screen_pixel_bounds_.top_left());
for (CGRectCount i = 0; i < count; ++i) {
// Convert from Density-Independent Pixel to physical pixel coordinates.
- DesktopRect rect =
- ScaleAndRoundCGRect(rect_array[i], desktop_config_.dip_to_pixel_scale);
-
+ DesktopRect rect = ScaleAndRoundCGRect(rect_array[i], dip_to_pixel_scale_);
// Translate from local desktop to capturer framebuffer coordinates.
- rect.Translate(-desktop_config_.pixel_bounds.left(),
- -desktop_config_.pixel_bounds.top());
-
+ rect.Translate(translate_vector);
region.AddRect(rect);
}
@@ -824,7 +857,7 @@
void* user_parameter) {
ScreenCapturerMac* capturer =
reinterpret_cast<ScreenCapturerMac*>(user_parameter);
- if (capturer->desktop_config_.pixel_bounds.is_empty())
+ if (capturer->screen_pixel_bounds_.is_empty())
capturer->ScreenConfigurationChanged();
capturer->ScreenRefresh(count, rect_array);
}
@@ -839,6 +872,15 @@
capturer->ScreenUpdateMove(delta, count, rect_array);
}
+DesktopFrame* ScreenCapturerMac::CreateFrame() {
+ scoped_ptr<DesktopFrame> frame(
+ new BasicDesktopFrame(screen_pixel_bounds_.size()));
+
+ frame->set_dpi(DesktopVector(kStandardDPI * dip_to_pixel_scale_,
+ kStandardDPI * dip_to_pixel_scale_));
+ return frame.release();
+}
+
} // namespace
// static