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_single_on_top.h"
13 #include "cc/output/overlay_strategy_underlay.h"
14 #include "cc/quads/checkerboard_draw_quad.h"
15 #include "cc/quads/render_pass.h"
16 #include "cc/quads/stream_video_draw_quad.h"
17 #include "cc/quads/texture_draw_quad.h"
18 #include "cc/resources/resource_provider.h"
19 #include "cc/resources/texture_mailbox.h"
20 #include "cc/test/fake_output_surface_client.h"
21 #include "cc/test/fake_resource_provider.h"
22 #include "cc/test/geometry_test_utils.h"
23 #include "cc/test/test_context_provider.h"
24 #include "cc/test/test_shared_bitmap_manager.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
34 const gfx::Rect
kOverlayRect(0, 0, 128, 128);
35 const gfx::Rect
kOverlayTopLeftRect(0, 0, 64, 64);
36 const gfx::Rect
kOverlayBottomRightRect(64, 64, 64, 64);
37 const gfx::PointF
kUVTopLeft(0.1f
, 0.2f
);
38 const gfx::PointF
kUVBottomRight(1.0f
, 1.0f
);
39 const gfx::Transform kNormalTransform
=
40 gfx::Transform(0.9f
, 0, 0, 0.8f
, 0.1f
, 0.2f
); // x,y -> x,y.
41 const gfx::Transform kXMirrorTransform
=
42 gfx::Transform(-0.9f
, 0, 0, 0.8f
, 1.0f
, 0.2f
); // x,y -> 1-x,y.
43 const gfx::Transform kYMirrorTransform
=
44 gfx::Transform(0.9f
, 0, 0, -0.8f
, 0.1f
, 1.0f
); // x,y -> x,1-y.
45 const gfx::Transform kBothMirrorTransform
=
46 gfx::Transform(-0.9f
, 0, 0, -0.8f
, 1.0f
, 1.0f
); // x,y -> 1-x,1-y.
47 const gfx::Transform kSwapTransform
=
48 gfx::Transform(0, 1, 1, 0, 0, 0); // x,y -> y,x.
50 void MailboxReleased(unsigned sync_point
,
52 BlockingTaskRunner
* main_thread_task_runner
) {
55 class SingleOverlayValidator
: public OverlayCandidateValidator
{
57 void CheckOverlaySupport(OverlayCandidateList
* surfaces
) override
;
60 void SingleOverlayValidator::CheckOverlaySupport(
61 OverlayCandidateList
* surfaces
) {
62 ASSERT_EQ(2U, surfaces
->size());
64 OverlayCandidate
& candidate
= surfaces
->back();
65 if (candidate
.display_rect
.width() == 64) {
66 EXPECT_EQ(kOverlayBottomRightRect
, candidate
.display_rect
);
68 EXPECT_NEAR(kOverlayRect
.x(), candidate
.display_rect
.x(), 0.01f
);
69 EXPECT_NEAR(kOverlayRect
.y(), candidate
.display_rect
.y(), 0.01f
);
70 EXPECT_NEAR(kOverlayRect
.width(), candidate
.display_rect
.width(), 0.01f
);
71 EXPECT_NEAR(kOverlayRect
.height(), candidate
.display_rect
.height(), 0.01f
);
73 EXPECT_EQ(BoundingRect(kUVTopLeft
, kUVBottomRight
).ToString(),
74 candidate
.uv_rect
.ToString());
75 candidate
.overlay_handled
= true;
78 template <typename OverlayStrategyType
>
79 class SingleOverlayProcessor
: public OverlayProcessor
{
81 SingleOverlayProcessor(OutputSurface
* surface
,
82 ResourceProvider
* resource_provider
)
83 : OverlayProcessor(surface
, resource_provider
) {
84 EXPECT_EQ(surface
, surface_
);
85 EXPECT_EQ(resource_provider
, resource_provider_
);
88 // Virtual to allow testing different strategies.
89 void Initialize() override
{
90 OverlayCandidateValidator
* candidates
=
91 surface_
->GetOverlayCandidateValidator();
92 ASSERT_TRUE(candidates
!= NULL
);
93 strategies_
.push_back(scoped_ptr
<Strategy
>(
94 new OverlayStrategyType(candidates
, resource_provider_
)));
98 class DefaultOverlayProcessor
: public OverlayProcessor
{
100 DefaultOverlayProcessor(OutputSurface
* surface
,
101 ResourceProvider
* resource_provider
);
102 size_t GetStrategyCount();
105 DefaultOverlayProcessor::DefaultOverlayProcessor(
106 OutputSurface
* surface
,
107 ResourceProvider
* resource_provider
)
108 : OverlayProcessor(surface
, resource_provider
) {}
110 size_t DefaultOverlayProcessor::GetStrategyCount() {
111 return strategies_
.size();
114 class OverlayOutputSurface
: public OutputSurface
{
116 explicit OverlayOutputSurface(scoped_refptr
<ContextProvider
> context_provider
)
117 : OutputSurface(context_provider
) {}
119 // OutputSurface implementation
120 void SwapBuffers(CompositorFrame
* frame
) override
;
122 void InitWithSingleOverlayValidator() {
123 overlay_candidate_validator_
.reset(new SingleOverlayValidator
);
126 OverlayCandidateValidator
* GetOverlayCandidateValidator() const override
{
127 return overlay_candidate_validator_
.get();
131 scoped_ptr
<OverlayCandidateValidator
> overlay_candidate_validator_
;
134 void OverlayOutputSurface::SwapBuffers(CompositorFrame
* frame
) {
135 client_
->DidSwapBuffers();
136 client_
->DidSwapBuffersComplete();
139 scoped_ptr
<RenderPass
> CreateRenderPass() {
140 RenderPassId
id(1, 0);
141 gfx::Rect
output_rect(0, 0, 256, 256);
142 bool has_transparent_background
= true;
144 scoped_ptr
<RenderPass
> pass
= RenderPass::Create();
149 has_transparent_background
);
151 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
152 shared_state
->opacity
= 1.f
;
156 ResourceId
CreateResource(ResourceProvider
* resource_provider
) {
157 unsigned sync_point
= 0;
158 TextureMailbox mailbox
=
159 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D
, sync_point
);
160 mailbox
.set_allow_overlay(true);
161 scoped_ptr
<SingleReleaseCallbackImpl
> release_callback
=
162 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased
));
164 return resource_provider
->CreateResourceFromTextureMailbox(
165 mailbox
, release_callback
.Pass());
168 SolidColorDrawQuad
* CreateSolidColorQuadAt(
169 const SharedQuadState
* shared_quad_state
,
171 RenderPass
* render_pass
,
172 const gfx::Rect
& rect
) {
173 SolidColorDrawQuad
* quad
=
174 render_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
175 quad
->SetNew(shared_quad_state
, rect
, rect
, color
, false);
179 TextureDrawQuad
* CreateCandidateQuadAt(ResourceProvider
* resource_provider
,
180 const SharedQuadState
* shared_quad_state
,
181 RenderPass
* render_pass
,
182 const gfx::Rect
& rect
) {
183 ResourceId resource_id
= CreateResource(resource_provider
);
184 bool premultiplied_alpha
= false;
185 bool flipped
= false;
186 bool nearest_neighbor
= false;
187 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
189 TextureDrawQuad
* overlay_quad
=
190 render_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
191 overlay_quad
->SetNew(shared_quad_state
,
207 StreamVideoDrawQuad
* CreateCandidateVideoQuadAt(
208 ResourceProvider
* resource_provider
,
209 const SharedQuadState
* shared_quad_state
,
210 RenderPass
* render_pass
,
211 const gfx::Rect
& rect
,
212 const gfx::Transform
& transform
) {
213 ResourceId resource_id
= CreateResource(resource_provider
);
215 StreamVideoDrawQuad
* overlay_quad
=
216 render_pass
->CreateAndAppendDrawQuad
<StreamVideoDrawQuad
>();
217 overlay_quad
->SetNew(shared_quad_state
, rect
, rect
, rect
, resource_id
,
223 TextureDrawQuad
* CreateFullscreenCandidateQuad(
224 ResourceProvider
* resource_provider
,
225 const SharedQuadState
* shared_quad_state
,
226 RenderPass
* render_pass
) {
227 return CreateCandidateQuadAt(
228 resource_provider
, shared_quad_state
, render_pass
, kOverlayRect
);
231 StreamVideoDrawQuad
* CreateFullscreenCandidateVideoQuad(
232 ResourceProvider
* resource_provider
,
233 const SharedQuadState
* shared_quad_state
,
234 RenderPass
* render_pass
,
235 const gfx::Transform
& transform
) {
236 return CreateCandidateVideoQuadAt(resource_provider
, shared_quad_state
,
237 render_pass
, kOverlayRect
, transform
);
240 void CreateCheckeredQuadAt(ResourceProvider
* resource_provider
,
241 const SharedQuadState
* shared_quad_state
,
242 RenderPass
* render_pass
,
243 const gfx::Rect
& rect
) {
244 CheckerboardDrawQuad
* checkerboard_quad
=
245 render_pass
->CreateAndAppendDrawQuad
<CheckerboardDrawQuad
>();
246 checkerboard_quad
->SetNew(shared_quad_state
, rect
, rect
, SkColor(), 1.f
);
249 void CreateFullscreenCheckeredQuad(ResourceProvider
* resource_provider
,
250 const SharedQuadState
* shared_quad_state
,
251 RenderPass
* render_pass
) {
252 CreateCheckeredQuadAt(
253 resource_provider
, shared_quad_state
, render_pass
, kOverlayRect
);
256 static void CompareRenderPassLists(const RenderPassList
& expected_list
,
257 const RenderPassList
& actual_list
) {
258 EXPECT_EQ(expected_list
.size(), actual_list
.size());
259 for (size_t i
= 0; i
< actual_list
.size(); ++i
) {
260 RenderPass
* expected
= expected_list
[i
];
261 RenderPass
* actual
= actual_list
[i
];
263 EXPECT_EQ(expected
->id
, actual
->id
);
264 EXPECT_EQ(expected
->output_rect
, actual
->output_rect
);
265 EXPECT_EQ(expected
->transform_to_root_target
,
266 actual
->transform_to_root_target
);
267 EXPECT_EQ(expected
->damage_rect
, actual
->damage_rect
);
268 EXPECT_EQ(expected
->has_transparent_background
,
269 actual
->has_transparent_background
);
271 EXPECT_EQ(expected
->shared_quad_state_list
.size(),
272 actual
->shared_quad_state_list
.size());
273 EXPECT_EQ(expected
->quad_list
.size(), actual
->quad_list
.size());
275 for (auto exp_iter
= expected
->quad_list
.cbegin(),
276 act_iter
= actual
->quad_list
.cbegin();
277 exp_iter
!= expected
->quad_list
.cend();
278 ++exp_iter
, ++act_iter
) {
279 EXPECT_EQ(exp_iter
->rect
.ToString(), act_iter
->rect
.ToString());
280 EXPECT_EQ(exp_iter
->shared_quad_state
->content_bounds
.ToString(),
281 act_iter
->shared_quad_state
->content_bounds
.ToString());
286 TEST(OverlayTest
, NoOverlaysByDefault
) {
287 scoped_refptr
<TestContextProvider
> provider
= TestContextProvider::Create();
288 OverlayOutputSurface
output_surface(provider
);
289 EXPECT_EQ(NULL
, output_surface
.GetOverlayCandidateValidator());
291 output_surface
.InitWithSingleOverlayValidator();
292 EXPECT_TRUE(output_surface
.GetOverlayCandidateValidator() != NULL
);
295 TEST(OverlayTest
, OverlaysProcessorHasStrategy
) {
296 scoped_refptr
<TestContextProvider
> provider
= TestContextProvider::Create();
297 OverlayOutputSurface
output_surface(provider
);
298 FakeOutputSurfaceClient client
;
299 EXPECT_TRUE(output_surface
.BindToClient(&client
));
300 output_surface
.InitWithSingleOverlayValidator();
301 EXPECT_TRUE(output_surface
.GetOverlayCandidateValidator() != NULL
);
303 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
304 new TestSharedBitmapManager());
305 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
306 &output_surface
, shared_bitmap_manager
.get());
308 scoped_ptr
<DefaultOverlayProcessor
> overlay_processor(
309 new DefaultOverlayProcessor(&output_surface
, resource_provider
.get()));
310 overlay_processor
->Initialize();
311 EXPECT_GE(2U, overlay_processor
->GetStrategyCount());
314 template <typename OverlayStrategyType
>
315 class OverlayTest
: public testing::Test
{
317 void SetUp() override
{
318 provider_
= TestContextProvider::Create();
319 output_surface_
.reset(new OverlayOutputSurface(provider_
));
320 EXPECT_TRUE(output_surface_
->BindToClient(&client_
));
321 output_surface_
->InitWithSingleOverlayValidator();
322 EXPECT_TRUE(output_surface_
->GetOverlayCandidateValidator() != NULL
);
324 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
325 resource_provider_
= FakeResourceProvider::Create(
326 output_surface_
.get(), shared_bitmap_manager_
.get());
328 overlay_processor_
.reset(new SingleOverlayProcessor
<OverlayStrategyType
>(
329 output_surface_
.get(), resource_provider_
.get()));
330 overlay_processor_
->Initialize();
333 scoped_refptr
<TestContextProvider
> provider_
;
334 scoped_ptr
<OverlayOutputSurface
> output_surface_
;
335 FakeOutputSurfaceClient client_
;
336 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
337 scoped_ptr
<ResourceProvider
> resource_provider_
;
338 scoped_ptr
<SingleOverlayProcessor
<OverlayStrategyType
>> overlay_processor_
;
341 typedef OverlayTest
<OverlayStrategySingleOnTop
> SingleOverlayOnTopTest
;
342 typedef OverlayTest
<OverlayStrategyUnderlay
> UnderlayTest
;
344 TEST_F(SingleOverlayOnTopTest
, SuccessfullOverlay
) {
345 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
346 TextureDrawQuad
* original_quad
=
347 CreateFullscreenCandidateQuad(resource_provider_
.get(),
348 pass
->shared_quad_state_list
.back(),
350 unsigned original_resource_id
= original_quad
->resource_id
;
352 // Add something behind it.
353 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
354 pass
->shared_quad_state_list
.back(),
356 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
357 pass
->shared_quad_state_list
.back(),
360 RenderPassList pass_list
;
361 pass_list
.push_back(pass
.Pass());
363 // Check for potential candidates.
364 OverlayCandidateList candidate_list
;
365 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
367 ASSERT_EQ(1U, pass_list
.size());
368 ASSERT_EQ(2U, candidate_list
.size());
370 RenderPass
* main_pass
= pass_list
.back();
371 // Check that the quad is gone.
372 EXPECT_EQ(2U, main_pass
->quad_list
.size());
373 const QuadList
& quad_list
= main_pass
->quad_list
;
374 for (QuadList::ConstBackToFrontIterator it
= quad_list
.BackToFrontBegin();
375 it
!= quad_list
.BackToFrontEnd();
377 EXPECT_NE(DrawQuad::TEXTURE_CONTENT
, it
->material
);
380 // Check that the right resource id got extracted.
381 EXPECT_EQ(original_resource_id
, candidate_list
.back().resource_id
);
384 TEST_F(SingleOverlayOnTopTest
, NoCandidates
) {
385 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
386 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
387 pass
->shared_quad_state_list
.back(),
389 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
390 pass
->shared_quad_state_list
.back(),
393 RenderPassList pass_list
;
394 pass_list
.push_back(pass
.Pass());
396 RenderPassList original_pass_list
;
397 RenderPass::CopyAll(pass_list
, &original_pass_list
);
399 OverlayCandidateList candidate_list
;
400 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
401 EXPECT_EQ(0U, candidate_list
.size());
402 // There should be nothing new here.
403 CompareRenderPassLists(pass_list
, original_pass_list
);
406 TEST_F(SingleOverlayOnTopTest
, OccludedCandidates
) {
407 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
408 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
409 pass
->shared_quad_state_list
.back(),
411 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
412 pass
->shared_quad_state_list
.back(),
415 CreateFullscreenCandidateQuad(resource_provider_
.get(),
416 pass
->shared_quad_state_list
.back(),
419 RenderPassList pass_list
;
420 pass_list
.push_back(pass
.Pass());
422 RenderPassList original_pass_list
;
423 RenderPass::CopyAll(pass_list
, &original_pass_list
);
425 OverlayCandidateList candidate_list
;
426 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
427 EXPECT_EQ(0U, candidate_list
.size());
428 // There should be nothing new here.
429 CompareRenderPassLists(pass_list
, original_pass_list
);
432 // Test with multiple render passes.
433 TEST_F(SingleOverlayOnTopTest
, MultipleRenderPasses
) {
434 RenderPassList pass_list
;
435 pass_list
.push_back(CreateRenderPass());
437 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
438 CreateFullscreenCandidateQuad(resource_provider_
.get(),
439 pass
->shared_quad_state_list
.back(),
442 // Add something behind it.
443 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
444 pass
->shared_quad_state_list
.back(),
446 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
447 pass
->shared_quad_state_list
.back(),
450 pass_list
.push_back(pass
.Pass());
452 RenderPassList original_pass_list
;
453 RenderPass::CopyAll(pass_list
, &original_pass_list
);
455 // Check for potential candidates.
456 OverlayCandidateList candidate_list
;
457 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
458 EXPECT_EQ(2U, candidate_list
.size());
460 // This should be the same.
461 ASSERT_EQ(2U, pass_list
.size());
464 TEST_F(SingleOverlayOnTopTest
, RejectPremultipliedAlpha
) {
465 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
466 TextureDrawQuad
* quad
=
467 CreateFullscreenCandidateQuad(resource_provider_
.get(),
468 pass
->shared_quad_state_list
.back(),
470 quad
->premultiplied_alpha
= true;
472 RenderPassList pass_list
;
473 pass_list
.push_back(pass
.Pass());
474 OverlayCandidateList candidate_list
;
475 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
476 EXPECT_EQ(1U, pass_list
.size());
477 EXPECT_EQ(0U, candidate_list
.size());
480 TEST_F(SingleOverlayOnTopTest
, RejectBlending
) {
481 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
482 TextureDrawQuad
* quad
=
483 CreateFullscreenCandidateQuad(resource_provider_
.get(),
484 pass
->shared_quad_state_list
.back(),
486 quad
->needs_blending
= true;
488 RenderPassList pass_list
;
489 pass_list
.push_back(pass
.Pass());
490 OverlayCandidateList candidate_list
;
491 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
492 ASSERT_EQ(1U, pass_list
.size());
493 EXPECT_EQ(0U, candidate_list
.size());
496 TEST_F(SingleOverlayOnTopTest
, RejectBackgroundColor
) {
497 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
498 TextureDrawQuad
* quad
=
499 CreateFullscreenCandidateQuad(resource_provider_
.get(),
500 pass
->shared_quad_state_list
.back(),
502 quad
->background_color
= SK_ColorBLACK
;
504 RenderPassList pass_list
;
505 pass_list
.push_back(pass
.Pass());
506 OverlayCandidateList candidate_list
;
507 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
508 ASSERT_EQ(1U, pass_list
.size());
509 EXPECT_EQ(0U, candidate_list
.size());
512 TEST_F(SingleOverlayOnTopTest
, RejectBlendMode
) {
513 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
514 CreateFullscreenCandidateQuad(resource_provider_
.get(),
515 pass
->shared_quad_state_list
.back(),
517 pass
->shared_quad_state_list
.back()->blend_mode
= SkXfermode::kScreen_Mode
;
519 RenderPassList pass_list
;
520 pass_list
.push_back(pass
.Pass());
521 OverlayCandidateList candidate_list
;
522 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
523 ASSERT_EQ(1U, pass_list
.size());
524 EXPECT_EQ(0U, candidate_list
.size());
527 TEST_F(SingleOverlayOnTopTest
, RejectOpacity
) {
528 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
529 CreateFullscreenCandidateQuad(resource_provider_
.get(),
530 pass
->shared_quad_state_list
.back(),
532 pass
->shared_quad_state_list
.back()->opacity
= 0.5f
;
534 RenderPassList pass_list
;
535 pass_list
.push_back(pass
.Pass());
536 OverlayCandidateList candidate_list
;
537 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
538 ASSERT_EQ(1U, pass_list
.size());
539 EXPECT_EQ(0U, candidate_list
.size());
542 TEST_F(SingleOverlayOnTopTest
, RejectNonAxisAlignedTransform
) {
543 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
544 CreateFullscreenCandidateQuad(resource_provider_
.get(),
545 pass
->shared_quad_state_list
.back(),
547 pass
->shared_quad_state_list
.back()
548 ->content_to_target_transform
.RotateAboutXAxis(45.f
);
550 RenderPassList pass_list
;
551 pass_list
.push_back(pass
.Pass());
552 OverlayCandidateList candidate_list
;
553 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
554 ASSERT_EQ(1U, pass_list
.size());
555 EXPECT_EQ(0U, candidate_list
.size());
558 TEST_F(SingleOverlayOnTopTest
, AllowVerticalFlip
) {
559 gfx::Rect rect
= kOverlayRect
;
560 rect
.set_width(rect
.width() / 2);
561 rect
.Offset(0, -rect
.height());
562 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
563 CreateCandidateQuadAt(resource_provider_
.get(),
564 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
565 pass
->shared_quad_state_list
.back()->content_to_target_transform
.Scale(2.0f
,
568 RenderPassList pass_list
;
569 pass_list
.push_back(pass
.Pass());
570 OverlayCandidateList candidate_list
;
571 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
572 ASSERT_EQ(1U, pass_list
.size());
573 ASSERT_EQ(2U, candidate_list
.size());
574 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
,
575 candidate_list
.back().transform
);
578 TEST_F(SingleOverlayOnTopTest
, AllowHorizontalFlip
) {
579 gfx::Rect rect
= kOverlayRect
;
580 rect
.set_height(rect
.height() / 2);
581 rect
.Offset(-rect
.width(), 0);
582 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
583 CreateCandidateQuadAt(resource_provider_
.get(),
584 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
585 pass
->shared_quad_state_list
.back()->content_to_target_transform
.Scale(-1.0f
,
588 RenderPassList pass_list
;
589 pass_list
.push_back(pass
.Pass());
590 OverlayCandidateList candidate_list
;
591 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
592 ASSERT_EQ(1U, pass_list
.size());
593 ASSERT_EQ(2U, candidate_list
.size());
594 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
,
595 candidate_list
.back().transform
);
598 TEST_F(SingleOverlayOnTopTest
, AllowPositiveScaleTransform
) {
599 gfx::Rect rect
= kOverlayRect
;
600 rect
.set_width(rect
.width() / 2);
601 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
602 CreateCandidateQuadAt(resource_provider_
.get(),
603 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
604 pass
->shared_quad_state_list
.back()->content_to_target_transform
.Scale(2.0f
,
607 RenderPassList pass_list
;
608 pass_list
.push_back(pass
.Pass());
609 OverlayCandidateList candidate_list
;
610 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
611 ASSERT_EQ(1U, pass_list
.size());
612 EXPECT_EQ(2U, candidate_list
.size());
615 TEST_F(SingleOverlayOnTopTest
, Allow90DegreeRotation
) {
616 gfx::Rect rect
= kOverlayRect
;
617 rect
.Offset(0, -rect
.height());
618 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
619 CreateCandidateQuadAt(resource_provider_
.get(),
620 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
621 pass
->shared_quad_state_list
.back()
622 ->content_to_target_transform
.RotateAboutZAxis(90.f
);
624 RenderPassList pass_list
;
625 pass_list
.push_back(pass
.Pass());
626 OverlayCandidateList candidate_list
;
627 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
628 ASSERT_EQ(1U, pass_list
.size());
629 ASSERT_EQ(2U, candidate_list
.size());
630 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_90
, candidate_list
.back().transform
);
633 TEST_F(SingleOverlayOnTopTest
, Allow180DegreeRotation
) {
634 gfx::Rect rect
= kOverlayRect
;
635 rect
.Offset(-rect
.width(), -rect
.height());
636 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
637 CreateCandidateQuadAt(resource_provider_
.get(),
638 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
639 pass
->shared_quad_state_list
.back()
640 ->content_to_target_transform
.RotateAboutZAxis(180.f
);
642 RenderPassList pass_list
;
643 pass_list
.push_back(pass
.Pass());
644 OverlayCandidateList candidate_list
;
645 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
646 ASSERT_EQ(1U, pass_list
.size());
647 ASSERT_EQ(2U, candidate_list
.size());
648 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_180
, candidate_list
.back().transform
);
651 TEST_F(SingleOverlayOnTopTest
, Allow270DegreeRotation
) {
652 gfx::Rect rect
= kOverlayRect
;
653 rect
.Offset(-rect
.width(), 0);
654 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
655 CreateCandidateQuadAt(resource_provider_
.get(),
656 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
657 pass
->shared_quad_state_list
.back()
658 ->content_to_target_transform
.RotateAboutZAxis(270.f
);
660 RenderPassList pass_list
;
661 pass_list
.push_back(pass
.Pass());
662 OverlayCandidateList candidate_list
;
663 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
664 ASSERT_EQ(1U, pass_list
.size());
665 ASSERT_EQ(2U, candidate_list
.size());
666 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_270
, candidate_list
.back().transform
);
669 TEST_F(SingleOverlayOnTopTest
, AllowNotTopIfNotOccluded
) {
670 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
671 CreateCheckeredQuadAt(resource_provider_
.get(),
672 pass
->shared_quad_state_list
.back(),
674 kOverlayTopLeftRect
);
675 CreateCandidateQuadAt(resource_provider_
.get(),
676 pass
->shared_quad_state_list
.back(),
678 kOverlayBottomRightRect
);
680 RenderPassList pass_list
;
681 pass_list
.push_back(pass
.Pass());
683 RenderPassList original_pass_list
;
684 RenderPass::CopyAll(pass_list
, &original_pass_list
);
686 OverlayCandidateList candidate_list
;
687 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
688 EXPECT_EQ(1U, pass_list
.size());
689 EXPECT_EQ(2U, candidate_list
.size());
692 TEST_F(SingleOverlayOnTopTest
, AllowTransparentOnTop
) {
693 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
694 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
695 shared_state
->opacity
= 0.f
;
696 CreateSolidColorQuadAt(shared_state
, SK_ColorBLACK
, pass
.get(),
697 kOverlayBottomRightRect
);
698 shared_state
= pass
->CreateAndAppendSharedQuadState();
699 shared_state
->opacity
= 1.f
;
700 CreateCandidateQuadAt(resource_provider_
.get(), shared_state
, pass
.get(),
701 kOverlayBottomRightRect
);
703 RenderPassList pass_list
;
704 pass_list
.push_back(pass
.Pass());
706 RenderPassList original_pass_list
;
707 RenderPass::CopyAll(pass_list
, &original_pass_list
);
709 OverlayCandidateList candidate_list
;
710 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
711 EXPECT_EQ(1U, pass_list
.size());
712 EXPECT_EQ(2U, candidate_list
.size());
715 TEST_F(SingleOverlayOnTopTest
, AllowTransparentColorOnTop
) {
716 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
717 CreateSolidColorQuadAt(pass
->shared_quad_state_list
.back(),
718 SK_ColorTRANSPARENT
, pass
.get(),
719 kOverlayBottomRightRect
);
720 CreateCandidateQuadAt(resource_provider_
.get(),
721 pass
->shared_quad_state_list
.back(), pass
.get(),
722 kOverlayBottomRightRect
);
724 RenderPassList pass_list
;
725 pass_list
.push_back(pass
.Pass());
727 RenderPassList original_pass_list
;
728 RenderPass::CopyAll(pass_list
, &original_pass_list
);
730 OverlayCandidateList candidate_list
;
731 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
732 EXPECT_EQ(1U, pass_list
.size());
733 EXPECT_EQ(2U, candidate_list
.size());
736 TEST_F(SingleOverlayOnTopTest
, RejectOpaqueColorOnTop
) {
737 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
738 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
739 shared_state
->opacity
= 0.5f
;
740 CreateSolidColorQuadAt(shared_state
, SK_ColorBLACK
, pass
.get(),
741 kOverlayBottomRightRect
);
742 shared_state
= pass
->CreateAndAppendSharedQuadState();
743 shared_state
->opacity
= 1.f
;
744 CreateCandidateQuadAt(resource_provider_
.get(), shared_state
, pass
.get(),
745 kOverlayBottomRightRect
);
747 RenderPassList pass_list
;
748 pass_list
.push_back(pass
.Pass());
750 RenderPassList original_pass_list
;
751 RenderPass::CopyAll(pass_list
, &original_pass_list
);
753 OverlayCandidateList candidate_list
;
754 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
755 EXPECT_EQ(1U, pass_list
.size());
756 EXPECT_EQ(0U, candidate_list
.size());
759 TEST_F(SingleOverlayOnTopTest
, RejectTransparentColorOnTopWithoutBlending
) {
760 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
761 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
762 CreateSolidColorQuadAt(shared_state
, SK_ColorTRANSPARENT
, pass
.get(),
763 kOverlayBottomRightRect
)->opaque_rect
=
764 kOverlayBottomRightRect
;
765 CreateCandidateQuadAt(resource_provider_
.get(), shared_state
, pass
.get(),
766 kOverlayBottomRightRect
);
768 RenderPassList pass_list
;
769 pass_list
.push_back(pass
.Pass());
771 RenderPassList original_pass_list
;
772 RenderPass::CopyAll(pass_list
, &original_pass_list
);
774 OverlayCandidateList candidate_list
;
775 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
776 EXPECT_EQ(1U, pass_list
.size());
777 EXPECT_EQ(0U, candidate_list
.size());
780 TEST_F(SingleOverlayOnTopTest
, RejectVideoSwapTransform
) {
781 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
782 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
783 pass
->shared_quad_state_list
.back(),
784 pass
.get(), kSwapTransform
);
786 RenderPassList pass_list
;
787 pass_list
.push_back(pass
.Pass());
788 OverlayCandidateList candidate_list
;
789 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
790 ASSERT_EQ(1U, pass_list
.size());
791 EXPECT_EQ(0U, candidate_list
.size());
794 TEST_F(SingleOverlayOnTopTest
, AllowVideoXMirrorTransform
) {
795 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
796 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
797 pass
->shared_quad_state_list
.back(),
798 pass
.get(), kXMirrorTransform
);
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
, AllowVideoBothMirrorTransform
) {
809 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
810 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
811 pass
->shared_quad_state_list
.back(),
812 pass
.get(), kBothMirrorTransform
);
814 RenderPassList pass_list
;
815 pass_list
.push_back(pass
.Pass());
816 OverlayCandidateList candidate_list
;
817 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
818 ASSERT_EQ(1U, pass_list
.size());
819 EXPECT_EQ(2U, candidate_list
.size());
822 TEST_F(SingleOverlayOnTopTest
, AllowVideoNormalTransform
) {
823 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
824 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
825 pass
->shared_quad_state_list
.back(),
826 pass
.get(), kNormalTransform
);
828 RenderPassList pass_list
;
829 pass_list
.push_back(pass
.Pass());
830 OverlayCandidateList candidate_list
;
831 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
832 ASSERT_EQ(1U, pass_list
.size());
833 EXPECT_EQ(2U, candidate_list
.size());
836 TEST_F(SingleOverlayOnTopTest
, AllowVideoYMirrorTransform
) {
837 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
838 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
839 pass
->shared_quad_state_list
.back(),
840 pass
.get(), kYMirrorTransform
);
842 RenderPassList pass_list
;
843 pass_list
.push_back(pass
.Pass());
844 OverlayCandidateList candidate_list
;
845 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
846 ASSERT_EQ(1U, pass_list
.size());
847 EXPECT_EQ(2U, candidate_list
.size());
850 TEST_F(UnderlayTest
, OverlayLayerUnderMainLayer
) {
851 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
852 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
853 pass
->shared_quad_state_list
.back(),
855 CreateCandidateQuadAt(resource_provider_
.get(),
856 pass
->shared_quad_state_list
.back(), pass
.get(),
857 kOverlayBottomRightRect
);
859 RenderPassList pass_list
;
860 pass_list
.push_back(pass
.Pass());
862 OverlayCandidateList candidate_list
;
863 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
864 EXPECT_EQ(1U, pass_list
.size());
865 ASSERT_EQ(2U, candidate_list
.size());
866 EXPECT_EQ(0, candidate_list
[0].plane_z_order
);
867 EXPECT_EQ(-1, candidate_list
[1].plane_z_order
);
868 EXPECT_EQ(2U, pass_list
[0]->quad_list
.size());
869 // The overlay quad should have changed to a SOLID_COLOR quad.
870 EXPECT_EQ(pass_list
[0]->quad_list
.back()->material
, DrawQuad::SOLID_COLOR
);
873 TEST_F(UnderlayTest
, AllowOnTop
) {
874 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
875 CreateFullscreenCandidateQuad(resource_provider_
.get(),
876 pass
->shared_quad_state_list
.back(),
878 pass
->CreateAndAppendSharedQuadState()->opacity
= 0.5f
;
879 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
880 pass
->shared_quad_state_list
.back(),
883 RenderPassList pass_list
;
884 pass_list
.push_back(pass
.Pass());
886 OverlayCandidateList candidate_list
;
887 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
888 EXPECT_EQ(1U, pass_list
.size());
889 ASSERT_EQ(2U, candidate_list
.size());
890 EXPECT_EQ(0, candidate_list
[0].plane_z_order
);
891 EXPECT_EQ(-1, candidate_list
[1].plane_z_order
);
892 // The overlay quad should have changed to a SOLID_COLOR quad.
893 EXPECT_EQ(pass_list
[0]->quad_list
.front()->material
, DrawQuad::SOLID_COLOR
);
896 class OverlayInfoRendererGL
: public GLRenderer
{
898 OverlayInfoRendererGL(RendererClient
* client
,
899 const RendererSettings
* settings
,
900 OutputSurface
* output_surface
,
901 ResourceProvider
* resource_provider
)
908 expect_overlays_(false) {}
910 MOCK_METHOD3(DoDrawQuad
,
911 void(DrawingFrame
* frame
,
912 const DrawQuad
* quad
,
913 const gfx::QuadF
* draw_region
));
915 using GLRenderer::BeginDrawingFrame
;
917 void FinishDrawingFrame(DrawingFrame
* frame
) override
{
918 GLRenderer::FinishDrawingFrame(frame
);
920 if (!expect_overlays_
) {
921 EXPECT_EQ(0U, frame
->overlay_list
.size());
925 ASSERT_EQ(2U, frame
->overlay_list
.size());
926 EXPECT_NE(0U, frame
->overlay_list
.back().resource_id
);
929 void set_expect_overlays(bool expect_overlays
) {
930 expect_overlays_
= expect_overlays
;
934 bool expect_overlays_
;
937 class FakeRendererClient
: public RendererClient
{
939 // RendererClient methods.
940 void SetFullRootLayerDamage() override
{}
943 class MockOverlayScheduler
{
945 MOCK_METHOD5(Schedule
,
946 void(int plane_z_order
,
947 gfx::OverlayTransform plane_transform
,
948 unsigned overlay_texture_id
,
949 const gfx::Rect
& display_bounds
,
950 const gfx::RectF
& uv_rect
));
953 class GLRendererWithOverlaysTest
: public testing::Test
{
955 GLRendererWithOverlaysTest() {
956 provider_
= TestContextProvider::Create();
957 output_surface_
.reset(new OverlayOutputSurface(provider_
));
958 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
960 FakeResourceProvider::Create(output_surface_
.get(), nullptr);
962 provider_
->support()->SetScheduleOverlayPlaneCallback(base::Bind(
963 &MockOverlayScheduler::Schedule
, base::Unretained(&scheduler_
)));
966 void Init(bool use_validator
) {
968 output_surface_
->InitWithSingleOverlayValidator();
971 make_scoped_ptr(new OverlayInfoRendererGL(&renderer_client_
,
973 output_surface_
.get(),
974 resource_provider_
.get()));
977 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
979 RendererSettings settings_
;
980 FakeOutputSurfaceClient output_surface_client_
;
981 scoped_ptr
<OverlayOutputSurface
> output_surface_
;
982 FakeRendererClient renderer_client_
;
983 scoped_ptr
<ResourceProvider
> resource_provider_
;
984 scoped_ptr
<OverlayInfoRendererGL
> renderer_
;
985 scoped_refptr
<TestContextProvider
> provider_
;
986 MockOverlayScheduler scheduler_
;
989 TEST_F(GLRendererWithOverlaysTest
, OverlayQuadNotDrawn
) {
990 bool use_validator
= true;
992 renderer_
->set_expect_overlays(true);
993 gfx::Rect
viewport_rect(16, 16);
995 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
997 CreateFullscreenCandidateQuad(resource_provider_
.get(),
998 pass
->shared_quad_state_list
.back(),
1001 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
1002 pass
->shared_quad_state_list
.back(),
1004 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
1005 pass
->shared_quad_state_list
.back(),
1008 RenderPassList pass_list
;
1009 pass_list
.push_back(pass
.Pass());
1011 // Candidate pass was taken out and extra skipped pass added,
1012 // so only draw 2 quads.
1013 EXPECT_CALL(*renderer_
, DoDrawQuad(_
, _
, _
)).Times(2);
1014 EXPECT_CALL(scheduler_
,
1016 gfx::OVERLAY_TRANSFORM_NONE
,
1019 BoundingRect(kUVTopLeft
, kUVBottomRight
))).Times(1);
1020 renderer_
->DrawFrame(&pass_list
, 1.f
, viewport_rect
, viewport_rect
, false);
1024 Mock::VerifyAndClearExpectations(renderer_
.get());
1025 Mock::VerifyAndClearExpectations(&scheduler_
);
1028 TEST_F(GLRendererWithOverlaysTest
, OccludedQuadInUnderlay
) {
1029 bool use_validator
= true;
1030 Init(use_validator
);
1031 renderer_
->set_expect_overlays(true);
1032 gfx::Rect
viewport_rect(16, 16);
1034 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1036 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
1037 pass
->shared_quad_state_list
.back(),
1039 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
1040 pass
->shared_quad_state_list
.back(),
1043 CreateFullscreenCandidateQuad(resource_provider_
.get(),
1044 pass
->shared_quad_state_list
.back(),
1047 RenderPassList pass_list
;
1048 pass_list
.push_back(pass
.Pass());
1050 // Candidate quad should fail to be overlaid on top because of occlusion.
1051 // Expect to be replaced with transparent hole quad and placed in underlay.
1052 EXPECT_CALL(*renderer_
, DoDrawQuad(_
, _
, _
)).Times(3);
1053 EXPECT_CALL(scheduler_
,
1054 Schedule(-1, gfx::OVERLAY_TRANSFORM_NONE
, _
, kOverlayRect
,
1055 BoundingRect(kUVTopLeft
, kUVBottomRight
))).Times(1);
1056 renderer_
->DrawFrame(&pass_list
, 1.f
, viewport_rect
, viewport_rect
, false);
1060 Mock::VerifyAndClearExpectations(renderer_
.get());
1061 Mock::VerifyAndClearExpectations(&scheduler_
);
1064 TEST_F(GLRendererWithOverlaysTest
, NoValidatorNoOverlay
) {
1065 bool use_validator
= false;
1066 Init(use_validator
);
1067 renderer_
->set_expect_overlays(false);
1068 gfx::Rect
viewport_rect(16, 16);
1070 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1072 CreateFullscreenCandidateQuad(resource_provider_
.get(),
1073 pass
->shared_quad_state_list
.back(),
1076 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
1077 pass
->shared_quad_state_list
.back(),
1079 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
1080 pass
->shared_quad_state_list
.back(),
1083 RenderPassList pass_list
;
1084 pass_list
.push_back(pass
.Pass());
1086 // Should see no overlays.
1087 EXPECT_CALL(*renderer_
, DoDrawQuad(_
, _
, _
)).Times(3);
1088 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1089 renderer_
->DrawFrame(&pass_list
, 1.f
, viewport_rect
, viewport_rect
, false);
1093 Mock::VerifyAndClearExpectations(renderer_
.get());
1094 Mock::VerifyAndClearExpectations(&scheduler_
);
1097 TEST_F(GLRendererWithOverlaysTest
, ResourcesExportedAndReturned
) {
1098 bool use_validator
= true;
1099 Init(use_validator
);
1100 renderer_
->set_expect_overlays(true);
1102 ResourceId resource1
= CreateResource(resource_provider_
.get());
1103 ResourceId resource2
= CreateResource(resource_provider_
.get());
1105 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1106 RenderPassList pass_list
;
1107 pass_list
.push_back(pass
.Pass());
1109 DirectRenderer::DrawingFrame frame1
;
1110 frame1
.render_passes_in_draw_order
= &pass_list
;
1111 frame1
.overlay_list
.resize(2);
1112 OverlayCandidate
& overlay1
= frame1
.overlay_list
.back();
1113 overlay1
.resource_id
= resource1
;
1114 overlay1
.plane_z_order
= 1;
1116 DirectRenderer::DrawingFrame frame2
;
1117 frame2
.render_passes_in_draw_order
= &pass_list
;
1118 frame2
.overlay_list
.resize(2);
1119 OverlayCandidate
& overlay2
= frame2
.overlay_list
.back();
1120 overlay2
.resource_id
= resource2
;
1121 overlay2
.plane_z_order
= 1;
1123 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1124 renderer_
->BeginDrawingFrame(&frame1
);
1125 renderer_
->FinishDrawingFrame(&frame1
);
1126 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1127 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1129 Mock::VerifyAndClearExpectations(&scheduler_
);
1131 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1132 renderer_
->BeginDrawingFrame(&frame2
);
1133 renderer_
->FinishDrawingFrame(&frame2
);
1134 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1135 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource2
));
1137 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1138 Mock::VerifyAndClearExpectations(&scheduler_
);
1140 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1141 renderer_
->BeginDrawingFrame(&frame1
);
1142 renderer_
->FinishDrawingFrame(&frame1
);
1143 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1144 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource2
));
1146 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1147 Mock::VerifyAndClearExpectations(&scheduler_
);
1149 // No overlays, release the resource.
1150 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1151 DirectRenderer::DrawingFrame frame3
;
1152 frame3
.render_passes_in_draw_order
= &pass_list
;
1153 renderer_
->set_expect_overlays(false);
1154 renderer_
->BeginDrawingFrame(&frame3
);
1155 renderer_
->FinishDrawingFrame(&frame3
);
1156 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1157 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1159 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1160 Mock::VerifyAndClearExpectations(&scheduler_
);
1162 // Use the same buffer twice.
1163 renderer_
->set_expect_overlays(true);
1164 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1165 renderer_
->BeginDrawingFrame(&frame1
);
1166 renderer_
->FinishDrawingFrame(&frame1
);
1167 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1169 Mock::VerifyAndClearExpectations(&scheduler_
);
1171 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1172 renderer_
->BeginDrawingFrame(&frame1
);
1173 renderer_
->FinishDrawingFrame(&frame1
);
1174 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1176 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1177 Mock::VerifyAndClearExpectations(&scheduler_
);
1179 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1180 renderer_
->set_expect_overlays(false);
1181 renderer_
->BeginDrawingFrame(&frame3
);
1182 renderer_
->FinishDrawingFrame(&frame3
);
1183 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1185 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1186 Mock::VerifyAndClearExpectations(&scheduler_
);