Allow Windows to return a monitor out of the first quadrant
Windows may return a DesktopCoordinate out of the first quadrant (x >= 0 && y >= 0), this typically happens when the primary and secondary monitors are swapped. i.e. The secondary monitor is on the left but the primary one is on the right. This change "moves" the entire screen from any quadrant to the (0, 0), so we can capture the monitors in other quadrants. BUG=chromium:715689 Review-Url: https://codereview.webrtc.org/2848443004 Cr-Commit-Position: refs/heads/master@{#17935}
This commit is contained in:
parent
281aecdca6
commit
049ec71e65
@ -25,8 +25,7 @@ using Microsoft::WRL::ComPtr;
|
||||
namespace {
|
||||
|
||||
bool IsValidRect(const RECT& rect) {
|
||||
return rect.left >= 0 && rect.top >= 0 && rect.right > rect.left &&
|
||||
rect.bottom > rect.top;
|
||||
return rect.right > rect.left && rect.bottom > rect.top;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@ -153,4 +152,12 @@ int64_t DxgiAdapterDuplicator::GetNumFramesCaptured() const {
|
||||
return min;
|
||||
}
|
||||
|
||||
void DxgiAdapterDuplicator::TranslateRect(const DesktopVector& position) {
|
||||
desktop_rect_.Translate(position);
|
||||
RTC_DCHECK(desktop_rect_.left() >= 0 && desktop_rect_.top() >= 0);
|
||||
for (auto& duplicator : duplicators_) {
|
||||
duplicator.TranslateRect(position);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -71,6 +71,10 @@ class DxgiAdapterDuplicator {
|
||||
// The minimum num_frames_captured() returned by |duplicators_|.
|
||||
int64_t GetNumFramesCaptured() const;
|
||||
|
||||
// Moves |desktop_rect_| and all underlying |duplicators_|. See
|
||||
// DxgiDuplicatorController::TranslateRect().
|
||||
void TranslateRect(const DesktopVector& position);
|
||||
|
||||
private:
|
||||
bool DoInitialize();
|
||||
|
||||
|
||||
@ -193,6 +193,7 @@ bool DxgiDuplicatorController::DoInitialize() {
|
||||
std::max(left.right(), right.right()),
|
||||
std::max(left.bottom(), right.bottom()));
|
||||
}
|
||||
TranslateRect();
|
||||
}
|
||||
|
||||
HDC hdc = GetDC(nullptr);
|
||||
@ -295,7 +296,7 @@ int64_t DxgiDuplicatorController::GetNumFramesCaptured() const {
|
||||
}
|
||||
|
||||
DesktopSize DxgiDuplicatorController::desktop_size() const {
|
||||
return DesktopSize(desktop_rect_.right(), desktop_rect_.bottom());
|
||||
return desktop_rect_.size();
|
||||
}
|
||||
|
||||
DesktopRect DxgiDuplicatorController::ScreenRect(int id) const {
|
||||
@ -378,4 +379,13 @@ bool DxgiDuplicatorController::EnsureFrameCaptured(Context* context,
|
||||
return true;
|
||||
}
|
||||
|
||||
void DxgiDuplicatorController::TranslateRect() {
|
||||
const DesktopVector position =
|
||||
DesktopVector().subtract(desktop_rect_.top_left());
|
||||
desktop_rect_.Translate(position);
|
||||
for (auto& duplicator : duplicators_) {
|
||||
duplicator.TranslateRect(position);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -158,9 +158,7 @@ class DxgiDuplicatorController {
|
||||
// The minimum GetNumFramesCaptured() returned by |duplicators_|.
|
||||
int64_t GetNumFramesCaptured() const;
|
||||
|
||||
// Returns a DesktopSize to cover entire desktop_rect. This may be different
|
||||
// than desktop_rect().size(), since top-left of the screen does not need to
|
||||
// be started from (0, 0).
|
||||
// Returns a DesktopSize to cover entire |desktop_rect_|.
|
||||
DesktopSize desktop_size() const;
|
||||
|
||||
// Returns the size of one screen. |id| should be >= 0. If system does not
|
||||
@ -181,6 +179,12 @@ class DxgiDuplicatorController {
|
||||
// during first several capture attempts.
|
||||
bool EnsureFrameCaptured(Context* context, SharedDesktopFrame* target);
|
||||
|
||||
// Moves |desktop_rect_| and all underlying |duplicators_|, putting top left
|
||||
// corner of the desktop at (0, 0). This is necessary because DXGI_OUTPUT_DESC
|
||||
// may return negative coordinates. Called from DoInitialize() after all
|
||||
// DxgiAdapterDuplicator and DxgiOutputDuplicator instances are initialized.
|
||||
void TranslateRect();
|
||||
|
||||
// This lock must be locked whenever accessing any of the following objects.
|
||||
rtc::CriticalSection lock_;
|
||||
|
||||
|
||||
@ -67,7 +67,7 @@ DxgiOutputDuplicator::DxgiOutputDuplicator(const D3dDevice& device,
|
||||
desktop_rect_(RECTToDesktopRect(desc.DesktopCoordinates)) {
|
||||
RTC_DCHECK(output_);
|
||||
RTC_DCHECK(!desktop_rect_.is_empty());
|
||||
RTC_DCHECK(desktop_rect_.left() >= 0 && desktop_rect_.top() >= 0);
|
||||
RTC_DCHECK(desktop_rect_.width() > 0 && desktop_rect_.height() > 0);
|
||||
}
|
||||
|
||||
DxgiOutputDuplicator::DxgiOutputDuplicator(DxgiOutputDuplicator&& other) =
|
||||
@ -381,4 +381,9 @@ int64_t DxgiOutputDuplicator::num_frames_captured() const {
|
||||
return num_frames_captured_;
|
||||
}
|
||||
|
||||
void DxgiOutputDuplicator::TranslateRect(const DesktopVector& position) {
|
||||
desktop_rect_.Translate(position);
|
||||
RTC_DCHECK(desktop_rect_.left() >= 0 && desktop_rect_.top() >= 0);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -75,6 +75,9 @@ class DxgiOutputDuplicator {
|
||||
// How many frames have been captured by this DxigOutputDuplicator.
|
||||
int64_t num_frames_captured() const;
|
||||
|
||||
// Moves |desktop_rect_|. See DxgiDuplicatorController::TranslateRect().
|
||||
void TranslateRect(const DesktopVector& position);
|
||||
|
||||
private:
|
||||
// Calls DoDetectUpdatedRegion(). If it fails, this function sets the
|
||||
// |updated_region| as entire UntranslatedDesktopRect().
|
||||
@ -109,7 +112,7 @@ class DxgiOutputDuplicator {
|
||||
|
||||
const D3dDevice device_;
|
||||
const Microsoft::WRL::ComPtr<IDXGIOutput1> output_;
|
||||
const DesktopRect desktop_rect_;
|
||||
DesktopRect desktop_rect_;
|
||||
Microsoft::WRL::ComPtr<IDXGIOutputDuplication> duplication_;
|
||||
DXGI_OUTDUPL_DESC desc_;
|
||||
std::vector<uint8_t> metadata_;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user