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/base/scoped_ptr_vector.h"
6 #include "cc/output/compositor_frame_metadata.h"
7 #include "cc/output/gl_renderer.h"
8 #include "cc/output/output_surface.h"
9 #include "cc/output/output_surface_client.h"
10 #include "cc/output/overlay_candidate_validator.h"
11 #include "cc/output/overlay_processor.h"
12 #include "cc/output/overlay_strategy_sandwich.h"
13 #include "cc/output/overlay_strategy_single_on_top.h"
14 #include "cc/output/overlay_strategy_underlay.h"
15 #include "cc/quads/render_pass.h"
16 #include "cc/quads/solid_color_draw_quad.h"
17 #include "cc/quads/stream_video_draw_quad.h"
18 #include "cc/quads/texture_draw_quad.h"
19 #include "cc/resources/resource_provider.h"
20 #include "cc/resources/texture_mailbox.h"
21 #include "cc/test/fake_output_surface_client.h"
22 #include "cc/test/fake_resource_provider.h"
23 #include "cc/test/geometry_test_utils.h"
24 #include "cc/test/test_context_provider.h"
25 #include "cc/test/test_shared_bitmap_manager.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
35 const gfx::Size
kDisplaySize(256, 256);
36 const gfx::Rect
kOverlayRect(0, 0, 128, 128);
37 const gfx::Rect
kOverlayTopLeftRect(0, 0, 64, 64);
38 const gfx::Rect
kOverlayBottomRightRect(64, 64, 64, 64);
39 const gfx::PointF
kUVTopLeft(0.1f
, 0.2f
);
40 const gfx::PointF
kUVBottomRight(1.0f
, 1.0f
);
41 const gfx::Transform kNormalTransform
=
42 gfx::Transform(0.9f
, 0, 0, 0.8f
, 0.1f
, 0.2f
); // x,y -> x,y.
43 const gfx::Transform kXMirrorTransform
=
44 gfx::Transform(-0.9f
, 0, 0, 0.8f
, 1.0f
, 0.2f
); // x,y -> 1-x,y.
45 const gfx::Transform kYMirrorTransform
=
46 gfx::Transform(0.9f
, 0, 0, -0.8f
, 0.1f
, 1.0f
); // x,y -> x,1-y.
47 const gfx::Transform kBothMirrorTransform
=
48 gfx::Transform(-0.9f
, 0, 0, -0.8f
, 1.0f
, 1.0f
); // x,y -> 1-x,1-y.
49 const gfx::Transform kSwapTransform
=
50 gfx::Transform(0, 1, 1, 0, 0, 0); // x,y -> y,x.
52 void MailboxReleased(unsigned sync_point
,
54 BlockingTaskRunner
* main_thread_task_runner
) {
57 class SingleOverlayValidator
: public OverlayCandidateValidator
{
59 void GetStrategies(OverlayProcessor::StrategyList
* strategies
) override
{
60 strategies
->push_back(scoped_ptr
<OverlayProcessor::Strategy
>(
61 new OverlayStrategyCommon(this, new OverlayStrategySingleOnTop
)));
62 strategies
->push_back(scoped_ptr
<OverlayProcessor::Strategy
>(
63 new OverlayStrategyCommon(this, new OverlayStrategyUnderlay
)));
65 void CheckOverlaySupport(OverlayCandidateList
* surfaces
) override
{
66 ASSERT_EQ(2U, surfaces
->size());
68 OverlayCandidate
& candidate
= surfaces
->back();
69 if (candidate
.display_rect
.width() == 64) {
70 EXPECT_EQ(kOverlayBottomRightRect
, candidate
.display_rect
);
72 EXPECT_NEAR(kOverlayRect
.x(), candidate
.display_rect
.x(), 0.01f
);
73 EXPECT_NEAR(kOverlayRect
.y(), candidate
.display_rect
.y(), 0.01f
);
74 EXPECT_NEAR(kOverlayRect
.width(), candidate
.display_rect
.width(), 0.01f
);
75 EXPECT_NEAR(kOverlayRect
.height(), candidate
.display_rect
.height(),
78 EXPECT_EQ(BoundingRect(kUVTopLeft
, kUVBottomRight
).ToString(),
79 candidate
.uv_rect
.ToString());
80 candidate
.overlay_handled
= true;
84 class SandwichOverlayValidator
: public OverlayCandidateValidator
{
86 void GetStrategies(OverlayProcessor::StrategyList
* strategies
) override
{
87 strategies
->push_back(scoped_ptr
<OverlayProcessor::Strategy
>(
88 new OverlayStrategyCommon(this, new OverlayStrategySandwich
)));
90 void CheckOverlaySupport(OverlayCandidateList
* surfaces
) override
{
91 for (OverlayCandidate
& candidate
: *surfaces
)
92 candidate
.overlay_handled
= true;
96 template <typename OverlayStrategyType
>
97 class SingleOverlayProcessor
: public OverlayProcessor
{
99 explicit SingleOverlayProcessor(OutputSurface
* surface
)
100 : OverlayProcessor(surface
) {
101 EXPECT_EQ(surface
, surface_
);
104 // Virtual to allow testing different strategies.
105 void Initialize() override
{
106 OverlayCandidateValidator
* validator
=
107 surface_
->GetOverlayCandidateValidator();
108 ASSERT_TRUE(validator
!= NULL
);
109 strategies_
.push_back(scoped_ptr
<Strategy
>(
110 new OverlayStrategyCommon(validator
, new OverlayStrategyType
)));
114 class DefaultOverlayProcessor
: public OverlayProcessor
{
116 explicit DefaultOverlayProcessor(OutputSurface
* surface
);
117 size_t GetStrategyCount();
120 DefaultOverlayProcessor::DefaultOverlayProcessor(OutputSurface
* surface
)
121 : OverlayProcessor(surface
) {
124 size_t DefaultOverlayProcessor::GetStrategyCount() {
125 return strategies_
.size();
128 class OverlayOutputSurface
: public OutputSurface
{
130 explicit OverlayOutputSurface(scoped_refptr
<ContextProvider
> context_provider
)
131 : OutputSurface(context_provider
) {
132 surface_size_
= kDisplaySize
;
133 device_scale_factor_
= 1;
136 void SetScaleFactor(float scale_factor
) {
137 device_scale_factor_
= scale_factor
;
140 // OutputSurface implementation
141 void SwapBuffers(CompositorFrame
* frame
) override
;
143 void InitWithSingleOverlayValidator() {
144 overlay_candidate_validator_
.reset(new SingleOverlayValidator
);
146 void InitWithSandwichOverlayValidator() {
147 overlay_candidate_validator_
.reset(new SandwichOverlayValidator
);
150 OverlayCandidateValidator
* GetOverlayCandidateValidator() const override
{
151 return overlay_candidate_validator_
.get();
155 scoped_ptr
<OverlayCandidateValidator
> overlay_candidate_validator_
;
158 void OverlayOutputSurface::SwapBuffers(CompositorFrame
* frame
) {
159 client_
->DidSwapBuffers();
160 client_
->DidSwapBuffersComplete();
163 scoped_ptr
<RenderPass
> CreateRenderPass() {
164 RenderPassId
id(1, 0);
165 gfx::Rect
output_rect(0, 0, 256, 256);
166 bool has_transparent_background
= true;
168 scoped_ptr
<RenderPass
> pass
= RenderPass::Create();
173 has_transparent_background
);
175 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
176 shared_state
->opacity
= 1.f
;
180 ResourceId
CreateResource(ResourceProvider
* resource_provider
) {
181 unsigned sync_point
= 0;
182 TextureMailbox mailbox
=
183 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D
, sync_point
);
184 scoped_ptr
<SingleReleaseCallbackImpl
> release_callback
=
185 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased
));
187 return resource_provider
->CreateResourceFromTextureMailbox(
188 mailbox
, release_callback
.Pass());
191 SolidColorDrawQuad
* CreateSolidColorQuadAt(
192 const SharedQuadState
* shared_quad_state
,
194 RenderPass
* render_pass
,
195 const gfx::Rect
& rect
) {
196 SolidColorDrawQuad
* quad
=
197 render_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
198 quad
->SetNew(shared_quad_state
, rect
, rect
, color
, false);
202 TextureDrawQuad
* CreateCandidateQuadAt(ResourceProvider
* resource_provider
,
203 const SharedQuadState
* shared_quad_state
,
204 RenderPass
* render_pass
,
205 const gfx::Rect
& rect
) {
206 ResourceId resource_id
= CreateResource(resource_provider
);
207 bool premultiplied_alpha
= false;
208 bool flipped
= false;
209 bool nearest_neighbor
= false;
210 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
211 gfx::Size resource_size_in_pixels
= gfx::Size(64, 64);
212 bool allow_overlay
= true;
214 TextureDrawQuad
* overlay_quad
=
215 render_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
216 overlay_quad
->SetNew(shared_quad_state
,
228 overlay_quad
->set_allow_overlay(allow_overlay
);
229 overlay_quad
->set_resource_size_in_pixels(resource_size_in_pixels
);
234 StreamVideoDrawQuad
* CreateCandidateVideoQuadAt(
235 ResourceProvider
* resource_provider
,
236 const SharedQuadState
* shared_quad_state
,
237 RenderPass
* render_pass
,
238 const gfx::Rect
& rect
,
239 const gfx::Transform
& transform
) {
240 ResourceId resource_id
= CreateResource(resource_provider
);
241 gfx::Size resource_size_in_pixels
= gfx::Size(64, 64);
242 bool allow_overlay
= true;
244 StreamVideoDrawQuad
* overlay_quad
=
245 render_pass
->CreateAndAppendDrawQuad
<StreamVideoDrawQuad
>();
246 overlay_quad
->SetNew(shared_quad_state
, rect
, rect
, rect
, resource_id
,
247 resource_size_in_pixels
, allow_overlay
, transform
);
252 TextureDrawQuad
* CreateFullscreenCandidateQuad(
253 ResourceProvider
* resource_provider
,
254 const SharedQuadState
* shared_quad_state
,
255 RenderPass
* render_pass
) {
256 return CreateCandidateQuadAt(
257 resource_provider
, shared_quad_state
, render_pass
, kOverlayRect
);
260 StreamVideoDrawQuad
* CreateFullscreenCandidateVideoQuad(
261 ResourceProvider
* resource_provider
,
262 const SharedQuadState
* shared_quad_state
,
263 RenderPass
* render_pass
,
264 const gfx::Transform
& transform
) {
265 return CreateCandidateVideoQuadAt(resource_provider
, shared_quad_state
,
266 render_pass
, kOverlayRect
, transform
);
269 void CreateOpaqueQuadAt(ResourceProvider
* resource_provider
,
270 const SharedQuadState
* shared_quad_state
,
271 RenderPass
* render_pass
,
272 const gfx::Rect
& rect
) {
273 SolidColorDrawQuad
* color_quad
=
274 render_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
275 color_quad
->SetNew(shared_quad_state
, rect
, rect
, SK_ColorBLACK
, false);
278 void CreateFullscreenOpaqueQuad(ResourceProvider
* resource_provider
,
279 const SharedQuadState
* shared_quad_state
,
280 RenderPass
* render_pass
) {
281 CreateOpaqueQuadAt(resource_provider
, shared_quad_state
, render_pass
,
285 static void CompareRenderPassLists(const RenderPassList
& expected_list
,
286 const RenderPassList
& actual_list
) {
287 EXPECT_EQ(expected_list
.size(), actual_list
.size());
288 for (size_t i
= 0; i
< actual_list
.size(); ++i
) {
289 RenderPass
* expected
= expected_list
[i
];
290 RenderPass
* actual
= actual_list
[i
];
292 EXPECT_EQ(expected
->id
, actual
->id
);
293 EXPECT_EQ(expected
->output_rect
, actual
->output_rect
);
294 EXPECT_EQ(expected
->transform_to_root_target
,
295 actual
->transform_to_root_target
);
296 EXPECT_EQ(expected
->damage_rect
, actual
->damage_rect
);
297 EXPECT_EQ(expected
->has_transparent_background
,
298 actual
->has_transparent_background
);
300 EXPECT_EQ(expected
->shared_quad_state_list
.size(),
301 actual
->shared_quad_state_list
.size());
302 EXPECT_EQ(expected
->quad_list
.size(), actual
->quad_list
.size());
304 for (auto exp_iter
= expected
->quad_list
.cbegin(),
305 act_iter
= actual
->quad_list
.cbegin();
306 exp_iter
!= expected
->quad_list
.cend();
307 ++exp_iter
, ++act_iter
) {
308 EXPECT_EQ(exp_iter
->rect
.ToString(), act_iter
->rect
.ToString());
309 EXPECT_EQ(exp_iter
->shared_quad_state
->quad_layer_bounds
.ToString(),
310 act_iter
->shared_quad_state
->quad_layer_bounds
.ToString());
315 TEST(OverlayTest
, NoOverlaysByDefault
) {
316 scoped_refptr
<TestContextProvider
> provider
= TestContextProvider::Create();
317 OverlayOutputSurface
output_surface(provider
);
318 EXPECT_EQ(NULL
, output_surface
.GetOverlayCandidateValidator());
320 output_surface
.InitWithSingleOverlayValidator();
321 EXPECT_TRUE(output_surface
.GetOverlayCandidateValidator() != NULL
);
324 TEST(OverlayTest
, OverlaysProcessorHasStrategy
) {
325 scoped_refptr
<TestContextProvider
> provider
= TestContextProvider::Create();
326 OverlayOutputSurface
output_surface(provider
);
327 FakeOutputSurfaceClient client
;
328 EXPECT_TRUE(output_surface
.BindToClient(&client
));
329 output_surface
.InitWithSingleOverlayValidator();
330 EXPECT_TRUE(output_surface
.GetOverlayCandidateValidator() != NULL
);
332 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
333 new TestSharedBitmapManager());
334 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
335 &output_surface
, shared_bitmap_manager
.get());
337 scoped_ptr
<DefaultOverlayProcessor
> overlay_processor(
338 new DefaultOverlayProcessor(&output_surface
));
339 overlay_processor
->Initialize();
340 EXPECT_GE(2U, overlay_processor
->GetStrategyCount());
343 template <typename OverlayStrategyType
>
344 class OverlayTest
: public testing::Test
{
346 void SetUp() override
{
347 provider_
= TestContextProvider::Create();
348 output_surface_
.reset(new OverlayOutputSurface(provider_
));
349 EXPECT_TRUE(output_surface_
->BindToClient(&client_
));
350 output_surface_
->InitWithSingleOverlayValidator();
351 EXPECT_TRUE(output_surface_
->GetOverlayCandidateValidator() != NULL
);
353 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
354 resource_provider_
= FakeResourceProvider::Create(
355 output_surface_
.get(), shared_bitmap_manager_
.get());
357 overlay_processor_
.reset(
358 new SingleOverlayProcessor
<OverlayStrategyType
>(output_surface_
.get()));
359 overlay_processor_
->Initialize();
362 scoped_refptr
<TestContextProvider
> provider_
;
363 scoped_ptr
<OverlayOutputSurface
> output_surface_
;
364 FakeOutputSurfaceClient client_
;
365 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
366 scoped_ptr
<ResourceProvider
> resource_provider_
;
367 scoped_ptr
<SingleOverlayProcessor
<OverlayStrategyType
>> overlay_processor_
;
370 typedef OverlayTest
<OverlayStrategySingleOnTop
> SingleOverlayOnTopTest
;
371 typedef OverlayTest
<OverlayStrategyUnderlay
> UnderlayTest
;
373 class SandwichTest
: public testing::Test
{
375 void SetUp() override
{
376 provider_
= TestContextProvider::Create();
377 output_surface_
.reset(new OverlayOutputSurface(provider_
));
378 EXPECT_TRUE(output_surface_
->BindToClient(&client_
));
379 output_surface_
->InitWithSandwichOverlayValidator();
380 EXPECT_TRUE(output_surface_
->GetOverlayCandidateValidator() != NULL
);
382 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
383 resource_provider_
= FakeResourceProvider::Create(
384 output_surface_
.get(), shared_bitmap_manager_
.get());
386 overlay_processor_
.reset(new OverlayProcessor(output_surface_
.get()));
387 overlay_processor_
->Initialize();
390 scoped_refptr
<TestContextProvider
> provider_
;
391 scoped_ptr
<OverlayOutputSurface
> output_surface_
;
392 FakeOutputSurfaceClient client_
;
393 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
394 scoped_ptr
<ResourceProvider
> resource_provider_
;
395 scoped_ptr
<OverlayProcessor
> overlay_processor_
;
398 TEST_F(SandwichTest
, SuccessfulSingleOverlay
) {
399 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
400 TextureDrawQuad
* original_quad
= CreateFullscreenCandidateQuad(
401 resource_provider_
.get(), pass
->shared_quad_state_list
.back(),
403 unsigned original_resource_id
= original_quad
->resource_id();
405 // Add something behind it.
406 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
407 pass
->shared_quad_state_list
.back(), pass
.get());
408 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
409 pass
->shared_quad_state_list
.back(), pass
.get());
411 RenderPassList pass_list
;
412 pass_list
.push_back(pass
.Pass());
414 // Check for potential candidates.
415 OverlayCandidateList candidate_list
;
416 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
418 ASSERT_EQ(1U, pass_list
.size());
419 ASSERT_EQ(2U, candidate_list
.size());
421 RenderPass
* main_pass
= pass_list
.back();
422 // Check that the quad is gone.
423 EXPECT_EQ(2U, main_pass
->quad_list
.size());
424 const QuadList
& quad_list
= main_pass
->quad_list
;
425 for (QuadList::ConstBackToFrontIterator it
= quad_list
.BackToFrontBegin();
426 it
!= quad_list
.BackToFrontEnd(); ++it
) {
427 EXPECT_NE(DrawQuad::TEXTURE_CONTENT
, it
->material
);
430 // Check that the right resource id got extracted.
431 EXPECT_EQ(original_resource_id
, candidate_list
.back().resource_id
);
434 TEST_F(SandwichTest
, SuccessfulSandwichOverlay
) {
435 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
437 CreateOpaqueQuadAt(resource_provider_
.get(),
438 pass
->shared_quad_state_list
.back(), pass
.get(),
439 gfx::Rect(16, 16, 32, 32));
440 unsigned candidate_id
=
441 CreateCandidateQuadAt(resource_provider_
.get(),
442 pass
->shared_quad_state_list
.back(), pass
.get(),
443 gfx::Rect(32, 32, 32, 32))
445 CreateOpaqueQuadAt(resource_provider_
.get(),
446 pass
->shared_quad_state_list
.back(), pass
.get(),
447 gfx::Rect(kDisplaySize
));
449 RenderPassList pass_list
;
450 pass_list
.push_back(pass
.Pass());
452 // Check for potential candidates.
453 OverlayCandidateList candidate_list
;
454 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
456 ASSERT_EQ(1U, pass_list
.size());
457 ASSERT_EQ(3U, candidate_list
.size());
459 RenderPass
* main_pass
= pass_list
.back();
460 // Check that the quad is gone.
461 EXPECT_EQ(3U, main_pass
->quad_list
.size());
462 const QuadList
& quad_list
= main_pass
->quad_list
;
463 for (QuadList::ConstBackToFrontIterator it
= quad_list
.BackToFrontBegin();
464 it
!= quad_list
.BackToFrontEnd(); ++it
) {
465 EXPECT_NE(DrawQuad::TEXTURE_CONTENT
, it
->material
);
468 EXPECT_FALSE(candidate_list
[0].use_output_surface_for_resource
);
469 EXPECT_EQ(candidate_id
, candidate_list
[1].resource_id
);
470 EXPECT_EQ(gfx::Rect(32, 32, 32, 32), candidate_list
[1].display_rect
);
471 EXPECT_TRUE(candidate_list
[2].use_output_surface_for_resource
);
472 EXPECT_EQ(gfx::Rect(32, 32, 16, 16), candidate_list
[2].display_rect
);
473 EXPECT_EQ(gfx::RectF(32. / 256, 32. / 256, 16. / 256, 16. / 256),
474 candidate_list
[2].uv_rect
);
477 TEST_F(SandwichTest
, GrowTopOverlayForToAlignWithDIP
) {
478 output_surface_
->SetScaleFactor(2);
479 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
481 // The opaque quad on top is not DIP aligned, so it should be enlarged to
482 // include the surrounding DIP.
483 CreateOpaqueQuadAt(resource_provider_
.get(),
484 pass
->shared_quad_state_list
.back(), pass
.get(),
485 gfx::Rect(16, 16, 33, 33));
486 unsigned candidate_id
=
487 CreateCandidateQuadAt(resource_provider_
.get(),
488 pass
->shared_quad_state_list
.back(), pass
.get(),
489 gfx::Rect(32, 32, 32, 32))
491 CreateOpaqueQuadAt(resource_provider_
.get(),
492 pass
->shared_quad_state_list
.back(), pass
.get(),
493 gfx::Rect(kDisplaySize
));
495 RenderPassList pass_list
;
496 pass_list
.push_back(pass
.Pass());
498 // Check for potential candidates.
499 OverlayCandidateList candidate_list
;
500 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
501 ASSERT_EQ(1U, pass_list
.size());
502 ASSERT_EQ(3U, candidate_list
.size());
504 // Check that the quad is gone.
505 RenderPass
* main_pass
= pass_list
.back();
506 EXPECT_EQ(3U, main_pass
->quad_list
.size());
507 const QuadList
& quad_list
= main_pass
->quad_list
;
508 for (QuadList::ConstBackToFrontIterator it
= quad_list
.BackToFrontBegin();
509 it
!= quad_list
.BackToFrontEnd(); ++it
) {
510 EXPECT_NE(DrawQuad::TEXTURE_CONTENT
, it
->material
);
513 EXPECT_FALSE(candidate_list
[0].use_output_surface_for_resource
);
514 EXPECT_EQ(candidate_id
, candidate_list
[1].resource_id
);
515 EXPECT_EQ(gfx::Rect(32, 32, 32, 32), candidate_list
[1].display_rect
);
516 EXPECT_TRUE(candidate_list
[2].use_output_surface_for_resource
);
517 EXPECT_EQ(gfx::Rect(32, 32, 18, 18), candidate_list
[2].display_rect
);
518 EXPECT_EQ(gfx::RectF(32. / 256, 32. / 256, 18. / 256, 18. / 256),
519 candidate_list
[2].uv_rect
);
522 TEST_F(SandwichTest
, MisalignedOverlay
) {
523 output_surface_
->SetScaleFactor(2);
524 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
526 // We can't create an overlay for a candidate that is not DIP aligned.
527 CreateCandidateQuadAt(resource_provider_
.get(),
528 pass
->shared_quad_state_list
.back(), pass
.get(),
529 gfx::Rect(32, 32, 33, 33))
531 CreateOpaqueQuadAt(resource_provider_
.get(),
532 pass
->shared_quad_state_list
.back(), pass
.get(),
533 gfx::Rect(kDisplaySize
));
535 RenderPassList pass_list
;
536 pass_list
.push_back(pass
.Pass());
538 OverlayCandidateList candidate_list
;
539 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
541 ASSERT_EQ(1U, pass_list
.size());
542 ASSERT_EQ(0U, candidate_list
.size());
545 TEST_F(SingleOverlayOnTopTest
, SuccessfullOverlay
) {
546 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
547 TextureDrawQuad
* original_quad
=
548 CreateFullscreenCandidateQuad(resource_provider_
.get(),
549 pass
->shared_quad_state_list
.back(),
551 unsigned original_resource_id
= original_quad
->resource_id();
553 // Add something behind it.
554 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
555 pass
->shared_quad_state_list
.back(), pass
.get());
556 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
557 pass
->shared_quad_state_list
.back(), pass
.get());
559 RenderPassList pass_list
;
560 pass_list
.push_back(pass
.Pass());
562 // Check for potential candidates.
563 OverlayCandidateList candidate_list
;
564 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
566 ASSERT_EQ(1U, pass_list
.size());
567 ASSERT_EQ(2U, candidate_list
.size());
569 RenderPass
* main_pass
= pass_list
.back();
570 // Check that the quad is gone.
571 EXPECT_EQ(2U, main_pass
->quad_list
.size());
572 const QuadList
& quad_list
= main_pass
->quad_list
;
573 for (QuadList::ConstBackToFrontIterator it
= quad_list
.BackToFrontBegin();
574 it
!= quad_list
.BackToFrontEnd();
576 EXPECT_NE(DrawQuad::TEXTURE_CONTENT
, it
->material
);
579 // Check that the right resource id got extracted.
580 EXPECT_EQ(original_resource_id
, candidate_list
.back().resource_id
);
583 TEST_F(SingleOverlayOnTopTest
, NoCandidates
) {
584 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
585 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
586 pass
->shared_quad_state_list
.back(), pass
.get());
587 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
588 pass
->shared_quad_state_list
.back(), pass
.get());
590 RenderPassList pass_list
;
591 pass_list
.push_back(pass
.Pass());
593 RenderPassList original_pass_list
;
594 RenderPass::CopyAll(pass_list
, &original_pass_list
);
596 OverlayCandidateList candidate_list
;
597 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
598 EXPECT_EQ(0U, candidate_list
.size());
599 // There should be nothing new here.
600 CompareRenderPassLists(pass_list
, original_pass_list
);
603 TEST_F(SingleOverlayOnTopTest
, OccludedCandidates
) {
604 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
605 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
606 pass
->shared_quad_state_list
.back(), pass
.get());
607 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
608 pass
->shared_quad_state_list
.back(), pass
.get());
610 CreateFullscreenCandidateQuad(resource_provider_
.get(),
611 pass
->shared_quad_state_list
.back(),
614 RenderPassList pass_list
;
615 pass_list
.push_back(pass
.Pass());
617 RenderPassList original_pass_list
;
618 RenderPass::CopyAll(pass_list
, &original_pass_list
);
620 OverlayCandidateList candidate_list
;
621 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
622 EXPECT_EQ(0U, candidate_list
.size());
623 // There should be nothing new here.
624 CompareRenderPassLists(pass_list
, original_pass_list
);
627 // Test with multiple render passes.
628 TEST_F(SingleOverlayOnTopTest
, MultipleRenderPasses
) {
629 RenderPassList pass_list
;
630 pass_list
.push_back(CreateRenderPass());
632 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
633 CreateFullscreenCandidateQuad(resource_provider_
.get(),
634 pass
->shared_quad_state_list
.back(),
637 // Add something behind it.
638 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
639 pass
->shared_quad_state_list
.back(), pass
.get());
640 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
641 pass
->shared_quad_state_list
.back(), pass
.get());
643 pass_list
.push_back(pass
.Pass());
645 RenderPassList original_pass_list
;
646 RenderPass::CopyAll(pass_list
, &original_pass_list
);
648 // Check for potential candidates.
649 OverlayCandidateList candidate_list
;
650 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
651 EXPECT_EQ(2U, candidate_list
.size());
653 // This should be the same.
654 ASSERT_EQ(2U, pass_list
.size());
657 TEST_F(SingleOverlayOnTopTest
, RejectPremultipliedAlpha
) {
658 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
659 TextureDrawQuad
* quad
=
660 CreateFullscreenCandidateQuad(resource_provider_
.get(),
661 pass
->shared_quad_state_list
.back(),
663 quad
->premultiplied_alpha
= true;
665 RenderPassList pass_list
;
666 pass_list
.push_back(pass
.Pass());
667 OverlayCandidateList candidate_list
;
668 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
669 EXPECT_EQ(1U, pass_list
.size());
670 EXPECT_EQ(0U, candidate_list
.size());
673 TEST_F(SingleOverlayOnTopTest
, RejectBlending
) {
674 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
675 TextureDrawQuad
* quad
=
676 CreateFullscreenCandidateQuad(resource_provider_
.get(),
677 pass
->shared_quad_state_list
.back(),
679 quad
->needs_blending
= true;
681 RenderPassList pass_list
;
682 pass_list
.push_back(pass
.Pass());
683 OverlayCandidateList candidate_list
;
684 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
685 ASSERT_EQ(1U, pass_list
.size());
686 EXPECT_EQ(0U, candidate_list
.size());
689 TEST_F(SingleOverlayOnTopTest
, RejectBackgroundColor
) {
690 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
691 TextureDrawQuad
* quad
=
692 CreateFullscreenCandidateQuad(resource_provider_
.get(),
693 pass
->shared_quad_state_list
.back(),
695 quad
->background_color
= SK_ColorBLACK
;
697 RenderPassList pass_list
;
698 pass_list
.push_back(pass
.Pass());
699 OverlayCandidateList candidate_list
;
700 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
701 ASSERT_EQ(1U, pass_list
.size());
702 EXPECT_EQ(0U, candidate_list
.size());
705 TEST_F(SingleOverlayOnTopTest
, RejectBlendMode
) {
706 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
707 CreateFullscreenCandidateQuad(resource_provider_
.get(),
708 pass
->shared_quad_state_list
.back(),
710 pass
->shared_quad_state_list
.back()->blend_mode
= SkXfermode::kScreen_Mode
;
712 RenderPassList pass_list
;
713 pass_list
.push_back(pass
.Pass());
714 OverlayCandidateList candidate_list
;
715 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
716 ASSERT_EQ(1U, pass_list
.size());
717 EXPECT_EQ(0U, candidate_list
.size());
720 TEST_F(SingleOverlayOnTopTest
, RejectOpacity
) {
721 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
722 CreateFullscreenCandidateQuad(resource_provider_
.get(),
723 pass
->shared_quad_state_list
.back(),
725 pass
->shared_quad_state_list
.back()->opacity
= 0.5f
;
727 RenderPassList pass_list
;
728 pass_list
.push_back(pass
.Pass());
729 OverlayCandidateList candidate_list
;
730 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
731 ASSERT_EQ(1U, pass_list
.size());
732 EXPECT_EQ(0U, candidate_list
.size());
735 TEST_F(SingleOverlayOnTopTest
, RejectNonAxisAlignedTransform
) {
736 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
737 CreateFullscreenCandidateQuad(resource_provider_
.get(),
738 pass
->shared_quad_state_list
.back(),
740 pass
->shared_quad_state_list
.back()
741 ->quad_to_target_transform
.RotateAboutXAxis(45.f
);
743 RenderPassList pass_list
;
744 pass_list
.push_back(pass
.Pass());
745 OverlayCandidateList candidate_list
;
746 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
747 ASSERT_EQ(1U, pass_list
.size());
748 EXPECT_EQ(0U, candidate_list
.size());
751 TEST_F(SingleOverlayOnTopTest
, AllowVerticalFlip
) {
752 gfx::Rect rect
= kOverlayRect
;
753 rect
.set_width(rect
.width() / 2);
754 rect
.Offset(0, -rect
.height());
755 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
756 CreateCandidateQuadAt(resource_provider_
.get(),
757 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
758 pass
->shared_quad_state_list
.back()->quad_to_target_transform
.Scale(2.0f
,
761 RenderPassList pass_list
;
762 pass_list
.push_back(pass
.Pass());
763 OverlayCandidateList candidate_list
;
764 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
765 ASSERT_EQ(1U, pass_list
.size());
766 ASSERT_EQ(2U, candidate_list
.size());
767 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
,
768 candidate_list
.back().transform
);
771 TEST_F(SingleOverlayOnTopTest
, AllowHorizontalFlip
) {
772 gfx::Rect rect
= kOverlayRect
;
773 rect
.set_height(rect
.height() / 2);
774 rect
.Offset(-rect
.width(), 0);
775 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
776 CreateCandidateQuadAt(resource_provider_
.get(),
777 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
778 pass
->shared_quad_state_list
.back()->quad_to_target_transform
.Scale(-1.0f
,
781 RenderPassList pass_list
;
782 pass_list
.push_back(pass
.Pass());
783 OverlayCandidateList candidate_list
;
784 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
785 ASSERT_EQ(1U, pass_list
.size());
786 ASSERT_EQ(2U, candidate_list
.size());
787 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
,
788 candidate_list
.back().transform
);
791 TEST_F(SingleOverlayOnTopTest
, AllowPositiveScaleTransform
) {
792 gfx::Rect rect
= kOverlayRect
;
793 rect
.set_width(rect
.width() / 2);
794 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
795 CreateCandidateQuadAt(resource_provider_
.get(),
796 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
797 pass
->shared_quad_state_list
.back()->quad_to_target_transform
.Scale(2.0f
,
800 RenderPassList pass_list
;
801 pass_list
.push_back(pass
.Pass());
802 OverlayCandidateList candidate_list
;
803 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
804 ASSERT_EQ(1U, pass_list
.size());
805 EXPECT_EQ(2U, candidate_list
.size());
808 TEST_F(SingleOverlayOnTopTest
, Allow90DegreeRotation
) {
809 gfx::Rect rect
= kOverlayRect
;
810 rect
.Offset(0, -rect
.height());
811 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
812 CreateCandidateQuadAt(resource_provider_
.get(),
813 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
814 pass
->shared_quad_state_list
.back()
815 ->quad_to_target_transform
.RotateAboutZAxis(90.f
);
817 RenderPassList pass_list
;
818 pass_list
.push_back(pass
.Pass());
819 OverlayCandidateList candidate_list
;
820 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
821 ASSERT_EQ(1U, pass_list
.size());
822 ASSERT_EQ(2U, candidate_list
.size());
823 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_90
, candidate_list
.back().transform
);
826 TEST_F(SingleOverlayOnTopTest
, Allow180DegreeRotation
) {
827 gfx::Rect rect
= kOverlayRect
;
828 rect
.Offset(-rect
.width(), -rect
.height());
829 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
830 CreateCandidateQuadAt(resource_provider_
.get(),
831 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
832 pass
->shared_quad_state_list
.back()
833 ->quad_to_target_transform
.RotateAboutZAxis(180.f
);
835 RenderPassList pass_list
;
836 pass_list
.push_back(pass
.Pass());
837 OverlayCandidateList candidate_list
;
838 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
839 ASSERT_EQ(1U, pass_list
.size());
840 ASSERT_EQ(2U, candidate_list
.size());
841 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_180
, candidate_list
.back().transform
);
844 TEST_F(SingleOverlayOnTopTest
, Allow270DegreeRotation
) {
845 gfx::Rect rect
= kOverlayRect
;
846 rect
.Offset(-rect
.width(), 0);
847 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
848 CreateCandidateQuadAt(resource_provider_
.get(),
849 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
850 pass
->shared_quad_state_list
.back()
851 ->quad_to_target_transform
.RotateAboutZAxis(270.f
);
853 RenderPassList pass_list
;
854 pass_list
.push_back(pass
.Pass());
855 OverlayCandidateList candidate_list
;
856 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
857 ASSERT_EQ(1U, pass_list
.size());
858 ASSERT_EQ(2U, candidate_list
.size());
859 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_270
, candidate_list
.back().transform
);
862 TEST_F(SingleOverlayOnTopTest
, AllowNotTopIfNotOccluded
) {
863 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
864 CreateOpaqueQuadAt(resource_provider_
.get(),
865 pass
->shared_quad_state_list
.back(), pass
.get(),
866 kOverlayTopLeftRect
);
867 CreateCandidateQuadAt(resource_provider_
.get(),
868 pass
->shared_quad_state_list
.back(),
870 kOverlayBottomRightRect
);
872 RenderPassList pass_list
;
873 pass_list
.push_back(pass
.Pass());
875 RenderPassList original_pass_list
;
876 RenderPass::CopyAll(pass_list
, &original_pass_list
);
878 OverlayCandidateList candidate_list
;
879 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
880 EXPECT_EQ(1U, pass_list
.size());
881 EXPECT_EQ(2U, candidate_list
.size());
884 TEST_F(SingleOverlayOnTopTest
, AllowTransparentOnTop
) {
885 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
886 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
887 shared_state
->opacity
= 0.f
;
888 CreateSolidColorQuadAt(shared_state
, SK_ColorBLACK
, pass
.get(),
889 kOverlayBottomRightRect
);
890 shared_state
= pass
->CreateAndAppendSharedQuadState();
891 shared_state
->opacity
= 1.f
;
892 CreateCandidateQuadAt(resource_provider_
.get(), shared_state
, pass
.get(),
893 kOverlayBottomRightRect
);
895 RenderPassList pass_list
;
896 pass_list
.push_back(pass
.Pass());
898 RenderPassList original_pass_list
;
899 RenderPass::CopyAll(pass_list
, &original_pass_list
);
901 OverlayCandidateList candidate_list
;
902 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
903 EXPECT_EQ(1U, pass_list
.size());
904 EXPECT_EQ(2U, candidate_list
.size());
907 TEST_F(SingleOverlayOnTopTest
, AllowTransparentColorOnTop
) {
908 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
909 CreateSolidColorQuadAt(pass
->shared_quad_state_list
.back(),
910 SK_ColorTRANSPARENT
, pass
.get(),
911 kOverlayBottomRightRect
);
912 CreateCandidateQuadAt(resource_provider_
.get(),
913 pass
->shared_quad_state_list
.back(), pass
.get(),
914 kOverlayBottomRightRect
);
916 RenderPassList pass_list
;
917 pass_list
.push_back(pass
.Pass());
919 RenderPassList original_pass_list
;
920 RenderPass::CopyAll(pass_list
, &original_pass_list
);
922 OverlayCandidateList candidate_list
;
923 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
924 EXPECT_EQ(1U, pass_list
.size());
925 EXPECT_EQ(2U, candidate_list
.size());
928 TEST_F(SingleOverlayOnTopTest
, RejectOpaqueColorOnTop
) {
929 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
930 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
931 shared_state
->opacity
= 0.5f
;
932 CreateSolidColorQuadAt(shared_state
, SK_ColorBLACK
, pass
.get(),
933 kOverlayBottomRightRect
);
934 shared_state
= pass
->CreateAndAppendSharedQuadState();
935 shared_state
->opacity
= 1.f
;
936 CreateCandidateQuadAt(resource_provider_
.get(), shared_state
, pass
.get(),
937 kOverlayBottomRightRect
);
939 RenderPassList pass_list
;
940 pass_list
.push_back(pass
.Pass());
942 RenderPassList original_pass_list
;
943 RenderPass::CopyAll(pass_list
, &original_pass_list
);
945 OverlayCandidateList candidate_list
;
946 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
947 EXPECT_EQ(1U, pass_list
.size());
948 EXPECT_EQ(0U, candidate_list
.size());
951 TEST_F(SingleOverlayOnTopTest
, RejectTransparentColorOnTopWithoutBlending
) {
952 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
953 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
954 CreateSolidColorQuadAt(shared_state
, SK_ColorTRANSPARENT
, pass
.get(),
955 kOverlayBottomRightRect
)->opaque_rect
=
956 kOverlayBottomRightRect
;
957 CreateCandidateQuadAt(resource_provider_
.get(), shared_state
, pass
.get(),
958 kOverlayBottomRightRect
);
960 RenderPassList pass_list
;
961 pass_list
.push_back(pass
.Pass());
963 RenderPassList original_pass_list
;
964 RenderPass::CopyAll(pass_list
, &original_pass_list
);
966 OverlayCandidateList candidate_list
;
967 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
968 EXPECT_EQ(1U, pass_list
.size());
969 EXPECT_EQ(0U, candidate_list
.size());
972 TEST_F(SingleOverlayOnTopTest
, RejectVideoSwapTransform
) {
973 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
974 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
975 pass
->shared_quad_state_list
.back(),
976 pass
.get(), kSwapTransform
);
978 RenderPassList pass_list
;
979 pass_list
.push_back(pass
.Pass());
980 OverlayCandidateList candidate_list
;
981 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
982 ASSERT_EQ(1U, pass_list
.size());
983 EXPECT_EQ(0U, candidate_list
.size());
986 TEST_F(SingleOverlayOnTopTest
, AllowVideoXMirrorTransform
) {
987 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
988 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
989 pass
->shared_quad_state_list
.back(),
990 pass
.get(), kXMirrorTransform
);
992 RenderPassList pass_list
;
993 pass_list
.push_back(pass
.Pass());
994 OverlayCandidateList candidate_list
;
995 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
996 ASSERT_EQ(1U, pass_list
.size());
997 EXPECT_EQ(2U, candidate_list
.size());
1000 TEST_F(SingleOverlayOnTopTest
, AllowVideoBothMirrorTransform
) {
1001 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1002 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
1003 pass
->shared_quad_state_list
.back(),
1004 pass
.get(), kBothMirrorTransform
);
1006 RenderPassList pass_list
;
1007 pass_list
.push_back(pass
.Pass());
1008 OverlayCandidateList candidate_list
;
1009 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1010 ASSERT_EQ(1U, pass_list
.size());
1011 EXPECT_EQ(2U, candidate_list
.size());
1014 TEST_F(SingleOverlayOnTopTest
, AllowVideoNormalTransform
) {
1015 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1016 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
1017 pass
->shared_quad_state_list
.back(),
1018 pass
.get(), kNormalTransform
);
1020 RenderPassList pass_list
;
1021 pass_list
.push_back(pass
.Pass());
1022 OverlayCandidateList candidate_list
;
1023 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1024 ASSERT_EQ(1U, pass_list
.size());
1025 EXPECT_EQ(2U, candidate_list
.size());
1028 TEST_F(SingleOverlayOnTopTest
, AllowVideoYMirrorTransform
) {
1029 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1030 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
1031 pass
->shared_quad_state_list
.back(),
1032 pass
.get(), kYMirrorTransform
);
1034 RenderPassList pass_list
;
1035 pass_list
.push_back(pass
.Pass());
1036 OverlayCandidateList candidate_list
;
1037 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1038 ASSERT_EQ(1U, pass_list
.size());
1039 EXPECT_EQ(2U, candidate_list
.size());
1042 TEST_F(UnderlayTest
, OverlayLayerUnderMainLayer
) {
1043 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1044 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1045 pass
->shared_quad_state_list
.back(), pass
.get());
1046 CreateCandidateQuadAt(resource_provider_
.get(),
1047 pass
->shared_quad_state_list
.back(), pass
.get(),
1048 kOverlayBottomRightRect
);
1050 RenderPassList pass_list
;
1051 pass_list
.push_back(pass
.Pass());
1053 OverlayCandidateList candidate_list
;
1054 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1055 EXPECT_EQ(1U, pass_list
.size());
1056 ASSERT_EQ(2U, candidate_list
.size());
1057 EXPECT_EQ(0, candidate_list
[0].plane_z_order
);
1058 EXPECT_EQ(-1, candidate_list
[1].plane_z_order
);
1059 EXPECT_EQ(2U, pass_list
[0]->quad_list
.size());
1060 // The overlay quad should have changed to a SOLID_COLOR quad.
1061 EXPECT_EQ(pass_list
[0]->quad_list
.back()->material
, DrawQuad::SOLID_COLOR
);
1064 TEST_F(UnderlayTest
, AllowOnTop
) {
1065 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1066 CreateFullscreenCandidateQuad(resource_provider_
.get(),
1067 pass
->shared_quad_state_list
.back(),
1069 pass
->CreateAndAppendSharedQuadState()->opacity
= 0.5f
;
1070 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1071 pass
->shared_quad_state_list
.back(), pass
.get());
1073 RenderPassList pass_list
;
1074 pass_list
.push_back(pass
.Pass());
1076 OverlayCandidateList candidate_list
;
1077 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1078 EXPECT_EQ(1U, pass_list
.size());
1079 ASSERT_EQ(2U, candidate_list
.size());
1080 EXPECT_EQ(0, candidate_list
[0].plane_z_order
);
1081 EXPECT_EQ(-1, candidate_list
[1].plane_z_order
);
1082 // The overlay quad should have changed to a SOLID_COLOR quad.
1083 EXPECT_EQ(pass_list
[0]->quad_list
.front()->material
, DrawQuad::SOLID_COLOR
);
1086 class OverlayInfoRendererGL
: public GLRenderer
{
1088 OverlayInfoRendererGL(RendererClient
* client
,
1089 const RendererSettings
* settings
,
1090 OutputSurface
* output_surface
,
1091 ResourceProvider
* resource_provider
)
1092 : GLRenderer(client
,
1098 expect_overlays_(false) {}
1100 MOCK_METHOD3(DoDrawQuad
,
1101 void(DrawingFrame
* frame
,
1102 const DrawQuad
* quad
,
1103 const gfx::QuadF
* draw_region
));
1105 using GLRenderer::BeginDrawingFrame
;
1107 void FinishDrawingFrame(DrawingFrame
* frame
) override
{
1108 GLRenderer::FinishDrawingFrame(frame
);
1110 if (!expect_overlays_
) {
1111 EXPECT_EQ(0U, frame
->overlay_list
.size());
1115 ASSERT_EQ(2U, frame
->overlay_list
.size());
1116 EXPECT_NE(0U, frame
->overlay_list
.back().resource_id
);
1119 void set_expect_overlays(bool expect_overlays
) {
1120 expect_overlays_
= expect_overlays
;
1124 bool expect_overlays_
;
1127 class FakeRendererClient
: public RendererClient
{
1129 // RendererClient methods.
1130 void SetFullRootLayerDamage() override
{}
1133 class MockOverlayScheduler
{
1135 MOCK_METHOD5(Schedule
,
1136 void(int plane_z_order
,
1137 gfx::OverlayTransform plane_transform
,
1138 unsigned overlay_texture_id
,
1139 const gfx::Rect
& display_bounds
,
1140 const gfx::RectF
& uv_rect
));
1143 class GLRendererWithOverlaysTest
: public testing::Test
{
1145 GLRendererWithOverlaysTest() {
1146 provider_
= TestContextProvider::Create();
1147 output_surface_
.reset(new OverlayOutputSurface(provider_
));
1148 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
1149 resource_provider_
=
1150 FakeResourceProvider::Create(output_surface_
.get(), nullptr);
1152 provider_
->support()->SetScheduleOverlayPlaneCallback(base::Bind(
1153 &MockOverlayScheduler::Schedule
, base::Unretained(&scheduler_
)));
1156 void Init(bool use_validator
) {
1158 output_surface_
->InitWithSingleOverlayValidator();
1161 make_scoped_ptr(new OverlayInfoRendererGL(&renderer_client_
,
1163 output_surface_
.get(),
1164 resource_provider_
.get()));
1167 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
1169 RendererSettings settings_
;
1170 FakeOutputSurfaceClient output_surface_client_
;
1171 scoped_ptr
<OverlayOutputSurface
> output_surface_
;
1172 FakeRendererClient renderer_client_
;
1173 scoped_ptr
<ResourceProvider
> resource_provider_
;
1174 scoped_ptr
<OverlayInfoRendererGL
> renderer_
;
1175 scoped_refptr
<TestContextProvider
> provider_
;
1176 MockOverlayScheduler scheduler_
;
1179 TEST_F(GLRendererWithOverlaysTest
, OverlayQuadNotDrawn
) {
1180 bool use_validator
= true;
1181 Init(use_validator
);
1182 renderer_
->set_expect_overlays(true);
1183 gfx::Rect
viewport_rect(16, 16);
1185 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1187 CreateFullscreenCandidateQuad(resource_provider_
.get(),
1188 pass
->shared_quad_state_list
.back(),
1191 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1192 pass
->shared_quad_state_list
.back(), pass
.get());
1193 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1194 pass
->shared_quad_state_list
.back(), pass
.get());
1196 RenderPassList pass_list
;
1197 pass_list
.push_back(pass
.Pass());
1199 // Candidate pass was taken out and extra skipped pass added,
1200 // so only draw 2 quads.
1201 EXPECT_CALL(*renderer_
, DoDrawQuad(_
, _
, _
)).Times(2);
1202 EXPECT_CALL(scheduler_
,
1204 gfx::OVERLAY_TRANSFORM_NONE
,
1207 BoundingRect(kUVTopLeft
, kUVBottomRight
))).Times(1);
1208 renderer_
->DrawFrame(&pass_list
, 1.f
, viewport_rect
, viewport_rect
, false);
1212 Mock::VerifyAndClearExpectations(renderer_
.get());
1213 Mock::VerifyAndClearExpectations(&scheduler_
);
1216 TEST_F(GLRendererWithOverlaysTest
, OccludedQuadInUnderlay
) {
1217 bool use_validator
= true;
1218 Init(use_validator
);
1219 renderer_
->set_expect_overlays(true);
1220 gfx::Rect
viewport_rect(16, 16);
1222 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1224 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1225 pass
->shared_quad_state_list
.back(), pass
.get());
1226 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1227 pass
->shared_quad_state_list
.back(), pass
.get());
1229 CreateFullscreenCandidateQuad(resource_provider_
.get(),
1230 pass
->shared_quad_state_list
.back(),
1233 RenderPassList pass_list
;
1234 pass_list
.push_back(pass
.Pass());
1236 // Candidate quad should fail to be overlaid on top because of occlusion.
1237 // Expect to be replaced with transparent hole quad and placed in underlay.
1238 EXPECT_CALL(*renderer_
, DoDrawQuad(_
, _
, _
)).Times(3);
1239 EXPECT_CALL(scheduler_
,
1240 Schedule(-1, gfx::OVERLAY_TRANSFORM_NONE
, _
, kOverlayRect
,
1241 BoundingRect(kUVTopLeft
, kUVBottomRight
))).Times(1);
1242 renderer_
->DrawFrame(&pass_list
, 1.f
, viewport_rect
, viewport_rect
, false);
1246 Mock::VerifyAndClearExpectations(renderer_
.get());
1247 Mock::VerifyAndClearExpectations(&scheduler_
);
1250 TEST_F(GLRendererWithOverlaysTest
, NoValidatorNoOverlay
) {
1251 bool use_validator
= false;
1252 Init(use_validator
);
1253 renderer_
->set_expect_overlays(false);
1254 gfx::Rect
viewport_rect(16, 16);
1256 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1258 CreateFullscreenCandidateQuad(resource_provider_
.get(),
1259 pass
->shared_quad_state_list
.back(),
1262 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1263 pass
->shared_quad_state_list
.back(), pass
.get());
1264 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1265 pass
->shared_quad_state_list
.back(), pass
.get());
1267 RenderPassList pass_list
;
1268 pass_list
.push_back(pass
.Pass());
1270 // Should see no overlays.
1271 EXPECT_CALL(*renderer_
, DoDrawQuad(_
, _
, _
)).Times(3);
1272 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1273 renderer_
->DrawFrame(&pass_list
, 1.f
, viewport_rect
, viewport_rect
, false);
1277 Mock::VerifyAndClearExpectations(renderer_
.get());
1278 Mock::VerifyAndClearExpectations(&scheduler_
);
1281 TEST_F(GLRendererWithOverlaysTest
, ResourcesExportedAndReturned
) {
1282 bool use_validator
= true;
1283 Init(use_validator
);
1284 renderer_
->set_expect_overlays(true);
1286 ResourceId resource1
= CreateResource(resource_provider_
.get());
1287 ResourceId resource2
= CreateResource(resource_provider_
.get());
1289 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1290 RenderPassList pass_list
;
1291 pass_list
.push_back(pass
.Pass());
1293 DirectRenderer::DrawingFrame frame1
;
1294 frame1
.render_passes_in_draw_order
= &pass_list
;
1295 frame1
.overlay_list
.resize(2);
1296 OverlayCandidate
& overlay1
= frame1
.overlay_list
.back();
1297 overlay1
.resource_id
= resource1
;
1298 overlay1
.plane_z_order
= 1;
1300 DirectRenderer::DrawingFrame frame2
;
1301 frame2
.render_passes_in_draw_order
= &pass_list
;
1302 frame2
.overlay_list
.resize(2);
1303 OverlayCandidate
& overlay2
= frame2
.overlay_list
.back();
1304 overlay2
.resource_id
= resource2
;
1305 overlay2
.plane_z_order
= 1;
1307 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1308 renderer_
->BeginDrawingFrame(&frame1
);
1309 renderer_
->FinishDrawingFrame(&frame1
);
1310 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1311 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1313 Mock::VerifyAndClearExpectations(&scheduler_
);
1315 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1316 renderer_
->BeginDrawingFrame(&frame2
);
1317 renderer_
->FinishDrawingFrame(&frame2
);
1318 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1319 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource2
));
1321 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1322 Mock::VerifyAndClearExpectations(&scheduler_
);
1324 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1325 renderer_
->BeginDrawingFrame(&frame1
);
1326 renderer_
->FinishDrawingFrame(&frame1
);
1327 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1328 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource2
));
1330 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1331 Mock::VerifyAndClearExpectations(&scheduler_
);
1333 // No overlays, release the resource.
1334 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1335 DirectRenderer::DrawingFrame frame3
;
1336 frame3
.render_passes_in_draw_order
= &pass_list
;
1337 renderer_
->set_expect_overlays(false);
1338 renderer_
->BeginDrawingFrame(&frame3
);
1339 renderer_
->FinishDrawingFrame(&frame3
);
1340 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1341 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1343 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1344 Mock::VerifyAndClearExpectations(&scheduler_
);
1346 // Use the same buffer twice.
1347 renderer_
->set_expect_overlays(true);
1348 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1349 renderer_
->BeginDrawingFrame(&frame1
);
1350 renderer_
->FinishDrawingFrame(&frame1
);
1351 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1353 Mock::VerifyAndClearExpectations(&scheduler_
);
1355 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1356 renderer_
->BeginDrawingFrame(&frame1
);
1357 renderer_
->FinishDrawingFrame(&frame1
);
1358 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1360 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1361 Mock::VerifyAndClearExpectations(&scheduler_
);
1363 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1364 renderer_
->set_expect_overlays(false);
1365 renderer_
->BeginDrawingFrame(&frame3
);
1366 renderer_
->FinishDrawingFrame(&frame3
);
1367 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1369 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1370 Mock::VerifyAndClearExpectations(&scheduler_
);