Return translated position in MouseCursorMonitor

This change returns translated position in the newly added overload
MouseCursorMonitor::Callback::OnMouseCursorPosition(DesktopVector) callback.

Meanwhile it also reduces the duplicate logic in Windows capturer
implementations. So except for the deprecated logic in MouseCursorMonitorWin,
all GetSystemMetrics() function calls are merged into GetScreenRect(),
GetFullscreenRect() and GetFullscreenTopLeft() functions.

Bug: webrtc:7950
Change-Id: Ic2a85a80b6947367bdd20d8f96f11e0f5c269006
Reviewed-on: https://chromium-review.googlesource.com/581951
Reviewed-by: Jamie Walch <jamiewalch@chromium.org>
Reviewed-by: Zijie He <zijiehe@chromium.org>
Commit-Queue: Zijie He <zijiehe@chromium.org>
Cr-Commit-Position: refs/heads/master@{#19157}
This commit is contained in:
Zijie He
2017-07-24 16:52:17 -07:00
committed by Commit Bot
parent 54c721541d
commit 74544f9d1b
17 changed files with 122 additions and 31 deletions

View File

@ -218,6 +218,8 @@ rtc_static_library("desktop_capture") {
"win/d3d_device.h",
"win/desktop.cc",
"win/desktop.h",
"win/display_configuration_monitor.cc",
"win/display_configuration_monitor.h",
"win/dxgi_adapter_duplicator.cc",
"win/dxgi_adapter_duplicator.h",
"win/dxgi_context.cc",

View File

@ -201,7 +201,7 @@ DesktopRect CroppingWindowCapturerWin::GetWindowRectInVirtualScreen() {
window_rect.IntersectWith(window_region_rect_);
// Convert |window_rect| to be relative to the top-left of the virtual screen.
DesktopRect screen_rect(GetScreenRect(kFullDesktopScreenId, L""));
DesktopRect screen_rect(GetFullscreenRect());
window_rect.IntersectWith(screen_rect);
window_rect.Translate(-screen_rect.left(), -screen_rect.top());
return window_rect;

View File

@ -29,6 +29,8 @@ const WindowId kNullWindowId = 0;
// - On Windows: integer display device index.
// - On OSX: CGDirectDisplayID cast to intptr_t.
// - On Linux (with X11): TBD.
// On Windows, ScreenId is implementation dependent: sending a ScreenId from one
// implementation to another usually won't work correctly.
typedef intptr_t ScreenId;
// The screen id corresponds to all screen combined together.

View File

@ -57,9 +57,11 @@ struct MacDesktopConfiguration {
MacDesktopConfiguration& operator=(const MacDesktopConfiguration& other);
MacDesktopConfiguration& operator=(MacDesktopConfiguration&& other);
// Returns the desktop & display configurations in Cocoa-style "bottom-up"
// Returns the desktop & display configurations.
// If BottomLeftOrigin is used, the output is in Cocoa-style "bottom-up"
// (the origin is the bottom-left of the primary monitor, and coordinates
// increase as you move up the screen).
// increase as you move up the screen). Otherwise, the configuration will be
// converted to follow top-left coordinate system as Windows and X11.
static MacDesktopConfiguration GetCurrent(Origin origin);
// Returns true if the given desktop configuration equals this one.

View File

@ -241,15 +241,15 @@ void MouseCursorMonitorMac::Capture() {
state = OUTSIDE;
position.set(-1, -1);
}
} else {
position.subtract(configuration.bounds.top_left());
}
}
// Convert Density Independent Pixel to physical pixel.
position = DesktopVector(round(position.x() * scale),
round(position.y() * scale));
// TODO(zijiehe): Remove this overload.
callback_->OnMouseCursorPosition(state, position);
callback_->OnMouseCursorPosition(position);
callback_->OnMouseCursorPosition(
position.subtract(configuration.bounds.top_left()));
}
void MouseCursorMonitorMac::CaptureImage(float scale) {

View File

@ -20,6 +20,7 @@
#include "webrtc/modules/desktop_capture/desktop_geometry.h"
#include "webrtc/modules/desktop_capture/mouse_cursor.h"
#include "webrtc/modules/desktop_capture/win/cursor.h"
#include "webrtc/modules/desktop_capture/win/screen_capture_utils.h"
#include "webrtc/modules/desktop_capture/win/window_capture_utils.h"
#include "webrtc/rtc_base/logging.h"
@ -162,8 +163,10 @@ void MouseCursorMonitorWin::Capture() {
position = position.subtract(rect.top_left());
}
// TODO(zijiehe): Remove this overload.
callback_->OnMouseCursorPosition(inside ? INSIDE : OUTSIDE, position);
callback_->OnMouseCursorPosition(position);
callback_->OnMouseCursorPosition(
position.subtract(GetFullscreenRect().top_left()));
}
DesktopRect MouseCursorMonitorWin::GetScreenRect() {

View File

@ -202,7 +202,10 @@ void MouseCursorMonitorX11::Capture() {
}
const DesktopVector position(win_x, win_y);
// TODO(zijiehe): Remove this overload.
callback_->OnMouseCursorPosition(state, position);
// X11 always starts the coordinate from (0, 0), so we do not need to
// translate here.
callback_->OnMouseCursorPosition(position);
}
}

