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