Fix flaky PDFExtensionTest
[chromium-blink-merge.git] / cc / layers / video_layer_impl_unittest.cc
blob088560c7956bae6e3191e82e821b88ea2aa37651
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.
5 #include "cc/layers/video_layer_impl.h"
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/quads/yuv_video_draw_quad.h"
12 #include "cc/test/fake_video_frame_provider.h"
13 #include "cc/test/layer_test_common.h"
14 #include "cc/trees/single_thread_proxy.h"
15 #include "media/base/video_frame.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 namespace cc {
19 namespace {
21 // NOTE: We cannot use DebugScopedSetImplThreadAndMainThreadBlocked in these
22 // tests because it gets destroyed before the VideoLayerImpl is destroyed. This
23 // causes a DCHECK in VideoLayerImpl's destructor to fail.
24 static void DebugSetImplThreadAndMainThreadBlocked(Proxy* proxy) {
25 #if DCHECK_IS_ON()
26 proxy->SetCurrentThreadIsImplThread(true);
27 proxy->SetMainThreadBlocked(true);
28 #endif
31 TEST(VideoLayerImplTest, Occlusion) {
32 gfx::Size layer_size(1000, 1000);
33 gfx::Size viewport_size(1000, 1000);
35 LayerTestCommon::LayerImplTest impl;
36 DebugSetImplThreadAndMainThreadBlocked(impl.proxy());
38 scoped_refptr<media::VideoFrame> video_frame =
39 media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
40 gfx::Size(10, 10),
41 gfx::Rect(10, 10),
42 gfx::Size(10, 10),
43 base::TimeDelta());
44 FakeVideoFrameProvider provider;
45 provider.set_frame(video_frame);
47 VideoLayerImpl* video_layer_impl =
48 impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0);
49 video_layer_impl->SetBounds(layer_size);
50 video_layer_impl->SetContentBounds(layer_size);
51 video_layer_impl->SetDrawsContent(true);
53 impl.CalcDrawProps(viewport_size);
56 SCOPED_TRACE("No occlusion");
57 gfx::Rect occluded;
58 impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
60 LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(),
61 gfx::Rect(layer_size));
62 EXPECT_EQ(1u, impl.quad_list().size());
66 SCOPED_TRACE("Full occlusion");
67 gfx::Rect occluded(video_layer_impl->visible_content_rect());
68 impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
70 LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
71 EXPECT_EQ(impl.quad_list().size(), 0u);
75 SCOPED_TRACE("Partial occlusion");
76 gfx::Rect occluded(200, 0, 800, 1000);
77 impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
79 size_t partially_occluded_count = 0;
80 LayerTestCommon::VerifyQuadsAreOccluded(
81 impl.quad_list(), occluded, &partially_occluded_count);
82 // The layer outputs one quad, which is partially occluded.
83 EXPECT_EQ(1u, impl.quad_list().size());
84 EXPECT_EQ(1u, partially_occluded_count);
88 TEST(VideoLayerImplTest, OccludesOtherLayers) {
89 gfx::Size layer_size(1000, 1000);
90 gfx::Rect visible(layer_size);
92 LayerTestCommon::LayerImplTest impl;
93 impl.host_impl()->SetViewportSize(layer_size);
94 DebugSetImplThreadAndMainThreadBlocked(impl.proxy());
95 auto active_tree = impl.host_impl()->active_tree();
97 // Create a video layer with no frame on top of another layer.
98 scoped_ptr<LayerImpl> layer_impl = LayerImpl::Create(active_tree, 3);
99 layer_impl->SetHasRenderSurface(true);
100 layer_impl->SetBounds(layer_size);
101 layer_impl->SetContentBounds(layer_size);
102 layer_impl->SetDrawsContent(true);
103 const auto& draw_properties = layer_impl->draw_properties();
105 FakeVideoFrameProvider provider;
106 scoped_ptr<VideoLayerImpl> video_layer_impl = VideoLayerImpl::Create(
107 active_tree, 4, &provider, media::VIDEO_ROTATION_0);
108 video_layer_impl->SetBounds(layer_size);
109 video_layer_impl->SetContentBounds(layer_size);
110 video_layer_impl->SetDrawsContent(true);
111 video_layer_impl->SetContentsOpaque(true);
113 layer_impl->AddChild(video_layer_impl.Pass());
114 active_tree->SetRootLayer(layer_impl.Pass());
116 active_tree->BuildPropertyTreesForTesting();
118 active_tree->UpdateDrawProperties(false);
120 // We don't have a frame yet, so the video doesn't occlude the layer below it.
121 EXPECT_FALSE(draw_properties.occlusion_in_content_space.IsOccluded(visible));
123 scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
124 media::VideoFrame::YV12, gfx::Size(10, 10), gfx::Rect(10, 10),
125 gfx::Size(10, 10), base::TimeDelta());
126 provider.set_frame(video_frame);
127 active_tree->set_needs_update_draw_properties();
128 active_tree->UpdateDrawProperties(false);
130 // We have a frame now, so the video occludes the layer below it.
131 EXPECT_TRUE(draw_properties.occlusion_in_content_space.IsOccluded(visible));
134 TEST(VideoLayerImplTest, DidBecomeActiveShouldSetActiveVideoLayer) {
135 LayerTestCommon::LayerImplTest impl;
136 DebugSetImplThreadAndMainThreadBlocked(impl.proxy());
138 FakeVideoFrameProvider provider;
139 VideoLayerImpl* video_layer_impl =
140 impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0);
142 VideoFrameProviderClientImpl* client =
143 static_cast<VideoFrameProviderClientImpl*>(provider.client());
144 ASSERT_TRUE(client);
146 EXPECT_FALSE(client->ActiveVideoLayer());
147 video_layer_impl->DidBecomeActive();
148 EXPECT_EQ(video_layer_impl, client->ActiveVideoLayer());
151 TEST(VideoLayerImplTest, Rotated0) {
152 gfx::Size layer_size(100, 50);
153 gfx::Size viewport_size(1000, 500);
155 LayerTestCommon::LayerImplTest impl;
156 DebugSetImplThreadAndMainThreadBlocked(impl.proxy());
158 scoped_refptr<media::VideoFrame> video_frame =
159 media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
160 gfx::Size(20, 10),
161 gfx::Rect(20, 10),
162 gfx::Size(20, 10),
163 base::TimeDelta());
164 FakeVideoFrameProvider provider;
165 provider.set_frame(video_frame);
167 VideoLayerImpl* video_layer_impl =
168 impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0);
169 video_layer_impl->SetBounds(layer_size);
170 video_layer_impl->SetContentBounds(layer_size);
171 video_layer_impl->SetDrawsContent(true);
173 impl.CalcDrawProps(viewport_size);
174 gfx::Rect occluded;
175 impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
177 EXPECT_EQ(1u, impl.quad_list().size());
179 gfx::Point3F p1(0, impl.quad_list().front()->rect.height(), 0);
180 gfx::Point3F p2(impl.quad_list().front()->rect.width(), 0, 0);
181 impl.quad_list().front()->quadTransform().TransformPoint(&p1);
182 impl.quad_list().front()->quadTransform().TransformPoint(&p2);
183 EXPECT_EQ(gfx::Point3F(0, 50, 0), p1);
184 EXPECT_EQ(gfx::Point3F(100, 0, 0), p2);
187 TEST(VideoLayerImplTest, Rotated90) {
188 gfx::Size layer_size(100, 50);
189 gfx::Size viewport_size(1000, 500);
191 LayerTestCommon::LayerImplTest impl;
192 DebugSetImplThreadAndMainThreadBlocked(impl.proxy());
194 scoped_refptr<media::VideoFrame> video_frame =
195 media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
196 gfx::Size(20, 10),
197 gfx::Rect(20, 10),
198 gfx::Size(20, 10),
199 base::TimeDelta());
200 FakeVideoFrameProvider provider;
201 provider.set_frame(video_frame);
203 VideoLayerImpl* video_layer_impl =
204 impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_90);
205 video_layer_impl->SetBounds(layer_size);
206 video_layer_impl->SetContentBounds(layer_size);
207 video_layer_impl->SetDrawsContent(true);
209 impl.CalcDrawProps(viewport_size);
210 gfx::Rect occluded;
211 impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
213 EXPECT_EQ(1u, impl.quad_list().size());
215 gfx::Point3F p1(0, impl.quad_list().front()->rect.height(), 0);
216 gfx::Point3F p2(impl.quad_list().front()->rect.width(), 0, 0);
217 impl.quad_list().front()->quadTransform().TransformPoint(&p1);
218 impl.quad_list().front()->quadTransform().TransformPoint(&p2);
219 EXPECT_EQ(gfx::Point3F(0, 0, 0), p1);
220 EXPECT_EQ(gfx::Point3F(100, 50, 0), p2);
223 TEST(VideoLayerImplTest, Rotated180) {
224 gfx::Size layer_size(100, 50);
225 gfx::Size viewport_size(1000, 500);
227 LayerTestCommon::LayerImplTest impl;
228 DebugSetImplThreadAndMainThreadBlocked(impl.proxy());
230 scoped_refptr<media::VideoFrame> video_frame =
231 media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
232 gfx::Size(20, 10),
233 gfx::Rect(20, 10),
234 gfx::Size(20, 10),
235 base::TimeDelta());
236 FakeVideoFrameProvider provider;
237 provider.set_frame(video_frame);
239 VideoLayerImpl* video_layer_impl =
240 impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_180);
241 video_layer_impl->SetBounds(layer_size);
242 video_layer_impl->SetContentBounds(layer_size);
243 video_layer_impl->SetDrawsContent(true);
245 impl.CalcDrawProps(viewport_size);
246 gfx::Rect occluded;
247 impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
249 EXPECT_EQ(1u, impl.quad_list().size());
251 gfx::Point3F p1(0, impl.quad_list().front()->rect.height(), 0);
252 gfx::Point3F p2(impl.quad_list().front()->rect.width(), 0, 0);
253 impl.quad_list().front()->quadTransform().TransformPoint(&p1);
254 impl.quad_list().front()->quadTransform().TransformPoint(&p2);
255 EXPECT_EQ(gfx::Point3F(100, 0, 0), p1);
256 EXPECT_EQ(gfx::Point3F(0, 50, 0), p2);
259 TEST(VideoLayerImplTest, Rotated270) {
260 gfx::Size layer_size(100, 50);
261 gfx::Size viewport_size(1000, 500);
263 LayerTestCommon::LayerImplTest impl;
264 DebugSetImplThreadAndMainThreadBlocked(impl.proxy());
266 scoped_refptr<media::VideoFrame> video_frame =
267 media::VideoFrame::CreateFrame(media::VideoFrame::YV12,
268 gfx::Size(20, 10),
269 gfx::Rect(20, 10),
270 gfx::Size(20, 10),
271 base::TimeDelta());
272 FakeVideoFrameProvider provider;
273 provider.set_frame(video_frame);
275 VideoLayerImpl* video_layer_impl =
276 impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_270);
277 video_layer_impl->SetBounds(layer_size);
278 video_layer_impl->SetContentBounds(layer_size);
279 video_layer_impl->SetDrawsContent(true);
281 impl.CalcDrawProps(viewport_size);
282 gfx::Rect occluded;
283 impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
285 EXPECT_EQ(1u, impl.quad_list().size());
287 gfx::Point3F p1(0, impl.quad_list().front()->rect.height(), 0);
288 gfx::Point3F p2(impl.quad_list().front()->rect.width(), 0, 0);
289 impl.quad_list().front()->quadTransform().TransformPoint(&p1);
290 impl.quad_list().front()->quadTransform().TransformPoint(&p2);
291 EXPECT_EQ(gfx::Point3F(100, 50, 0), p1);
292 EXPECT_EQ(gfx::Point3F(0, 0, 0), p2);
295 void EmptyCallback(unsigned sync_point) {
298 TEST(VideoLayerImplTest, SoftwareVideoFrameGeneratesYUVQuad) {
299 gfx::Size layer_size(1000, 1000);
300 gfx::Size viewport_size(1000, 1000);
302 LayerTestCommon::LayerImplTest impl;
303 DebugSetImplThreadAndMainThreadBlocked(impl.proxy());
305 gpu::MailboxHolder mailbox_holder;
306 mailbox_holder.mailbox.name[0] = 1;
308 scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
309 media::VideoFrame::YV12, gfx::Size(20, 10), gfx::Rect(20, 10),
310 gfx::Size(20, 10), base::TimeDelta());
312 FakeVideoFrameProvider provider;
313 provider.set_frame(video_frame);
315 VideoLayerImpl* video_layer_impl =
316 impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0);
317 video_layer_impl->SetBounds(layer_size);
318 video_layer_impl->SetContentBounds(layer_size);
319 video_layer_impl->SetDrawsContent(true);
321 gfx::Rect occluded;
322 impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
324 EXPECT_EQ(1u, impl.quad_list().size());
325 const DrawQuad* draw_quad = impl.quad_list().ElementAt(0);
326 ASSERT_EQ(DrawQuad::YUV_VIDEO_CONTENT, draw_quad->material);
328 const YUVVideoDrawQuad* yuv_draw_quad =
329 static_cast<const YUVVideoDrawQuad*>(draw_quad);
330 EXPECT_EQ(yuv_draw_quad->uv_tex_size.height(),
331 (yuv_draw_quad->ya_tex_size.height() + 1) / 2);
332 EXPECT_EQ(yuv_draw_quad->uv_tex_size.width(),
333 (yuv_draw_quad->ya_tex_size.width() + 1) / 2);
336 TEST(VideoLayerImplTest, NativeYUVFrameGeneratesYUVQuad) {
337 gfx::Size layer_size(1000, 1000);
338 gfx::Size viewport_size(1000, 1000);
340 LayerTestCommon::LayerImplTest impl;
341 DebugSetImplThreadAndMainThreadBlocked(impl.proxy());
343 gpu::MailboxHolder mailbox_holder;
344 mailbox_holder.mailbox.name[0] = 1;
346 scoped_refptr<media::VideoFrame> video_frame =
347 media::VideoFrame::WrapYUV420NativeTextures(
348 mailbox_holder, mailbox_holder, mailbox_holder,
349 base::Bind(EmptyCallback), gfx::Size(10, 10), gfx::Rect(10, 10),
350 gfx::Size(10, 10), base::TimeDelta(), true);
351 FakeVideoFrameProvider provider;
352 provider.set_frame(video_frame);
354 VideoLayerImpl* video_layer_impl =
355 impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0);
356 video_layer_impl->SetBounds(layer_size);
357 video_layer_impl->SetContentBounds(layer_size);
358 video_layer_impl->SetDrawsContent(true);
360 gfx::Rect occluded;
361 impl.AppendQuadsWithOcclusion(video_layer_impl, occluded);
363 EXPECT_EQ(1u, impl.quad_list().size());
364 const DrawQuad* draw_quad = impl.quad_list().ElementAt(0);
365 ASSERT_EQ(DrawQuad::YUV_VIDEO_CONTENT, draw_quad->material);
367 const YUVVideoDrawQuad* yuv_draw_quad =
368 static_cast<const YUVVideoDrawQuad*>(draw_quad);
369 EXPECT_EQ(yuv_draw_quad->uv_tex_size.height(),
370 (yuv_draw_quad->ya_tex_size.height() + 1) / 2);
371 EXPECT_EQ(yuv_draw_quad->uv_tex_size.width(),
372 (yuv_draw_quad->ya_tex_size.width() + 1) / 2);
375 } // namespace
376 } // namespace cc