Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: webrtc/modules/desktop_capture/screen_capturer_differ_wrapper_unittest.cc

Issue 2202443002: [WebRTC] Add ScreenCapturerDifferWrapper to share Differ across ScreenCapturers (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Disable perf test without SSE2 Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "webrtc/modules/desktop_capture/screen_capturer_differ_wrapper.h"
12
13 #include <initializer_list>
14 #include <memory>
15 #include <utility>
16 #include <vector>
17
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "webrtc/base/random.h"
20 #include "webrtc/base/timeutils.h"
21 #include "webrtc/modules/desktop_capture/desktop_geometry.h"
22 #include "webrtc/modules/desktop_capture/desktop_region.h"
23 #include "webrtc/modules/desktop_capture/differ_block.h"
24 #include "webrtc/modules/desktop_capture/screen_capturer_mock_objects.h"
25 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h"
26 #include "webrtc/typedefs.h"
27
28 namespace webrtc {
29
30 namespace {
31
32 // ScreenCapturerDifferWrapper always use a 32 pixel block. So we normalize the
33 // |rects|.
34 DesktopRect NormalizeDesktopRect(DesktopRect rect, DesktopSize size) {
35 DesktopRect block_size_rect = DesktopRect::MakeLTRB(
36 rect.left() / kBlockSize * kBlockSize,
37 rect.top() / kBlockSize * kBlockSize,
38 (rect.right() + kBlockSize - 1) / kBlockSize * kBlockSize,
39 (rect.bottom() + kBlockSize - 1) / kBlockSize * kBlockSize);
40 block_size_rect.IntersectWith(DesktopRect::MakeSize(size));
41 return block_size_rect;
42 }
43
44 // Compares and asserts |frame|.updated_region() equals to |rects|. This
45 // function does not care about the order of the |rects|.
46 template <template <typename, typename...> class T = std::initializer_list,
47 typename... Rect>
48 void AssertUpdatedRegionIs(const DesktopFrame& frame,
49 const T<DesktopRect, Rect...>& rects) {
50 for (const DesktopRect& rect : rects) {
51 DesktopRect block_size_rect = NormalizeDesktopRect(rect, frame.size());
52 bool found = false;
53 for (DesktopRegion::Iterator it(frame.updated_region()); !it.IsAtEnd();
54 it.Advance()) {
55 if (it.rect().equals(block_size_rect)) {
56 found = true;
57 break;
58 }
59 }
60 ASSERT_TRUE(found);
61 }
62 }
63
64 // Compares and asserts |frame|.updated_region() covers all rectangles in
65 // |rects|, but does not cover areas other than a kBlockSize expansion. This
66 // function does not care about the order of the |rects|, and it does not expect
67 // DesktopRegion to return an exact area of each rectangle in |rects|.
68 template <template <typename, typename...> class T = std::initializer_list,
69 typename... Rect>
70 void AssertUpdatedRegionCovers(const DesktopFrame& frame,
71 const T<DesktopRect, Rect...>& rects) {
72 DesktopRegion region;
73 for (const auto& rect : rects) {
74 region.AddRect(NormalizeDesktopRect(rect, frame.size()));
75 }
76 ASSERT_TRUE(frame.updated_region().Equals(region));
77 }
78
79 template <template <typename, typename...> class T = std::initializer_list,
80 typename... Rect>
81 void ExecuteDifferWrapperCase(MockScreenCapturer* mock_capturer,
82 ScreenCapturerDifferWrapper* capturer,
83 MockScreenCapturerCallback* callback,
84 const T<DesktopRect, Rect...>& dirty_region,
85 bool check_result,
86 bool exactly_match) {
87 EXPECT_CALL(*callback,
88 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, testing::_))
89 .Times(1)
90 .WillOnce(testing::Invoke([&dirty_region, check_result, exactly_match](
91 DesktopCapturer::Result result,
92 std::unique_ptr<DesktopFrame>* frame) {
93 ASSERT_EQ(result, DesktopCapturer::Result::SUCCESS);
94 if (check_result) {
95 if (exactly_match) {
96 AssertUpdatedRegionIs(**frame, dirty_region);
97 } else {
98 AssertUpdatedRegionCovers(**frame, dirty_region);
99 }
100 }
101 }));
102 EXPECT_CALL(*mock_capturer, Capture(testing::_)).Times(1);
103 for (const auto& rect : dirty_region) {
104 mock_capturer->dirty_region()->AddRect(rect);
105 }
106 capturer->Capture(DesktopRegion());
107 }
108
109 // Executes a ScreenCapturerDifferWrapper::Capture(), if dirty_region() is not
110 // set, this function will reset ScreenCapturerDifferWrapper internal
111 // DesktopFrame into white.
112 void ExecuteCapturer(MockScreenCapturer* mock_capturer,
113 ScreenCapturerDifferWrapper* capturer,
114 MockScreenCapturerCallback* callback) {
115 EXPECT_CALL(*callback,
116 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, testing::_))
117 .Times(1);
118 EXPECT_CALL(*mock_capturer, Capture(testing::_)).Times(1);
119 capturer->Capture(DesktopRegion());
120 }
121
122 void ExecuteDifferWrapperTest(bool with_hints,
123 bool enlarge_dirty_region,
124 bool random_dirty_region,
125 bool check_result) {
126 std::unique_ptr<MockScreenCapturer> mock(new MockScreenCapturer());
127 MockScreenCapturer* mock_capturer = mock.get();
128 ScreenCapturerDifferWrapper capturer(std::move(mock), !with_hints);
129 MockScreenCapturerCallback callback;
130 *mock_capturer->provide_dirty_region_hints() = with_hints;
131 *mock_capturer->enlarge_dirty_region() = enlarge_dirty_region;
132 *mock_capturer->random_dirty_region() = random_dirty_region;
133
134 EXPECT_CALL(*mock_capturer, Start(testing::_)).Times(1);
135 capturer.Start(&callback);
136
137 EXPECT_CALL(callback,
138 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, testing::_))
139 .Times(1)
140 .WillOnce(testing::Invoke([](DesktopCapturer::Result result,
141 std::unique_ptr<DesktopFrame>* frame) {
142 ASSERT_EQ(result, DesktopCapturer::Result::SUCCESS);
143 AssertUpdatedRegionIs(**frame,
144 {DesktopRect::MakeSize((*frame)->size())});
145 }));
146 EXPECT_CALL(*mock_capturer, Capture(testing::_)).Times(1);
147 capturer.Capture(DesktopRegion());
148
149 ExecuteDifferWrapperCase(mock_capturer, &capturer, &callback,
150 {DesktopRect::MakeLTRB(100, 100, 200, 200),
151 DesktopRect::MakeLTRB(300, 300, 400, 400)},
152 check_result, true);
153 ExecuteCapturer(mock_capturer, &capturer, &callback);
154
155 ExecuteDifferWrapperCase(
156 mock_capturer, &capturer, &callback,
157 {DesktopRect::MakeLTRB(0, 0, 40, 40),
158 DesktopRect::MakeLTRB(0, mock_capturer->size()->height() - 40, 40,
159 mock_capturer->size()->height()),
160 DesktopRect::MakeLTRB(mock_capturer->size()->width() - 40, 0,
161 mock_capturer->size()->width(), 40),
162 DesktopRect::MakeLTRB(mock_capturer->size()->width() - 40,
163 mock_capturer->size()->height() - 40,
164 mock_capturer->size()->width(),
165 mock_capturer->size()->height())},
166 check_result, true);
167
168 Random random(rtc::TimeMillis());
169 // Fuzzing tests.
170 for (int i = 0; i < 1000; i++) {
171 if (enlarge_dirty_region) {
172 *mock_capturer->enlarge_range() = random.Rand(1, 50);
173 }
174 mock_capturer->size()->set(random.Rand(500, 2000), random.Rand(500, 2000));
175 ExecuteCapturer(mock_capturer, &capturer, &callback);
176 std::vector<DesktopRect> dirty_region;
177 for (int j = random.Rand(50); j >= 0; j--) {
178 // At least a 1 x 1 dirty region.
179 const int left = random.Rand(0, mock_capturer->size()->width() - 2);
180 const int top = random.Rand(0, mock_capturer->size()->height() - 2);
181 const int right = random.Rand(left + 1, mock_capturer->size()->width());
182 const int bottom = random.Rand(top + 1, mock_capturer->size()->height());
183 dirty_region.push_back(DesktopRect::MakeLTRB(left, top, right, bottom));
184 }
185 ExecuteDifferWrapperCase(mock_capturer, &capturer, &callback, dirty_region,
186 check_result, false);
187 }
188 }
189
190 } // namespace
191
192 TEST(ScreenCapturerDifferWrapperTest, FunctionForwarding) {
193 std::unique_ptr<MockScreenCapturer> mock(new MockScreenCapturer());
194 MockScreenCapturer* mock_capturer = mock.get();
195 ScreenCapturerDifferWrapper capturer(std::move(mock), true);
196 MockScreenCapturerCallback callback;
197
198 EXPECT_CALL(*mock_capturer, Start(testing::_)).Times(1);
199 capturer.Start(&callback);
200
201 EXPECT_CALL(*mock_capturer, Capture(testing::_)).Times(1);
202 EXPECT_CALL(callback,
203 OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, testing::_))
204 .Times(1);
205 capturer.Capture(DesktopRegion());
206
207 EXPECT_CALL(*mock_capturer, GetScreenList(testing::_)).Times(1);
208 ASSERT_TRUE(capturer.GetScreenList(nullptr));
209
210 EXPECT_CALL(*mock_capturer, SelectScreen(testing::_)).Times(2);
211 ASSERT_FALSE(capturer.SelectScreen(ScreenId{100}));
212 ASSERT_TRUE(capturer.SelectScreen(kFullDesktopScreenId));
213 }
214
215 TEST(ScreenCapturerDifferWrapperTest, CaptureWithoutHints) {
216 ExecuteDifferWrapperTest(false, false, false, true);
217 }
218
219 TEST(ScreenCapturerDifferWrapperTest, CaptureWithHints) {
220 ExecuteDifferWrapperTest(true, false, false, true);
221 }
222
223 TEST(ScreenCapturerDifferWrapperTest, CaptureWithEnlargedHints) {
224 ExecuteDifferWrapperTest(true, true, false, true);
225 }
226
227 TEST(ScreenCapturerDifferWrapperTest, CaptureWithRandomHints) {
228 ExecuteDifferWrapperTest(true, false, true, true);
229 }
230
231 TEST(ScreenCapturerDifferWrapperTest, CaptureWithEnlargedAndRandomHints) {
232 ExecuteDifferWrapperTest(true, true, true, true);
233 }
234
235 // SSE2 is not available on ARM / MIPS, so the performance should be extremely
236 // lower.
237 #if defined(WEBRTC_ARCH_X86_FAMILY)
238 // When hints are enabled, ScreenCapturerDifferWrapper has a slightly better
239 // performance in current configuration, but not so significant. Following is
240 // one run result.
241 // [ RUN ] CaptureWithoutHintsPerf
242 // [ OK ] CaptureWithoutHintsPerf (8889 ms)
243 // [ RUN ] CaptureWithHintsPerf
244 // [ OK ] CaptureWithHintsPerf (7814 ms)
245 // [ RUN ] CaptureWithEnlargedHintsPerf
246 // [ OK ] CaptureWithEnlargedHintsPerf (7999 ms)
247 // [ RUN ] CaptureWithRandomHintsPerf
248 // [ OK ] CaptureWithRandomHintsPerf (8429 ms)
249 // [ RUN ] CaptureWithEnlargedAndRandomHintsPerf
250 // [ OK ] CaptureWithEnlargedAndRandomHintsPerf (8552 ms)
251 TEST(ScreenCapturerDifferWrapperTest, CaptureWithoutHintsPerf) {
Sergey Ulanov 2016/08/12 05:25:51 Perf test shouldn't be mixed with unittests. They
Hzj_jie 2016/08/15 00:38:06 Done.
252 if (WebRtc_GetCPUInfo(kSSE2) == 0) {
253 return;
254 }
255
256 int64_t started = rtc::TimeMillis();
257 ExecuteDifferWrapperTest(false, false, false, false);
258 ASSERT_LE(rtc::TimeMillis() - started, 15000);
259 }
260
261 TEST(ScreenCapturerDifferWrapperTest, CaptureWithHintsPerf) {
262 if (WebRtc_GetCPUInfo(kSSE2) == 0) {
263 return;
264 }
265
266 int64_t started = rtc::TimeMillis();
267 ExecuteDifferWrapperTest(true, false, false, false);
268 ASSERT_LE(rtc::TimeMillis() - started, 15000);
269 }
270
271 TEST(ScreenCapturerDifferWrapperTest, CaptureWithEnlargedHintsPerf) {
272 if (WebRtc_GetCPUInfo(kSSE2) == 0) {
273 return;
274 }
275
276 int64_t started = rtc::TimeMillis();
277 ExecuteDifferWrapperTest(true, true, false, false);
278 ASSERT_LE(rtc::TimeMillis() - started, 15000);
279 }
280
281 TEST(ScreenCapturerDifferWrapperTest, CaptureWithRandomHintsPerf) {
282 if (WebRtc_GetCPUInfo(kSSE2) == 0) {
283 return;
284 }
285
286 int64_t started = rtc::TimeMillis();
287 ExecuteDifferWrapperTest(true, false, true, false);
288 ASSERT_LE(rtc::TimeMillis() - started, 15000);
289 }
290
291 TEST(ScreenCapturerDifferWrapperTest, CaptureWithEnlargedAndRandomHintsPerf) {
292 if (WebRtc_GetCPUInfo(kSSE2) == 0) {
293 return;
294 }
295
296 int64_t started = rtc::TimeMillis();
297 ExecuteDifferWrapperTest(true, true, true, false);
298 ASSERT_LE(rtc::TimeMillis() - started, 15000);
299 }
300 #endif
301
302 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698