1// Copyright 2014 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_layer_impl.h"
6
7#include "cc/layers/video_frame_provider_client_impl.h"
8#include "cc/output/context_provider.h"
9#include "cc/output/output_surface.h"
10#include "cc/quads/draw_quad.h"
11#include "cc/test/fake_video_frame_provider.h"
12#include "cc/test/layer_test_common.h"
13#include "cc/trees/single_thread_proxy.h"
14#include "media/base/video_frame.h"
15#include "testing/gtest/include/gtest/gtest.h"
16
17namespace cc {
18namespace {
19
20TEST(VideoLayerImplTest, Occlusion) {
21  gfx::Size layer_size(1000, 1000);
22  gfx::Size viewport_size(1000, 1000);
23
24  LayerTestCommon::LayerImplTest impl;
25  DebugScopedSetImplThreadAndMainThreadBlocked thread(impl.proxy());
26
27  scoped_refptr<media::VideoFrame> video_frame =
28      media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
29                                     gfx::Size(10, 10),
30                                     gfx::Rect(10, 10),
31                                     gfx::Size(10, 10),
32                                     base::TimeDelta());
33  FakeVideoFrameProvider provider;
34  provider.set_frame(video_frame);
35
36  VideoLayerImpl* video_layer_impl =
37      impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0);
38  video_layer_impl->SetBounds(layer_size);
39  video_layer_impl->SetContentBounds(layer_size);
40  video_layer_impl->SetDrawsContent(true);
41
42  impl.CalcDrawProps(viewport_size);
43
44  {
45    SCOPED_TRACE("No occlusion");
46    gfx::Rect occluded;
47    impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
48
49    LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(),
50                                                 gfx::Rect(layer_size));
51    EXPECT_EQ(1u, impl.quad_list().size());
52  }
53
54  {
55    SCOPED_TRACE("Full occlusion");
56    gfx::Rect occluded(video_layer_impl->visible_content_rect());
57    impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
58
59    LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
60    EXPECT_EQ(impl.quad_list().size(), 0u);
61  }
62
63  {
64    SCOPED_TRACE("Partial occlusion");
65    gfx::Rect occluded(200, 0, 800, 1000);
66    impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
67
68    size_t partially_occluded_count = 0;
69    LayerTestCommon::VerifyQuadsAreOccluded(
70        impl.quad_list(), occluded, &partially_occluded_count);
71    // The layer outputs one quad, which is partially occluded.
72    EXPECT_EQ(1u, impl.quad_list().size());
73    EXPECT_EQ(1u, partially_occluded_count);
74  }
75}
76
77TEST(VideoLayerImplTest, DidBecomeActiveShouldSetActiveVideoLayer) {
78  LayerTestCommon::LayerImplTest impl;
79  DebugScopedSetImplThreadAndMainThreadBlocked thread(impl.proxy());
80
81  FakeVideoFrameProvider provider;
82  VideoLayerImpl* video_layer_impl =
83      impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0);
84
85  VideoFrameProviderClientImpl* client =
86      static_cast<VideoFrameProviderClientImpl*>(provider.client());
87  ASSERT_TRUE(client);
88  EXPECT_FALSE(client->active_video_layer());
89
90  video_layer_impl->DidBecomeActive();
91  EXPECT_EQ(video_layer_impl, client->active_video_layer());
92}
93
94TEST(VideoLayerImplTest, Rotated0) {
95  gfx::Size layer_size(100, 50);
96  gfx::Size viewport_size(1000, 500);
97
98  LayerTestCommon::LayerImplTest impl;
99  DebugScopedSetImplThreadAndMainThreadBlocked thread(impl.proxy());
100
101  scoped_refptr<media::VideoFrame> video_frame =
102      media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
103                                     gfx::Size(20, 10),
104                                     gfx::Rect(20, 10),
105                                     gfx::Size(20, 10),
106                                     base::TimeDelta());
107  FakeVideoFrameProvider provider;
108  provider.set_frame(video_frame);
109
110  VideoLayerImpl* video_layer_impl =
111      impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0);
112  video_layer_impl->SetBounds(layer_size);
113  video_layer_impl->SetContentBounds(layer_size);
114  video_layer_impl->SetDrawsContent(true);
115
116  impl.CalcDrawProps(viewport_size);
117  gfx::Rect occluded;
118  impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
119
120  EXPECT_EQ(1u, impl.quad_list().size());
121
122  gfx::Point3F p1(0, impl.quad_list().front()->rect.height(), 0);
123  gfx::Point3F p2(impl.quad_list().front()->rect.width(), 0, 0);
124  impl.quad_list().front()->quadTransform().TransformPoint(&p1);
125  impl.quad_list().front()->quadTransform().TransformPoint(&p2);
126  EXPECT_EQ(gfx::Point3F(0, 50, 0), p1);
127  EXPECT_EQ(gfx::Point3F(100, 0, 0), p2);
128}
129
130TEST(VideoLayerImplTest, Rotated90) {
131  gfx::Size layer_size(100, 50);
132  gfx::Size viewport_size(1000, 500);
133
134  LayerTestCommon::LayerImplTest impl;
135  DebugScopedSetImplThreadAndMainThreadBlocked thread(impl.proxy());
136
137  scoped_refptr<media::VideoFrame> video_frame =
138      media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
139                                     gfx::Size(20, 10),
140                                     gfx::Rect(20, 10),
141                                     gfx::Size(20, 10),
142                                     base::TimeDelta());
143  FakeVideoFrameProvider provider;
144  provider.set_frame(video_frame);
145
146  VideoLayerImpl* video_layer_impl =
147      impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_90);
148  video_layer_impl->SetBounds(layer_size);
149  video_layer_impl->SetContentBounds(layer_size);
150  video_layer_impl->SetDrawsContent(true);
151
152  impl.CalcDrawProps(viewport_size);
153  gfx::Rect occluded;
154  impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
155
156  EXPECT_EQ(1u, impl.quad_list().size());
157
158  gfx::Point3F p1(0, impl.quad_list().front()->rect.height(), 0);
159  gfx::Point3F p2(impl.quad_list().front()->rect.width(), 0, 0);
160  impl.quad_list().front()->quadTransform().TransformPoint(&p1);
161  impl.quad_list().front()->quadTransform().TransformPoint(&p2);
162  EXPECT_EQ(gfx::Point3F(0, 0, 0), p1);
163  EXPECT_EQ(gfx::Point3F(100, 50, 0), p2);
164}
165
166TEST(VideoLayerImplTest, Rotated180) {
167  gfx::Size layer_size(100, 50);
168  gfx::Size viewport_size(1000, 500);
169
170  LayerTestCommon::LayerImplTest impl;
171  DebugScopedSetImplThreadAndMainThreadBlocked thread(impl.proxy());
172
173  scoped_refptr<media::VideoFrame> video_frame =
174      media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
175                                     gfx::Size(20, 10),
176                                     gfx::Rect(20, 10),
177                                     gfx::Size(20, 10),
178                                     base::TimeDelta());
179  FakeVideoFrameProvider provider;
180  provider.set_frame(video_frame);
181
182  VideoLayerImpl* video_layer_impl =
183      impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_180);
184  video_layer_impl->SetBounds(layer_size);
185  video_layer_impl->SetContentBounds(layer_size);
186  video_layer_impl->SetDrawsContent(true);
187
188  impl.CalcDrawProps(viewport_size);
189  gfx::Rect occluded;
190  impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
191
192  EXPECT_EQ(1u, impl.quad_list().size());
193
194  gfx::Point3F p1(0, impl.quad_list().front()->rect.height(), 0);
195  gfx::Point3F p2(impl.quad_list().front()->rect.width(), 0, 0);
196  impl.quad_list().front()->quadTransform().TransformPoint(&p1);
197  impl.quad_list().front()->quadTransform().TransformPoint(&p2);
198  EXPECT_EQ(gfx::Point3F(100, 0, 0), p1);
199  EXPECT_EQ(gfx::Point3F(0, 50, 0), p2);
200}
201
202TEST(VideoLayerImplTest, Rotated270) {
203  gfx::Size layer_size(100, 50);
204  gfx::Size viewport_size(1000, 500);
205
206  LayerTestCommon::LayerImplTest impl;
207  DebugScopedSetImplThreadAndMainThreadBlocked thread(impl.proxy());
208
209  scoped_refptr<media::VideoFrame> video_frame =
210      media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
211                                     gfx::Size(20, 10),
212                                     gfx::Rect(20, 10),
213                                     gfx::Size(20, 10),
214                                     base::TimeDelta());
215  FakeVideoFrameProvider provider;
216  provider.set_frame(video_frame);
217
218  VideoLayerImpl* video_layer_impl =
219      impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_270);
220  video_layer_impl->SetBounds(layer_size);
221  video_layer_impl->SetContentBounds(layer_size);
222  video_layer_impl->SetDrawsContent(true);
223
224  impl.CalcDrawProps(viewport_size);
225  gfx::Rect occluded;
226  impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
227
228  EXPECT_EQ(1u, impl.quad_list().size());
229
230  gfx::Point3F p1(0, impl.quad_list().front()->rect.height(), 0);
231  gfx::Point3F p2(impl.quad_list().front()->rect.width(), 0, 0);
232  impl.quad_list().front()->quadTransform().TransformPoint(&p1);
233  impl.quad_list().front()->quadTransform().TransformPoint(&p2);
234  EXPECT_EQ(gfx::Point3F(100, 50, 0), p1);
235  EXPECT_EQ(gfx::Point3F(0, 0, 0), p2);
236}
237
238}  // namespace
239}  // namespace cc
240