OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/scoped_ptr.h" | 5 #include "base/scoped_ptr.h" |
6 #include "remoting/host/differ.h" | 6 #include "remoting/host/differ.h" |
7 #include "testing/gmock/include/gmock/gmock.h" | 7 #include "testing/gmock/include/gmock/gmock.h" |
8 | 8 |
9 namespace remoting { | 9 namespace remoting { |
10 | 10 |
11 // 96x96 screen gives a 3x3 grid of blocks. | 11 // 96x96 screen gives a 3x3 grid of blocks. |
12 const int kScreenWidth = 96; | 12 const int kScreenWidth= 96; |
13 const int kScreenHeight = 96; | 13 const int kScreenHeight = 96; |
14 const int kBytesPerPixel = 3; | 14 const int kBytesPerPixel = 3; |
| 15 const int kBytesPerRow = (kBytesPerPixel * kScreenWidth); |
15 | 16 |
16 class DifferTest : public testing::Test { | 17 class DifferTest : public testing::Test { |
17 public: | 18 public: |
18 DifferTest() { | 19 DifferTest() { |
19 } | 20 } |
20 | 21 |
21 protected: | 22 protected: |
22 virtual void SetUp() { | 23 virtual void SetUp() { |
23 InitDiffer(kScreenWidth, kScreenHeight, kBytesPerPixel); | 24 InitDiffer(kScreenWidth, kScreenHeight, kBytesPerPixel, kBytesPerRow); |
24 } | 25 } |
25 | 26 |
26 void InitDiffer(int width, int height, int bpp) { | 27 void InitDiffer(int width, int height, int bpp, int stride) { |
27 width_ = width; | 28 width_ = width; |
28 height_ = height; | 29 height_ = height; |
29 bytes_per_pixel_ = bpp; | 30 bytes_per_pixel_ = bpp; |
30 | 31 stride_ = stride; |
31 stride_ = width_ * bytes_per_pixel_; | |
32 buffer_size_ = width_ * height_ * bytes_per_pixel_; | 32 buffer_size_ = width_ * height_ * bytes_per_pixel_; |
33 | 33 |
34 differ_.reset(new Differ(width_, height_, bytes_per_pixel_)); | 34 differ_.reset(new Differ(width_, height_, bytes_per_pixel_, stride_)); |
35 | 35 |
36 prev_.reset(new uint8[buffer_size_]); | 36 prev_.reset(new uint8[buffer_size_]); |
37 memset(prev_.get(), 0, buffer_size_); | 37 memset(prev_.get(), 0, buffer_size_); |
38 | 38 |
39 curr_.reset(new uint8[buffer_size_]); | 39 curr_.reset(new uint8[buffer_size_]); |
40 memset(curr_.get(), 0, buffer_size_); | 40 memset(curr_.get(), 0, buffer_size_); |
41 } | 41 } |
42 | 42 |
43 void ClearBuffer(uint8* buffer) { | 43 void ClearBuffer(uint8* buffer) { |
44 memset(buffer, 0, buffer_size_); | 44 memset(buffer, 0, buffer_size_); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 for (int y = 0; y < height; y++) { | 119 for (int y = 0; y < height; y++) { |
120 for (int x = 0; x < width; x++) { | 120 for (int x = 0; x < width; x++) { |
121 SetDiffInfo(x_origin + x, y_origin + y, 1); | 121 SetDiffInfo(x_origin + x, y_origin + y, 1); |
122 } | 122 } |
123 } | 123 } |
124 } | 124 } |
125 | 125 |
126 // Verify that the given dirty rect matches the expected |x|, |y|, |width| | 126 // Verify that the given dirty rect matches the expected |x|, |y|, |width| |
127 // and |height|. | 127 // and |height|. |
128 // |x|, |y|, |width| and |height| are specified in block (not pixel) units. | 128 // |x|, |y|, |width| and |height| are specified in block (not pixel) units. |
129 void CheckDirtyRect(const gfx::Rect& rect, int x, int y, | 129 void CheckDirtyRect(const InvalidRects& rects, int x, int y, |
130 int width, int height) { | 130 int width, int height) { |
131 EXPECT_EQ(x * kBlockSize, rect.x()); | 131 gfx::Rect r(x * kBlockSize, y * kBlockSize, |
132 EXPECT_EQ(y * kBlockSize, rect.y()); | 132 width * kBlockSize, height * kBlockSize); |
133 EXPECT_EQ(width * kBlockSize, rect.width()); | 133 EXPECT_TRUE(rects.find(r) != rects.end()); |
134 EXPECT_EQ(height * kBlockSize, rect.height()); | |
135 } | 134 } |
136 | 135 |
137 // Mark the range of blocks specified and then verify that they are | 136 // Mark the range of blocks specified and then verify that they are |
138 // merged correctly. | 137 // merged correctly. |
139 // Only one rectangular region of blocks can be checked with this routine. | 138 // Only one rectangular region of blocks can be checked with this routine. |
140 void MarkBlocksAndCheckMerge(int x_origin, int y_origin, | 139 void MarkBlocksAndCheckMerge(int x_origin, int y_origin, |
141 int width, int height) { | 140 int width, int height) { |
142 ClearDiffInfo(); | 141 ClearDiffInfo(); |
143 MarkBlocks(x_origin, y_origin, width, height); | 142 MarkBlocks(x_origin, y_origin, width, height); |
144 | 143 |
145 scoped_ptr<DirtyRects> dirty(new DirtyRects()); | 144 scoped_ptr<InvalidRects> dirty(new InvalidRects()); |
146 differ_->MergeBlocks(dirty.get()); | 145 differ_->MergeBlocks(dirty.get()); |
147 | 146 |
148 ASSERT_EQ(1UL, dirty->size()); | 147 ASSERT_EQ(1UL, dirty->size()); |
149 CheckDirtyRect(dirty->at(0), x_origin, y_origin, width, height); | 148 CheckDirtyRect(*dirty.get(), x_origin, y_origin, width, height); |
150 } | 149 } |
151 | 150 |
152 // The differ class we're testing. | 151 // The differ class we're testing. |
153 scoped_ptr<Differ> differ_; | 152 scoped_ptr<Differ> differ_; |
154 | 153 |
155 // Screen/buffer info. | 154 // Screen/buffer info. |
156 int width_; | 155 int width_; |
157 int height_; | 156 int height_; |
158 int bytes_per_pixel_; | 157 int bytes_per_pixel_; |
159 int stride_; | 158 int stride_; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 // | | | | _ | | 261 // | | | | _ | |
263 // +---+---+---+---+ | 262 // +---+---+---+---+ |
264 // | | | | _ | | 263 // | | | | _ | |
265 // +---+---+---+---+ | 264 // +---+---+---+---+ |
266 // | | | | _ | | 265 // | | | | _ | |
267 // +---+---+---+---+ | 266 // +---+---+---+---+ |
268 // | _ | _ | _ | _ | | 267 // | _ | _ | _ | _ | |
269 // +---+---+---+---+ | 268 // +---+---+---+---+ |
270 ClearDiffInfo(); | 269 ClearDiffInfo(); |
271 | 270 |
272 scoped_ptr<DirtyRects> dirty(new DirtyRects()); | 271 scoped_ptr<InvalidRects> dirty(new InvalidRects()); |
273 differ_->MergeBlocks(dirty.get()); | 272 differ_->MergeBlocks(dirty.get()); |
274 | 273 |
275 EXPECT_EQ(0UL, dirty->size()); | 274 EXPECT_EQ(0UL, dirty->size()); |
276 } | 275 } |
277 | 276 |
278 TEST_F(DifferTest, MergeBlocks_SingleBlock) { | 277 TEST_F(DifferTest, MergeBlocks_SingleBlock) { |
279 // Mark a single block and make sure that there is a single merged | 278 // Mark a single block and make sure that there is a single merged |
280 // rect with the correct bounds. | 279 // rect with the correct bounds. |
281 for (int y = 0; y < GetDiffInfoHeight() - 1; y++) { | 280 for (int y = 0; y < GetDiffInfoHeight() - 1; y++) { |
282 for (int x = 0; x < GetDiffInfoWidth() - 1; x++) { | 281 for (int x = 0; x < GetDiffInfoWidth() - 1; x++) { |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 // +---+---+---+---+ | 408 // +---+---+---+---+ |
410 // | _ | _ | _ | _ | | 409 // | _ | _ | _ | _ | |
411 // +---+---+---+---+ | 410 // +---+---+---+---+ |
412 MarkBlocksAndCheckMerge(0, 0, 3, 3); | 411 MarkBlocksAndCheckMerge(0, 0, 3, 3); |
413 } | 412 } |
414 | 413 |
415 // This tests marked regions that require more than 1 single dirty rect. | 414 // This tests marked regions that require more than 1 single dirty rect. |
416 // The exact rects returned depend on the current implementation, so these | 415 // The exact rects returned depend on the current implementation, so these |
417 // may need to be updated if we modify how we merge blocks. | 416 // may need to be updated if we modify how we merge blocks. |
418 TEST_F(DifferTest, MergeBlocks_MultiRect) { | 417 TEST_F(DifferTest, MergeBlocks_MultiRect) { |
419 scoped_ptr<DirtyRects> dirty; | 418 scoped_ptr<InvalidRects> dirty; |
420 | 419 |
421 // +---+---+---+---+ +---+---+---+ | 420 // +---+---+---+---+ +---+---+---+ |
422 // | | X | | _ | | | 0 | | | 421 // | | X | | _ | | | 0 | | |
423 // +---+---+---+---+ +---+---+---+ | 422 // +---+---+---+---+ +---+---+---+ |
424 // | X | | | _ | | 1 | | | | 423 // | X | | | _ | | 1 | | | |
425 // +---+---+---+---+ => +---+---+---+ | 424 // +---+---+---+---+ => +---+---+---+ |
426 // | | | X | _ | | | | 2 | | 425 // | | | X | _ | | | | 2 | |
427 // +---+---+---+---+ +---+---+---+ | 426 // +---+---+---+---+ +---+---+---+ |
428 // | _ | _ | _ | _ | | 427 // | _ | _ | _ | _ | |
429 // +---+---+---+---+ | 428 // +---+---+---+---+ |
430 ClearDiffInfo(); | 429 ClearDiffInfo(); |
431 MarkBlocks(1, 0, 1, 1); | 430 MarkBlocks(1, 0, 1, 1); |
432 MarkBlocks(0, 1, 1, 1); | 431 MarkBlocks(0, 1, 1, 1); |
433 MarkBlocks(2, 2, 1, 1); | 432 MarkBlocks(2, 2, 1, 1); |
434 | 433 |
435 dirty.reset(new DirtyRects()); | 434 dirty.reset(new InvalidRects()); |
436 differ_->MergeBlocks(dirty.get()); | 435 differ_->MergeBlocks(dirty.get()); |
437 | 436 |
438 ASSERT_EQ(3UL, dirty->size()); | 437 ASSERT_EQ(3UL, dirty->size()); |
439 CheckDirtyRect(dirty->at(0), 1, 0, 1, 1); | 438 CheckDirtyRect(*dirty.get(), 1, 0, 1, 1); |
440 CheckDirtyRect(dirty->at(1), 0, 1, 1, 1); | 439 CheckDirtyRect(*dirty.get(), 0, 1, 1, 1); |
441 CheckDirtyRect(dirty->at(2), 2, 2, 1, 1); | 440 CheckDirtyRect(*dirty.get(), 2, 2, 1, 1); |
442 | 441 |
443 // +---+---+---+---+ +---+---+---+ | 442 // +---+---+---+---+ +---+---+---+ |
444 // | | | X | _ | | | | 0 | | 443 // | | | X | _ | | | | 0 | |
445 // +---+---+---+---+ +---+---+ + | 444 // +---+---+---+---+ +---+---+ + |
446 // | X | X | X | _ | | 1 1 | 0 | | 445 // | X | X | X | _ | | 1 1 | 0 | |
447 // +---+---+---+---+ => + + + | 446 // +---+---+---+---+ => + + + |
448 // | X | X | X | _ | | 1 1 | 0 | | 447 // | X | X | X | _ | | 1 1 | 0 | |
449 // +---+---+---+---+ +---+---+---+ | 448 // +---+---+---+---+ +---+---+---+ |
450 // | _ | _ | _ | _ | | 449 // | _ | _ | _ | _ | |
451 // +---+---+---+---+ | 450 // +---+---+---+---+ |
452 ClearDiffInfo(); | 451 ClearDiffInfo(); |
453 MarkBlocks(2, 0, 1, 3); | 452 MarkBlocks(2, 0, 1, 3); |
454 MarkBlocks(0, 1, 2, 2); | 453 MarkBlocks(0, 1, 2, 2); |
455 | 454 |
456 dirty.reset(new DirtyRects()); | 455 dirty.reset(new InvalidRects()); |
457 differ_->MergeBlocks(dirty.get()); | 456 differ_->MergeBlocks(dirty.get()); |
458 | 457 |
459 ASSERT_EQ(2UL, dirty->size()); | 458 ASSERT_EQ(2UL, dirty->size()); |
460 CheckDirtyRect(dirty->at(0), 2, 0, 1, 3); | 459 CheckDirtyRect(*dirty.get(), 2, 0, 1, 3); |
461 CheckDirtyRect(dirty->at(1), 0, 1, 2, 2); | 460 CheckDirtyRect(*dirty.get(), 0, 1, 2, 2); |
462 | 461 |
463 // +---+---+---+---+ +---+---+---+ | 462 // +---+---+---+---+ +---+---+---+ |
464 // | | | | _ | | | | | | 463 // | | | | _ | | | | | |
465 // +---+---+---+---+ +---+---+---+ | 464 // +---+---+---+---+ +---+---+---+ |
466 // | X | | X | _ | | 0 | | 1 | | 465 // | X | | X | _ | | 0 | | 1 | |
467 // +---+---+---+---+ => + +---+ + | 466 // +---+---+---+---+ => + +---+ + |
468 // | X | X | X | _ | | 0 | 2 | 1 | | 467 // | X | X | X | _ | | 0 | 2 | 1 | |
469 // +---+---+---+---+ +---+---+---+ | 468 // +---+---+---+---+ +---+---+---+ |
470 // | _ | _ | _ | _ | | 469 // | _ | _ | _ | _ | |
471 // +---+---+---+---+ | 470 // +---+---+---+---+ |
472 ClearDiffInfo(); | 471 ClearDiffInfo(); |
473 MarkBlocks(0, 1, 1, 1); | 472 MarkBlocks(0, 1, 1, 1); |
474 MarkBlocks(2, 1, 1, 1); | 473 MarkBlocks(2, 1, 1, 1); |
475 MarkBlocks(0, 2, 3, 1); | 474 MarkBlocks(0, 2, 3, 1); |
476 | 475 |
477 dirty.reset(new DirtyRects()); | 476 dirty.reset(new InvalidRects()); |
478 differ_->MergeBlocks(dirty.get()); | 477 differ_->MergeBlocks(dirty.get()); |
479 | 478 |
480 ASSERT_EQ(3UL, dirty->size()); | 479 ASSERT_EQ(3UL, dirty->size()); |
481 CheckDirtyRect(dirty->at(0), 0, 1, 1, 2); | 480 CheckDirtyRect(*dirty.get(), 0, 1, 1, 2); |
482 CheckDirtyRect(dirty->at(1), 2, 1, 1, 2); | 481 CheckDirtyRect(*dirty.get(), 2, 1, 1, 2); |
483 CheckDirtyRect(dirty->at(2), 1, 2, 1, 1); | 482 CheckDirtyRect(*dirty.get(), 1, 2, 1, 1); |
484 | 483 |
485 // +---+---+---+---+ +---+---+---+ | 484 // +---+---+---+---+ +---+---+---+ |
486 // | X | X | X | _ | | 0 0 0 | | 485 // | X | X | X | _ | | 0 0 0 | |
487 // +---+---+---+---+ +---+---+---+ | 486 // +---+---+---+---+ +---+---+---+ |
488 // | X | | X | _ | | 1 | | 2 | | 487 // | X | | X | _ | | 1 | | 2 | |
489 // +---+---+---+---+ => + +---+ + | 488 // +---+---+---+---+ => + +---+ + |
490 // | X | X | X | _ | | 1 | 3 | 2 | | 489 // | X | X | X | _ | | 1 | 3 | 2 | |
491 // +---+---+---+---+ +---+---+---+ | 490 // +---+---+---+---+ +---+---+---+ |
492 // | _ | _ | _ | _ | | 491 // | _ | _ | _ | _ | |
493 // +---+---+---+---+ | 492 // +---+---+---+---+ |
494 ClearDiffInfo(); | 493 ClearDiffInfo(); |
495 MarkBlocks(0, 0, 3, 1); | 494 MarkBlocks(0, 0, 3, 1); |
496 MarkBlocks(0, 1, 1, 1); | 495 MarkBlocks(0, 1, 1, 1); |
497 MarkBlocks(2, 1, 1, 1); | 496 MarkBlocks(2, 1, 1, 1); |
498 MarkBlocks(0, 2, 3, 1); | 497 MarkBlocks(0, 2, 3, 1); |
499 | 498 |
500 dirty.reset(new DirtyRects()); | 499 dirty.reset(new InvalidRects()); |
501 differ_->MergeBlocks(dirty.get()); | 500 differ_->MergeBlocks(dirty.get()); |
502 | 501 |
503 ASSERT_EQ(4UL, dirty->size()); | 502 ASSERT_EQ(4UL, dirty->size()); |
504 CheckDirtyRect(dirty->at(0), 0, 0, 3, 1); | 503 CheckDirtyRect(*dirty.get(), 0, 0, 3, 1); |
505 CheckDirtyRect(dirty->at(1), 0, 1, 1, 2); | 504 CheckDirtyRect(*dirty.get(), 0, 1, 1, 2); |
506 CheckDirtyRect(dirty->at(2), 2, 1, 1, 2); | 505 CheckDirtyRect(*dirty.get(), 2, 1, 1, 2); |
507 CheckDirtyRect(dirty->at(3), 1, 2, 1, 1); | 506 CheckDirtyRect(*dirty.get(), 1, 2, 1, 1); |
508 | 507 |
509 // +---+---+---+---+ +---+---+---+ | 508 // +---+---+---+---+ +---+---+---+ |
510 // | X | X | | _ | | 0 0 | | | 509 // | X | X | | _ | | 0 0 | | |
511 // +---+---+---+---+ + +---+ | 510 // +---+---+---+---+ + +---+ |
512 // | X | X | | _ | | 0 0 | | | 511 // | X | X | | _ | | 0 0 | | |
513 // +---+---+---+---+ => +---+---+---+ | 512 // +---+---+---+---+ => +---+---+---+ |
514 // | | X | | _ | | | 1 | | | 513 // | | X | | _ | | | 1 | | |
515 // +---+---+---+---+ +---+---+---+ | 514 // +---+---+---+---+ +---+---+---+ |
516 // | _ | _ | _ | _ | | 515 // | _ | _ | _ | _ | |
517 // +---+---+---+---+ | 516 // +---+---+---+---+ |
518 ClearDiffInfo(); | 517 ClearDiffInfo(); |
519 MarkBlocks(0, 0, 2, 2); | 518 MarkBlocks(0, 0, 2, 2); |
520 MarkBlocks(1, 2, 1, 1); | 519 MarkBlocks(1, 2, 1, 1); |
521 | 520 |
522 dirty.reset(new DirtyRects()); | 521 dirty.reset(new InvalidRects()); |
523 differ_->MergeBlocks(dirty.get()); | 522 differ_->MergeBlocks(dirty.get()); |
524 | 523 |
525 ASSERT_EQ(2UL, dirty->size()); | 524 ASSERT_EQ(2UL, dirty->size()); |
526 CheckDirtyRect(dirty->at(0), 0, 0, 2, 2); | 525 CheckDirtyRect(*dirty.get(), 0, 0, 2, 2); |
527 CheckDirtyRect(dirty->at(1), 1, 2, 1, 1); | 526 CheckDirtyRect(*dirty.get(), 1, 2, 1, 1); |
528 } | 527 } |
529 | 528 |
530 } // namespace remoting | 529 } // namespace remoting |
OLD | NEW |