View File

@ -17,7 +17,12 @@ namespace webrtc {
class ResolutionChangeDetector {
public:
// Checks whether the |size| has been changed comparing to the |size| passed
// in during last IsChanged() call. This function won't return false for the
// first time after construction or Reset() call.
bool IsChanged(DesktopSize size);
// Resets to the initial state.
void Reset();
private:

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2017 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/win/display_configuration_monitor.h"
#include "webrtc/modules/desktop_capture/win/screen_capture_utils.h"
namespace webrtc {
bool DisplayConfigurationMonitor::IsChanged() {
DesktopRect rect = GetFullscreenRect();
if (!initialized_) {
initialized_ = true;
rect_ = rect;
return false;
}
if (rect.equals(rect_)) {
return false;
}
rect_ = rect;
return true;
}
void DisplayConfigurationMonitor::Reset() {
initialized_ = false;
}
} // namespace webrtc

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2017 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_WIN_DISPLAY_CONFIGURATION_MONITOR_H_
#define WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DISPLAY_CONFIGURATION_MONITOR_H_
#include "webrtc/modules/desktop_capture/desktop_geometry.h"
namespace webrtc {
// A passive monitor to detect the change of display configuration on a Windows
// system.
// TODO(zijiehe): Also check for pixel format changes.
class DisplayConfigurationMonitor {
public:
// Checks whether the change of display configuration has happened after last
// IsChanged() call. This function won't return false for the first time after
// constructor or Reset() call.
bool IsChanged();
// Resets to the initial state.
void Reset();
private:
DesktopRect rect_;
bool initialized_ = false;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DISPLAY_CONFIGURATION_MONITOR_H_

View File

@ -137,8 +137,7 @@ DxgiDuplicatorController::DoDuplicate(DxgiFrame* frame, int monitor_id) {
// TODO(zijiehe): Confirm whether IDXGIOutput::GetDesc() and
// IDXGIOutputDuplication::GetDesc() can detect the resolution change without
// reinitialization.
if (resolution_change_detector_.IsChanged(
GetScreenRect(kFullDesktopScreenId, std::wstring()).size())) {
if (display_configuration_monitor_.IsChanged()) {
Deinitialize();
}
@ -266,7 +265,7 @@ bool DxgiDuplicatorController::DoInitialize() {
void DxgiDuplicatorController::Deinitialize() {
desktop_rect_ = DesktopRect();
duplicators_.clear();
resolution_change_detector_.Reset();
display_configuration_monitor_.Reset();
}
bool DxgiDuplicatorController::ContextExpired(

View File

@ -18,9 +18,9 @@
#include <vector>
#include "webrtc/modules/desktop_capture/desktop_geometry.h"
#include "webrtc/modules/desktop_capture/resolution_change_detector.h"
#include "webrtc/modules/desktop_capture/shared_desktop_frame.h"
#include "webrtc/modules/desktop_capture/win/d3d_device.h"
#include "webrtc/modules/desktop_capture/win/display_configuration_monitor.h"
#include "webrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.h"
#include "webrtc/modules/desktop_capture/win/dxgi_context.h"
#include "webrtc/modules/desktop_capture/win/dxgi_frame.h"
@ -224,7 +224,7 @@ class DxgiDuplicatorController {
DesktopVector dpi_;
std::vector<DxgiAdapterDuplicator> duplicators_;
D3dInfo d3d_info_;
ResolutionChangeDetector resolution_change_detector_;
DisplayConfigurationMonitor display_configuration_monitor_;
// A number to indicate how many succeeded duplications have been performed.
uint32_t succeeded_duplications_ = 0;
};

View File

@ -65,13 +65,17 @@ bool IsScreenValid(DesktopCapturer::SourceId screen, std::wstring* device_key) {
return !!enum_result;
}
DesktopRect GetFullscreenRect() {
return DesktopRect::MakeXYWH(GetSystemMetrics(SM_XVIRTUALSCREEN),
GetSystemMetrics(SM_YVIRTUALSCREEN),
GetSystemMetrics(SM_CXVIRTUALSCREEN),
GetSystemMetrics(SM_CYVIRTUALSCREEN));
}
DesktopRect GetScreenRect(DesktopCapturer::SourceId screen,
const std::wstring& device_key) {
if (screen == kFullDesktopScreenId) {
return DesktopRect::MakeXYWH(GetSystemMetrics(SM_XVIRTUALSCREEN),
GetSystemMetrics(SM_YVIRTUALSCREEN),
GetSystemMetrics(SM_CXVIRTUALSCREEN),
GetSystemMetrics(SM_CYVIRTUALSCREEN));
return GetFullscreenRect();
}
DISPLAY_DEVICE device;

View File

@ -32,6 +32,10 @@ bool GetScreenList(DesktopCapturer::SourceList* screens,
// id.
bool IsScreenValid(DesktopCapturer::SourceId screen, std::wstring* device_key);
// Get the rect of the entire system in system coordinate system. I.e. the
// primary monitor always starts from (0, 0).
DesktopRect GetFullscreenRect();
// Get the rect of the screen identified by |screen|, relative to the primary
// display's top-left. If the screen device key does not match |device_key|, or
// the screen does not exist, or any error happens, an empty rect is returned.

View File

@ -148,14 +148,8 @@ void ScreenCapturerWinGdi::PrepareCaptureResources() {
}
}
// If the display bounds have changed then recreate GDI resources.
// TODO(wez): Also check for pixel format changes.
DesktopRect screen_rect(DesktopRect::MakeXYWH(
GetSystemMetrics(SM_XVIRTUALSCREEN),
GetSystemMetrics(SM_YVIRTUALSCREEN),
GetSystemMetrics(SM_CXVIRTUALSCREEN),
GetSystemMetrics(SM_CYVIRTUALSCREEN)));
if (!screen_rect.equals(desktop_dc_rect_)) {
// If the display configurations have changed then recreate GDI resources.
if (display_configuration_monitor_.IsChanged()) {
if (desktop_dc_) {
ReleaseDC(NULL, desktop_dc_);
desktop_dc_ = nullptr;
@ -164,7 +158,6 @@ void ScreenCapturerWinGdi::PrepareCaptureResources() {
DeleteDC(memory_dc_);
memory_dc_ = nullptr;
}
desktop_dc_rect_ = DesktopRect();
}
if (!desktop_dc_) {
@ -176,8 +169,6 @@ void ScreenCapturerWinGdi::PrepareCaptureResources() {
memory_dc_ = CreateCompatibleDC(desktop_dc_);
RTC_CHECK(memory_dc_);
desktop_dc_rect_ = screen_rect;
// Make sure the frame buffers will be reallocated.
queue_.Reset();
}

View File

@ -18,6 +18,7 @@
#include "webrtc/modules/desktop_capture/desktop_capturer.h"
#include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h"
#include "webrtc/modules/desktop_capture/shared_desktop_frame.h"
#include "webrtc/modules/desktop_capture/win/display_configuration_monitor.h"
#include "webrtc/modules/desktop_capture/win/scoped_thread_desktop.h"
#include "webrtc/rtc_base/constructormagic.h"
@ -69,9 +70,7 @@ class ScreenCapturerWinGdi : public DesktopCapturer {
// Queue of the frames buffers.
ScreenCaptureFrameQueue<SharedDesktopFrame> queue_;
// Rectangle describing the bounds of the desktop device context, relative to
// the primary display's top-left.
DesktopRect desktop_dc_rect_;
DisplayConfigurationMonitor display_configuration_monitor_;
HMODULE dwmapi_library_ = NULL;
DwmEnableCompositionFunc composition_func_ = nullptr;

View File

@ -18,7 +18,9 @@ namespace webrtc {
// Output the window rect, with the left/right/bottom frame border cropped if
// the window is maximized. |cropped_rect| is the cropped rect relative to the
// desktop. |original_rect| is the original rect returned from GetWindowRect.
// Returns true if all API calls succeeded.
// Returns true if all API calls succeeded. The returned DesktopRect is in
// system coordinates, i.e. the primary monitor on the system always starts from
// (0, 0).
bool GetCroppedWindowRect(HWND window,
DesktopRect* cropped_rect,
DesktopRect* original_rect);