1/*
2 *  Copyright (c) 2013 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_helper.h"
12
13#include "testing/gtest/include/gtest/gtest.h"
14#include "webrtc/system_wrappers/interface/scoped_ptr.h"
15
16namespace webrtc {
17
18class ScreenCapturerHelperTest : public testing::Test {
19 protected:
20  ScreenCapturerHelper capturer_helper_;
21};
22
23TEST_F(ScreenCapturerHelperTest, ClearInvalidRegion) {
24  DesktopRegion region(DesktopRect::MakeXYWH(1, 2, 3, 4));
25  capturer_helper_.InvalidateRegion(region);
26  capturer_helper_.ClearInvalidRegion();
27  capturer_helper_.TakeInvalidRegion(&region);
28  EXPECT_TRUE(region.is_empty());
29}
30
31TEST_F(ScreenCapturerHelperTest, InvalidateRegion) {
32  DesktopRegion region;
33  capturer_helper_.TakeInvalidRegion(&region);
34  EXPECT_TRUE(region.is_empty());
35
36  region.SetRect(DesktopRect::MakeXYWH(1, 2, 3, 4));
37  capturer_helper_.InvalidateRegion(region);
38  capturer_helper_.TakeInvalidRegion(&region);
39  EXPECT_TRUE(DesktopRegion(DesktopRect::MakeXYWH(1, 2, 3, 4)).Equals(region));
40
41  capturer_helper_.InvalidateRegion(
42      DesktopRegion(DesktopRect::MakeXYWH(1, 2, 3, 4)));
43  capturer_helper_.InvalidateRegion(
44      DesktopRegion(DesktopRect::MakeXYWH(4, 2, 3, 4)));
45  capturer_helper_.TakeInvalidRegion(&region);
46  EXPECT_TRUE(DesktopRegion(DesktopRect::MakeXYWH(1, 2, 6, 4)).Equals(region));
47}
48
49TEST_F(ScreenCapturerHelperTest, InvalidateScreen) {
50  DesktopRegion region;
51  capturer_helper_.InvalidateScreen(DesktopSize(12, 34));
52  capturer_helper_.TakeInvalidRegion(&region);
53  EXPECT_TRUE(DesktopRegion(DesktopRect::MakeWH(12, 34)).Equals(region));
54}
55
56TEST_F(ScreenCapturerHelperTest, SizeMostRecent) {
57  EXPECT_TRUE(capturer_helper_.size_most_recent().is_empty());
58  capturer_helper_.set_size_most_recent(DesktopSize(12, 34));
59  EXPECT_TRUE(
60      DesktopSize(12, 34).equals(capturer_helper_.size_most_recent()));
61}
62
63TEST_F(ScreenCapturerHelperTest, SetLogGridSize) {
64  capturer_helper_.set_size_most_recent(DesktopSize(10, 10));
65
66  DesktopRegion region;
67  capturer_helper_.TakeInvalidRegion(&region);
68  EXPECT_TRUE(DesktopRegion().Equals(region));
69
70  capturer_helper_.InvalidateRegion(
71      DesktopRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)));
72  capturer_helper_.TakeInvalidRegion(&region);
73  EXPECT_TRUE(DesktopRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)).Equals(region));
74
75  capturer_helper_.SetLogGridSize(-1);
76  capturer_helper_.InvalidateRegion(
77      DesktopRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)));
78  capturer_helper_.TakeInvalidRegion(&region);
79  EXPECT_TRUE(DesktopRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)).Equals(region));
80
81  capturer_helper_.SetLogGridSize(0);
82  capturer_helper_.InvalidateRegion(
83      DesktopRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)));
84  capturer_helper_.TakeInvalidRegion(&region);
85  EXPECT_TRUE(DesktopRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)).Equals(region));
86
87  capturer_helper_.SetLogGridSize(1);
88  capturer_helper_.InvalidateRegion(
89      DesktopRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)));
90  capturer_helper_.TakeInvalidRegion(&region);
91
92  EXPECT_TRUE(DesktopRegion(DesktopRect::MakeXYWH(6, 6, 2, 2)).Equals(region));
93
94  capturer_helper_.SetLogGridSize(2);
95  capturer_helper_.InvalidateRegion(
96      DesktopRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)));
97  capturer_helper_.TakeInvalidRegion(&region);
98  EXPECT_TRUE(DesktopRegion(DesktopRect::MakeXYWH(4, 4, 4, 4)).Equals(region));
99
100  capturer_helper_.SetLogGridSize(0);
101  capturer_helper_.InvalidateRegion(
102      DesktopRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)));
103  capturer_helper_.TakeInvalidRegion(&region);
104  EXPECT_TRUE(DesktopRegion(DesktopRect::MakeXYWH(7, 7, 1, 1)).Equals(region));
105}
106
107void TestExpandRegionToGrid(const DesktopRegion& region, int log_grid_size,
108                            const DesktopRegion& expanded_region_expected) {
109  DesktopRegion expanded_region1;
110  ScreenCapturerHelper::ExpandToGrid(region, log_grid_size, &expanded_region1);
111  EXPECT_TRUE(expanded_region_expected.Equals(expanded_region1));
112
113  DesktopRegion expanded_region2;
114  ScreenCapturerHelper::ExpandToGrid(expanded_region1, log_grid_size,
115                                     &expanded_region2);
116  EXPECT_TRUE(expanded_region1.Equals(expanded_region2));
117}
118
119void TestExpandRectToGrid(int l, int t, int r, int b, int log_grid_size,
120                          int lExpanded, int tExpanded,
121                          int rExpanded, int bExpanded) {
122  TestExpandRegionToGrid(DesktopRegion(DesktopRect::MakeLTRB(l, t, r, b)),
123                         log_grid_size,
124                         DesktopRegion(DesktopRect::MakeLTRB(
125                             lExpanded, tExpanded, rExpanded, bExpanded)));
126}
127
128TEST_F(ScreenCapturerHelperTest, ExpandToGrid) {
129  const int kLogGridSize = 4;
130  const int kGridSize = 1 << kLogGridSize;
131  for (int i = -2; i <= 2; i++) {
132    int x = i * kGridSize;
133    for (int j = -2; j <= 2; j++) {
134      int y = j * kGridSize;
135      TestExpandRectToGrid(x + 0, y + 0, x + 1, y + 1, kLogGridSize,
136                           x + 0, y + 0, x + kGridSize, y + kGridSize);
137      TestExpandRectToGrid(x + 0, y + kGridSize - 1, x + 1, y + kGridSize,
138                           kLogGridSize,
139                           x + 0, y + 0, x + kGridSize, y + kGridSize);
140      TestExpandRectToGrid(x + kGridSize - 1, y + kGridSize - 1,
141                           x + kGridSize, y + kGridSize, kLogGridSize,
142                           x + 0, y + 0, x + kGridSize, y + kGridSize);
143      TestExpandRectToGrid(x + kGridSize - 1, y + 0,
144                           x + kGridSize, y + 1, kLogGridSize,
145                           x + 0, y + 0, x + kGridSize, y + kGridSize);
146      TestExpandRectToGrid(x - 1, y + 0, x + 1, y + 1, kLogGridSize,
147                           x - kGridSize, y + 0, x + kGridSize, y + kGridSize);
148      TestExpandRectToGrid(x - 1, y - 1, x + 1, y + 0, kLogGridSize,
149                           x - kGridSize, y - kGridSize, x + kGridSize, y);
150      TestExpandRectToGrid(x + 0, y - 1, x + 1, y + 1, kLogGridSize,
151                           x, y - kGridSize, x + kGridSize, y + kGridSize);
152      TestExpandRectToGrid(x - 1, y - 1, x + 0, y + 1, kLogGridSize,
153                           x - kGridSize, y - kGridSize, x, y + kGridSize);
154
155      // Construct a region consisting of 3 pixels and verify that it's expanded
156      // properly to 3 squares that are kGridSize by kGridSize.
157      for (int q = 0; q < 4; ++q) {
158        DesktopRegion region;
159        DesktopRegion expanded_region_expected;
160
161        if (q != 0) {
162          region.AddRect(DesktopRect::MakeXYWH(x - 1, y - 1, 1, 1));
163          expanded_region_expected.AddRect(DesktopRect::MakeXYWH(
164              x - kGridSize, y - kGridSize, kGridSize, kGridSize));
165        }
166        if (q != 1) {
167          region.AddRect(DesktopRect::MakeXYWH(x, y - 1, 1, 1));
168          expanded_region_expected.AddRect(DesktopRect::MakeXYWH(
169              x, y - kGridSize, kGridSize, kGridSize));
170        }
171        if (q != 2) {
172          region.AddRect(DesktopRect::MakeXYWH(x - 1, y, 1, 1));
173          expanded_region_expected.AddRect(DesktopRect::MakeXYWH(
174              x - kGridSize, y, kGridSize, kGridSize));
175        }
176        if (q != 3) {
177          region.AddRect(DesktopRect::MakeXYWH(x, y, 1, 1));
178          expanded_region_expected.AddRect(DesktopRect::MakeXYWH(
179              x, y, kGridSize, kGridSize));
180        }
181
182        TestExpandRegionToGrid(region, kLogGridSize, expanded_region_expected);
183      }
184    }
185  }
186}
187
188}  // namespace webrtc
189