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/render_pass.h"
15 #include "cc/quads/solid_color_draw_quad.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 CreateOpaqueQuadAt(ResourceProvider
* resource_provider
,
242 const SharedQuadState
* shared_quad_state
,
243 RenderPass
* render_pass
,
244 const gfx::Rect
& rect
) {
245 SolidColorDrawQuad
* color_quad
=
246 render_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
247 color_quad
->SetNew(shared_quad_state
, rect
, rect
, SK_ColorBLACK
, false);
250 void CreateFullscreenOpaqueQuad(ResourceProvider
* resource_provider
,
251 const SharedQuadState
* shared_quad_state
,
252 RenderPass
* render_pass
) {
253 CreateOpaqueQuadAt(resource_provider
, shared_quad_state
, render_pass
,
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 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
355 pass
->shared_quad_state_list
.back(), pass
.get());
356 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
357 pass
->shared_quad_state_list
.back(), pass
.get());
359 RenderPassList pass_list
;
360 pass_list
.push_back(pass
.Pass());
362 // Check for potential candidates.
363 OverlayCandidateList candidate_list
;
364 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
366 ASSERT_EQ(1U, pass_list
.size());
367 ASSERT_EQ(2U, candidate_list
.size());
369 RenderPass
* main_pass
= pass_list
.back();
370 // Check that the quad is gone.
371 EXPECT_EQ(2U, main_pass
->quad_list
.size());
372 const QuadList
& quad_list
= main_pass
->quad_list
;
373 for (QuadList::ConstBackToFrontIterator it
= quad_list
.BackToFrontBegin();
374 it
!= quad_list
.BackToFrontEnd();
376 EXPECT_NE(DrawQuad::TEXTURE_CONTENT
, it
->material
);
379 // Check that the right resource id got extracted.
380 EXPECT_EQ(original_resource_id
, candidate_list
.back().resource_id
);
383 TEST_F(SingleOverlayOnTopTest
, NoCandidates
) {
384 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
385 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
386 pass
->shared_quad_state_list
.back(), pass
.get());
387 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
388 pass
->shared_quad_state_list
.back(), pass
.get());
390 RenderPassList pass_list
;
391 pass_list
.push_back(pass
.Pass());
393 RenderPassList original_pass_list
;
394 RenderPass::CopyAll(pass_list
, &original_pass_list
);
396 OverlayCandidateList candidate_list
;
397 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
398 EXPECT_EQ(0U, candidate_list
.size());
399 // There should be nothing new here.
400 CompareRenderPassLists(pass_list
, original_pass_list
);
403 TEST_F(SingleOverlayOnTopTest
, OccludedCandidates
) {
404 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
405 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
406 pass
->shared_quad_state_list
.back(), pass
.get());
407 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
408 pass
->shared_quad_state_list
.back(), pass
.get());
410 CreateFullscreenCandidateQuad(resource_provider_
.get(),
411 pass
->shared_quad_state_list
.back(),
414 RenderPassList pass_list
;
415 pass_list
.push_back(pass
.Pass());
417 RenderPassList original_pass_list
;
418 RenderPass::CopyAll(pass_list
, &original_pass_list
);
420 OverlayCandidateList candidate_list
;
421 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
422 EXPECT_EQ(0U, candidate_list
.size());
423 // There should be nothing new here.
424 CompareRenderPassLists(pass_list
, original_pass_list
);
427 // Test with multiple render passes.
428 TEST_F(SingleOverlayOnTopTest
, MultipleRenderPasses
) {
429 RenderPassList pass_list
;
430 pass_list
.push_back(CreateRenderPass());
432 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
433 CreateFullscreenCandidateQuad(resource_provider_
.get(),
434 pass
->shared_quad_state_list
.back(),
437 // Add something behind it.
438 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
439 pass
->shared_quad_state_list
.back(), pass
.get());
440 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
441 pass
->shared_quad_state_list
.back(), pass
.get());
443 pass_list
.push_back(pass
.Pass());
445 RenderPassList original_pass_list
;
446 RenderPass::CopyAll(pass_list
, &original_pass_list
);
448 // Check for potential candidates.
449 OverlayCandidateList candidate_list
;
450 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
451 EXPECT_EQ(2U, candidate_list
.size());
453 // This should be the same.
454 ASSERT_EQ(2U, pass_list
.size());
457 TEST_F(SingleOverlayOnTopTest
, RejectPremultipliedAlpha
) {
458 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
459 TextureDrawQuad
* quad
=
460 CreateFullscreenCandidateQuad(resource_provider_
.get(),
461 pass
->shared_quad_state_list
.back(),
463 quad
->premultiplied_alpha
= true;
465 RenderPassList pass_list
;
466 pass_list
.push_back(pass
.Pass());
467 OverlayCandidateList candidate_list
;
468 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
469 EXPECT_EQ(1U, pass_list
.size());
470 EXPECT_EQ(0U, candidate_list
.size());
473 TEST_F(SingleOverlayOnTopTest
, RejectBlending
) {
474 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
475 TextureDrawQuad
* quad
=
476 CreateFullscreenCandidateQuad(resource_provider_
.get(),
477 pass
->shared_quad_state_list
.back(),
479 quad
->needs_blending
= true;
481 RenderPassList pass_list
;
482 pass_list
.push_back(pass
.Pass());
483 OverlayCandidateList candidate_list
;
484 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
485 ASSERT_EQ(1U, pass_list
.size());
486 EXPECT_EQ(0U, candidate_list
.size());
489 TEST_F(SingleOverlayOnTopTest
, RejectBackgroundColor
) {
490 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
491 TextureDrawQuad
* quad
=
492 CreateFullscreenCandidateQuad(resource_provider_
.get(),
493 pass
->shared_quad_state_list
.back(),
495 quad
->background_color
= SK_ColorBLACK
;
497 RenderPassList pass_list
;
498 pass_list
.push_back(pass
.Pass());
499 OverlayCandidateList candidate_list
;
500 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
501 ASSERT_EQ(1U, pass_list
.size());
502 EXPECT_EQ(0U, candidate_list
.size());
505 TEST_F(SingleOverlayOnTopTest
, RejectBlendMode
) {
506 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
507 CreateFullscreenCandidateQuad(resource_provider_
.get(),
508 pass
->shared_quad_state_list
.back(),
510 pass
->shared_quad_state_list
.back()->blend_mode
= SkXfermode::kScreen_Mode
;
512 RenderPassList pass_list
;
513 pass_list
.push_back(pass
.Pass());
514 OverlayCandidateList candidate_list
;
515 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
516 ASSERT_EQ(1U, pass_list
.size());
517 EXPECT_EQ(0U, candidate_list
.size());
520 TEST_F(SingleOverlayOnTopTest
, RejectOpacity
) {
521 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
522 CreateFullscreenCandidateQuad(resource_provider_
.get(),
523 pass
->shared_quad_state_list
.back(),
525 pass
->shared_quad_state_list
.back()->opacity
= 0.5f
;
527 RenderPassList pass_list
;
528 pass_list
.push_back(pass
.Pass());
529 OverlayCandidateList candidate_list
;
530 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
531 ASSERT_EQ(1U, pass_list
.size());
532 EXPECT_EQ(0U, candidate_list
.size());
535 TEST_F(SingleOverlayOnTopTest
, RejectNonAxisAlignedTransform
) {
536 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
537 CreateFullscreenCandidateQuad(resource_provider_
.get(),
538 pass
->shared_quad_state_list
.back(),
540 pass
->shared_quad_state_list
.back()
541 ->quad_to_target_transform
.RotateAboutXAxis(45.f
);
543 RenderPassList pass_list
;
544 pass_list
.push_back(pass
.Pass());
545 OverlayCandidateList candidate_list
;
546 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
547 ASSERT_EQ(1U, pass_list
.size());
548 EXPECT_EQ(0U, candidate_list
.size());
551 TEST_F(SingleOverlayOnTopTest
, AllowVerticalFlip
) {
552 gfx::Rect rect
= kOverlayRect
;
553 rect
.set_width(rect
.width() / 2);
554 rect
.Offset(0, -rect
.height());
555 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
556 CreateCandidateQuadAt(resource_provider_
.get(),
557 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
558 pass
->shared_quad_state_list
.back()->quad_to_target_transform
.Scale(2.0f
,
561 RenderPassList pass_list
;
562 pass_list
.push_back(pass
.Pass());
563 OverlayCandidateList candidate_list
;
564 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
565 ASSERT_EQ(1U, pass_list
.size());
566 ASSERT_EQ(2U, candidate_list
.size());
567 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
,
568 candidate_list
.back().transform
);
571 TEST_F(SingleOverlayOnTopTest
, AllowHorizontalFlip
) {
572 gfx::Rect rect
= kOverlayRect
;
573 rect
.set_height(rect
.height() / 2);
574 rect
.Offset(-rect
.width(), 0);
575 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
576 CreateCandidateQuadAt(resource_provider_
.get(),
577 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
578 pass
->shared_quad_state_list
.back()->quad_to_target_transform
.Scale(-1.0f
,
581 RenderPassList pass_list
;
582 pass_list
.push_back(pass
.Pass());
583 OverlayCandidateList candidate_list
;
584 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
585 ASSERT_EQ(1U, pass_list
.size());
586 ASSERT_EQ(2U, candidate_list
.size());
587 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
,
588 candidate_list
.back().transform
);
591 TEST_F(SingleOverlayOnTopTest
, AllowPositiveScaleTransform
) {
592 gfx::Rect rect
= kOverlayRect
;
593 rect
.set_width(rect
.width() / 2);
594 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
595 CreateCandidateQuadAt(resource_provider_
.get(),
596 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
597 pass
->shared_quad_state_list
.back()->quad_to_target_transform
.Scale(2.0f
,
600 RenderPassList pass_list
;
601 pass_list
.push_back(pass
.Pass());
602 OverlayCandidateList candidate_list
;
603 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
604 ASSERT_EQ(1U, pass_list
.size());
605 EXPECT_EQ(2U, candidate_list
.size());
608 TEST_F(SingleOverlayOnTopTest
, Allow90DegreeRotation
) {
609 gfx::Rect rect
= kOverlayRect
;
610 rect
.Offset(0, -rect
.height());
611 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
612 CreateCandidateQuadAt(resource_provider_
.get(),
613 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
614 pass
->shared_quad_state_list
.back()
615 ->quad_to_target_transform
.RotateAboutZAxis(90.f
);
617 RenderPassList pass_list
;
618 pass_list
.push_back(pass
.Pass());
619 OverlayCandidateList candidate_list
;
620 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
621 ASSERT_EQ(1U, pass_list
.size());
622 ASSERT_EQ(2U, candidate_list
.size());
623 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_90
, candidate_list
.back().transform
);
626 TEST_F(SingleOverlayOnTopTest
, Allow180DegreeRotation
) {
627 gfx::Rect rect
= kOverlayRect
;
628 rect
.Offset(-rect
.width(), -rect
.height());
629 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
630 CreateCandidateQuadAt(resource_provider_
.get(),
631 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
632 pass
->shared_quad_state_list
.back()
633 ->quad_to_target_transform
.RotateAboutZAxis(180.f
);
635 RenderPassList pass_list
;
636 pass_list
.push_back(pass
.Pass());
637 OverlayCandidateList candidate_list
;
638 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
639 ASSERT_EQ(1U, pass_list
.size());
640 ASSERT_EQ(2U, candidate_list
.size());
641 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_180
, candidate_list
.back().transform
);
644 TEST_F(SingleOverlayOnTopTest
, Allow270DegreeRotation
) {
645 gfx::Rect rect
= kOverlayRect
;
646 rect
.Offset(-rect
.width(), 0);
647 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
648 CreateCandidateQuadAt(resource_provider_
.get(),
649 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
650 pass
->shared_quad_state_list
.back()
651 ->quad_to_target_transform
.RotateAboutZAxis(270.f
);
653 RenderPassList pass_list
;
654 pass_list
.push_back(pass
.Pass());
655 OverlayCandidateList candidate_list
;
656 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
657 ASSERT_EQ(1U, pass_list
.size());
658 ASSERT_EQ(2U, candidate_list
.size());
659 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_270
, candidate_list
.back().transform
);
662 TEST_F(SingleOverlayOnTopTest
, AllowNotTopIfNotOccluded
) {
663 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
664 CreateOpaqueQuadAt(resource_provider_
.get(),
665 pass
->shared_quad_state_list
.back(), pass
.get(),
666 kOverlayTopLeftRect
);
667 CreateCandidateQuadAt(resource_provider_
.get(),
668 pass
->shared_quad_state_list
.back(),
670 kOverlayBottomRightRect
);
672 RenderPassList pass_list
;
673 pass_list
.push_back(pass
.Pass());
675 RenderPassList original_pass_list
;
676 RenderPass::CopyAll(pass_list
, &original_pass_list
);
678 OverlayCandidateList candidate_list
;
679 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
680 EXPECT_EQ(1U, pass_list
.size());
681 EXPECT_EQ(2U, candidate_list
.size());
684 TEST_F(SingleOverlayOnTopTest
, AllowTransparentOnTop
) {
685 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
686 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
687 shared_state
->opacity
= 0.f
;
688 CreateSolidColorQuadAt(shared_state
, SK_ColorBLACK
, pass
.get(),
689 kOverlayBottomRightRect
);
690 shared_state
= pass
->CreateAndAppendSharedQuadState();
691 shared_state
->opacity
= 1.f
;
692 CreateCandidateQuadAt(resource_provider_
.get(), shared_state
, pass
.get(),
693 kOverlayBottomRightRect
);
695 RenderPassList pass_list
;
696 pass_list
.push_back(pass
.Pass());
698 RenderPassList original_pass_list
;
699 RenderPass::CopyAll(pass_list
, &original_pass_list
);
701 OverlayCandidateList candidate_list
;
702 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
703 EXPECT_EQ(1U, pass_list
.size());
704 EXPECT_EQ(2U, candidate_list
.size());
707 TEST_F(SingleOverlayOnTopTest
, AllowTransparentColorOnTop
) {
708 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
709 CreateSolidColorQuadAt(pass
->shared_quad_state_list
.back(),
710 SK_ColorTRANSPARENT
, pass
.get(),
711 kOverlayBottomRightRect
);
712 CreateCandidateQuadAt(resource_provider_
.get(),
713 pass
->shared_quad_state_list
.back(), pass
.get(),
714 kOverlayBottomRightRect
);
716 RenderPassList pass_list
;
717 pass_list
.push_back(pass
.Pass());
719 RenderPassList original_pass_list
;
720 RenderPass::CopyAll(pass_list
, &original_pass_list
);
722 OverlayCandidateList candidate_list
;
723 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
724 EXPECT_EQ(1U, pass_list
.size());
725 EXPECT_EQ(2U, candidate_list
.size());
728 TEST_F(SingleOverlayOnTopTest
, RejectOpaqueColorOnTop
) {
729 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
730 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
731 shared_state
->opacity
= 0.5f
;
732 CreateSolidColorQuadAt(shared_state
, SK_ColorBLACK
, pass
.get(),
733 kOverlayBottomRightRect
);
734 shared_state
= pass
->CreateAndAppendSharedQuadState();
735 shared_state
->opacity
= 1.f
;
736 CreateCandidateQuadAt(resource_provider_
.get(), shared_state
, pass
.get(),
737 kOverlayBottomRightRect
);
739 RenderPassList pass_list
;
740 pass_list
.push_back(pass
.Pass());
742 RenderPassList original_pass_list
;
743 RenderPass::CopyAll(pass_list
, &original_pass_list
);
745 OverlayCandidateList candidate_list
;
746 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
747 EXPECT_EQ(1U, pass_list
.size());
748 EXPECT_EQ(0U, candidate_list
.size());
751 TEST_F(SingleOverlayOnTopTest
, RejectTransparentColorOnTopWithoutBlending
) {
752 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
753 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
754 CreateSolidColorQuadAt(shared_state
, SK_ColorTRANSPARENT
, pass
.get(),
755 kOverlayBottomRightRect
)->opaque_rect
=
756 kOverlayBottomRightRect
;
757 CreateCandidateQuadAt(resource_provider_
.get(), shared_state
, pass
.get(),
758 kOverlayBottomRightRect
);
760 RenderPassList pass_list
;
761 pass_list
.push_back(pass
.Pass());
763 RenderPassList original_pass_list
;
764 RenderPass::CopyAll(pass_list
, &original_pass_list
);
766 OverlayCandidateList candidate_list
;
767 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
768 EXPECT_EQ(1U, pass_list
.size());
769 EXPECT_EQ(0U, candidate_list
.size());
772 TEST_F(SingleOverlayOnTopTest
, RejectVideoSwapTransform
) {
773 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
774 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
775 pass
->shared_quad_state_list
.back(),
776 pass
.get(), kSwapTransform
);
778 RenderPassList pass_list
;
779 pass_list
.push_back(pass
.Pass());
780 OverlayCandidateList candidate_list
;
781 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
782 ASSERT_EQ(1U, pass_list
.size());
783 EXPECT_EQ(0U, candidate_list
.size());
786 TEST_F(SingleOverlayOnTopTest
, AllowVideoXMirrorTransform
) {
787 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
788 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
789 pass
->shared_quad_state_list
.back(),
790 pass
.get(), kXMirrorTransform
);
792 RenderPassList pass_list
;
793 pass_list
.push_back(pass
.Pass());
794 OverlayCandidateList candidate_list
;
795 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
796 ASSERT_EQ(1U, pass_list
.size());
797 EXPECT_EQ(2U, candidate_list
.size());
800 TEST_F(SingleOverlayOnTopTest
, AllowVideoBothMirrorTransform
) {
801 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
802 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
803 pass
->shared_quad_state_list
.back(),
804 pass
.get(), kBothMirrorTransform
);
806 RenderPassList pass_list
;
807 pass_list
.push_back(pass
.Pass());
808 OverlayCandidateList candidate_list
;
809 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
810 ASSERT_EQ(1U, pass_list
.size());
811 EXPECT_EQ(2U, candidate_list
.size());
814 TEST_F(SingleOverlayOnTopTest
, AllowVideoNormalTransform
) {
815 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
816 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
817 pass
->shared_quad_state_list
.back(),
818 pass
.get(), kNormalTransform
);
820 RenderPassList pass_list
;
821 pass_list
.push_back(pass
.Pass());
822 OverlayCandidateList candidate_list
;
823 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
824 ASSERT_EQ(1U, pass_list
.size());
825 EXPECT_EQ(2U, candidate_list
.size());
828 TEST_F(SingleOverlayOnTopTest
, AllowVideoYMirrorTransform
) {
829 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
830 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
831 pass
->shared_quad_state_list
.back(),
832 pass
.get(), kYMirrorTransform
);
834 RenderPassList pass_list
;
835 pass_list
.push_back(pass
.Pass());
836 OverlayCandidateList candidate_list
;
837 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
838 ASSERT_EQ(1U, pass_list
.size());
839 EXPECT_EQ(2U, candidate_list
.size());
842 TEST_F(UnderlayTest
, OverlayLayerUnderMainLayer
) {
843 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
844 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
845 pass
->shared_quad_state_list
.back(), pass
.get());
846 CreateCandidateQuadAt(resource_provider_
.get(),
847 pass
->shared_quad_state_list
.back(), pass
.get(),
848 kOverlayBottomRightRect
);
850 RenderPassList pass_list
;
851 pass_list
.push_back(pass
.Pass());
853 OverlayCandidateList candidate_list
;
854 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
855 EXPECT_EQ(1U, pass_list
.size());
856 ASSERT_EQ(2U, candidate_list
.size());
857 EXPECT_EQ(0, candidate_list
[0].plane_z_order
);
858 EXPECT_EQ(-1, candidate_list
[1].plane_z_order
);
859 EXPECT_EQ(2U, pass_list
[0]->quad_list
.size());
860 // The overlay quad should have changed to a SOLID_COLOR quad.
861 EXPECT_EQ(pass_list
[0]->quad_list
.back()->material
, DrawQuad::SOLID_COLOR
);
864 TEST_F(UnderlayTest
, AllowOnTop
) {
865 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
866 CreateFullscreenCandidateQuad(resource_provider_
.get(),
867 pass
->shared_quad_state_list
.back(),
869 pass
->CreateAndAppendSharedQuadState()->opacity
= 0.5f
;
870 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
871 pass
->shared_quad_state_list
.back(), pass
.get());
873 RenderPassList pass_list
;
874 pass_list
.push_back(pass
.Pass());
876 OverlayCandidateList candidate_list
;
877 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
878 EXPECT_EQ(1U, pass_list
.size());
879 ASSERT_EQ(2U, candidate_list
.size());
880 EXPECT_EQ(0, candidate_list
[0].plane_z_order
);
881 EXPECT_EQ(-1, candidate_list
[1].plane_z_order
);
882 // The overlay quad should have changed to a SOLID_COLOR quad.
883 EXPECT_EQ(pass_list
[0]->quad_list
.front()->material
, DrawQuad::SOLID_COLOR
);
886 class OverlayInfoRendererGL
: public GLRenderer
{
888 OverlayInfoRendererGL(RendererClient
* client
,
889 const RendererSettings
* settings
,
890 OutputSurface
* output_surface
,
891 ResourceProvider
* resource_provider
)
898 expect_overlays_(false) {}
900 MOCK_METHOD3(DoDrawQuad
,
901 void(DrawingFrame
* frame
,
902 const DrawQuad
* quad
,
903 const gfx::QuadF
* draw_region
));
905 using GLRenderer::BeginDrawingFrame
;
907 void FinishDrawingFrame(DrawingFrame
* frame
) override
{
908 GLRenderer::FinishDrawingFrame(frame
);
910 if (!expect_overlays_
) {
911 EXPECT_EQ(0U, frame
->overlay_list
.size());
915 ASSERT_EQ(2U, frame
->overlay_list
.size());
916 EXPECT_NE(0U, frame
->overlay_list
.back().resource_id
);
919 void set_expect_overlays(bool expect_overlays
) {
920 expect_overlays_
= expect_overlays
;
924 bool expect_overlays_
;
927 class FakeRendererClient
: public RendererClient
{
929 // RendererClient methods.
930 void SetFullRootLayerDamage() override
{}
933 class MockOverlayScheduler
{
935 MOCK_METHOD5(Schedule
,
936 void(int plane_z_order
,
937 gfx::OverlayTransform plane_transform
,
938 unsigned overlay_texture_id
,
939 const gfx::Rect
& display_bounds
,
940 const gfx::RectF
& uv_rect
));
943 class GLRendererWithOverlaysTest
: public testing::Test
{
945 GLRendererWithOverlaysTest() {
946 provider_
= TestContextProvider::Create();
947 output_surface_
.reset(new OverlayOutputSurface(provider_
));
948 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
950 FakeResourceProvider::Create(output_surface_
.get(), nullptr);
952 provider_
->support()->SetScheduleOverlayPlaneCallback(base::Bind(
953 &MockOverlayScheduler::Schedule
, base::Unretained(&scheduler_
)));
956 void Init(bool use_validator
) {
958 output_surface_
->InitWithSingleOverlayValidator();
961 make_scoped_ptr(new OverlayInfoRendererGL(&renderer_client_
,
963 output_surface_
.get(),
964 resource_provider_
.get()));
967 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
969 RendererSettings settings_
;
970 FakeOutputSurfaceClient output_surface_client_
;
971 scoped_ptr
<OverlayOutputSurface
> output_surface_
;
972 FakeRendererClient renderer_client_
;
973 scoped_ptr
<ResourceProvider
> resource_provider_
;
974 scoped_ptr
<OverlayInfoRendererGL
> renderer_
;
975 scoped_refptr
<TestContextProvider
> provider_
;
976 MockOverlayScheduler scheduler_
;
979 TEST_F(GLRendererWithOverlaysTest
, OverlayQuadNotDrawn
) {
980 bool use_validator
= true;
982 renderer_
->set_expect_overlays(true);
983 gfx::Rect
viewport_rect(16, 16);
985 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
987 CreateFullscreenCandidateQuad(resource_provider_
.get(),
988 pass
->shared_quad_state_list
.back(),
991 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
992 pass
->shared_quad_state_list
.back(), pass
.get());
993 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
994 pass
->shared_quad_state_list
.back(), pass
.get());
996 RenderPassList pass_list
;
997 pass_list
.push_back(pass
.Pass());
999 // Candidate pass was taken out and extra skipped pass added,
1000 // so only draw 2 quads.
1001 EXPECT_CALL(*renderer_
, DoDrawQuad(_
, _
, _
)).Times(2);
1002 EXPECT_CALL(scheduler_
,
1004 gfx::OVERLAY_TRANSFORM_NONE
,
1007 BoundingRect(kUVTopLeft
, kUVBottomRight
))).Times(1);
1008 renderer_
->DrawFrame(&pass_list
, 1.f
, viewport_rect
, viewport_rect
, false);
1012 Mock::VerifyAndClearExpectations(renderer_
.get());
1013 Mock::VerifyAndClearExpectations(&scheduler_
);
1016 TEST_F(GLRendererWithOverlaysTest
, OccludedQuadInUnderlay
) {
1017 bool use_validator
= true;
1018 Init(use_validator
);
1019 renderer_
->set_expect_overlays(true);
1020 gfx::Rect
viewport_rect(16, 16);
1022 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1024 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1025 pass
->shared_quad_state_list
.back(), pass
.get());
1026 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1027 pass
->shared_quad_state_list
.back(), pass
.get());
1029 CreateFullscreenCandidateQuad(resource_provider_
.get(),
1030 pass
->shared_quad_state_list
.back(),
1033 RenderPassList pass_list
;
1034 pass_list
.push_back(pass
.Pass());
1036 // Candidate quad should fail to be overlaid on top because of occlusion.
1037 // Expect to be replaced with transparent hole quad and placed in underlay.
1038 EXPECT_CALL(*renderer_
, DoDrawQuad(_
, _
, _
)).Times(3);
1039 EXPECT_CALL(scheduler_
,
1040 Schedule(-1, gfx::OVERLAY_TRANSFORM_NONE
, _
, kOverlayRect
,
1041 BoundingRect(kUVTopLeft
, kUVBottomRight
))).Times(1);
1042 renderer_
->DrawFrame(&pass_list
, 1.f
, viewport_rect
, viewport_rect
, false);
1046 Mock::VerifyAndClearExpectations(renderer_
.get());
1047 Mock::VerifyAndClearExpectations(&scheduler_
);
1050 TEST_F(GLRendererWithOverlaysTest
, NoValidatorNoOverlay
) {
1051 bool use_validator
= false;
1052 Init(use_validator
);
1053 renderer_
->set_expect_overlays(false);
1054 gfx::Rect
viewport_rect(16, 16);
1056 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1058 CreateFullscreenCandidateQuad(resource_provider_
.get(),
1059 pass
->shared_quad_state_list
.back(),
1062 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1063 pass
->shared_quad_state_list
.back(), pass
.get());
1064 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1065 pass
->shared_quad_state_list
.back(), pass
.get());
1067 RenderPassList pass_list
;
1068 pass_list
.push_back(pass
.Pass());
1070 // Should see no overlays.
1071 EXPECT_CALL(*renderer_
, DoDrawQuad(_
, _
, _
)).Times(3);
1072 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1073 renderer_
->DrawFrame(&pass_list
, 1.f
, viewport_rect
, viewport_rect
, false);
1077 Mock::VerifyAndClearExpectations(renderer_
.get());
1078 Mock::VerifyAndClearExpectations(&scheduler_
);
1081 TEST_F(GLRendererWithOverlaysTest
, ResourcesExportedAndReturned
) {
1082 bool use_validator
= true;
1083 Init(use_validator
);
1084 renderer_
->set_expect_overlays(true);
1086 ResourceId resource1
= CreateResource(resource_provider_
.get());
1087 ResourceId resource2
= CreateResource(resource_provider_
.get());
1089 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1090 RenderPassList pass_list
;
1091 pass_list
.push_back(pass
.Pass());
1093 DirectRenderer::DrawingFrame frame1
;
1094 frame1
.render_passes_in_draw_order
= &pass_list
;
1095 frame1
.overlay_list
.resize(2);
1096 OverlayCandidate
& overlay1
= frame1
.overlay_list
.back();
1097 overlay1
.resource_id
= resource1
;
1098 overlay1
.plane_z_order
= 1;
1100 DirectRenderer::DrawingFrame frame2
;
1101 frame2
.render_passes_in_draw_order
= &pass_list
;
1102 frame2
.overlay_list
.resize(2);
1103 OverlayCandidate
& overlay2
= frame2
.overlay_list
.back();
1104 overlay2
.resource_id
= resource2
;
1105 overlay2
.plane_z_order
= 1;
1107 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1108 renderer_
->BeginDrawingFrame(&frame1
);
1109 renderer_
->FinishDrawingFrame(&frame1
);
1110 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1111 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1113 Mock::VerifyAndClearExpectations(&scheduler_
);
1115 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1116 renderer_
->BeginDrawingFrame(&frame2
);
1117 renderer_
->FinishDrawingFrame(&frame2
);
1118 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1119 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource2
));
1121 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1122 Mock::VerifyAndClearExpectations(&scheduler_
);
1124 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1125 renderer_
->BeginDrawingFrame(&frame1
);
1126 renderer_
->FinishDrawingFrame(&frame1
);
1127 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1128 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource2
));
1130 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1131 Mock::VerifyAndClearExpectations(&scheduler_
);
1133 // No overlays, release the resource.
1134 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1135 DirectRenderer::DrawingFrame frame3
;
1136 frame3
.render_passes_in_draw_order
= &pass_list
;
1137 renderer_
->set_expect_overlays(false);
1138 renderer_
->BeginDrawingFrame(&frame3
);
1139 renderer_
->FinishDrawingFrame(&frame3
);
1140 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1141 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1143 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1144 Mock::VerifyAndClearExpectations(&scheduler_
);
1146 // Use the same buffer twice.
1147 renderer_
->set_expect_overlays(true);
1148 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1149 renderer_
->BeginDrawingFrame(&frame1
);
1150 renderer_
->FinishDrawingFrame(&frame1
);
1151 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1153 Mock::VerifyAndClearExpectations(&scheduler_
);
1155 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1156 renderer_
->BeginDrawingFrame(&frame1
);
1157 renderer_
->FinishDrawingFrame(&frame1
);
1158 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1160 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1161 Mock::VerifyAndClearExpectations(&scheduler_
);
1163 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1164 renderer_
->set_expect_overlays(false);
1165 renderer_
->BeginDrawingFrame(&frame3
);
1166 renderer_
->FinishDrawingFrame(&frame3
);
1167 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1169 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1170 Mock::VerifyAndClearExpectations(&scheduler_
);