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

Side by Side Diff: remoting/host/differ_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698