Index: remoting/client/dual_buffer_frame_consumer_unittest.cc |
diff --git a/remoting/client/dual_buffer_frame_consumer_unittest.cc b/remoting/client/dual_buffer_frame_consumer_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..be3a05ba5ce78cd04218789b9e5eb6ad61206d7b |
--- /dev/null |
+++ b/remoting/client/dual_buffer_frame_consumer_unittest.cc |
@@ -0,0 +1,205 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "remoting/client/dual_buffer_frame_consumer.h" |
+ |
+#include <memory> |
+ |
+#include "base/bind.h" |
+#include "base/bind_helpers.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
+#include "third_party/webrtc/modules/desktop_capture/shared_desktop_frame.h" |
+ |
+namespace remoting { |
+ |
+namespace { |
+ |
+webrtc::DesktopFrame* GetUnderlyingFrame( |
+ const std::unique_ptr<webrtc::DesktopFrame>& frame) { |
+ return reinterpret_cast<webrtc::SharedDesktopFrame*>(frame.get())-> |
+ GetUnderlyingFrame(); |
+} |
+ |
+void FillRGBARect(uint8_t r, |
+ uint8_t g, |
+ uint8_t b, |
+ uint8_t a, |
+ const webrtc::DesktopRect& rect, |
+ webrtc::DesktopFrame* frame) { |
+ for (int x = 0; x < rect.width(); x++) { |
+ for (int y = 0; y < rect.height(); y++) { |
+ uint8_t* data = frame->GetFrameDataAtPos( |
+ rect.top_left().add(webrtc::DesktopVector(x, y))); |
+ data[0] = r; |
+ data[1] = g; |
+ data[2] = b; |
+ data[3] = a; |
+ } |
+ } |
+ frame->mutable_updated_region()->SetRect(rect); |
+} |
+ |
+void CheckFrameColor(uint8_t r, |
+ uint8_t g, |
+ uint8_t b, |
+ uint8_t a, |
+ const webrtc::DesktopVector& pos, |
+ const webrtc::DesktopFrame& frame) { |
+ uint8_t* data = frame.GetFrameDataAtPos(pos); |
+ EXPECT_EQ(r, data[0]); |
+ EXPECT_EQ(g, data[1]); |
+ EXPECT_EQ(b, data[2]); |
+ EXPECT_EQ(a, data[3]); |
+} |
+ |
+} // namespace |
+ |
+class DualBufferFrameConsumerTest : public testing::Test { |
+ public: |
+ void SetUp() override; |
+ protected: |
+ std::unique_ptr<DualBufferFrameConsumer> consumer_; |
+ std::unique_ptr<webrtc::DesktopFrame> received_frame_; |
+ base::Closure done_closure_; |
+ private: |
+ void OnFrameReceived(std::unique_ptr<webrtc::DesktopFrame> frame, |
+ const base::Closure& done); |
+}; |
+ |
+void DualBufferFrameConsumerTest::SetUp() { |
+ consumer_.reset(new DualBufferFrameConsumer( |
+ base::Bind(&DualBufferFrameConsumerTest::OnFrameReceived, |
+ base::Unretained(this)), nullptr, |
+ protocol::FrameConsumer::FORMAT_RGBA)); |
+} |
+ |
+void DualBufferFrameConsumerTest::OnFrameReceived( |
+ std::unique_ptr<webrtc::DesktopFrame> frame, |
+ const base::Closure& done) { |
+ received_frame_ = std::move(frame); |
+ done_closure_ = done; |
+} |
+ |
+TEST_F(DualBufferFrameConsumerTest, AllocateOneFrame) { |
+ std::unique_ptr<webrtc::DesktopFrame> frame = |
+ consumer_->AllocateFrame(webrtc::DesktopSize(16, 16)); |
+ ASSERT_TRUE(frame->size().equals(webrtc::DesktopSize(16, 16))); |
+ webrtc::DesktopFrame* raw_frame = frame.get(); |
+ consumer_->DrawFrame(std::move(frame), base::Closure()); |
+ EXPECT_EQ(raw_frame, received_frame_.get()); |
+} |
+ |
+TEST_F(DualBufferFrameConsumerTest, BufferRotation) { |
+ webrtc::DesktopSize size16x16(16, 16); |
+ |
+ std::unique_ptr<webrtc::DesktopFrame> frame = |
+ consumer_->AllocateFrame(size16x16); |
+ webrtc::DesktopFrame* underlying_frame_1 = GetUnderlyingFrame(frame); |
+ consumer_->DrawFrame(std::move(frame), base::Closure()); |
+ |
+ frame = consumer_->AllocateFrame(size16x16); |
+ webrtc::DesktopFrame* underlying_frame_2 = GetUnderlyingFrame(frame); |
+ EXPECT_NE(underlying_frame_1, underlying_frame_2); |
+ consumer_->DrawFrame(std::move(frame), base::Closure()); |
+ |
+ frame = consumer_->AllocateFrame(size16x16); |
+ webrtc::DesktopFrame* underlying_frame_3 = GetUnderlyingFrame(frame); |
+ EXPECT_EQ(underlying_frame_1, underlying_frame_3); |
+ consumer_->DrawFrame(std::move(frame), base::Closure()); |
+ |
+ frame = consumer_->AllocateFrame(size16x16); |
+ webrtc::DesktopFrame* underlying_frame_4 = GetUnderlyingFrame(frame); |
+ EXPECT_EQ(underlying_frame_2, underlying_frame_4); |
+ consumer_->DrawFrame(std::move(frame), base::Closure()); |
+} |
+ |
+TEST_F(DualBufferFrameConsumerTest, DrawAndMergeFrames) { |
+ webrtc::DesktopSize size2x2(2, 2); |
+ |
+ // X means uninitialized color. |
+ |
+ // Frame 1: |
+ // RR |
+ // RR |
+ std::unique_ptr<webrtc::DesktopFrame> frame = |
+ consumer_->AllocateFrame(size2x2); |
+ FillRGBARect(0xff, 0, 0, 0xff, webrtc::DesktopRect::MakeXYWH(0, 0, 2, 2), |
+ frame.get()); |
+ consumer_->DrawFrame(std::move(frame), base::Closure()); |
+ |
+ // Frame 2: |
+ // GG |
+ // XX |
+ frame = consumer_->AllocateFrame(size2x2); |
+ FillRGBARect(0, 0xff, 0, 0xff, webrtc::DesktopRect::MakeXYWH(0, 0, 2, 1), |
+ frame.get()); |
+ consumer_->DrawFrame(std::move(frame), base::Closure()); |
+ |
+ // Merged Frame: |
+ // GG |
+ // RR |
+ consumer_->RequestFullDesktopFrame(); |
+ ASSERT_TRUE(received_frame_->size().equals(size2x2)); |
+ |
+ CheckFrameColor(0, 0xff, 0, 0xff, webrtc::DesktopVector(0, 0), |
+ *received_frame_); |
+ CheckFrameColor(0xff, 0, 0, 0xff, webrtc::DesktopVector(0, 1), |
+ *received_frame_); |
+ CheckFrameColor(0, 0xff, 0, 0xff, webrtc::DesktopVector(1, 0), |
+ *received_frame_); |
+ CheckFrameColor(0xff, 0, 0, 0xff, webrtc::DesktopVector(1, 1), |
+ *received_frame_); |
+ |
+ // Frame 3: |
+ // BX |
+ // BX |
+ frame = consumer_->AllocateFrame(size2x2); |
+ FillRGBARect(0, 0, 0xff, 0xff, webrtc::DesktopRect::MakeXYWH(0, 0, 1, 2), |
+ frame.get()); |
+ consumer_->DrawFrame(std::move(frame), base::Closure()); |
+ |
+ // Merged Frame: |
+ // BG |
+ // BR |
+ consumer_->RequestFullDesktopFrame(); |
+ ASSERT_TRUE(received_frame_->size().equals(size2x2)); |
+ |
+ CheckFrameColor(0, 0, 0xff, 0xff, webrtc::DesktopVector(0, 0), |
+ *received_frame_); |
+ CheckFrameColor(0, 0, 0xff, 0xff, webrtc::DesktopVector(0, 1), |
+ *received_frame_); |
+ CheckFrameColor(0, 0xff, 0, 0xff, webrtc::DesktopVector(1, 0), |
+ *received_frame_); |
+ CheckFrameColor(0xff, 0, 0, 0xff, webrtc::DesktopVector(1, 1), |
+ *received_frame_); |
+} |
+ |
+TEST_F(DualBufferFrameConsumerTest, ChangeScreenSizeAndReallocateBuffers) { |
+ webrtc::DesktopSize size16x16(16, 16); |
+ |
+ std::unique_ptr<webrtc::DesktopFrame> frame = |
+ consumer_->AllocateFrame(size16x16); |
+ webrtc::DesktopFrame* underlying_frame_1 = GetUnderlyingFrame(frame); |
+ consumer_->DrawFrame(std::move(frame), base::Closure()); |
+ |
+ frame = consumer_->AllocateFrame(size16x16); |
+ webrtc::DesktopFrame* underlying_frame_2 = GetUnderlyingFrame(frame); |
+ EXPECT_NE(underlying_frame_1, underlying_frame_2); |
+ consumer_->DrawFrame(std::move(frame), base::Closure()); |
+ |
+ webrtc::DesktopSize size32x32(32, 32); |
+ |
+ frame = consumer_->AllocateFrame(size32x32); |
+ webrtc::DesktopFrame* underlying_frame_3 = GetUnderlyingFrame(frame); |
+ EXPECT_NE(underlying_frame_1, underlying_frame_3); |
+ consumer_->DrawFrame(std::move(frame), base::Closure()); |
+ |
+ frame = consumer_->AllocateFrame(size32x32); |
+ webrtc::DesktopFrame* underlying_frame_4 = GetUnderlyingFrame(frame); |
+ EXPECT_NE(underlying_frame_2, underlying_frame_4); |
+ consumer_->DrawFrame(std::move(frame), base::Closure()); |
+} |
+ |
+} // namespace remoting |