Revert of [WebRTC] A real ScreenCapturer test (patchset #8 id:240001 of https://codereview.webrtc.org/2268093002/ )
Reason for revert: ScreenCapturerTest.CaptureUpdatedRegion fails on Win DrMemory Full. Original issue's description: > [WebRTC] A real ScreenCapturer test > > We do not have a real ScreenCapturer test before. And after CL 2210443002, a new > ScreenDrawer interface is added to the code base to draw various shapes on the > screen. This change is to use ScreenDrawer to test ScreenCapturer. Besides test > cases, some other changes are included, > > 1. A WaitForPendingPaintings() function in ScreenDrawer, to wait for a > ScreenDrawer to finish all the pending draws. This function now only sleeps 50 > milliseconds on X11 and 100 milliseconds on Windows. > > 2. A Color structure to help handle a big-endian or little-endian safe color and > provide functions to compare with DesktopFrame::data(). Both ScreenDrawer and > DesktopFrameGenerator (in change 2202443002) can use this class to create colors > and compare with or paint to a DesktopFrame. > > 3. ScreenDrawer now uses Color structure instead of uint32_t. > > BUG=314516 > > TBR=kjellander@chromium.org > > Committed: https://crrev.com/9d1c54ace0dc9f68da0152aa1ded2a8dba0a43ae > Cr-Commit-Position: refs/heads/master@{#14058} TBR=sergeyu@chromium.org,jamiewalch@chromium.org,kjellander@chromium.org,zijiehe@chromium.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=314516 Review-Url: https://codereview.webrtc.org/2310953002 Cr-Commit-Position: refs/heads/master@{#14071}
This commit is contained in:
parent
d6e65b39ea
commit
4c44202dc3
@ -505,8 +505,6 @@ if (rtc_include_tests) {
|
||||
sources += [
|
||||
"desktop_capture/desktop_and_cursor_composer_unittest.cc",
|
||||
"desktop_capture/mouse_cursor_monitor_unittest.cc",
|
||||
"desktop_capture/rgba_color.cc",
|
||||
"desktop_capture/rgba_color.h",
|
||||
"desktop_capture/screen_capturer_helper_unittest.cc",
|
||||
"desktop_capture/screen_capturer_mac_unittest.cc",
|
||||
"desktop_capture/screen_capturer_mock_objects.h",
|
||||
|
||||
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 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/rgba_color.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
bool AlphaEquals(uint8_t i, uint8_t j) {
|
||||
// On Linux and Windows 8 or early version, '0' was returned for alpha channel
|
||||
// from capturer APIs, on Windows 10, '255' was returned. So a workaround is
|
||||
// to treat 0 as 255.
|
||||
return i == j || ((i == 0 || i == 255) && (j == 0 || j == 255));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
RgbaColor::RgbaColor(uint8_t blue, uint8_t green, uint8_t red, uint8_t alpha) {
|
||||
this->blue = blue;
|
||||
this->green = green;
|
||||
this->red = red;
|
||||
this->alpha = alpha;
|
||||
}
|
||||
|
||||
RgbaColor::RgbaColor(uint8_t blue, uint8_t green, uint8_t red)
|
||||
: RgbaColor(blue, green, red, 0xff) {}
|
||||
|
||||
RgbaColor::RgbaColor(const uint8_t* bgra)
|
||||
: RgbaColor(bgra[0], bgra[1], bgra[2], bgra[3]) {}
|
||||
|
||||
bool RgbaColor::operator==(const RgbaColor& right) const {
|
||||
return blue == right.blue && green == right.green && red == right.red &&
|
||||
AlphaEquals(alpha, right.alpha);
|
||||
}
|
||||
|
||||
bool RgbaColor::operator!=(const RgbaColor& right) const {
|
||||
return !(*this == right);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 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_RGBA_COLOR_H_
|
||||
#define WEBRTC_MODULES_DESKTOP_CAPTURE_RGBA_COLOR_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "webrtc/modules/desktop_capture/desktop_frame.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// A four-byte structure to store a color in BGRA format. This structure also
|
||||
// provides functions to be created from uint8_t array, say,
|
||||
// DesktopFrame::data(). It always uses BGRA order for internal storage to match
|
||||
// DesktopFrame::data().
|
||||
//
|
||||
// This struct is for testing purpose only, and should not be used in production
|
||||
// logic.
|
||||
struct RgbaColor final {
|
||||
// Creates a color with BGRA channels.
|
||||
RgbaColor(uint8_t blue, uint8_t green, uint8_t red, uint8_t alpha);
|
||||
|
||||
// Creates a color with BGR channels, and set alpha channel to 255 (opaque).
|
||||
RgbaColor(uint8_t blue, uint8_t green, uint8_t red);
|
||||
|
||||
// Creates a color from four-byte in BGRA order, i.e. DesktopFrame::data().
|
||||
explicit RgbaColor(const uint8_t* bgra);
|
||||
|
||||
// Returns true if |this| and |right| is the same color.
|
||||
bool operator==(const RgbaColor& right) const;
|
||||
|
||||
// Returns true if |this| and |right| are different colors.
|
||||
bool operator!=(const RgbaColor& right) const;
|
||||
|
||||
uint8_t blue;
|
||||
uint8_t green;
|
||||
uint8_t red;
|
||||
uint8_t alpha;
|
||||
};
|
||||
static_assert(
|
||||
DesktopFrame::kBytesPerPixel == sizeof(RgbaColor),
|
||||
"A pixel in DesktopFrame should be safe to be represented by a RgbaColor");
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_RGBA_COLOR_H_
|
||||
@ -8,10 +8,6 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
@ -19,16 +15,12 @@
|
||||
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/modules/desktop_capture/rgba_color.h"
|
||||
#include "webrtc/modules/desktop_capture/desktop_capture_options.h"
|
||||
#include "webrtc/modules/desktop_capture/desktop_frame.h"
|
||||
#include "webrtc/modules/desktop_capture/desktop_region.h"
|
||||
#include "webrtc/modules/desktop_capture/screen_capturer_mock_objects.h"
|
||||
#include "webrtc/modules/desktop_capture/screen_drawer.h"
|
||||
#include "webrtc/system_wrappers/include/sleep.h"
|
||||
|
||||
#if defined(WEBRTC_WIN)
|
||||
#include "webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h"
|
||||
@ -42,48 +34,6 @@ const int kTestSharedMemoryId = 123;
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
ACTION_P(SaveUniquePtrArg, dest) {
|
||||
*dest = std::move(*arg1);
|
||||
}
|
||||
|
||||
// Expects |capturer| to successfully capture a frame, and returns it.
|
||||
std::unique_ptr<DesktopFrame> CaptureFrame(
|
||||
ScreenCapturer* capturer,
|
||||
MockScreenCapturerCallback* callback) {
|
||||
std::unique_ptr<DesktopFrame> frame;
|
||||
EXPECT_CALL(*callback,
|
||||
OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
|
||||
.WillOnce(SaveUniquePtrArg(&frame));
|
||||
capturer->Capture(DesktopRegion());
|
||||
EXPECT_TRUE(frame);
|
||||
return frame;
|
||||
}
|
||||
|
||||
// Expects color in |rect| of |frame| is |color|.
|
||||
void ExpectPixelsAreColoredBy(const DesktopFrame& frame,
|
||||
DesktopRect rect,
|
||||
RgbaColor color) {
|
||||
// updated_region() should cover the painted area.
|
||||
DesktopRegion updated_region(frame.updated_region());
|
||||
updated_region.IntersectWith(rect);
|
||||
ASSERT_TRUE(updated_region.Equals(DesktopRegion(rect)));
|
||||
|
||||
// Color in the |rect| should be |color|.
|
||||
uint8_t* row = frame.GetFrameDataAtPos(rect.top_left());
|
||||
for (int i = 0; i < rect.height(); i++) {
|
||||
uint8_t* column = row;
|
||||
for (int j = 0; j < rect.width(); j++) {
|
||||
ASSERT_EQ(color, RgbaColor(column));
|
||||
column += DesktopFrame::kBytesPerPixel;
|
||||
}
|
||||
row += frame.stride();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class ScreenCapturerTest : public testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
@ -92,84 +42,6 @@ class ScreenCapturerTest : public testing::Test {
|
||||
}
|
||||
|
||||
protected:
|
||||
void TestCaptureUpdatedRegion(
|
||||
std::initializer_list<ScreenCapturer*> capturers) {
|
||||
// A large enough area for the tests, which should be able to fulfill by
|
||||
// most of systems.
|
||||
const int kTestArea = 512;
|
||||
const int kRectSize = 32;
|
||||
std::unique_ptr<ScreenDrawer> drawer = ScreenDrawer::Create();
|
||||
if (!drawer || drawer->DrawableRegion().is_empty()) {
|
||||
LOG(LS_WARNING) << "No ScreenDrawer implementation for current platform.";
|
||||
return;
|
||||
}
|
||||
if (drawer->DrawableRegion().width() < kTestArea ||
|
||||
drawer->DrawableRegion().height() < kTestArea) {
|
||||
LOG(LS_WARNING) << "ScreenDrawer::DrawableRegion() is too small for the "
|
||||
"CaptureUpdatedRegion tests.";
|
||||
return;
|
||||
}
|
||||
|
||||
for (ScreenCapturer* capturer : capturers) {
|
||||
capturer->Start(&callback_);
|
||||
}
|
||||
|
||||
#if defined(WEBRTC_LINUX)
|
||||
// TODO(zijiehe): ScreenCapturerX11 won't be able to capture correct images
|
||||
// in the first several capture attempts.
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (ScreenCapturer* capturer : capturers) {
|
||||
std::unique_ptr<DesktopFrame> frame =
|
||||
CaptureFrame(capturer, &callback_);
|
||||
if (!frame) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int c = 0; c < 3; c++) {
|
||||
for (int i = 0; i < kTestArea - kRectSize; i += 16) {
|
||||
DesktopRect rect = DesktopRect::MakeXYWH(i, i, kRectSize, kRectSize);
|
||||
rect.Translate(drawer->DrawableRegion().top_left());
|
||||
RgbaColor color((c == 0 ? (i & 0xff) : 0x7f),
|
||||
(c == 1 ? (i & 0xff) : 0x7f),
|
||||
(c == 2 ? (i & 0xff) : 0x7f));
|
||||
drawer->Clear();
|
||||
drawer->DrawRectangle(rect, color);
|
||||
drawer->WaitForPendingDraws();
|
||||
|
||||
for (ScreenCapturer* capturer : capturers) {
|
||||
std::unique_ptr<DesktopFrame> frame =
|
||||
CaptureFrame(capturer, &callback_);
|
||||
if (!frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
ExpectPixelsAreColoredBy(*frame, rect, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TestCaptureUpdatedRegion() {
|
||||
TestCaptureUpdatedRegion({capturer_.get()});
|
||||
}
|
||||
|
||||
#if defined(WEBRTC_WIN)
|
||||
bool SetDirectxCapturerMode() {
|
||||
if (!ScreenCapturerWinDirectx::IsSupported()) {
|
||||
LOG(LS_WARNING) << "Directx capturer is not supported";
|
||||
return false;
|
||||
}
|
||||
|
||||
DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
|
||||
options.set_allow_directx_capturer(true);
|
||||
capturer_.reset(ScreenCapturer::Create(options));
|
||||
return true;
|
||||
}
|
||||
#endif // defined(WEBRTC_WIN)
|
||||
|
||||
std::unique_ptr<ScreenCapturer> capturer_;
|
||||
MockScreenCapturerCallback callback_;
|
||||
};
|
||||
@ -202,6 +74,10 @@ class FakeSharedMemoryFactory : public SharedMemoryFactory {
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemoryFactory);
|
||||
};
|
||||
|
||||
ACTION_P(SaveUniquePtrArg, dest) {
|
||||
*dest = std::move(*arg1);
|
||||
}
|
||||
|
||||
TEST_F(ScreenCapturerTest, GetScreenListAndSelectScreen) {
|
||||
webrtc::ScreenCapturer::ScreenList screens;
|
||||
EXPECT_TRUE(capturer_->GetScreenList(&screens));
|
||||
@ -241,10 +117,6 @@ TEST_F(ScreenCapturerTest, Capture) {
|
||||
EXPECT_TRUE(it.IsAtEnd());
|
||||
}
|
||||
|
||||
TEST_F(ScreenCapturerTest, CaptureUpdatedRegion) {
|
||||
TestCaptureUpdatedRegion();
|
||||
}
|
||||
|
||||
#if defined(WEBRTC_WIN)
|
||||
|
||||
TEST_F(ScreenCapturerTest, UseSharedBuffers) {
|
||||
@ -279,10 +151,15 @@ TEST_F(ScreenCapturerTest, UseMagnifier) {
|
||||
}
|
||||
|
||||
TEST_F(ScreenCapturerTest, UseDirectxCapturer) {
|
||||
if (!SetDirectxCapturerMode()) {
|
||||
if (!ScreenCapturerWinDirectx::IsSupported()) {
|
||||
LOG(LS_WARNING) << "Directx capturer is not supported";
|
||||
return;
|
||||
}
|
||||
|
||||
DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
|
||||
options.set_allow_directx_capturer(true);
|
||||
capturer_.reset(ScreenCapturer::Create(options));
|
||||
|
||||
std::unique_ptr<DesktopFrame> frame;
|
||||
EXPECT_CALL(callback_,
|
||||
OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
|
||||
@ -294,10 +171,15 @@ TEST_F(ScreenCapturerTest, UseDirectxCapturer) {
|
||||
}
|
||||
|
||||
TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) {
|
||||
if (!SetDirectxCapturerMode()) {
|
||||
if (!ScreenCapturerWinDirectx::IsSupported()) {
|
||||
LOG(LS_WARNING) << "Directx capturer is not supported";
|
||||
return;
|
||||
}
|
||||
|
||||
DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
|
||||
options.set_allow_directx_capturer(true);
|
||||
capturer_.reset(ScreenCapturer::Create(options));
|
||||
|
||||
std::unique_ptr<DesktopFrame> frame;
|
||||
EXPECT_CALL(callback_,
|
||||
OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
|
||||
@ -312,25 +194,6 @@ TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) {
|
||||
EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId);
|
||||
}
|
||||
|
||||
TEST_F(ScreenCapturerTest, CaptureUpdatedRegionWithDirectxCapturer) {
|
||||
if (!SetDirectxCapturerMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
TestCaptureUpdatedRegion();
|
||||
}
|
||||
|
||||
// TODO(zijiehe): Enable this test after CL 2299663003 has been submitted.
|
||||
TEST_F(ScreenCapturerTest, DISABLED_TwoDirectxCapturers) {
|
||||
if (!SetDirectxCapturerMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<ScreenCapturer> capturer2(capturer_.release());
|
||||
RTC_CHECK(SetDirectxCapturerMode());
|
||||
TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()});
|
||||
}
|
||||
|
||||
#endif // defined(WEBRTC_WIN)
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -15,40 +15,30 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "webrtc/modules/desktop_capture/rgba_color.h"
|
||||
#include "webrtc/modules/desktop_capture/desktop_geometry.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// A set of basic platform dependent functions to draw various shapes on the
|
||||
// screen.
|
||||
// A set of platform independent functions to draw various of shapes on the
|
||||
// screen. This class is for testing ScreenCapturer* implementations only, and
|
||||
// should not be used in production logic.
|
||||
class ScreenDrawer {
|
||||
public:
|
||||
// Creates a ScreenDrawer for the current platform, returns nullptr if no
|
||||
// ScreenDrawer implementation available.
|
||||
// Creates a ScreenDrawer for the current platform.
|
||||
static std::unique_ptr<ScreenDrawer> Create();
|
||||
|
||||
ScreenDrawer() {}
|
||||
virtual ~ScreenDrawer() {}
|
||||
|
||||
// Returns the region inside which DrawRectangle() function are expected to
|
||||
// work, in capturer coordinates (assuming ScreenCapturer::SelectScreen has
|
||||
// not been called). This region may exclude regions of the screen reserved by
|
||||
// the OS for things like menu bars or app launchers.
|
||||
// Returns a rect, on which this instance can draw.
|
||||
virtual DesktopRect DrawableRegion() = 0;
|
||||
|
||||
// Draws a rectangle to cover |rect| with |color|. Note, rect.bottom() and
|
||||
// rect.right() two lines are not included. The part of |rect| which is out of
|
||||
// DrawableRegion() will be ignored.
|
||||
virtual void DrawRectangle(DesktopRect rect, RgbaColor color) = 0;
|
||||
// Draws a rectangle to cover |rect| with color |rgba|. Note, rect.bottom()
|
||||
// and rect.right() two lines are not included.
|
||||
virtual void DrawRectangle(DesktopRect rect, uint32_t rgba) = 0;
|
||||
|
||||
// Clears all content on the screen by filling the area with black.
|
||||
// Clears all content on the screen.
|
||||
virtual void Clear() = 0;
|
||||
|
||||
// Blocks current thread until OS finishes previous DrawRectangle() actions.
|
||||
// ScreenCapturer should be able to capture the changes after this function
|
||||
// finish.
|
||||
virtual void WaitForPendingDraws() = 0;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/modules/desktop_capture/screen_drawer.h"
|
||||
#include "webrtc/modules/desktop_capture/x11/shared_x_display.h"
|
||||
#include "webrtc/system_wrappers/include/sleep.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -27,12 +26,12 @@ class ScreenDrawerLinux : public ScreenDrawer {
|
||||
|
||||
// ScreenDrawer interface.
|
||||
DesktopRect DrawableRegion() override;
|
||||
void DrawRectangle(DesktopRect rect, RgbaColor color) override;
|
||||
void DrawRectangle(DesktopRect rect, uint32_t rgba) override;
|
||||
void Clear() override;
|
||||
void WaitForPendingDraws() override;
|
||||
|
||||
private:
|
||||
rtc::scoped_refptr<SharedXDisplay> display_;
|
||||
Screen* screen_;
|
||||
int screen_num_;
|
||||
DesktopRect rect_;
|
||||
Window window_;
|
||||
@ -43,18 +42,15 @@ class ScreenDrawerLinux : public ScreenDrawer {
|
||||
ScreenDrawerLinux::ScreenDrawerLinux() {
|
||||
display_ = SharedXDisplay::CreateDefault();
|
||||
RTC_CHECK(display_.get());
|
||||
screen_ = DefaultScreenOfDisplay(display_->display());
|
||||
RTC_CHECK(screen_);
|
||||
screen_num_ = DefaultScreen(display_->display());
|
||||
XWindowAttributes root_attributes;
|
||||
if (!XGetWindowAttributes(display_->display(),
|
||||
RootWindow(display_->display(), screen_num_),
|
||||
&root_attributes)) {
|
||||
RTC_DCHECK(false) << "Failed to get root window size.";
|
||||
}
|
||||
window_ = XCreateSimpleWindow(
|
||||
display_->display(), RootWindow(display_->display(), screen_num_), 0, 0,
|
||||
root_attributes.width, root_attributes.height, 0,
|
||||
BlackPixel(display_->display(), screen_num_),
|
||||
BlackPixel(display_->display(), screen_num_));
|
||||
rect_ = DesktopRect::MakeWH(screen_->width, screen_->height);
|
||||
window_ = XCreateSimpleWindow(display_->display(),
|
||||
RootWindow(display_->display(), screen_num_), 0,
|
||||
0, rect_.width(), rect_.height(), 0,
|
||||
BlackPixel(display_->display(), screen_num_),
|
||||
BlackPixel(display_->display(), screen_num_));
|
||||
XSelectInput(display_->display(), window_, StructureNotifyMask);
|
||||
XMapWindow(display_->display(), window_);
|
||||
while (true) {
|
||||
@ -65,23 +61,8 @@ ScreenDrawerLinux::ScreenDrawerLinux() {
|
||||
}
|
||||
}
|
||||
XFlush(display_->display());
|
||||
Window child;
|
||||
int x, y;
|
||||
if (!XTranslateCoordinates(display_->display(), window_,
|
||||
RootWindow(display_->display(), screen_num_), 0, 0,
|
||||
&x, &y, &child)) {
|
||||
RTC_DCHECK(false) << "Failed to get window position.";
|
||||
}
|
||||
// Some window manager does not allow a window to cover two or more monitors.
|
||||
// So if the window is on the first monitor of a two-monitor system, the
|
||||
// second half won't be able to show up without changing configurations of WM,
|
||||
// and its DrawableRegion() is not accurate.
|
||||
rect_ = DesktopRect::MakeLTRB(x, y, root_attributes.width,
|
||||
root_attributes.height);
|
||||
context_ = DefaultGC(display_->display(), screen_num_);
|
||||
colormap_ = DefaultColormap(display_->display(), screen_num_);
|
||||
// Wait for window animations.
|
||||
SleepMs(200);
|
||||
}
|
||||
|
||||
ScreenDrawerLinux::~ScreenDrawerLinux() {
|
||||
@ -93,42 +74,33 @@ DesktopRect ScreenDrawerLinux::DrawableRegion() {
|
||||
return rect_;
|
||||
}
|
||||
|
||||
void ScreenDrawerLinux::DrawRectangle(DesktopRect rect, RgbaColor color) {
|
||||
rect.Translate(-rect_.left(), -rect_.top());
|
||||
XColor xcolor;
|
||||
void ScreenDrawerLinux::DrawRectangle(DesktopRect rect, uint32_t rgba) {
|
||||
int r = (rgba & 0xff00) >> 8;
|
||||
int g = (rgba & 0xff0000) >> 16;
|
||||
int b = (rgba & 0xff000000) >> 24;
|
||||
// X11 does not support Alpha.
|
||||
// X11 uses 16 bits for each primary color, so we need to slightly normalize
|
||||
// a 8 bits channel to 16 bits channel, by setting the low 8 bits as its high
|
||||
// 8 bits to avoid a mismatch of color returned by capturer.
|
||||
xcolor.red = (color.red << 8) + color.red;
|
||||
xcolor.green = (color.green << 8) + color.green;
|
||||
xcolor.blue = (color.blue << 8) + color.blue;
|
||||
xcolor.flags = DoRed | DoGreen | DoBlue;
|
||||
XAllocColor(display_->display(), colormap_, &xcolor);
|
||||
XSetForeground(display_->display(), context_, xcolor.pixel);
|
||||
XColor color;
|
||||
// X11 uses 16 bits for each primary color.
|
||||
color.red = r * 256;
|
||||
color.green = g * 256;
|
||||
color.blue = b * 256;
|
||||
color.flags = DoRed | DoGreen | DoBlue;
|
||||
XAllocColor(display_->display(), colormap_, &color);
|
||||
XSetForeground(display_->display(), context_, color.pixel);
|
||||
XFillRectangle(display_->display(), window_, context_, rect.left(),
|
||||
rect.top(), rect.width(), rect.height());
|
||||
XFlush(display_->display());
|
||||
}
|
||||
|
||||
void ScreenDrawerLinux::Clear() {
|
||||
DrawRectangle(rect_, RgbaColor(0, 0, 0));
|
||||
}
|
||||
|
||||
// TODO(zijiehe): Find the right signal from X11 to indicate the finish of all
|
||||
// pending paintings.
|
||||
void ScreenDrawerLinux::WaitForPendingDraws() {
|
||||
SleepMs(50);
|
||||
DrawRectangle(DrawableRegion(), 0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
std::unique_ptr<ScreenDrawer> ScreenDrawer::Create() {
|
||||
if (SharedXDisplay::CreateDefault().get()) {
|
||||
return std::unique_ptr<ScreenDrawer>(new ScreenDrawerLinux());
|
||||
}
|
||||
return nullptr;
|
||||
return std::unique_ptr<ScreenDrawer>(new ScreenDrawerLinux());
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "webrtc/base/random.h"
|
||||
#include "webrtc/base/timeutils.h"
|
||||
#include "webrtc/system_wrappers/include/logging.h"
|
||||
#include "webrtc/system_wrappers/include/sleep.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -27,16 +26,11 @@ namespace webrtc {
|
||||
TEST(ScreenDrawerTest, DISABLED_DrawRectangles) {
|
||||
std::unique_ptr<ScreenDrawer> drawer = ScreenDrawer::Create();
|
||||
if (!drawer) {
|
||||
LOG(LS_WARNING) << "No ScreenDrawer implementation for current platform.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (drawer->DrawableRegion().is_empty()) {
|
||||
LOG(LS_WARNING) << "ScreenDrawer of current platform does not provide a "
|
||||
"non-empty DrawableRegion().";
|
||||
// No ScreenDrawer implementation for current platform.
|
||||
return;
|
||||
}
|
||||
|
||||
drawer->Clear();
|
||||
DesktopRect rect = drawer->DrawableRegion();
|
||||
Random random(rtc::TimeMicros());
|
||||
for (int i = 0; i < 100; i++) {
|
||||
@ -46,15 +40,16 @@ TEST(ScreenDrawerTest, DISABLED_DrawRectangles) {
|
||||
drawer->DrawRectangle(
|
||||
DesktopRect::MakeLTRB(left, top, random.Rand(left + 1, rect.right()),
|
||||
random.Rand(top + 1, rect.bottom())),
|
||||
RgbaColor(random.Rand<uint8_t>(), random.Rand<uint8_t>(),
|
||||
random.Rand<uint8_t>(), random.Rand<uint8_t>()));
|
||||
random.Rand<uint32_t>());
|
||||
|
||||
if (i == 50) {
|
||||
SleepMs(10000);
|
||||
drawer->Clear();
|
||||
}
|
||||
}
|
||||
|
||||
SleepMs(10000);
|
||||
drawer->Clear();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
#include <memory>
|
||||
|
||||
#include "webrtc/modules/desktop_capture/screen_drawer.h"
|
||||
#include "webrtc/system_wrappers/include/sleep.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -35,11 +34,6 @@ HWND CreateDrawerWindow(DesktopRect rect) {
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
COLORREF ColorToRef(RgbaColor color) {
|
||||
// Windows device context does not support alpha.
|
||||
return RGB(color.red, color.green, color.blue);
|
||||
}
|
||||
|
||||
// A ScreenDrawer implementation for Windows.
|
||||
class ScreenDrawerWin : public ScreenDrawer {
|
||||
public:
|
||||
@ -48,17 +42,10 @@ class ScreenDrawerWin : public ScreenDrawer {
|
||||
|
||||
// ScreenDrawer interface.
|
||||
DesktopRect DrawableRegion() override;
|
||||
void DrawRectangle(DesktopRect rect, RgbaColor color) override;
|
||||
void DrawRectangle(DesktopRect rect, uint32_t rgba) override;
|
||||
void Clear() override;
|
||||
void WaitForPendingDraws() override;
|
||||
|
||||
private:
|
||||
// Draw a line with |color|.
|
||||
void DrawLine(DesktopVector start, DesktopVector end, RgbaColor color);
|
||||
|
||||
// Draw a dot with |color|.
|
||||
void DrawDot(DesktopVector vect, RgbaColor color);
|
||||
|
||||
const DesktopRect rect_;
|
||||
HWND window_;
|
||||
HDC hdc_;
|
||||
@ -70,12 +57,8 @@ ScreenDrawerWin::ScreenDrawerWin()
|
||||
window_(CreateDrawerWindow(rect_)),
|
||||
hdc_(GetWindowDC(window_)) {
|
||||
// We do not need to handle any messages for the |window_|, so disable Windows
|
||||
// from processing windows ghosting feature.
|
||||
// process windows ghosting feature.
|
||||
DisableProcessWindowsGhosting();
|
||||
|
||||
// Always use stock pen (DC_PEN) and brush (DC_BRUSH).
|
||||
SelectObject(hdc_, GetStockObject(DC_PEN));
|
||||
SelectObject(hdc_, GetStockObject(DC_BRUSH));
|
||||
}
|
||||
|
||||
ScreenDrawerWin::~ScreenDrawerWin() {
|
||||
@ -88,51 +71,20 @@ DesktopRect ScreenDrawerWin::DrawableRegion() {
|
||||
return rect_;
|
||||
}
|
||||
|
||||
void ScreenDrawerWin::DrawRectangle(DesktopRect rect, RgbaColor color) {
|
||||
if (rect.width() == 1 && rect.height() == 1) {
|
||||
// Rectangle function cannot draw a 1 pixel rectangle.
|
||||
DrawDot(rect.top_left(), color);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rect.width() == 1 || rect.height() == 1) {
|
||||
// Rectangle function cannot draw a 1 pixel rectangle.
|
||||
DrawLine(rect.top_left(), DesktopVector(rect.right(), rect.bottom()),
|
||||
color);
|
||||
return;
|
||||
}
|
||||
|
||||
SetDCBrushColor(hdc_, ColorToRef(color));
|
||||
SetDCPenColor(hdc_, ColorToRef(color));
|
||||
void ScreenDrawerWin::DrawRectangle(DesktopRect rect, uint32_t rgba) {
|
||||
int r = (rgba & 0xff00) >> 8;
|
||||
int g = (rgba & 0xff0000) >> 16;
|
||||
int b = (rgba & 0xff000000) >> 24;
|
||||
// Windows device context does not support Alpha.
|
||||
SelectObject(hdc_, GetStockObject(DC_PEN));
|
||||
SelectObject(hdc_, GetStockObject(DC_BRUSH));
|
||||
SetDCBrushColor(hdc_, RGB(r, g, b));
|
||||
SetDCPenColor(hdc_, RGB(r, g, b));
|
||||
Rectangle(hdc_, rect.left(), rect.top(), rect.right(), rect.bottom());
|
||||
}
|
||||
|
||||
void ScreenDrawerWin::Clear() {
|
||||
DrawRectangle(rect_, RgbaColor(0, 0, 0));
|
||||
}
|
||||
|
||||
// TODO(zijiehe): Find the right signal to indicate the finish of all pending
|
||||
// paintings.
|
||||
void ScreenDrawerWin::WaitForPendingDraws() {
|
||||
// DirectX capturer reads data from GPU, so there is a certain delay before
|
||||
// Windows sends the data to GPU.
|
||||
SleepMs(100);
|
||||
}
|
||||
|
||||
void ScreenDrawerWin::DrawLine(DesktopVector start,
|
||||
DesktopVector end,
|
||||
RgbaColor color) {
|
||||
POINT points[2];
|
||||
points[0].x = start.x();
|
||||
points[0].y = start.y();
|
||||
points[1].x = end.x();
|
||||
points[1].y = end.y();
|
||||
SetDCPenColor(hdc_, ColorToRef(color));
|
||||
Polyline(hdc_, points, 2);
|
||||
}
|
||||
|
||||
void ScreenDrawerWin::DrawDot(DesktopVector vect, RgbaColor color) {
|
||||
SetPixel(hdc_, vect.x(), vect.y(), ColorToRef(color));
|
||||
DrawRectangle(DrawableRegion(), 0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -433,8 +433,6 @@
|
||||
'sources': [
|
||||
'desktop_capture/desktop_and_cursor_composer_unittest.cc',
|
||||
'desktop_capture/mouse_cursor_monitor_unittest.cc',
|
||||
'desktop_capture/rgba_color.cc',
|
||||
'desktop_capture/rgba_color.h',
|
||||
'desktop_capture/screen_capturer_helper_unittest.cc',
|
||||
'desktop_capture/screen_capturer_mac_unittest.cc',
|
||||
'desktop_capture/screen_capturer_mock_objects.h',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user