| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2016 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 "remoting/client/dual_buffer_frame_consumer.h" | 
|  | 6 | 
|  | 7 #include <memory> | 
|  | 8 | 
|  | 9 #include "base/bind.h" | 
|  | 10 #include "base/bind_helpers.h" | 
|  | 11 #include "testing/gtest/include/gtest/gtest.h" | 
|  | 12 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" | 
|  | 13 #include "third_party/webrtc/modules/desktop_capture/shared_desktop_frame.h" | 
|  | 14 | 
|  | 15 namespace remoting { | 
|  | 16 | 
|  | 17 namespace { | 
|  | 18 | 
|  | 19 webrtc::DesktopFrame* GetUnderlyingFrame( | 
|  | 20     const std::unique_ptr<webrtc::DesktopFrame>& frame) { | 
|  | 21   return reinterpret_cast<webrtc::SharedDesktopFrame*>(frame.get())-> | 
|  | 22       GetUnderlyingFrame(); | 
|  | 23 } | 
|  | 24 | 
|  | 25 void FillRGBARect(uint8_t r, | 
|  | 26                   uint8_t g, | 
|  | 27                   uint8_t b, | 
|  | 28                   uint8_t a, | 
|  | 29                   const webrtc::DesktopRect& rect, | 
|  | 30                   webrtc::DesktopFrame* frame) { | 
|  | 31   for (int x = 0; x < rect.width(); x++) { | 
|  | 32     for (int y = 0; y < rect.height(); y++) { | 
|  | 33       uint8_t* data = frame->GetFrameDataAtPos( | 
|  | 34           rect.top_left().add(webrtc::DesktopVector(x, y))); | 
|  | 35       data[0] = r; | 
|  | 36       data[1] = g; | 
|  | 37       data[2] = b; | 
|  | 38       data[3] = a; | 
|  | 39     } | 
|  | 40   } | 
|  | 41   frame->mutable_updated_region()->SetRect(rect); | 
|  | 42 } | 
|  | 43 | 
|  | 44 void CheckFrameColor(uint8_t r, | 
|  | 45                      uint8_t g, | 
|  | 46                      uint8_t b, | 
|  | 47                      uint8_t a, | 
|  | 48                      const webrtc::DesktopVector& pos, | 
|  | 49                      const webrtc::DesktopFrame& frame) { | 
|  | 50   uint8_t* data = frame.GetFrameDataAtPos(pos); | 
|  | 51   EXPECT_EQ(r, data[0]); | 
|  | 52   EXPECT_EQ(g, data[1]); | 
|  | 53   EXPECT_EQ(b, data[2]); | 
|  | 54   EXPECT_EQ(a, data[3]); | 
|  | 55 } | 
|  | 56 | 
|  | 57 }  // namespace | 
|  | 58 | 
|  | 59 class DualBufferFrameConsumerTest : public testing::Test { | 
|  | 60  public: | 
|  | 61   void SetUp() override; | 
|  | 62  protected: | 
|  | 63   std::unique_ptr<DualBufferFrameConsumer> consumer_; | 
|  | 64   std::unique_ptr<webrtc::DesktopFrame> received_frame_; | 
|  | 65   base::Closure done_closure_; | 
|  | 66  private: | 
|  | 67   void OnFrameReceived(std::unique_ptr<webrtc::DesktopFrame> frame, | 
|  | 68                        const base::Closure& done); | 
|  | 69 }; | 
|  | 70 | 
|  | 71 void DualBufferFrameConsumerTest::SetUp() { | 
|  | 72   consumer_.reset(new DualBufferFrameConsumer( | 
|  | 73       base::Bind(&DualBufferFrameConsumerTest::OnFrameReceived, | 
|  | 74                  base::Unretained(this)), nullptr, | 
|  | 75                  protocol::FrameConsumer::FORMAT_RGBA)); | 
|  | 76 } | 
|  | 77 | 
|  | 78 void DualBufferFrameConsumerTest::OnFrameReceived( | 
|  | 79     std::unique_ptr<webrtc::DesktopFrame> frame, | 
|  | 80     const base::Closure& done) { | 
|  | 81   received_frame_ = std::move(frame); | 
|  | 82   done_closure_ = done; | 
|  | 83 } | 
|  | 84 | 
|  | 85 TEST_F(DualBufferFrameConsumerTest, AllocateOneFrame) { | 
|  | 86   std::unique_ptr<webrtc::DesktopFrame> frame = | 
|  | 87       consumer_->AllocateFrame(webrtc::DesktopSize(16, 16)); | 
|  | 88   ASSERT_TRUE(frame->size().equals(webrtc::DesktopSize(16, 16))); | 
|  | 89   webrtc::DesktopFrame* raw_frame = frame.get(); | 
|  | 90   consumer_->DrawFrame(std::move(frame), base::Closure()); | 
|  | 91   EXPECT_EQ(raw_frame, received_frame_.get()); | 
|  | 92 } | 
|  | 93 | 
|  | 94 TEST_F(DualBufferFrameConsumerTest, BufferRotation) { | 
|  | 95   webrtc::DesktopSize size16x16(16, 16); | 
|  | 96 | 
|  | 97   std::unique_ptr<webrtc::DesktopFrame> frame = | 
|  | 98       consumer_->AllocateFrame(size16x16); | 
|  | 99   webrtc::DesktopFrame* underlying_frame_1 = GetUnderlyingFrame(frame); | 
|  | 100   consumer_->DrawFrame(std::move(frame), base::Closure()); | 
|  | 101 | 
|  | 102   frame = consumer_->AllocateFrame(size16x16); | 
|  | 103   webrtc::DesktopFrame* underlying_frame_2 = GetUnderlyingFrame(frame); | 
|  | 104   EXPECT_NE(underlying_frame_1, underlying_frame_2); | 
|  | 105   consumer_->DrawFrame(std::move(frame), base::Closure()); | 
|  | 106 | 
|  | 107   frame = consumer_->AllocateFrame(size16x16); | 
|  | 108   webrtc::DesktopFrame* underlying_frame_3 = GetUnderlyingFrame(frame); | 
|  | 109   EXPECT_EQ(underlying_frame_1, underlying_frame_3); | 
|  | 110   consumer_->DrawFrame(std::move(frame), base::Closure()); | 
|  | 111 | 
|  | 112   frame = consumer_->AllocateFrame(size16x16); | 
|  | 113   webrtc::DesktopFrame* underlying_frame_4 = GetUnderlyingFrame(frame); | 
|  | 114   EXPECT_EQ(underlying_frame_2, underlying_frame_4); | 
|  | 115   consumer_->DrawFrame(std::move(frame), base::Closure()); | 
|  | 116 } | 
|  | 117 | 
|  | 118 TEST_F(DualBufferFrameConsumerTest, DrawAndMergeFrames) { | 
|  | 119   webrtc::DesktopSize size2x2(2, 2); | 
|  | 120 | 
|  | 121   // X means uninitialized color. | 
|  | 122 | 
|  | 123   // Frame 1: | 
|  | 124   // RR | 
|  | 125   // RR | 
|  | 126   std::unique_ptr<webrtc::DesktopFrame> frame = | 
|  | 127       consumer_->AllocateFrame(size2x2); | 
|  | 128   FillRGBARect(0xff, 0, 0, 0xff, webrtc::DesktopRect::MakeXYWH(0, 0, 2, 2), | 
|  | 129                frame.get()); | 
|  | 130   consumer_->DrawFrame(std::move(frame), base::Closure()); | 
|  | 131 | 
|  | 132   // Frame 2: | 
|  | 133   // GG | 
|  | 134   // XX | 
|  | 135   frame = consumer_->AllocateFrame(size2x2); | 
|  | 136   FillRGBARect(0, 0xff, 0, 0xff, webrtc::DesktopRect::MakeXYWH(0, 0, 2, 1), | 
|  | 137                frame.get()); | 
|  | 138   consumer_->DrawFrame(std::move(frame), base::Closure()); | 
|  | 139 | 
|  | 140   // Merged Frame: | 
|  | 141   // GG | 
|  | 142   // RR | 
|  | 143   consumer_->RequestFullDesktopFrame(); | 
|  | 144   ASSERT_TRUE(received_frame_->size().equals(size2x2)); | 
|  | 145 | 
|  | 146   CheckFrameColor(0, 0xff, 0, 0xff, webrtc::DesktopVector(0, 0), | 
|  | 147                   *received_frame_); | 
|  | 148   CheckFrameColor(0xff, 0, 0, 0xff, webrtc::DesktopVector(0, 1), | 
|  | 149                   *received_frame_); | 
|  | 150   CheckFrameColor(0, 0xff, 0, 0xff, webrtc::DesktopVector(1, 0), | 
|  | 151                   *received_frame_); | 
|  | 152   CheckFrameColor(0xff, 0, 0, 0xff, webrtc::DesktopVector(1, 1), | 
|  | 153                   *received_frame_); | 
|  | 154 | 
|  | 155   // Frame 3: | 
|  | 156   // BX | 
|  | 157   // BX | 
|  | 158   frame = consumer_->AllocateFrame(size2x2); | 
|  | 159   FillRGBARect(0, 0, 0xff, 0xff, webrtc::DesktopRect::MakeXYWH(0, 0, 1, 2), | 
|  | 160                frame.get()); | 
|  | 161   consumer_->DrawFrame(std::move(frame), base::Closure()); | 
|  | 162 | 
|  | 163   // Merged Frame: | 
|  | 164   // BG | 
|  | 165   // BR | 
|  | 166   consumer_->RequestFullDesktopFrame(); | 
|  | 167   ASSERT_TRUE(received_frame_->size().equals(size2x2)); | 
|  | 168 | 
|  | 169   CheckFrameColor(0, 0, 0xff, 0xff, webrtc::DesktopVector(0, 0), | 
|  | 170                   *received_frame_); | 
|  | 171   CheckFrameColor(0, 0, 0xff, 0xff, webrtc::DesktopVector(0, 1), | 
|  | 172                   *received_frame_); | 
|  | 173   CheckFrameColor(0, 0xff, 0, 0xff, webrtc::DesktopVector(1, 0), | 
|  | 174                   *received_frame_); | 
|  | 175   CheckFrameColor(0xff, 0, 0, 0xff, webrtc::DesktopVector(1, 1), | 
|  | 176                   *received_frame_); | 
|  | 177 } | 
|  | 178 | 
|  | 179 TEST_F(DualBufferFrameConsumerTest, ChangeScreenSizeAndReallocateBuffers) { | 
|  | 180   webrtc::DesktopSize size16x16(16, 16); | 
|  | 181 | 
|  | 182   std::unique_ptr<webrtc::DesktopFrame> frame = | 
|  | 183       consumer_->AllocateFrame(size16x16); | 
|  | 184   webrtc::DesktopFrame* underlying_frame_1 = GetUnderlyingFrame(frame); | 
|  | 185   consumer_->DrawFrame(std::move(frame), base::Closure()); | 
|  | 186 | 
|  | 187   frame = consumer_->AllocateFrame(size16x16); | 
|  | 188   webrtc::DesktopFrame* underlying_frame_2 = GetUnderlyingFrame(frame); | 
|  | 189   EXPECT_NE(underlying_frame_1, underlying_frame_2); | 
|  | 190   consumer_->DrawFrame(std::move(frame), base::Closure()); | 
|  | 191 | 
|  | 192   webrtc::DesktopSize size32x32(32, 32); | 
|  | 193 | 
|  | 194   frame = consumer_->AllocateFrame(size32x32); | 
|  | 195   webrtc::DesktopFrame* underlying_frame_3 = GetUnderlyingFrame(frame); | 
|  | 196   EXPECT_NE(underlying_frame_1, underlying_frame_3); | 
|  | 197   consumer_->DrawFrame(std::move(frame), base::Closure()); | 
|  | 198 | 
|  | 199   frame = consumer_->AllocateFrame(size32x32); | 
|  | 200   webrtc::DesktopFrame* underlying_frame_4 = GetUnderlyingFrame(frame); | 
|  | 201   EXPECT_NE(underlying_frame_2, underlying_frame_4); | 
|  | 202   consumer_->DrawFrame(std::move(frame), base::Closure()); | 
|  | 203 } | 
|  | 204 | 
|  | 205 }  // namespace remoting | 
| OLD | NEW | 
|---|