tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

desktop_frame_unittest.cc (14466B)


      1 /*
      2 *  Copyright (c) 2019 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 "modules/desktop_capture/desktop_frame.h"
     12 
     13 #include <cstdint>
     14 #include <cstring>
     15 #include <memory>
     16 #include <optional>
     17 
     18 #include "api/array_view.h"
     19 #include "modules/desktop_capture/desktop_geometry.h"
     20 #include "test/gtest.h"
     21 
     22 namespace webrtc {
     23 
     24 namespace {
     25 
     26 std::unique_ptr<DesktopFrame> CreateTestFrame(DesktopRect rect,
     27                                              int pixels_value) {
     28  DesktopSize size = rect.size();
     29  auto frame = std::make_unique<BasicDesktopFrame>(size);
     30  frame->set_top_left(rect.top_left());
     31  memset(frame->data(), pixels_value, frame->stride() * size.height());
     32  return frame;
     33 }
     34 
     35 struct TestData {
     36  const char* description;
     37  DesktopRect dest_frame_rect;
     38  DesktopRect src_frame_rect;
     39  double horizontal_scale;
     40  double vertical_scale;
     41  DesktopRect expected_overlap_rect;
     42 };
     43 
     44 void RunTest(const TestData& test) {
     45  // Copy a source frame with all bits set into a dest frame with none set.
     46  auto dest_frame = CreateTestFrame(test.dest_frame_rect, 0);
     47  auto src_frame = CreateTestFrame(test.src_frame_rect, 0xff);
     48 
     49  dest_frame->CopyIntersectingPixelsFrom(*src_frame, test.horizontal_scale,
     50                                         test.vertical_scale);
     51 
     52  // Translate the expected overlap rect to be relative to the dest frame/rect.
     53  DesktopVector dest_frame_origin = test.dest_frame_rect.top_left();
     54  DesktopRect relative_expected_overlap_rect = test.expected_overlap_rect;
     55  relative_expected_overlap_rect.Translate(-dest_frame_origin.x(),
     56                                           -dest_frame_origin.y());
     57 
     58  // Confirm bits are now set in the dest frame if & only if they fall in the
     59  // expected range.
     60  for (int y = 0; y < dest_frame->size().height(); ++y) {
     61    SCOPED_TRACE(y);
     62 
     63    for (int x = 0; x < dest_frame->size().width(); ++x) {
     64      SCOPED_TRACE(x);
     65 
     66      DesktopVector point(x, y);
     67      uint8_t* data = dest_frame->GetFrameDataAtPos(point);
     68      uint32_t pixel_value = *reinterpret_cast<uint32_t*>(data);
     69      bool was_copied = pixel_value == 0xffffffff;
     70      ASSERT_TRUE(was_copied || pixel_value == 0);
     71 
     72      bool expected_to_be_copied =
     73          relative_expected_overlap_rect.Contains(point);
     74 
     75      ASSERT_EQ(was_copied, expected_to_be_copied);
     76    }
     77  }
     78 }
     79 
     80 void RunTests(ArrayView<const TestData> tests) {
     81  for (const TestData& test : tests) {
     82    SCOPED_TRACE(test.description);
     83 
     84    RunTest(test);
     85  }
     86 }
     87 
     88 }  // namespace
     89 
     90 TEST(DesktopFrameTest, NewFrameIsBlack) {
     91  auto frame = std::make_unique<BasicDesktopFrame>(DesktopSize(10, 10));
     92  EXPECT_TRUE(frame->FrameDataIsBlack());
     93 }
     94 
     95 TEST(DesktopFrameTest, EmptyFrameIsNotBlack) {
     96  auto frame = std::make_unique<BasicDesktopFrame>(DesktopSize());
     97  EXPECT_FALSE(frame->FrameDataIsBlack());
     98 }
     99 
    100 TEST(DesktopFrameTest, FrameHasDefaultDeviceScaleFactor) {
    101  auto frame = std::make_unique<BasicDesktopFrame>(DesktopSize());
    102  EXPECT_EQ(frame->device_scale_factor(), std::nullopt);
    103 }
    104 
    105 TEST(DesktopFrameTest, FrameSetsDeviceScaleFactorCorrectly) {
    106  auto frame = std::make_unique<BasicDesktopFrame>(DesktopSize());
    107  EXPECT_EQ(frame->device_scale_factor(), std::nullopt);
    108  float device_scale_factor = 1.5f;
    109  frame->set_device_scale_factor(device_scale_factor);
    110  EXPECT_EQ(frame->device_scale_factor(), device_scale_factor);
    111 }
    112 
    113 TEST(DesktopFrameTest, FrameDataSwitchesBetweenNonBlackAndBlack) {
    114  auto frame = CreateTestFrame(DesktopRect::MakeXYWH(0, 0, 10, 10), 0xff);
    115  EXPECT_FALSE(frame->FrameDataIsBlack());
    116  frame->SetFrameDataToBlack();
    117  EXPECT_TRUE(frame->FrameDataIsBlack());
    118 }
    119 
    120 TEST(DesktopFrameTest, CopyIntersectingPixelsMatchingRects) {
    121  const TestData tests[] = {
    122      {.description = "0 origin",
    123       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    124       .src_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    125       .horizontal_scale = 1.0,
    126       .vertical_scale = 1.0,
    127       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 0, 2, 2)},
    128 
    129      {.description = "Negative origin",
    130       .dest_frame_rect = DesktopRect::MakeXYWH(-1, -1, 2, 2),
    131       .src_frame_rect = DesktopRect::MakeXYWH(-1, -1, 2, 2),
    132       .horizontal_scale = 1.0,
    133       .vertical_scale = 1.0,
    134       .expected_overlap_rect = DesktopRect::MakeXYWH(-1, -1, 2, 2)}};
    135 
    136  RunTests(tests);
    137 }
    138 
    139 TEST(DesktopFrameTest, CopyIntersectingPixelsMatchingRectsScaled) {
    140  // The scale factors shouldn't affect matching rects (they're only applied
    141  // to any difference between the origins)
    142  const TestData tests[] = {
    143      {.description = "0 origin 2x",
    144       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    145       .src_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    146       .horizontal_scale = 2.0,
    147       .vertical_scale = 2.0,
    148       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 0, 2, 2)},
    149 
    150      {.description = "0 origin 0.5x",
    151       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    152       .src_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    153       .horizontal_scale = 0.5,
    154       .vertical_scale = 0.5,
    155       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 0, 2, 2)},
    156 
    157      {.description = "Negative origin 2x",
    158       .dest_frame_rect = DesktopRect::MakeXYWH(-1, -1, 2, 2),
    159       .src_frame_rect = DesktopRect::MakeXYWH(-1, -1, 2, 2),
    160       .horizontal_scale = 2.0,
    161       .vertical_scale = 2.0,
    162       .expected_overlap_rect = DesktopRect::MakeXYWH(-1, -1, 2, 2)},
    163 
    164      {.description = "Negative origin 0.5x",
    165       .dest_frame_rect = DesktopRect::MakeXYWH(-1, -1, 2, 2),
    166       .src_frame_rect = DesktopRect::MakeXYWH(-1, -1, 2, 2),
    167       .horizontal_scale = 0.5,
    168       .vertical_scale = 0.5,
    169       .expected_overlap_rect = DesktopRect::MakeXYWH(-1, -1, 2, 2)}};
    170 
    171  RunTests(tests);
    172 }
    173 
    174 TEST(DesktopFrameTest, CopyIntersectingPixelsFullyContainedRects) {
    175  const TestData tests[] = {
    176      {.description = "0 origin top left",
    177       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    178       .src_frame_rect = DesktopRect::MakeXYWH(0, 0, 1, 1),
    179       .horizontal_scale = 1.0,
    180       .vertical_scale = 1.0,
    181       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 0, 1, 1)},
    182 
    183      {.description = "0 origin bottom right",
    184       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    185       .src_frame_rect = DesktopRect::MakeXYWH(1, 1, 1, 1),
    186       .horizontal_scale = 1.0,
    187       .vertical_scale = 1.0,
    188       .expected_overlap_rect = DesktopRect::MakeXYWH(1, 1, 1, 1)},
    189 
    190      {.description = "Negative origin bottom left",
    191       .dest_frame_rect = DesktopRect::MakeXYWH(-1, -1, 2, 2),
    192       .src_frame_rect = DesktopRect::MakeXYWH(-1, 0, 1, 1),
    193       .horizontal_scale = 1.0,
    194       .vertical_scale = 1.0,
    195       .expected_overlap_rect = DesktopRect::MakeXYWH(-1, 0, 1, 1)}};
    196 
    197  RunTests(tests);
    198 }
    199 
    200 TEST(DesktopFrameTest, CopyIntersectingPixelsFullyContainedRectsScaled) {
    201  const TestData tests[] = {
    202      {.description = "0 origin top left 2x",
    203       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    204       .src_frame_rect = DesktopRect::MakeXYWH(0, 0, 1, 1),
    205       .horizontal_scale = 2.0,
    206       .vertical_scale = 2.0,
    207       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 0, 1, 1)},
    208 
    209      {.description = "0 origin top left 0.5x",
    210       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    211       .src_frame_rect = DesktopRect::MakeXYWH(0, 0, 1, 1),
    212       .horizontal_scale = 0.5,
    213       .vertical_scale = 0.5,
    214       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 0, 1, 1)},
    215 
    216      {.description = "0 origin bottom left 2x",
    217       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 4, 4),
    218       .src_frame_rect = DesktopRect::MakeXYWH(1, 1, 2, 2),
    219       .horizontal_scale = 2.0,
    220       .vertical_scale = 2.0,
    221       .expected_overlap_rect = DesktopRect::MakeXYWH(2, 2, 2, 2)},
    222 
    223      {.description = "0 origin bottom middle 2x/1x",
    224       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 4, 3),
    225       .src_frame_rect = DesktopRect::MakeXYWH(1, 1, 2, 2),
    226       .horizontal_scale = 2.0,
    227       .vertical_scale = 1.0,
    228       .expected_overlap_rect = DesktopRect::MakeXYWH(2, 1, 2, 2)},
    229 
    230      {.description = "0 origin middle 0.5x",
    231       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 3, 3),
    232       .src_frame_rect = DesktopRect::MakeXYWH(2, 2, 1, 1),
    233       .horizontal_scale = 0.5,
    234       .vertical_scale = 0.5,
    235       .expected_overlap_rect = DesktopRect::MakeXYWH(1, 1, 1, 1)},
    236 
    237      {.description = "Negative origin bottom left 2x",
    238       .dest_frame_rect = DesktopRect::MakeXYWH(-1, -1, 3, 3),
    239       .src_frame_rect = DesktopRect::MakeXYWH(-1, 0, 1, 1),
    240       .horizontal_scale = 2.0,
    241       .vertical_scale = 2.0,
    242       .expected_overlap_rect = DesktopRect::MakeXYWH(-1, 1, 1, 1)},
    243 
    244      {.description = "Negative origin near middle 0.5x",
    245       .dest_frame_rect = DesktopRect::MakeXYWH(-2, -2, 2, 2),
    246       .src_frame_rect = DesktopRect::MakeXYWH(0, 0, 1, 1),
    247       .horizontal_scale = 0.5,
    248       .vertical_scale = 0.5,
    249       .expected_overlap_rect = DesktopRect::MakeXYWH(-1, -1, 1, 1)}};
    250 
    251  RunTests(tests);
    252 }
    253 
    254 TEST(DesktopFrameTest, CopyIntersectingPixelsPartiallyContainedRects) {
    255  const TestData tests[] = {
    256      {.description = "Top left",
    257       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    258       .src_frame_rect = DesktopRect::MakeXYWH(-1, -1, 2, 2),
    259       .horizontal_scale = 1.0,
    260       .vertical_scale = 1.0,
    261       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 0, 1, 1)},
    262 
    263      {.description = "Top right",
    264       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    265       .src_frame_rect = DesktopRect::MakeXYWH(1, -1, 2, 2),
    266       .horizontal_scale = 1.0,
    267       .vertical_scale = 1.0,
    268       .expected_overlap_rect = DesktopRect::MakeXYWH(1, 0, 1, 1)},
    269 
    270      {.description = "Bottom right",
    271       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    272       .src_frame_rect = DesktopRect::MakeXYWH(1, 1, 2, 2),
    273       .horizontal_scale = 1.0,
    274       .vertical_scale = 1.0,
    275       .expected_overlap_rect = DesktopRect::MakeXYWH(1, 1, 1, 1)},
    276 
    277      {.description = "Bottom left",
    278       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    279       .src_frame_rect = DesktopRect::MakeXYWH(-1, 1, 2, 2),
    280       .horizontal_scale = 1.0,
    281       .vertical_scale = 1.0,
    282       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 1, 1, 1)}};
    283 
    284  RunTests(tests);
    285 }
    286 
    287 TEST(DesktopFrameTest, CopyIntersectingPixelsPartiallyContainedRectsScaled) {
    288  const TestData tests[] = {
    289      {.description = "Top left 2x",
    290       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    291       .src_frame_rect = DesktopRect::MakeXYWH(-1, -1, 3, 3),
    292       .horizontal_scale = 2.0,
    293       .vertical_scale = 2.0,
    294       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 0, 1, 1)},
    295 
    296      {.description = "Top right 0.5x",
    297       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    298       .src_frame_rect = DesktopRect::MakeXYWH(2, -2, 2, 2),
    299       .horizontal_scale = 0.5,
    300       .vertical_scale = 0.5,
    301       .expected_overlap_rect = DesktopRect::MakeXYWH(1, 0, 1, 1)},
    302 
    303      {.description = "Bottom right 2x",
    304       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 3, 3),
    305       .src_frame_rect = DesktopRect::MakeXYWH(-1, 1, 3, 3),
    306       .horizontal_scale = 2.0,
    307       .vertical_scale = 2.0,
    308       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 2, 1, 1)},
    309 
    310      {.description = "Bottom left 0.5x",
    311       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    312       .src_frame_rect = DesktopRect::MakeXYWH(-2, 2, 2, 2),
    313       .horizontal_scale = 0.5,
    314       .vertical_scale = 0.5,
    315       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 1, 1, 1)}};
    316 
    317  RunTests(tests);
    318 }
    319 
    320 TEST(DesktopFrameTest, CopyIntersectingPixelsUncontainedRects) {
    321  const TestData tests[] = {
    322      {.description = "Left",
    323       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    324       .src_frame_rect = DesktopRect::MakeXYWH(-1, 0, 1, 2),
    325       .horizontal_scale = 1.0,
    326       .vertical_scale = 1.0,
    327       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 0, 0, 0)},
    328 
    329      {.description = "Top",
    330       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    331       .src_frame_rect = DesktopRect::MakeXYWH(0, -1, 2, 1),
    332       .horizontal_scale = 1.0,
    333       .vertical_scale = 1.0,
    334       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 0, 0, 0)},
    335 
    336      {.description = "Right",
    337       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    338       .src_frame_rect = DesktopRect::MakeXYWH(2, 0, 1, 2),
    339       .horizontal_scale = 1.0,
    340       .vertical_scale = 1.0,
    341       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 0, 0, 0)},
    342 
    343      {.description = "Bottom",
    344       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    345       .src_frame_rect = DesktopRect::MakeXYWH(0, 2, 2, 1),
    346       .horizontal_scale = 1.0,
    347       .vertical_scale = 1.0,
    348       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 0, 0, 0)}};
    349 
    350  RunTests(tests);
    351 }
    352 
    353 TEST(DesktopFrameTest, CopyIntersectingPixelsUncontainedRectsScaled) {
    354  const TestData tests[] = {
    355      {.description = "Left 2x",
    356       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    357       .src_frame_rect = DesktopRect::MakeXYWH(-1, 0, 2, 2),
    358       .horizontal_scale = 2.0,
    359       .vertical_scale = 2.0,
    360       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 0, 0, 0)},
    361 
    362      {.description = "Top 0.5x",
    363       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    364       .src_frame_rect = DesktopRect::MakeXYWH(0, -2, 2, 1),
    365       .horizontal_scale = 0.5,
    366       .vertical_scale = 0.5,
    367       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 0, 0, 0)},
    368 
    369      {.description = "Right 2x",
    370       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    371       .src_frame_rect = DesktopRect::MakeXYWH(1, 0, 1, 2),
    372       .horizontal_scale = 2.0,
    373       .vertical_scale = 2.0,
    374       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 0, 0, 0)},
    375 
    376      {.description = "Bottom 0.5x",
    377       .dest_frame_rect = DesktopRect::MakeXYWH(0, 0, 2, 2),
    378       .src_frame_rect = DesktopRect::MakeXYWH(0, 4, 2, 1),
    379       .horizontal_scale = 0.5,
    380       .vertical_scale = 0.5,
    381       .expected_overlap_rect = DesktopRect::MakeXYWH(0, 0, 0, 0)}};
    382 
    383  RunTests(tests);
    384 }
    385 
    386 }  // namespace webrtc