OLD | NEW |
| (Empty) |
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 <memory> | |
12 | |
13 #include "testing/gmock/include/gmock/gmock.h" | |
14 #include "webrtc/base/constructormagic.h" | |
15 #include "webrtc/modules/desktop_capture/differ.h" | |
16 #include "webrtc/modules/desktop_capture/differ_block.h" | |
17 | |
18 namespace webrtc { | |
19 | |
20 // 96x96 screen gives a 4x4 grid of blocks. | |
21 const int kScreenWidth= 96; | |
22 const int kScreenHeight = 96; | |
23 | |
24 // To test partial blocks, we need a width and height that are not multiples | |
25 // of 16 (or 32, depending on current block size). | |
26 const int kPartialScreenWidth = 70; | |
27 const int kPartialScreenHeight = 70; | |
28 | |
29 class DifferTest : public testing::Test { | |
30 public: | |
31 DifferTest() { | |
32 } | |
33 | |
34 protected: | |
35 void InitDiffer(int width, int height) { | |
36 width_ = width; | |
37 height_ = height; | |
38 bytes_per_pixel_ = kBytesPerPixel; | |
39 stride_ = (kBytesPerPixel * width); | |
40 buffer_size_ = width_ * height_ * bytes_per_pixel_; | |
41 | |
42 differ_.reset(new Differ(width_, height_, bytes_per_pixel_, stride_)); | |
43 | |
44 prev_.reset(new uint8_t[buffer_size_]); | |
45 memset(prev_.get(), 0, buffer_size_); | |
46 | |
47 curr_.reset(new uint8_t[buffer_size_]); | |
48 memset(curr_.get(), 0, buffer_size_); | |
49 } | |
50 | |
51 void ClearBuffer(uint8_t* buffer) { | |
52 memset(buffer, 0, buffer_size_); | |
53 } | |
54 | |
55 // Here in DifferTest so that tests can access private methods of Differ. | |
56 void MarkDirtyBlocks(const uint8_t* prev_buffer, const uint8_t* curr_buffer) { | |
57 differ_->MarkDirtyBlocks(prev_buffer, curr_buffer); | |
58 } | |
59 | |
60 void MergeBlocks(DesktopRegion* dirty) { | |
61 differ_->MergeBlocks(dirty); | |
62 } | |
63 | |
64 // Convenience method to count rectangles in a region. | |
65 int RegionRectCount(const DesktopRegion& region) { | |
66 int count = 0; | |
67 for (DesktopRegion::Iterator iter(region); | |
68 !iter.IsAtEnd(); iter.Advance()) { | |
69 ++count; | |
70 } | |
71 return count; | |
72 } | |
73 | |
74 // Convenience wrapper for Differ's DiffBlock that calculates the appropriate | |
75 // offset to the start of the desired block. | |
76 bool DiffBlock(int block_x, int block_y) { | |
77 // Offset from upper-left of buffer to upper-left of requested block. | |
78 int block_offset = ((block_y * stride_) + (block_x * bytes_per_pixel_)) | |
79 * kBlockSize; | |
80 return BlockDifference(prev_.get() + block_offset, | |
81 curr_.get() + block_offset, | |
82 stride_); | |
83 } | |
84 | |
85 // Write the pixel |value| into the specified block in the |buffer|. | |
86 // This is a convenience wrapper around WritePixel(). | |
87 void WriteBlockPixel(uint8_t* buffer, int block_x, int block_y, | |
88 int pixel_x, int pixel_y, uint32_t value) { | |
89 WritePixel(buffer, (block_x * kBlockSize) + pixel_x, | |
90 (block_y * kBlockSize) + pixel_y, value); | |
91 } | |
92 | |
93 // Write the test pixel |value| into the |buffer| at the specified |x|,|y| | |
94 // location. | |
95 // Only the low-order bytes from |value| are written (assuming little-endian). | |
96 // So, for |value| = 0xaabbccdd: | |
97 // If bytes_per_pixel = 4, then ddccbbaa will be written as the pixel value. | |
98 // If = 3, ddccbb | |
99 // If = 2, ddcc | |
100 // If = 1, dd | |
101 void WritePixel(uint8_t* buffer, int x, int y, uint32_t value) { | |
102 uint8_t* pixel = reinterpret_cast<uint8_t*>(&value); | |
103 buffer += (y * stride_) + (x * bytes_per_pixel_); | |
104 for (int b = bytes_per_pixel_ - 1; b >= 0; b--) { | |
105 *buffer++ = pixel[b]; | |
106 } | |
107 } | |
108 | |
109 // DiffInfo utility routines. | |
110 // These are here so that we don't have to make each DifferText_Xxx_Test | |
111 // class a friend class to Differ. | |
112 | |
113 // Clear out the entire |diff_info_| buffer. | |
114 void ClearDiffInfo() { | |
115 memset(differ_->diff_info_.get(), 0, differ_->diff_info_size_); | |
116 } | |
117 | |
118 // Get the value in the |diff_info_| array at (x,y). | |
119 bool GetDiffInfo(int x, int y) { | |
120 bool* diff_info = differ_->diff_info_.get(); | |
121 return diff_info[(y * GetDiffInfoWidth()) + x]; | |
122 } | |
123 | |
124 // Width of |diff_info_| array. | |
125 int GetDiffInfoWidth() { | |
126 return differ_->diff_info_width_; | |
127 } | |
128 | |
129 // Height of |diff_info_| array. | |
130 int GetDiffInfoHeight() { | |
131 return differ_->diff_info_height_; | |
132 } | |
133 | |
134 // Size of |diff_info_| array. | |
135 int GetDiffInfoSize() { | |
136 return differ_->diff_info_size_; | |
137 } | |
138 | |
139 void SetDiffInfo(int x, int y, bool value) { | |
140 bool* diff_info = differ_->diff_info_.get(); | |
141 diff_info[(y * GetDiffInfoWidth()) + x] = value; | |
142 } | |
143 | |
144 // Mark the range of blocks specified. | |
145 void MarkBlocks(int x_origin, int y_origin, int width, int height) { | |
146 for (int y = 0; y < height; y++) { | |
147 for (int x = 0; x < width; x++) { | |
148 SetDiffInfo(x_origin + x, y_origin + y, true); | |
149 } | |
150 } | |
151 } | |
152 | |
153 // Verify that |region| contains a rectangle defined by |x|, |y|, |width| and | |
154 // |height|. | |
155 // |x|, |y|, |width| and |height| are specified in block (not pixel) units. | |
156 bool CheckDirtyRegionContainsRect(const DesktopRegion& region, | |
157 int x, int y, | |
158 int width, int height) { | |
159 DesktopRect r = | |
160 DesktopRect::MakeXYWH(x * kBlockSize, y * kBlockSize, | |
161 width * kBlockSize, height * kBlockSize); | |
162 for (DesktopRegion::Iterator i(region); !i.IsAtEnd(); i.Advance()) { | |
163 if (i.rect().equals(r)) | |
164 return true; | |
165 } | |
166 return false; | |
167 } | |
168 | |
169 // Mark the range of blocks specified and then verify that they are | |
170 // merged correctly. | |
171 // Only one rectangular region of blocks can be checked with this routine. | |
172 bool MarkBlocksAndCheckMerge(int x_origin, int y_origin, | |
173 int width, int height) { | |
174 ClearDiffInfo(); | |
175 MarkBlocks(x_origin, y_origin, width, height); | |
176 | |
177 DesktopRegion dirty; | |
178 MergeBlocks(&dirty); | |
179 | |
180 | |
181 DesktopRect expected_rect = DesktopRect::MakeXYWH( | |
182 x_origin * kBlockSize, y_origin * kBlockSize, | |
183 width * kBlockSize, height * kBlockSize); | |
184 | |
185 // Verify that the region contains expected_rect and it's the only | |
186 // rectangle. | |
187 DesktopRegion::Iterator it(dirty); | |
188 return !it.IsAtEnd() && expected_rect.equals(it.rect()) && | |
189 (it.Advance(), it.IsAtEnd()); | |
190 } | |
191 | |
192 // The differ class we're testing. | |
193 std::unique_ptr<Differ> differ_; | |
194 | |
195 // Screen/buffer info. | |
196 int width_; | |
197 int height_; | |
198 int bytes_per_pixel_; | |
199 int stride_; | |
200 | |
201 // Size of each screen buffer. | |
202 int buffer_size_; | |
203 | |
204 // Previous and current screen buffers. | |
205 std::unique_ptr<uint8_t[]> prev_; | |
206 std::unique_ptr<uint8_t[]> curr_; | |
207 | |
208 private: | |
209 RTC_DISALLOW_COPY_AND_ASSIGN(DifferTest); | |
210 }; | |
211 | |
212 TEST_F(DifferTest, Setup) { | |
213 InitDiffer(kScreenWidth, kScreenHeight); | |
214 // 96x96 pixels results in 3x3 array. Add 1 to each dimension as boundary. | |
215 // +---+---+---+---+ | |
216 // | o | o | o | _ | | |
217 // +---+---+---+---+ o = blocks mapped to screen pixels | |
218 // | o | o | o | _ | | |
219 // +---+---+---+---+ _ = boundary blocks | |
220 // | o | o | o | _ | | |
221 // +---+---+---+---+ | |
222 // | _ | _ | _ | _ | | |
223 // +---+---+---+---+ | |
224 EXPECT_EQ(4, GetDiffInfoWidth()); | |
225 EXPECT_EQ(4, GetDiffInfoHeight()); | |
226 EXPECT_EQ(16, GetDiffInfoSize()); | |
227 } | |
228 | |
229 TEST_F(DifferTest, MarkDirtyBlocks_All) { | |
230 InitDiffer(kScreenWidth, kScreenHeight); | |
231 ClearDiffInfo(); | |
232 | |
233 // Update a pixel in each block. | |
234 for (int y = 0; y < GetDiffInfoHeight() - 1; y++) { | |
235 for (int x = 0; x < GetDiffInfoWidth() - 1; x++) { | |
236 WriteBlockPixel(curr_.get(), x, y, 10, 10, 0xff00ff); | |
237 } | |
238 } | |
239 | |
240 MarkDirtyBlocks(prev_.get(), curr_.get()); | |
241 | |
242 // Make sure each block is marked as dirty. | |
243 for (int y = 0; y < GetDiffInfoHeight() - 1; y++) { | |
244 for (int x = 0; x < GetDiffInfoWidth() - 1; x++) { | |
245 EXPECT_TRUE(GetDiffInfo(x, y)) | |
246 << "when x = " << x << ", and y = " << y; | |
247 } | |
248 } | |
249 } | |
250 | |
251 TEST_F(DifferTest, MarkDirtyBlocks_Sampling) { | |
252 InitDiffer(kScreenWidth, kScreenHeight); | |
253 ClearDiffInfo(); | |
254 | |
255 // Update some pixels in image. | |
256 WriteBlockPixel(curr_.get(), 1, 0, 10, 10, 0xff00ff); | |
257 WriteBlockPixel(curr_.get(), 2, 1, 10, 10, 0xff00ff); | |
258 WriteBlockPixel(curr_.get(), 0, 2, 10, 10, 0xff00ff); | |
259 | |
260 MarkDirtyBlocks(prev_.get(), curr_.get()); | |
261 | |
262 // Make sure corresponding blocks are updated. | |
263 EXPECT_FALSE(GetDiffInfo(0, 0)); | |
264 EXPECT_FALSE(GetDiffInfo(0, 1)); | |
265 EXPECT_TRUE(GetDiffInfo(0, 2)); | |
266 EXPECT_TRUE(GetDiffInfo(1, 0)); | |
267 EXPECT_FALSE(GetDiffInfo(1, 1)); | |
268 EXPECT_FALSE(GetDiffInfo(1, 2)); | |
269 EXPECT_FALSE(GetDiffInfo(2, 0)); | |
270 EXPECT_TRUE(GetDiffInfo(2, 1)); | |
271 EXPECT_FALSE(GetDiffInfo(2, 2)); | |
272 } | |
273 | |
274 TEST_F(DifferTest, DiffBlock) { | |
275 InitDiffer(kScreenWidth, kScreenHeight); | |
276 | |
277 // Verify no differences at start. | |
278 EXPECT_FALSE(DiffBlock(0, 0)); | |
279 EXPECT_FALSE(DiffBlock(1, 1)); | |
280 | |
281 // Write new data into the 4 corners of the middle block and verify that | |
282 // neighboring blocks are not affected. | |
283 int max = kBlockSize - 1; | |
284 WriteBlockPixel(curr_.get(), 1, 1, 0, 0, 0xffffff); | |
285 WriteBlockPixel(curr_.get(), 1, 1, 0, max, 0xffffff); | |
286 WriteBlockPixel(curr_.get(), 1, 1, max, 0, 0xffffff); | |
287 WriteBlockPixel(curr_.get(), 1, 1, max, max, 0xffffff); | |
288 EXPECT_FALSE(DiffBlock(0, 0)); | |
289 EXPECT_FALSE(DiffBlock(0, 1)); | |
290 EXPECT_FALSE(DiffBlock(0, 2)); | |
291 EXPECT_FALSE(DiffBlock(1, 0)); | |
292 EXPECT_TRUE(DiffBlock(1, 1)); // Only this block should change. | |
293 EXPECT_FALSE(DiffBlock(1, 2)); | |
294 EXPECT_FALSE(DiffBlock(2, 0)); | |
295 EXPECT_FALSE(DiffBlock(2, 1)); | |
296 EXPECT_FALSE(DiffBlock(2, 2)); | |
297 } | |
298 | |
299 TEST_F(DifferTest, Partial_Setup) { | |
300 InitDiffer(kPartialScreenWidth, kPartialScreenHeight); | |
301 // 70x70 pixels results in 3x3 array: 2x2 full blocks + partials around | |
302 // the edge. One more is added to each dimension as a boundary. | |
303 // +---+---+---+---+ | |
304 // | o | o | + | _ | | |
305 // +---+---+---+---+ o = blocks mapped to screen pixels | |
306 // | o | o | + | _ | | |
307 // +---+---+---+---+ + = partial blocks (top/left mapped to screen pixels) | |
308 // | + | + | + | _ | | |
309 // +---+---+---+---+ _ = boundary blocks | |
310 // | _ | _ | _ | _ | | |
311 // +---+---+---+---+ | |
312 EXPECT_EQ(4, GetDiffInfoWidth()); | |
313 EXPECT_EQ(4, GetDiffInfoHeight()); | |
314 EXPECT_EQ(16, GetDiffInfoSize()); | |
315 } | |
316 | |
317 TEST_F(DifferTest, Partial_FirstPixel) { | |
318 InitDiffer(kPartialScreenWidth, kPartialScreenHeight); | |
319 ClearDiffInfo(); | |
320 | |
321 // Update the first pixel in each block. | |
322 for (int y = 0; y < GetDiffInfoHeight() - 1; y++) { | |
323 for (int x = 0; x < GetDiffInfoWidth() - 1; x++) { | |
324 WriteBlockPixel(curr_.get(), x, y, 0, 0, 0xff00ff); | |
325 } | |
326 } | |
327 | |
328 MarkDirtyBlocks(prev_.get(), curr_.get()); | |
329 | |
330 // Make sure each block is marked as dirty. | |
331 for (int y = 0; y < GetDiffInfoHeight() - 1; y++) { | |
332 for (int x = 0; x < GetDiffInfoWidth() - 1; x++) { | |
333 EXPECT_TRUE(GetDiffInfo(x, y)) | |
334 << "when x = " << x << ", and y = " << y; | |
335 } | |
336 } | |
337 } | |
338 | |
339 TEST_F(DifferTest, Partial_BorderPixel) { | |
340 InitDiffer(kPartialScreenWidth, kPartialScreenHeight); | |
341 ClearDiffInfo(); | |
342 | |
343 // Update the right/bottom border pixels. | |
344 for (int y = 0; y < height_; y++) { | |
345 WritePixel(curr_.get(), width_ - 1, y, 0xff00ff); | |
346 } | |
347 for (int x = 0; x < width_; x++) { | |
348 WritePixel(curr_.get(), x, height_ - 1, 0xff00ff); | |
349 } | |
350 | |
351 MarkDirtyBlocks(prev_.get(), curr_.get()); | |
352 | |
353 // Make sure last (partial) block in each row/column is marked as dirty. | |
354 int x_last = GetDiffInfoWidth() - 2; | |
355 for (int y = 0; y < GetDiffInfoHeight() - 1; y++) { | |
356 EXPECT_TRUE(GetDiffInfo(x_last, y)) | |
357 << "when x = " << x_last << ", and y = " << y; | |
358 } | |
359 int y_last = GetDiffInfoHeight() - 2; | |
360 for (int x = 0; x < GetDiffInfoWidth() - 1; x++) { | |
361 EXPECT_TRUE(GetDiffInfo(x, y_last)) | |
362 << "when x = " << x << ", and y = " << y_last; | |
363 } | |
364 // All other blocks are clean. | |
365 for (int y = 0; y < GetDiffInfoHeight() - 2; y++) { | |
366 for (int x = 0; x < GetDiffInfoWidth() - 2; x++) { | |
367 EXPECT_FALSE(GetDiffInfo(x, y)) << "when x = " << x << ", and y = " << y; | |
368 } | |
369 } | |
370 } | |
371 | |
372 TEST_F(DifferTest, MergeBlocks_Empty) { | |
373 InitDiffer(kScreenWidth, kScreenHeight); | |
374 | |
375 // No blocks marked: | |
376 // +---+---+---+---+ | |
377 // | | | | _ | | |
378 // +---+---+---+---+ | |
379 // | | | | _ | | |
380 // +---+---+---+---+ | |
381 // | | | | _ | | |
382 // +---+---+---+---+ | |
383 // | _ | _ | _ | _ | | |
384 // +---+---+---+---+ | |
385 ClearDiffInfo(); | |
386 | |
387 DesktopRegion dirty; | |
388 MergeBlocks(&dirty); | |
389 | |
390 EXPECT_TRUE(dirty.is_empty()); | |
391 } | |
392 | |
393 TEST_F(DifferTest, MergeBlocks_SingleBlock) { | |
394 InitDiffer(kScreenWidth, kScreenHeight); | |
395 // Mark a single block and make sure that there is a single merged | |
396 // rect with the correct bounds. | |
397 for (int y = 0; y < GetDiffInfoHeight() - 1; y++) { | |
398 for (int x = 0; x < GetDiffInfoWidth() - 1; x++) { | |
399 ASSERT_TRUE(MarkBlocksAndCheckMerge(x, y, 1, 1)) << "x: " << x | |
400 << "y: " << y; | |
401 } | |
402 } | |
403 } | |
404 | |
405 TEST_F(DifferTest, MergeBlocks_BlockRow) { | |
406 InitDiffer(kScreenWidth, kScreenHeight); | |
407 | |
408 // +---+---+---+---+ | |
409 // | X | X | | _ | | |
410 // +---+---+---+---+ | |
411 // | | | | _ | | |
412 // +---+---+---+---+ | |
413 // | | | | _ | | |
414 // +---+---+---+---+ | |
415 // | _ | _ | _ | _ | | |
416 // +---+---+---+---+ | |
417 ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 2, 1)); | |
418 | |
419 // +---+---+---+---+ | |
420 // | | | | _ | | |
421 // +---+---+---+---+ | |
422 // | X | X | X | _ | | |
423 // +---+---+---+---+ | |
424 // | | | | _ | | |
425 // +---+---+---+---+ | |
426 // | _ | _ | _ | _ | | |
427 // +---+---+---+---+ | |
428 ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 1, 3, 1)); | |
429 | |
430 // +---+---+---+---+ | |
431 // | | | | _ | | |
432 // +---+---+---+---+ | |
433 // | | | | _ | | |
434 // +---+---+---+---+ | |
435 // | | X | X | _ | | |
436 // +---+---+---+---+ | |
437 // | _ | _ | _ | _ | | |
438 // +---+---+---+---+ | |
439 ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 2, 2, 1)); | |
440 } | |
441 | |
442 TEST_F(DifferTest, MergeBlocks_BlockColumn) { | |
443 InitDiffer(kScreenWidth, kScreenHeight); | |
444 | |
445 // +---+---+---+---+ | |
446 // | X | | | _ | | |
447 // +---+---+---+---+ | |
448 // | X | | | _ | | |
449 // +---+---+---+---+ | |
450 // | | | | _ | | |
451 // +---+---+---+---+ | |
452 // | _ | _ | _ | _ | | |
453 // +---+---+---+---+ | |
454 ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 1, 2)); | |
455 | |
456 // +---+---+---+---+ | |
457 // | | | | _ | | |
458 // +---+---+---+---+ | |
459 // | | X | | _ | | |
460 // +---+---+---+---+ | |
461 // | | X | | _ | | |
462 // +---+---+---+---+ | |
463 // | _ | _ | _ | _ | | |
464 // +---+---+---+---+ | |
465 ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 1, 1, 2)); | |
466 | |
467 // +---+---+---+---+ | |
468 // | | | X | _ | | |
469 // +---+---+---+---+ | |
470 // | | | X | _ | | |
471 // +---+---+---+---+ | |
472 // | | | X | _ | | |
473 // +---+---+---+---+ | |
474 // | _ | _ | _ | _ | | |
475 // +---+---+---+---+ | |
476 ASSERT_TRUE(MarkBlocksAndCheckMerge(2, 0, 1, 3)); | |
477 } | |
478 | |
479 TEST_F(DifferTest, MergeBlocks_BlockRect) { | |
480 InitDiffer(kScreenWidth, kScreenHeight); | |
481 | |
482 // +---+---+---+---+ | |
483 // | X | X | | _ | | |
484 // +---+---+---+---+ | |
485 // | X | X | | _ | | |
486 // +---+---+---+---+ | |
487 // | | | | _ | | |
488 // +---+---+---+---+ | |
489 // | _ | _ | _ | _ | | |
490 // +---+---+---+---+ | |
491 ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 2, 2)); | |
492 | |
493 // +---+---+---+---+ | |
494 // | | | | _ | | |
495 // +---+---+---+---+ | |
496 // | | X | X | _ | | |
497 // +---+---+---+---+ | |
498 // | | X | X | _ | | |
499 // +---+---+---+---+ | |
500 // | _ | _ | _ | _ | | |
501 // +---+---+---+---+ | |
502 ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 1, 2, 2)); | |
503 | |
504 // +---+---+---+---+ | |
505 // | | X | X | _ | | |
506 // +---+---+---+---+ | |
507 // | | X | X | _ | | |
508 // +---+---+---+---+ | |
509 // | | X | X | _ | | |
510 // +---+---+---+---+ | |
511 // | _ | _ | _ | _ | | |
512 // +---+---+---+---+ | |
513 ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 0, 2, 3)); | |
514 | |
515 // +---+---+---+---+ | |
516 // | | | | _ | | |
517 // +---+---+---+---+ | |
518 // | X | X | X | _ | | |
519 // +---+---+---+---+ | |
520 // | X | X | X | _ | | |
521 // +---+---+---+---+ | |
522 // | _ | _ | _ | _ | | |
523 // +---+---+---+---+ | |
524 ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 1, 3, 2)); | |
525 | |
526 // +---+---+---+---+ | |
527 // | X | X | X | _ | | |
528 // +---+---+---+---+ | |
529 // | X | X | X | _ | | |
530 // +---+---+---+---+ | |
531 // | X | X | X | _ | | |
532 // +---+---+---+---+ | |
533 // | _ | _ | _ | _ | | |
534 // +---+---+---+---+ | |
535 ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 3, 3)); | |
536 } | |
537 | |
538 // This tests marked regions that require more than 1 single dirty rect. | |
539 // The exact rects returned depend on the current implementation, so these | |
540 // may need to be updated if we modify how we merge blocks. | |
541 TEST_F(DifferTest, MergeBlocks_MultiRect) { | |
542 InitDiffer(kScreenWidth, kScreenHeight); | |
543 DesktopRegion dirty; | |
544 | |
545 // +---+---+---+---+ +---+---+---+ | |
546 // | | X | | _ | | | 0 | | | |
547 // +---+---+---+---+ +---+---+---+ | |
548 // | X | | | _ | | 1 | | | | |
549 // +---+---+---+---+ => +---+---+---+ | |
550 // | | | X | _ | | | | 2 | | |
551 // +---+---+---+---+ +---+---+---+ | |
552 // | _ | _ | _ | _ | | |
553 // +---+---+---+---+ | |
554 ClearDiffInfo(); | |
555 MarkBlocks(1, 0, 1, 1); | |
556 MarkBlocks(0, 1, 1, 1); | |
557 MarkBlocks(2, 2, 1, 1); | |
558 | |
559 dirty.Clear(); | |
560 MergeBlocks(&dirty); | |
561 | |
562 ASSERT_EQ(3, RegionRectCount(dirty)); | |
563 ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 0, 1, 1)); | |
564 ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 1, 1)); | |
565 ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 2, 1, 1)); | |
566 | |
567 // +---+---+---+---+ +---+---+---+ | |
568 // | | | X | _ | | | | 0 | | |
569 // +---+---+---+---+ +---+---+---+ | |
570 // | X | X | X | _ | | 1 1 1 | | |
571 // +---+---+---+---+ => + + | |
572 // | X | X | X | _ | | 1 1 1 | | |
573 // +---+---+---+---+ +---+---+---+ | |
574 // | _ | _ | _ | _ | | |
575 // +---+---+---+---+ | |
576 ClearDiffInfo(); | |
577 MarkBlocks(2, 0, 1, 1); | |
578 MarkBlocks(0, 1, 3, 2); | |
579 | |
580 dirty.Clear(); | |
581 MergeBlocks(&dirty); | |
582 | |
583 ASSERT_EQ(2, RegionRectCount(dirty)); | |
584 ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 0, 1, 1)); | |
585 ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 3, 2)); | |
586 | |
587 // +---+---+---+---+ +---+---+---+ | |
588 // | | | | _ | | | | | | |
589 // +---+---+---+---+ +---+---+---+ | |
590 // | X | | X | _ | | 0 | | 1 | | |
591 // +---+---+---+---+ => +---+---+---+ | |
592 // | X | X | X | _ | | 2 2 2 | | |
593 // +---+---+---+---+ +---+---+---+ | |
594 // | _ | _ | _ | _ | | |
595 // +---+---+---+---+ | |
596 ClearDiffInfo(); | |
597 MarkBlocks(0, 1, 1, 1); | |
598 MarkBlocks(2, 1, 1, 1); | |
599 MarkBlocks(0, 2, 3, 1); | |
600 | |
601 dirty.Clear(); | |
602 MergeBlocks(&dirty); | |
603 | |
604 ASSERT_EQ(3, RegionRectCount(dirty)); | |
605 ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 1, 1)); | |
606 ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 1, 1, 1)); | |
607 ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 2, 3, 1)); | |
608 | |
609 // +---+---+---+---+ +---+---+---+ | |
610 // | X | X | X | _ | | 0 0 0 | | |
611 // +---+---+---+---+ +---+---+---+ | |
612 // | X | | X | _ | | 1 | | 2 | | |
613 // +---+---+---+---+ => +---+---+---+ | |
614 // | X | X | X | _ | | 3 3 3 | | |
615 // +---+---+---+---+ +---+---+---+ | |
616 // | _ | _ | _ | _ | | |
617 // +---+---+---+---+ | |
618 ClearDiffInfo(); | |
619 MarkBlocks(0, 0, 3, 1); | |
620 MarkBlocks(0, 1, 1, 1); | |
621 MarkBlocks(2, 1, 1, 1); | |
622 MarkBlocks(0, 2, 3, 1); | |
623 | |
624 dirty.Clear(); | |
625 MergeBlocks(&dirty); | |
626 | |
627 ASSERT_EQ(4, RegionRectCount(dirty)); | |
628 ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 3, 1)); | |
629 ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 1, 1)); | |
630 ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 1, 1, 1)); | |
631 ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 2, 3, 1)); | |
632 | |
633 // +---+---+---+---+ +---+---+---+ | |
634 // | X | X | | _ | | 0 0 | | | |
635 // +---+---+---+---+ + +---+ | |
636 // | X | X | | _ | | 0 0 | | | |
637 // +---+---+---+---+ => +---+---+---+ | |
638 // | | X | | _ | | | 1 | | | |
639 // +---+---+---+---+ +---+---+---+ | |
640 // | _ | _ | _ | _ | | |
641 // +---+---+---+---+ | |
642 ClearDiffInfo(); | |
643 MarkBlocks(0, 0, 2, 2); | |
644 MarkBlocks(1, 2, 1, 1); | |
645 | |
646 dirty.Clear(); | |
647 MergeBlocks(&dirty); | |
648 | |
649 ASSERT_EQ(2, RegionRectCount(dirty)); | |
650 ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 2, 2)); | |
651 ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 2, 1, 1)); | |
652 } | |
653 | |
654 } // namespace webrtc | |
OLD | NEW |