1 // Copyright 2015 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 "cc/layers/video_frame_provider_client_impl.h"
6 #include "cc/layers/video_layer_impl.h"
7 #include "cc/test/fake_video_frame_provider.h"
8 #include "cc/test/layer_tree_impl_test_base.h"
9 #include "components/viz/common/frame_sinks/begin_frame_args.h"
10 #include "media/base/video_frame.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 
14 using testing::_;
15 
16 namespace cc {
17 
18 // NOTE: We cannot use DebugScopedSetImplThreadAndMainThreadBlocked in these
19 // tests because it gets destroyed before the VideoLayerImpl is destroyed. This
20 // causes a DCHECK in VideoLayerImpl's destructor to fail.
DebugSetImplThreadAndMainThreadBlocked(TaskRunnerProvider * task_runner_provider)21 static void DebugSetImplThreadAndMainThreadBlocked(
22     TaskRunnerProvider* task_runner_provider) {
23 #if DCHECK_IS_ON()
24   task_runner_provider->SetCurrentThreadIsImplThread(true);
25   task_runner_provider->SetMainThreadBlocked(true);
26 #endif
27 }
28 
29 class VideoFrameProviderClientImplTest : public testing::Test,
30                                          public VideoFrameControllerClient {
31  public:
VideoFrameProviderClientImplTest()32   VideoFrameProviderClientImplTest()
33       : client_impl_(VideoFrameProviderClientImpl::Create(&provider_, this)),
34         video_layer_impl_(nullptr),
35         test_frame_(media::VideoFrame::CreateFrame(media::PIXEL_FORMAT_I420,
36                                                    gfx::Size(10, 10),
37                                                    gfx::Rect(10, 10),
38                                                    gfx::Size(10, 10),
39                                                    base::TimeDelta())) {
40     DebugSetImplThreadAndMainThreadBlocked(impl_.task_runner_provider());
41   }
42   VideoFrameProviderClientImplTest(const VideoFrameProviderClientImplTest&) =
43       delete;
44 
~VideoFrameProviderClientImplTest()45   ~VideoFrameProviderClientImplTest() override {
46     if (!client_impl_->Stopped()) {
47       client_impl_->Stop();
48       DCHECK(client_impl_->Stopped());
49       DCHECK(!client_impl_->ActiveVideoLayer());
50     }
51 
52     provider_.SetVideoFrameProviderClient(nullptr);
53   }
54 
55   VideoFrameProviderClientImplTest& operator=(
56       const VideoFrameProviderClientImplTest&) = delete;
57 
StartRendering()58   void StartRendering() {
59     EXPECT_CALL(*this, AddVideoFrameController(_));
60     client_impl_->StartRendering();
61   }
62 
StopRendering()63   void StopRendering() {
64     EXPECT_CALL(*this, RemoveVideoFrameController(_));
65     client_impl_->StopRendering();
66   }
67 
StartRenderingAndRenderFrame()68   void StartRenderingAndRenderFrame() {
69     EXPECT_FALSE(client_impl_->HasCurrentFrame());
70     provider_.set_frame(test_frame_);
71     EXPECT_TRUE(client_impl_->HasCurrentFrame());
72 
73     // Start rendering and verify SetNeedsRedraw() was called for the new frame.
74     StartRendering();
75     EXPECT_EQ(gfx::Rect(), video_layer_impl_->update_rect());
76     client_impl_->OnBeginFrame(viz::BeginFrameArgs());
77     EXPECT_NE(gfx::Rect(), video_layer_impl_->update_rect());
78   }
79 
CreateActiveVideoLayer()80   void CreateActiveVideoLayer() {
81     gfx::Size layer_size(100, 100);
82     video_layer_impl_ =
83         impl_.AddLayer<VideoLayerImpl>(&provider_, media::VIDEO_ROTATION_0);
84     video_layer_impl_->SetBounds(layer_size);
85     video_layer_impl_->SetDrawsContent(true);
86     client_impl_->SetActiveVideoLayer(video_layer_impl_);
87     ASSERT_TRUE(client_impl_->ActiveVideoLayer());
88   }
89 
90   MOCK_METHOD1(AddVideoFrameController, void(VideoFrameController*));
91   MOCK_METHOD1(RemoveVideoFrameController, void(VideoFrameController*));
92 
93  protected:
94   FakeVideoFrameProvider provider_;
95   LayerTreeImplTestBase impl_;
96   scoped_refptr<VideoFrameProviderClientImpl> client_impl_;
97   VideoLayerImpl* video_layer_impl_;
98   scoped_refptr<media::VideoFrame> test_frame_;
99 };
100 
TEST_F(VideoFrameProviderClientImplTest,StartStopRendering)101 TEST_F(VideoFrameProviderClientImplTest, StartStopRendering) {
102   StartRendering();
103   StopRendering();
104 }
105 
TEST_F(VideoFrameProviderClientImplTest,StopRenderingUpdateDamage)106 TEST_F(VideoFrameProviderClientImplTest, StopRenderingUpdateDamage) {
107   CreateActiveVideoLayer();
108   StartRendering();
109   EXPECT_EQ(gfx::Rect(), video_layer_impl_->update_rect());
110   StopRendering();
111   EXPECT_NE(gfx::Rect(), video_layer_impl_->update_rect());
112 }
113 
TEST_F(VideoFrameProviderClientImplTest,StopUsingProvider)114 TEST_F(VideoFrameProviderClientImplTest, StopUsingProvider) {
115   ASSERT_TRUE(client_impl_->get_provider_for_testing());
116   StartRendering();
117   EXPECT_CALL(*this, RemoveVideoFrameController(_));
118   client_impl_->StopUsingProvider();
119   ASSERT_FALSE(client_impl_->get_provider_for_testing());
120 }
121 
TEST_F(VideoFrameProviderClientImplTest,StopUsingProviderUpdateDamage)122 TEST_F(VideoFrameProviderClientImplTest, StopUsingProviderUpdateDamage) {
123   CreateActiveVideoLayer();
124   ASSERT_TRUE(client_impl_->get_provider_for_testing());
125   StartRendering();
126   EXPECT_CALL(*this, RemoveVideoFrameController(_));
127   EXPECT_EQ(gfx::Rect(), video_layer_impl_->update_rect());
128   client_impl_->StopUsingProvider();
129   EXPECT_NE(gfx::Rect(), video_layer_impl_->update_rect());
130   ASSERT_FALSE(client_impl_->get_provider_for_testing());
131 }
132 
TEST_F(VideoFrameProviderClientImplTest,StopNotUpdateDamage)133 TEST_F(VideoFrameProviderClientImplTest, StopNotUpdateDamage) {
134   CreateActiveVideoLayer();
135   ASSERT_TRUE(client_impl_->get_provider_for_testing());
136   StartRendering();
137   EXPECT_CALL(*this, RemoveVideoFrameController(_));
138   EXPECT_EQ(gfx::Rect(), video_layer_impl_->update_rect());
139   client_impl_->Stop();
140   EXPECT_EQ(gfx::Rect(), video_layer_impl_->update_rect());
141   ASSERT_FALSE(client_impl_->get_provider_for_testing());
142 }
143 
TEST_F(VideoFrameProviderClientImplTest,FrameAcquisition)144 TEST_F(VideoFrameProviderClientImplTest, FrameAcquisition) {
145   CreateActiveVideoLayer();
146   StartRenderingAndRenderFrame();
147 
148   // Verify GetCurrentFrame() and PutCurrentFrame() work correctly.
149   EXPECT_EQ(test_frame_, client_impl_->AcquireLockAndCurrentFrame());
150   EXPECT_EQ(0, provider_.put_current_frame_count());
151   client_impl_->PutCurrentFrame();
152   EXPECT_EQ(1, provider_.put_current_frame_count());
153 
154   client_impl_->ReleaseLock();
155   StopRendering();
156 }
157 
TEST_F(VideoFrameProviderClientImplTest,DidReceiveFrame)158 TEST_F(VideoFrameProviderClientImplTest, DidReceiveFrame) {
159   CreateActiveVideoLayer();
160   EXPECT_EQ(gfx::Rect(), video_layer_impl_->update_rect());
161   client_impl_->DidReceiveFrame();
162   EXPECT_NE(gfx::Rect(), video_layer_impl_->update_rect());
163 }
164 
TEST_F(VideoFrameProviderClientImplTest,DidDrawFrameIssuesPutCurrentFrame)165 TEST_F(VideoFrameProviderClientImplTest, DidDrawFrameIssuesPutCurrentFrame) {
166   CreateActiveVideoLayer();
167   StartRenderingAndRenderFrame();
168   EXPECT_EQ(0, provider_.put_current_frame_count());
169   client_impl_->DidDrawFrame();
170   EXPECT_EQ(1, provider_.put_current_frame_count());
171   StopRendering();
172 }
173 
174 }  // namespace cc
175