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 explicit SingleOverlayProcessor(OutputSurface
* surface
)
82 : OverlayProcessor(surface
) {
83 EXPECT_EQ(surface
, surface_
);
86 // Virtual to allow testing different strategies.
87 void Initialize() override
{
88 OverlayCandidateValidator
* candidates
=
89 surface_
->GetOverlayCandidateValidator();
90 ASSERT_TRUE(candidates
!= NULL
);
91 strategies_
.push_back(
92 scoped_ptr
<Strategy
>(new OverlayStrategyType(candidates
)));
96 class DefaultOverlayProcessor
: public OverlayProcessor
{
98 explicit DefaultOverlayProcessor(OutputSurface
* surface
);
99 size_t GetStrategyCount();
102 DefaultOverlayProcessor::DefaultOverlayProcessor(OutputSurface
* surface
)
103 : OverlayProcessor(surface
) {
106 size_t DefaultOverlayProcessor::GetStrategyCount() {
107 return strategies_
.size();
110 class OverlayOutputSurface
: public OutputSurface
{
112 explicit OverlayOutputSurface(scoped_refptr
<ContextProvider
> context_provider
)
113 : OutputSurface(context_provider
) {}
115 // OutputSurface implementation
116 void SwapBuffers(CompositorFrame
* frame
) override
;
118 void InitWithSingleOverlayValidator() {
119 overlay_candidate_validator_
.reset(new SingleOverlayValidator
);
122 OverlayCandidateValidator
* GetOverlayCandidateValidator() const override
{
123 return overlay_candidate_validator_
.get();
127 scoped_ptr
<OverlayCandidateValidator
> overlay_candidate_validator_
;
130 void OverlayOutputSurface::SwapBuffers(CompositorFrame
* frame
) {
131 client_
->DidSwapBuffers();
132 client_
->DidSwapBuffersComplete();
135 scoped_ptr
<RenderPass
> CreateRenderPass() {
136 RenderPassId
id(1, 0);
137 gfx::Rect
output_rect(0, 0, 256, 256);
138 bool has_transparent_background
= true;
140 scoped_ptr
<RenderPass
> pass
= RenderPass::Create();
145 has_transparent_background
);
147 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
148 shared_state
->opacity
= 1.f
;
152 ResourceId
CreateResource(ResourceProvider
* resource_provider
) {
153 unsigned sync_point
= 0;
154 TextureMailbox mailbox
=
155 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D
, sync_point
);
156 scoped_ptr
<SingleReleaseCallbackImpl
> release_callback
=
157 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased
));
159 return resource_provider
->CreateResourceFromTextureMailbox(
160 mailbox
, release_callback
.Pass());
163 SolidColorDrawQuad
* CreateSolidColorQuadAt(
164 const SharedQuadState
* shared_quad_state
,
166 RenderPass
* render_pass
,
167 const gfx::Rect
& rect
) {
168 SolidColorDrawQuad
* quad
=
169 render_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
170 quad
->SetNew(shared_quad_state
, rect
, rect
, color
, false);
174 TextureDrawQuad
* CreateCandidateQuadAt(ResourceProvider
* resource_provider
,
175 const SharedQuadState
* shared_quad_state
,
176 RenderPass
* render_pass
,
177 const gfx::Rect
& rect
) {
178 ResourceId resource_id
= CreateResource(resource_provider
);
179 bool premultiplied_alpha
= false;
180 bool flipped
= false;
181 bool nearest_neighbor
= false;
182 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
183 gfx::Size resource_size_in_pixels
= gfx::Size(64, 64);
184 bool allow_overlay
= true;
186 TextureDrawQuad
* overlay_quad
=
187 render_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
188 overlay_quad
->SetNew(shared_quad_state
,
200 overlay_quad
->set_allow_overlay(allow_overlay
);
201 overlay_quad
->set_resource_size_in_pixels(resource_size_in_pixels
);
206 StreamVideoDrawQuad
* CreateCandidateVideoQuadAt(
207 ResourceProvider
* resource_provider
,
208 const SharedQuadState
* shared_quad_state
,
209 RenderPass
* render_pass
,
210 const gfx::Rect
& rect
,
211 const gfx::Transform
& transform
) {
212 ResourceId resource_id
= CreateResource(resource_provider
);
213 gfx::Size resource_size_in_pixels
= gfx::Size(64, 64);
214 bool allow_overlay
= true;
216 StreamVideoDrawQuad
* overlay_quad
=
217 render_pass
->CreateAndAppendDrawQuad
<StreamVideoDrawQuad
>();
218 overlay_quad
->SetNew(shared_quad_state
, rect
, rect
, rect
, resource_id
,
219 resource_size_in_pixels
, allow_overlay
, transform
);
224 TextureDrawQuad
* CreateFullscreenCandidateQuad(
225 ResourceProvider
* resource_provider
,
226 const SharedQuadState
* shared_quad_state
,
227 RenderPass
* render_pass
) {
228 return CreateCandidateQuadAt(
229 resource_provider
, shared_quad_state
, render_pass
, kOverlayRect
);
232 StreamVideoDrawQuad
* CreateFullscreenCandidateVideoQuad(
233 ResourceProvider
* resource_provider
,
234 const SharedQuadState
* shared_quad_state
,
235 RenderPass
* render_pass
,
236 const gfx::Transform
& transform
) {
237 return CreateCandidateVideoQuadAt(resource_provider
, shared_quad_state
,
238 render_pass
, kOverlayRect
, transform
);
241 void CreateCheckeredQuadAt(ResourceProvider
* resource_provider
,
242 const SharedQuadState
* shared_quad_state
,
243 RenderPass
* render_pass
,
244 const gfx::Rect
& rect
) {
245 CheckerboardDrawQuad
* checkerboard_quad
=
246 render_pass
->CreateAndAppendDrawQuad
<CheckerboardDrawQuad
>();
247 checkerboard_quad
->SetNew(shared_quad_state
, rect
, rect
, SkColor(), 1.f
);
250 void CreateFullscreenCheckeredQuad(ResourceProvider
* resource_provider
,
251 const SharedQuadState
* shared_quad_state
,
252 RenderPass
* render_pass
) {
253 CreateCheckeredQuadAt(
254 resource_provider
, shared_quad_state
, render_pass
, kOverlayRect
);
257 static void CompareRenderPassLists(const RenderPassList
& expected_list
,
258 const RenderPassList
& actual_list
) {
259 EXPECT_EQ(expected_list
.size(), actual_list
.size());
260 for (size_t i
= 0; i
< actual_list
.size(); ++i
) {
261 RenderPass
* expected
= expected_list
[i
];
262 RenderPass
* actual
= actual_list
[i
];
264 EXPECT_EQ(expected
->id
, actual
->id
);
265 EXPECT_EQ(expected
->output_rect
, actual
->output_rect
);
266 EXPECT_EQ(expected
->transform_to_root_target
,
267 actual
->transform_to_root_target
);
268 EXPECT_EQ(expected
->damage_rect
, actual
->damage_rect
);
269 EXPECT_EQ(expected
->has_transparent_background
,
270 actual
->has_transparent_background
);
272 EXPECT_EQ(expected
->shared_quad_state_list
.size(),
273 actual
->shared_quad_state_list
.size());
274 EXPECT_EQ(expected
->quad_list
.size(), actual
->quad_list
.size());
276 for (auto exp_iter
= expected
->quad_list
.cbegin(),
277 act_iter
= actual
->quad_list
.cbegin();
278 exp_iter
!= expected
->quad_list
.cend();
279 ++exp_iter
, ++act_iter
) {
280 EXPECT_EQ(exp_iter
->rect
.ToString(), act_iter
->rect
.ToString());
281 EXPECT_EQ(exp_iter
->shared_quad_state
->quad_layer_bounds
.ToString(),
282 act_iter
->shared_quad_state
->quad_layer_bounds
.ToString());
287 TEST(OverlayTest
, NoOverlaysByDefault
) {
288 scoped_refptr
<TestContextProvider
> provider
= TestContextProvider::Create();
289 OverlayOutputSurface
output_surface(provider
);
290 EXPECT_EQ(NULL
, output_surface
.GetOverlayCandidateValidator());
292 output_surface
.InitWithSingleOverlayValidator();
293 EXPECT_TRUE(output_surface
.GetOverlayCandidateValidator() != NULL
);
296 TEST(OverlayTest
, OverlaysProcessorHasStrategy
) {
297 scoped_refptr
<TestContextProvider
> provider
= TestContextProvider::Create();
298 OverlayOutputSurface
output_surface(provider
);
299 FakeOutputSurfaceClient client
;
300 EXPECT_TRUE(output_surface
.BindToClient(&client
));
301 output_surface
.InitWithSingleOverlayValidator();
302 EXPECT_TRUE(output_surface
.GetOverlayCandidateValidator() != NULL
);
304 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
305 new TestSharedBitmapManager());
306 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
307 &output_surface
, shared_bitmap_manager
.get());
309 scoped_ptr
<DefaultOverlayProcessor
> overlay_processor(
310 new DefaultOverlayProcessor(&output_surface
));
311 overlay_processor
->Initialize();
312 EXPECT_GE(2U, overlay_processor
->GetStrategyCount());
315 template <typename OverlayStrategyType
>
316 class OverlayTest
: public testing::Test
{
318 void SetUp() override
{
319 provider_
= TestContextProvider::Create();
320 output_surface_
.reset(new OverlayOutputSurface(provider_
));
321 EXPECT_TRUE(output_surface_
->BindToClient(&client_
));
322 output_surface_
->InitWithSingleOverlayValidator();
323 EXPECT_TRUE(output_surface_
->GetOverlayCandidateValidator() != NULL
);
325 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
326 resource_provider_
= FakeResourceProvider::Create(
327 output_surface_
.get(), shared_bitmap_manager_
.get());
329 overlay_processor_
.reset(
330 new SingleOverlayProcessor
<OverlayStrategyType
>(output_surface_
.get()));
331 overlay_processor_
->Initialize();
334 scoped_refptr
<TestContextProvider
> provider_
;
335 scoped_ptr
<OverlayOutputSurface
> output_surface_
;
336 FakeOutputSurfaceClient client_
;
337 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
338 scoped_ptr
<ResourceProvider
> resource_provider_
;
339 scoped_ptr
<SingleOverlayProcessor
<OverlayStrategyType
>> overlay_processor_
;
342 typedef OverlayTest
<OverlayStrategySingleOnTop
> SingleOverlayOnTopTest
;
343 typedef OverlayTest
<OverlayStrategyUnderlay
> UnderlayTest
;
345 TEST_F(SingleOverlayOnTopTest
, SuccessfullOverlay
) {
346 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
347 TextureDrawQuad
* original_quad
=
348 CreateFullscreenCandidateQuad(resource_provider_
.get(),
349 pass
->shared_quad_state_list
.back(),
351 unsigned original_resource_id
= original_quad
->resource_id();
353 // Add something behind it.
354 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
355 pass
->shared_quad_state_list
.back(),
357 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
358 pass
->shared_quad_state_list
.back(),
361 RenderPassList pass_list
;
362 pass_list
.push_back(pass
.Pass());
364 // Check for potential candidates.
365 OverlayCandidateList candidate_list
;
366 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
368 ASSERT_EQ(1U, pass_list
.size());
369 ASSERT_EQ(2U, candidate_list
.size());
371 RenderPass
* main_pass
= pass_list
.back();
372 // Check that the quad is gone.
373 EXPECT_EQ(2U, main_pass
->quad_list
.size());
374 const QuadList
& quad_list
= main_pass
->quad_list
;
375 for (QuadList::ConstBackToFrontIterator it
= quad_list
.BackToFrontBegin();
376 it
!= quad_list
.BackToFrontEnd();
378 EXPECT_NE(DrawQuad::TEXTURE_CONTENT
, it
->material
);
381 // Check that the right resource id got extracted.
382 EXPECT_EQ(original_resource_id
, candidate_list
.back().resource_id
);
385 TEST_F(SingleOverlayOnTopTest
, NoCandidates
) {
386 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
387 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
388 pass
->shared_quad_state_list
.back(),
390 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
391 pass
->shared_quad_state_list
.back(),
394 RenderPassList pass_list
;
395 pass_list
.push_back(pass
.Pass());
397 RenderPassList original_pass_list
;
398 RenderPass::CopyAll(pass_list
, &original_pass_list
);
400 OverlayCandidateList candidate_list
;
401 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
402 EXPECT_EQ(0U, candidate_list
.size());
403 // There should be nothing new here.
404 CompareRenderPassLists(pass_list
, original_pass_list
);
407 TEST_F(SingleOverlayOnTopTest
, OccludedCandidates
) {
408 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
409 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
410 pass
->shared_quad_state_list
.back(),
412 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
413 pass
->shared_quad_state_list
.back(),
416 CreateFullscreenCandidateQuad(resource_provider_
.get(),
417 pass
->shared_quad_state_list
.back(),
420 RenderPassList pass_list
;
421 pass_list
.push_back(pass
.Pass());
423 RenderPassList original_pass_list
;
424 RenderPass::CopyAll(pass_list
, &original_pass_list
);
426 OverlayCandidateList candidate_list
;
427 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
428 EXPECT_EQ(0U, candidate_list
.size());
429 // There should be nothing new here.
430 CompareRenderPassLists(pass_list
, original_pass_list
);
433 // Test with multiple render passes.
434 TEST_F(SingleOverlayOnTopTest
, MultipleRenderPasses
) {
435 RenderPassList pass_list
;
436 pass_list
.push_back(CreateRenderPass());
438 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
439 CreateFullscreenCandidateQuad(resource_provider_
.get(),
440 pass
->shared_quad_state_list
.back(),
443 // Add something behind it.
444 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
445 pass
->shared_quad_state_list
.back(),
447 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
448 pass
->shared_quad_state_list
.back(),
451 pass_list
.push_back(pass
.Pass());
453 RenderPassList original_pass_list
;
454 RenderPass::CopyAll(pass_list
, &original_pass_list
);
456 // Check for potential candidates.
457 OverlayCandidateList candidate_list
;
458 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
459 EXPECT_EQ(2U, candidate_list
.size());
461 // This should be the same.
462 ASSERT_EQ(2U, pass_list
.size());
465 TEST_F(SingleOverlayOnTopTest
, RejectPremultipliedAlpha
) {
466 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
467 TextureDrawQuad
* quad
=
468 CreateFullscreenCandidateQuad(resource_provider_
.get(),
469 pass
->shared_quad_state_list
.back(),
471 quad
->premultiplied_alpha
= true;
473 RenderPassList pass_list
;
474 pass_list
.push_back(pass
.Pass());
475 OverlayCandidateList candidate_list
;
476 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
477 EXPECT_EQ(1U, pass_list
.size());
478 EXPECT_EQ(0U, candidate_list
.size());
481 TEST_F(SingleOverlayOnTopTest
, RejectBlending
) {
482 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
483 TextureDrawQuad
* quad
=
484 CreateFullscreenCandidateQuad(resource_provider_
.get(),
485 pass
->shared_quad_state_list
.back(),
487 quad
->needs_blending
= true;
489 RenderPassList pass_list
;
490 pass_list
.push_back(pass
.Pass());
491 OverlayCandidateList candidate_list
;
492 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
493 ASSERT_EQ(1U, pass_list
.size());
494 EXPECT_EQ(0U, candidate_list
.size());
497 TEST_F(SingleOverlayOnTopTest
, RejectBackgroundColor
) {
498 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
499 TextureDrawQuad
* quad
=
500 CreateFullscreenCandidateQuad(resource_provider_
.get(),
501 pass
->shared_quad_state_list
.back(),
503 quad
->background_color
= SK_ColorBLACK
;
505 RenderPassList pass_list
;
506 pass_list
.push_back(pass
.Pass());
507 OverlayCandidateList candidate_list
;
508 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
509 ASSERT_EQ(1U, pass_list
.size());
510 EXPECT_EQ(0U, candidate_list
.size());
513 TEST_F(SingleOverlayOnTopTest
, RejectBlendMode
) {
514 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
515 CreateFullscreenCandidateQuad(resource_provider_
.get(),
516 pass
->shared_quad_state_list
.back(),
518 pass
->shared_quad_state_list
.back()->blend_mode
= SkXfermode::kScreen_Mode
;
520 RenderPassList pass_list
;
521 pass_list
.push_back(pass
.Pass());
522 OverlayCandidateList candidate_list
;
523 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
524 ASSERT_EQ(1U, pass_list
.size());
525 EXPECT_EQ(0U, candidate_list
.size());
528 TEST_F(SingleOverlayOnTopTest
, RejectOpacity
) {
529 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
530 CreateFullscreenCandidateQuad(resource_provider_
.get(),
531 pass
->shared_quad_state_list
.back(),
533 pass
->shared_quad_state_list
.back()->opacity
= 0.5f
;
535 RenderPassList pass_list
;
536 pass_list
.push_back(pass
.Pass());
537 OverlayCandidateList candidate_list
;
538 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
539 ASSERT_EQ(1U, pass_list
.size());
540 EXPECT_EQ(0U, candidate_list
.size());
543 TEST_F(SingleOverlayOnTopTest
, RejectNonAxisAlignedTransform
) {
544 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
545 CreateFullscreenCandidateQuad(resource_provider_
.get(),
546 pass
->shared_quad_state_list
.back(),
548 pass
->shared_quad_state_list
.back()
549 ->quad_to_target_transform
.RotateAboutXAxis(45.f
);
551 RenderPassList pass_list
;
552 pass_list
.push_back(pass
.Pass());
553 OverlayCandidateList candidate_list
;
554 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
555 ASSERT_EQ(1U, pass_list
.size());
556 EXPECT_EQ(0U, candidate_list
.size());
559 TEST_F(SingleOverlayOnTopTest
, AllowVerticalFlip
) {
560 gfx::Rect rect
= kOverlayRect
;
561 rect
.set_width(rect
.width() / 2);
562 rect
.Offset(0, -rect
.height());
563 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
564 CreateCandidateQuadAt(resource_provider_
.get(),
565 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
566 pass
->shared_quad_state_list
.back()->quad_to_target_transform
.Scale(2.0f
,
569 RenderPassList pass_list
;
570 pass_list
.push_back(pass
.Pass());
571 OverlayCandidateList candidate_list
;
572 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
573 ASSERT_EQ(1U, pass_list
.size());
574 ASSERT_EQ(2U, candidate_list
.size());
575 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
,
576 candidate_list
.back().transform
);
579 TEST_F(SingleOverlayOnTopTest
, AllowHorizontalFlip
) {
580 gfx::Rect rect
= kOverlayRect
;
581 rect
.set_height(rect
.height() / 2);
582 rect
.Offset(-rect
.width(), 0);
583 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
584 CreateCandidateQuadAt(resource_provider_
.get(),
585 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
586 pass
->shared_quad_state_list
.back()->quad_to_target_transform
.Scale(-1.0f
,
589 RenderPassList pass_list
;
590 pass_list
.push_back(pass
.Pass());
591 OverlayCandidateList candidate_list
;
592 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
593 ASSERT_EQ(1U, pass_list
.size());
594 ASSERT_EQ(2U, candidate_list
.size());
595 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
,
596 candidate_list
.back().transform
);
599 TEST_F(SingleOverlayOnTopTest
, AllowPositiveScaleTransform
) {
600 gfx::Rect rect
= kOverlayRect
;
601 rect
.set_width(rect
.width() / 2);
602 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
603 CreateCandidateQuadAt(resource_provider_
.get(),
604 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
605 pass
->shared_quad_state_list
.back()->quad_to_target_transform
.Scale(2.0f
,
608 RenderPassList pass_list
;
609 pass_list
.push_back(pass
.Pass());
610 OverlayCandidateList candidate_list
;
611 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
612 ASSERT_EQ(1U, pass_list
.size());
613 EXPECT_EQ(2U, candidate_list
.size());
616 TEST_F(SingleOverlayOnTopTest
, Allow90DegreeRotation
) {
617 gfx::Rect rect
= kOverlayRect
;
618 rect
.Offset(0, -rect
.height());
619 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
620 CreateCandidateQuadAt(resource_provider_
.get(),
621 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
622 pass
->shared_quad_state_list
.back()
623 ->quad_to_target_transform
.RotateAboutZAxis(90.f
);
625 RenderPassList pass_list
;
626 pass_list
.push_back(pass
.Pass());
627 OverlayCandidateList candidate_list
;
628 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
629 ASSERT_EQ(1U, pass_list
.size());
630 ASSERT_EQ(2U, candidate_list
.size());
631 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_90
, candidate_list
.back().transform
);
634 TEST_F(SingleOverlayOnTopTest
, Allow180DegreeRotation
) {
635 gfx::Rect rect
= kOverlayRect
;
636 rect
.Offset(-rect
.width(), -rect
.height());
637 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
638 CreateCandidateQuadAt(resource_provider_
.get(),
639 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
640 pass
->shared_quad_state_list
.back()
641 ->quad_to_target_transform
.RotateAboutZAxis(180.f
);
643 RenderPassList pass_list
;
644 pass_list
.push_back(pass
.Pass());
645 OverlayCandidateList candidate_list
;
646 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
647 ASSERT_EQ(1U, pass_list
.size());
648 ASSERT_EQ(2U, candidate_list
.size());
649 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_180
, candidate_list
.back().transform
);
652 TEST_F(SingleOverlayOnTopTest
, Allow270DegreeRotation
) {
653 gfx::Rect rect
= kOverlayRect
;
654 rect
.Offset(-rect
.width(), 0);
655 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
656 CreateCandidateQuadAt(resource_provider_
.get(),
657 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
658 pass
->shared_quad_state_list
.back()
659 ->quad_to_target_transform
.RotateAboutZAxis(270.f
);
661 RenderPassList pass_list
;
662 pass_list
.push_back(pass
.Pass());
663 OverlayCandidateList candidate_list
;
664 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
665 ASSERT_EQ(1U, pass_list
.size());
666 ASSERT_EQ(2U, candidate_list
.size());
667 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_270
, candidate_list
.back().transform
);
670 TEST_F(SingleOverlayOnTopTest
, AllowNotTopIfNotOccluded
) {
671 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
672 CreateCheckeredQuadAt(resource_provider_
.get(),
673 pass
->shared_quad_state_list
.back(),
675 kOverlayTopLeftRect
);
676 CreateCandidateQuadAt(resource_provider_
.get(),
677 pass
->shared_quad_state_list
.back(),
679 kOverlayBottomRightRect
);
681 RenderPassList pass_list
;
682 pass_list
.push_back(pass
.Pass());
684 RenderPassList original_pass_list
;
685 RenderPass::CopyAll(pass_list
, &original_pass_list
);
687 OverlayCandidateList candidate_list
;
688 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
689 EXPECT_EQ(1U, pass_list
.size());
690 EXPECT_EQ(2U, candidate_list
.size());
693 TEST_F(SingleOverlayOnTopTest
, AllowTransparentOnTop
) {
694 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
695 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
696 shared_state
->opacity
= 0.f
;
697 CreateSolidColorQuadAt(shared_state
, SK_ColorBLACK
, pass
.get(),
698 kOverlayBottomRightRect
);
699 shared_state
= pass
->CreateAndAppendSharedQuadState();
700 shared_state
->opacity
= 1.f
;
701 CreateCandidateQuadAt(resource_provider_
.get(), shared_state
, pass
.get(),
702 kOverlayBottomRightRect
);
704 RenderPassList pass_list
;
705 pass_list
.push_back(pass
.Pass());
707 RenderPassList original_pass_list
;
708 RenderPass::CopyAll(pass_list
, &original_pass_list
);
710 OverlayCandidateList candidate_list
;
711 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
712 EXPECT_EQ(1U, pass_list
.size());
713 EXPECT_EQ(2U, candidate_list
.size());
716 TEST_F(SingleOverlayOnTopTest
, AllowTransparentColorOnTop
) {
717 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
718 CreateSolidColorQuadAt(pass
->shared_quad_state_list
.back(),
719 SK_ColorTRANSPARENT
, pass
.get(),
720 kOverlayBottomRightRect
);
721 CreateCandidateQuadAt(resource_provider_
.get(),
722 pass
->shared_quad_state_list
.back(), pass
.get(),
723 kOverlayBottomRightRect
);
725 RenderPassList pass_list
;
726 pass_list
.push_back(pass
.Pass());
728 RenderPassList original_pass_list
;
729 RenderPass::CopyAll(pass_list
, &original_pass_list
);
731 OverlayCandidateList candidate_list
;
732 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
733 EXPECT_EQ(1U, pass_list
.size());
734 EXPECT_EQ(2U, candidate_list
.size());
737 TEST_F(SingleOverlayOnTopTest
, RejectOpaqueColorOnTop
) {
738 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
739 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
740 shared_state
->opacity
= 0.5f
;
741 CreateSolidColorQuadAt(shared_state
, SK_ColorBLACK
, pass
.get(),
742 kOverlayBottomRightRect
);
743 shared_state
= pass
->CreateAndAppendSharedQuadState();
744 shared_state
->opacity
= 1.f
;
745 CreateCandidateQuadAt(resource_provider_
.get(), shared_state
, pass
.get(),
746 kOverlayBottomRightRect
);
748 RenderPassList pass_list
;
749 pass_list
.push_back(pass
.Pass());
751 RenderPassList original_pass_list
;
752 RenderPass::CopyAll(pass_list
, &original_pass_list
);
754 OverlayCandidateList candidate_list
;
755 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
756 EXPECT_EQ(1U, pass_list
.size());
757 EXPECT_EQ(0U, candidate_list
.size());
760 TEST_F(SingleOverlayOnTopTest
, RejectTransparentColorOnTopWithoutBlending
) {
761 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
762 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
763 CreateSolidColorQuadAt(shared_state
, SK_ColorTRANSPARENT
, pass
.get(),
764 kOverlayBottomRightRect
)->opaque_rect
=
765 kOverlayBottomRightRect
;
766 CreateCandidateQuadAt(resource_provider_
.get(), shared_state
, pass
.get(),
767 kOverlayBottomRightRect
);
769 RenderPassList pass_list
;
770 pass_list
.push_back(pass
.Pass());
772 RenderPassList original_pass_list
;
773 RenderPass::CopyAll(pass_list
, &original_pass_list
);
775 OverlayCandidateList candidate_list
;
776 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
777 EXPECT_EQ(1U, pass_list
.size());
778 EXPECT_EQ(0U, candidate_list
.size());
781 TEST_F(SingleOverlayOnTopTest
, RejectVideoSwapTransform
) {
782 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
783 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
784 pass
->shared_quad_state_list
.back(),
785 pass
.get(), kSwapTransform
);
787 RenderPassList pass_list
;
788 pass_list
.push_back(pass
.Pass());
789 OverlayCandidateList candidate_list
;
790 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
791 ASSERT_EQ(1U, pass_list
.size());
792 EXPECT_EQ(0U, candidate_list
.size());
795 TEST_F(SingleOverlayOnTopTest
, AllowVideoXMirrorTransform
) {
796 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
797 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
798 pass
->shared_quad_state_list
.back(),
799 pass
.get(), kXMirrorTransform
);
801 RenderPassList pass_list
;
802 pass_list
.push_back(pass
.Pass());
803 OverlayCandidateList candidate_list
;
804 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
805 ASSERT_EQ(1U, pass_list
.size());
806 EXPECT_EQ(2U, candidate_list
.size());
809 TEST_F(SingleOverlayOnTopTest
, AllowVideoBothMirrorTransform
) {
810 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
811 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
812 pass
->shared_quad_state_list
.back(),
813 pass
.get(), kBothMirrorTransform
);
815 RenderPassList pass_list
;
816 pass_list
.push_back(pass
.Pass());
817 OverlayCandidateList candidate_list
;
818 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
819 ASSERT_EQ(1U, pass_list
.size());
820 EXPECT_EQ(2U, candidate_list
.size());
823 TEST_F(SingleOverlayOnTopTest
, AllowVideoNormalTransform
) {
824 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
825 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
826 pass
->shared_quad_state_list
.back(),
827 pass
.get(), kNormalTransform
);
829 RenderPassList pass_list
;
830 pass_list
.push_back(pass
.Pass());
831 OverlayCandidateList candidate_list
;
832 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
833 ASSERT_EQ(1U, pass_list
.size());
834 EXPECT_EQ(2U, candidate_list
.size());
837 TEST_F(SingleOverlayOnTopTest
, AllowVideoYMirrorTransform
) {
838 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
839 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
840 pass
->shared_quad_state_list
.back(),
841 pass
.get(), kYMirrorTransform
);
843 RenderPassList pass_list
;
844 pass_list
.push_back(pass
.Pass());
845 OverlayCandidateList candidate_list
;
846 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
847 ASSERT_EQ(1U, pass_list
.size());
848 EXPECT_EQ(2U, candidate_list
.size());
851 TEST_F(UnderlayTest
, OverlayLayerUnderMainLayer
) {
852 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
853 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
854 pass
->shared_quad_state_list
.back(),
856 CreateCandidateQuadAt(resource_provider_
.get(),
857 pass
->shared_quad_state_list
.back(), pass
.get(),
858 kOverlayBottomRightRect
);
860 RenderPassList pass_list
;
861 pass_list
.push_back(pass
.Pass());
863 OverlayCandidateList candidate_list
;
864 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
865 EXPECT_EQ(1U, pass_list
.size());
866 ASSERT_EQ(2U, candidate_list
.size());
867 EXPECT_EQ(0, candidate_list
[0].plane_z_order
);
868 EXPECT_EQ(-1, candidate_list
[1].plane_z_order
);
869 EXPECT_EQ(2U, pass_list
[0]->quad_list
.size());
870 // The overlay quad should have changed to a SOLID_COLOR quad.
871 EXPECT_EQ(pass_list
[0]->quad_list
.back()->material
, DrawQuad::SOLID_COLOR
);
874 TEST_F(UnderlayTest
, AllowOnTop
) {
875 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
876 CreateFullscreenCandidateQuad(resource_provider_
.get(),
877 pass
->shared_quad_state_list
.back(),
879 pass
->CreateAndAppendSharedQuadState()->opacity
= 0.5f
;
880 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
881 pass
->shared_quad_state_list
.back(),
884 RenderPassList pass_list
;
885 pass_list
.push_back(pass
.Pass());
887 OverlayCandidateList candidate_list
;
888 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
889 EXPECT_EQ(1U, pass_list
.size());
890 ASSERT_EQ(2U, candidate_list
.size());
891 EXPECT_EQ(0, candidate_list
[0].plane_z_order
);
892 EXPECT_EQ(-1, candidate_list
[1].plane_z_order
);
893 // The overlay quad should have changed to a SOLID_COLOR quad.
894 EXPECT_EQ(pass_list
[0]->quad_list
.front()->material
, DrawQuad::SOLID_COLOR
);
897 class OverlayInfoRendererGL
: public GLRenderer
{
899 OverlayInfoRendererGL(RendererClient
* client
,
900 const RendererSettings
* settings
,
901 OutputSurface
* output_surface
,
902 ResourceProvider
* resource_provider
)
909 expect_overlays_(false) {}
911 MOCK_METHOD3(DoDrawQuad
,
912 void(DrawingFrame
* frame
,
913 const DrawQuad
* quad
,
914 const gfx::QuadF
* draw_region
));
916 using GLRenderer::BeginDrawingFrame
;
918 void FinishDrawingFrame(DrawingFrame
* frame
) override
{
919 GLRenderer::FinishDrawingFrame(frame
);
921 if (!expect_overlays_
) {
922 EXPECT_EQ(0U, frame
->overlay_list
.size());
926 ASSERT_EQ(2U, frame
->overlay_list
.size());
927 EXPECT_NE(0U, frame
->overlay_list
.back().resource_id
);
930 void set_expect_overlays(bool expect_overlays
) {
931 expect_overlays_
= expect_overlays
;
935 bool expect_overlays_
;
938 class FakeRendererClient
: public RendererClient
{
940 // RendererClient methods.
941 void SetFullRootLayerDamage() override
{}
944 class MockOverlayScheduler
{
946 MOCK_METHOD5(Schedule
,
947 void(int plane_z_order
,
948 gfx::OverlayTransform plane_transform
,
949 unsigned overlay_texture_id
,
950 const gfx::Rect
& display_bounds
,
951 const gfx::RectF
& uv_rect
));
954 class GLRendererWithOverlaysTest
: public testing::Test
{
956 GLRendererWithOverlaysTest() {
957 provider_
= TestContextProvider::Create();
958 output_surface_
.reset(new OverlayOutputSurface(provider_
));
959 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
961 FakeResourceProvider::Create(output_surface_
.get(), nullptr);
963 provider_
->support()->SetScheduleOverlayPlaneCallback(base::Bind(
964 &MockOverlayScheduler::Schedule
, base::Unretained(&scheduler_
)));
967 void Init(bool use_validator
) {
969 output_surface_
->InitWithSingleOverlayValidator();
972 make_scoped_ptr(new OverlayInfoRendererGL(&renderer_client_
,
974 output_surface_
.get(),
975 resource_provider_
.get()));
978 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
980 RendererSettings settings_
;
981 FakeOutputSurfaceClient output_surface_client_
;
982 scoped_ptr
<OverlayOutputSurface
> output_surface_
;
983 FakeRendererClient renderer_client_
;
984 scoped_ptr
<ResourceProvider
> resource_provider_
;
985 scoped_ptr
<OverlayInfoRendererGL
> renderer_
;
986 scoped_refptr
<TestContextProvider
> provider_
;
987 MockOverlayScheduler scheduler_
;
990 TEST_F(GLRendererWithOverlaysTest
, OverlayQuadNotDrawn
) {
991 bool use_validator
= true;
993 renderer_
->set_expect_overlays(true);
994 gfx::Rect
viewport_rect(16, 16);
996 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
998 CreateFullscreenCandidateQuad(resource_provider_
.get(),
999 pass
->shared_quad_state_list
.back(),
1002 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
1003 pass
->shared_quad_state_list
.back(),
1005 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
1006 pass
->shared_quad_state_list
.back(),
1009 RenderPassList pass_list
;
1010 pass_list
.push_back(pass
.Pass());
1012 // Candidate pass was taken out and extra skipped pass added,
1013 // so only draw 2 quads.
1014 EXPECT_CALL(*renderer_
, DoDrawQuad(_
, _
, _
)).Times(2);
1015 EXPECT_CALL(scheduler_
,
1017 gfx::OVERLAY_TRANSFORM_NONE
,
1020 BoundingRect(kUVTopLeft
, kUVBottomRight
))).Times(1);
1021 renderer_
->DrawFrame(&pass_list
, 1.f
, viewport_rect
, viewport_rect
, false);
1025 Mock::VerifyAndClearExpectations(renderer_
.get());
1026 Mock::VerifyAndClearExpectations(&scheduler_
);
1029 TEST_F(GLRendererWithOverlaysTest
, OccludedQuadInUnderlay
) {
1030 bool use_validator
= true;
1031 Init(use_validator
);
1032 renderer_
->set_expect_overlays(true);
1033 gfx::Rect
viewport_rect(16, 16);
1035 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1037 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
1038 pass
->shared_quad_state_list
.back(),
1040 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
1041 pass
->shared_quad_state_list
.back(),
1044 CreateFullscreenCandidateQuad(resource_provider_
.get(),
1045 pass
->shared_quad_state_list
.back(),
1048 RenderPassList pass_list
;
1049 pass_list
.push_back(pass
.Pass());
1051 // Candidate quad should fail to be overlaid on top because of occlusion.
1052 // Expect to be replaced with transparent hole quad and placed in underlay.
1053 EXPECT_CALL(*renderer_
, DoDrawQuad(_
, _
, _
)).Times(3);
1054 EXPECT_CALL(scheduler_
,
1055 Schedule(-1, gfx::OVERLAY_TRANSFORM_NONE
, _
, kOverlayRect
,
1056 BoundingRect(kUVTopLeft
, kUVBottomRight
))).Times(1);
1057 renderer_
->DrawFrame(&pass_list
, 1.f
, viewport_rect
, viewport_rect
, false);
1061 Mock::VerifyAndClearExpectations(renderer_
.get());
1062 Mock::VerifyAndClearExpectations(&scheduler_
);
1065 TEST_F(GLRendererWithOverlaysTest
, NoValidatorNoOverlay
) {
1066 bool use_validator
= false;
1067 Init(use_validator
);
1068 renderer_
->set_expect_overlays(false);
1069 gfx::Rect
viewport_rect(16, 16);
1071 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1073 CreateFullscreenCandidateQuad(resource_provider_
.get(),
1074 pass
->shared_quad_state_list
.back(),
1077 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
1078 pass
->shared_quad_state_list
.back(),
1080 CreateFullscreenCheckeredQuad(resource_provider_
.get(),
1081 pass
->shared_quad_state_list
.back(),
1084 RenderPassList pass_list
;
1085 pass_list
.push_back(pass
.Pass());
1087 // Should see no overlays.
1088 EXPECT_CALL(*renderer_
, DoDrawQuad(_
, _
, _
)).Times(3);
1089 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1090 renderer_
->DrawFrame(&pass_list
, 1.f
, viewport_rect
, viewport_rect
, false);
1094 Mock::VerifyAndClearExpectations(renderer_
.get());
1095 Mock::VerifyAndClearExpectations(&scheduler_
);
1098 TEST_F(GLRendererWithOverlaysTest
, ResourcesExportedAndReturned
) {
1099 bool use_validator
= true;
1100 Init(use_validator
);
1101 renderer_
->set_expect_overlays(true);
1103 ResourceId resource1
= CreateResource(resource_provider_
.get());
1104 ResourceId resource2
= CreateResource(resource_provider_
.get());
1106 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1107 RenderPassList pass_list
;
1108 pass_list
.push_back(pass
.Pass());
1110 DirectRenderer::DrawingFrame frame1
;
1111 frame1
.render_passes_in_draw_order
= &pass_list
;
1112 frame1
.overlay_list
.resize(2);
1113 OverlayCandidate
& overlay1
= frame1
.overlay_list
.back();
1114 overlay1
.resource_id
= resource1
;
1115 overlay1
.plane_z_order
= 1;
1117 DirectRenderer::DrawingFrame frame2
;
1118 frame2
.render_passes_in_draw_order
= &pass_list
;
1119 frame2
.overlay_list
.resize(2);
1120 OverlayCandidate
& overlay2
= frame2
.overlay_list
.back();
1121 overlay2
.resource_id
= resource2
;
1122 overlay2
.plane_z_order
= 1;
1124 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1125 renderer_
->BeginDrawingFrame(&frame1
);
1126 renderer_
->FinishDrawingFrame(&frame1
);
1127 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1128 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1130 Mock::VerifyAndClearExpectations(&scheduler_
);
1132 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1133 renderer_
->BeginDrawingFrame(&frame2
);
1134 renderer_
->FinishDrawingFrame(&frame2
);
1135 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1136 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource2
));
1138 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1139 Mock::VerifyAndClearExpectations(&scheduler_
);
1141 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1142 renderer_
->BeginDrawingFrame(&frame1
);
1143 renderer_
->FinishDrawingFrame(&frame1
);
1144 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1145 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource2
));
1147 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1148 Mock::VerifyAndClearExpectations(&scheduler_
);
1150 // No overlays, release the resource.
1151 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1152 DirectRenderer::DrawingFrame frame3
;
1153 frame3
.render_passes_in_draw_order
= &pass_list
;
1154 renderer_
->set_expect_overlays(false);
1155 renderer_
->BeginDrawingFrame(&frame3
);
1156 renderer_
->FinishDrawingFrame(&frame3
);
1157 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1158 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1160 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1161 Mock::VerifyAndClearExpectations(&scheduler_
);
1163 // Use the same buffer twice.
1164 renderer_
->set_expect_overlays(true);
1165 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1166 renderer_
->BeginDrawingFrame(&frame1
);
1167 renderer_
->FinishDrawingFrame(&frame1
);
1168 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1170 Mock::VerifyAndClearExpectations(&scheduler_
);
1172 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1173 renderer_
->BeginDrawingFrame(&frame1
);
1174 renderer_
->FinishDrawingFrame(&frame1
);
1175 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1177 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1178 Mock::VerifyAndClearExpectations(&scheduler_
);
1180 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1181 renderer_
->set_expect_overlays(false);
1182 renderer_
->BeginDrawingFrame(&frame3
);
1183 renderer_
->FinishDrawingFrame(&frame3
);
1184 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1186 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1187 Mock::VerifyAndClearExpectations(&scheduler_
);