| 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
 | 
| 
 |