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/region.h"
6 #include "cc/base/scoped_ptr_vector.h"
7 #include "cc/output/compositor_frame_metadata.h"
8 #include "cc/output/gl_renderer.h"
9 #include "cc/output/output_surface.h"
10 #include "cc/output/output_surface_client.h"
11 #include "cc/output/overlay_candidate_validator.h"
12 #include "cc/output/overlay_processor.h"
13 #include "cc/output/overlay_strategy_sandwich.h"
14 #include "cc/output/overlay_strategy_single_on_top.h"
15 #include "cc/output/overlay_strategy_underlay.h"
16 #include "cc/quads/render_pass.h"
17 #include "cc/quads/solid_color_draw_quad.h"
18 #include "cc/quads/stream_video_draw_quad.h"
19 #include "cc/quads/texture_draw_quad.h"
20 #include "cc/resources/resource_provider.h"
21 #include "cc/resources/texture_mailbox.h"
22 #include "cc/test/fake_output_surface_client.h"
23 #include "cc/test/fake_resource_provider.h"
24 #include "cc/test/geometry_test_utils.h"
25 #include "cc/test/test_context_provider.h"
26 #include "cc/test/test_shared_bitmap_manager.h"
27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "ui/gfx/geometry/rect_conversions.h"
37 const gfx::Size
kDisplaySize(256, 256);
38 const gfx::Rect
kOverlayRect(0, 0, 128, 128);
39 const gfx::Rect
kOverlayTopLeftRect(0, 0, 64, 64);
40 const gfx::Rect
kOverlayBottomRightRect(64, 64, 64, 64);
41 const gfx::Rect
kOverlayClipRect(0, 0, 128, 128);
42 const gfx::PointF
kUVTopLeft(0.1f
, 0.2f
);
43 const gfx::PointF
kUVBottomRight(1.0f
, 1.0f
);
44 const gfx::Transform kNormalTransform
=
45 gfx::Transform(0.9f
, 0, 0, 0.8f
, 0.1f
, 0.2f
); // x,y -> x,y.
46 const gfx::Transform kXMirrorTransform
=
47 gfx::Transform(-0.9f
, 0, 0, 0.8f
, 1.0f
, 0.2f
); // x,y -> 1-x,y.
48 const gfx::Transform kYMirrorTransform
=
49 gfx::Transform(0.9f
, 0, 0, -0.8f
, 0.1f
, 1.0f
); // x,y -> x,1-y.
50 const gfx::Transform kBothMirrorTransform
=
51 gfx::Transform(-0.9f
, 0, 0, -0.8f
, 1.0f
, 1.0f
); // x,y -> 1-x,1-y.
52 const gfx::Transform kSwapTransform
=
53 gfx::Transform(0, 1, 1, 0, 0, 0); // x,y -> y,x.
55 void MailboxReleased(unsigned sync_point
,
57 BlockingTaskRunner
* main_thread_task_runner
) {
60 class SingleOverlayValidator
: public OverlayCandidateValidator
{
62 void GetStrategies(OverlayProcessor::StrategyList
* strategies
) override
{
63 strategies
->push_back(scoped_ptr
<OverlayProcessor::Strategy
>(
64 new OverlayStrategyCommon(this, new OverlayStrategySingleOnTop
)));
65 strategies
->push_back(scoped_ptr
<OverlayProcessor::Strategy
>(
66 new OverlayStrategyCommon(this, new OverlayStrategyUnderlay
)));
68 void CheckOverlaySupport(OverlayCandidateList
* surfaces
) override
{
69 ASSERT_EQ(2U, surfaces
->size());
71 OverlayCandidate
& candidate
= surfaces
->back();
72 if (candidate
.display_rect
.width() == 64) {
73 EXPECT_EQ(gfx::RectF(kOverlayBottomRightRect
), candidate
.display_rect
);
75 EXPECT_NEAR(kOverlayRect
.x(), candidate
.display_rect
.x(), 0.01f
);
76 EXPECT_NEAR(kOverlayRect
.y(), candidate
.display_rect
.y(), 0.01f
);
77 EXPECT_NEAR(kOverlayRect
.width(), candidate
.display_rect
.width(), 0.01f
);
78 EXPECT_NEAR(kOverlayRect
.height(), candidate
.display_rect
.height(),
81 EXPECT_FLOAT_RECT_EQ(BoundingRect(kUVTopLeft
, kUVBottomRight
),
83 if (!candidate
.clip_rect
.IsEmpty()) {
84 EXPECT_EQ(true, candidate
.is_clipped
);
85 EXPECT_EQ(kOverlayClipRect
, candidate
.clip_rect
);
87 candidate
.overlay_handled
= true;
91 class SandwichOverlayValidator
: public OverlayCandidateValidator
{
93 void GetStrategies(OverlayProcessor::StrategyList
* strategies
) override
{
94 strategies
->push_back(scoped_ptr
<OverlayProcessor::Strategy
>(
95 new OverlayStrategyCommon(this, new OverlayStrategySandwich
)));
97 void CheckOverlaySupport(OverlayCandidateList
* surfaces
) override
{
98 for (OverlayCandidate
& candidate
: *surfaces
)
99 candidate
.overlay_handled
= true;
103 template <typename OverlayStrategyType
>
104 class SingleOverlayProcessor
: public OverlayProcessor
{
106 explicit SingleOverlayProcessor(OutputSurface
* surface
)
107 : OverlayProcessor(surface
) {
108 EXPECT_EQ(surface
, surface_
);
111 // Virtual to allow testing different strategies.
112 void Initialize() override
{
113 OverlayCandidateValidator
* validator
=
114 surface_
->GetOverlayCandidateValidator();
115 ASSERT_TRUE(validator
!= NULL
);
116 strategies_
.push_back(scoped_ptr
<Strategy
>(
117 new OverlayStrategyCommon(validator
, new OverlayStrategyType
)));
121 class DefaultOverlayProcessor
: public OverlayProcessor
{
123 explicit DefaultOverlayProcessor(OutputSurface
* surface
);
124 size_t GetStrategyCount();
127 DefaultOverlayProcessor::DefaultOverlayProcessor(OutputSurface
* surface
)
128 : OverlayProcessor(surface
) {
131 size_t DefaultOverlayProcessor::GetStrategyCount() {
132 return strategies_
.size();
135 class OverlayOutputSurface
: public OutputSurface
{
137 explicit OverlayOutputSurface(scoped_refptr
<ContextProvider
> context_provider
)
138 : OutputSurface(context_provider
) {
139 surface_size_
= kDisplaySize
;
140 device_scale_factor_
= 1;
143 void SetScaleFactor(float scale_factor
) {
144 device_scale_factor_
= scale_factor
;
147 // OutputSurface implementation
148 void SwapBuffers(CompositorFrame
* frame
) override
;
150 void InitWithSingleOverlayValidator() {
151 overlay_candidate_validator_
.reset(new SingleOverlayValidator
);
153 void InitWithSandwichOverlayValidator() {
154 overlay_candidate_validator_
.reset(new SandwichOverlayValidator
);
157 OverlayCandidateValidator
* GetOverlayCandidateValidator() const override
{
158 return overlay_candidate_validator_
.get();
162 scoped_ptr
<OverlayCandidateValidator
> overlay_candidate_validator_
;
165 void OverlayOutputSurface::SwapBuffers(CompositorFrame
* frame
) {
166 client_
->DidSwapBuffers();
167 client_
->DidSwapBuffersComplete();
170 scoped_ptr
<RenderPass
> CreateRenderPass() {
171 RenderPassId
id(1, 0);
172 gfx::Rect
output_rect(0, 0, 256, 256);
173 bool has_transparent_background
= true;
175 scoped_ptr
<RenderPass
> pass
= RenderPass::Create();
180 has_transparent_background
);
182 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
183 shared_state
->opacity
= 1.f
;
187 ResourceId
CreateResource(ResourceProvider
* resource_provider
) {
188 unsigned sync_point
= 0;
189 TextureMailbox mailbox
=
190 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D
, sync_point
);
191 scoped_ptr
<SingleReleaseCallbackImpl
> release_callback
=
192 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased
));
194 return resource_provider
->CreateResourceFromTextureMailbox(
195 mailbox
, release_callback
.Pass());
198 SolidColorDrawQuad
* CreateSolidColorQuadAt(
199 const SharedQuadState
* shared_quad_state
,
201 RenderPass
* render_pass
,
202 const gfx::Rect
& rect
) {
203 SolidColorDrawQuad
* quad
=
204 render_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
205 quad
->SetNew(shared_quad_state
, rect
, rect
, color
, false);
209 TextureDrawQuad
* CreateCandidateQuadAt(ResourceProvider
* resource_provider
,
210 const SharedQuadState
* shared_quad_state
,
211 RenderPass
* render_pass
,
212 const gfx::Rect
& rect
) {
213 ResourceId resource_id
= CreateResource(resource_provider
);
214 bool premultiplied_alpha
= false;
215 bool flipped
= false;
216 bool nearest_neighbor
= false;
217 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
218 gfx::Size resource_size_in_pixels
= gfx::Size(64, 64);
219 bool allow_overlay
= true;
221 TextureDrawQuad
* overlay_quad
=
222 render_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
223 overlay_quad
->SetNew(shared_quad_state
,
235 overlay_quad
->set_allow_overlay(allow_overlay
);
236 overlay_quad
->set_resource_size_in_pixels(resource_size_in_pixels
);
241 StreamVideoDrawQuad
* CreateCandidateVideoQuadAt(
242 ResourceProvider
* resource_provider
,
243 const SharedQuadState
* shared_quad_state
,
244 RenderPass
* render_pass
,
245 const gfx::Rect
& rect
,
246 const gfx::Transform
& transform
) {
247 ResourceId resource_id
= CreateResource(resource_provider
);
248 gfx::Size resource_size_in_pixels
= gfx::Size(64, 64);
249 bool allow_overlay
= true;
251 StreamVideoDrawQuad
* overlay_quad
=
252 render_pass
->CreateAndAppendDrawQuad
<StreamVideoDrawQuad
>();
253 overlay_quad
->SetNew(shared_quad_state
, rect
, rect
, rect
, resource_id
,
254 resource_size_in_pixels
, allow_overlay
, transform
);
259 TextureDrawQuad
* CreateFullscreenCandidateQuad(
260 ResourceProvider
* resource_provider
,
261 const SharedQuadState
* shared_quad_state
,
262 RenderPass
* render_pass
) {
263 return CreateCandidateQuadAt(
264 resource_provider
, shared_quad_state
, render_pass
, kOverlayRect
);
267 StreamVideoDrawQuad
* CreateFullscreenCandidateVideoQuad(
268 ResourceProvider
* resource_provider
,
269 const SharedQuadState
* shared_quad_state
,
270 RenderPass
* render_pass
,
271 const gfx::Transform
& transform
) {
272 return CreateCandidateVideoQuadAt(resource_provider
, shared_quad_state
,
273 render_pass
, kOverlayRect
, transform
);
276 void CreateOpaqueQuadAt(ResourceProvider
* resource_provider
,
277 const SharedQuadState
* shared_quad_state
,
278 RenderPass
* render_pass
,
279 const gfx::Rect
& rect
) {
280 SolidColorDrawQuad
* color_quad
=
281 render_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
282 color_quad
->SetNew(shared_quad_state
, rect
, rect
, SK_ColorBLACK
, false);
285 void CreateFullscreenOpaqueQuad(ResourceProvider
* resource_provider
,
286 const SharedQuadState
* shared_quad_state
,
287 RenderPass
* render_pass
) {
288 CreateOpaqueQuadAt(resource_provider
, shared_quad_state
, render_pass
,
292 static void CompareRenderPassLists(const RenderPassList
& expected_list
,
293 const RenderPassList
& actual_list
) {
294 EXPECT_EQ(expected_list
.size(), actual_list
.size());
295 for (size_t i
= 0; i
< actual_list
.size(); ++i
) {
296 RenderPass
* expected
= expected_list
[i
];
297 RenderPass
* actual
= actual_list
[i
];
299 EXPECT_EQ(expected
->id
, actual
->id
);
300 EXPECT_EQ(expected
->output_rect
, actual
->output_rect
);
301 EXPECT_EQ(expected
->transform_to_root_target
,
302 actual
->transform_to_root_target
);
303 EXPECT_EQ(expected
->damage_rect
, actual
->damage_rect
);
304 EXPECT_EQ(expected
->has_transparent_background
,
305 actual
->has_transparent_background
);
307 EXPECT_EQ(expected
->shared_quad_state_list
.size(),
308 actual
->shared_quad_state_list
.size());
309 EXPECT_EQ(expected
->quad_list
.size(), actual
->quad_list
.size());
311 for (auto exp_iter
= expected
->quad_list
.cbegin(),
312 act_iter
= actual
->quad_list
.cbegin();
313 exp_iter
!= expected
->quad_list
.cend();
314 ++exp_iter
, ++act_iter
) {
315 EXPECT_EQ(exp_iter
->rect
.ToString(), act_iter
->rect
.ToString());
316 EXPECT_EQ(exp_iter
->shared_quad_state
->quad_layer_bounds
.ToString(),
317 act_iter
->shared_quad_state
->quad_layer_bounds
.ToString());
322 TEST(OverlayTest
, NoOverlaysByDefault
) {
323 scoped_refptr
<TestContextProvider
> provider
= TestContextProvider::Create();
324 OverlayOutputSurface
output_surface(provider
);
325 EXPECT_EQ(NULL
, output_surface
.GetOverlayCandidateValidator());
327 output_surface
.InitWithSingleOverlayValidator();
328 EXPECT_TRUE(output_surface
.GetOverlayCandidateValidator() != NULL
);
331 TEST(OverlayTest
, OverlaysProcessorHasStrategy
) {
332 scoped_refptr
<TestContextProvider
> provider
= TestContextProvider::Create();
333 OverlayOutputSurface
output_surface(provider
);
334 FakeOutputSurfaceClient client
;
335 EXPECT_TRUE(output_surface
.BindToClient(&client
));
336 output_surface
.InitWithSingleOverlayValidator();
337 EXPECT_TRUE(output_surface
.GetOverlayCandidateValidator() != NULL
);
339 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
340 new TestSharedBitmapManager());
341 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
342 &output_surface
, shared_bitmap_manager
.get());
344 scoped_ptr
<DefaultOverlayProcessor
> overlay_processor(
345 new DefaultOverlayProcessor(&output_surface
));
346 overlay_processor
->Initialize();
347 EXPECT_GE(2U, overlay_processor
->GetStrategyCount());
350 template <typename OverlayStrategyType
>
351 class OverlayTest
: public testing::Test
{
353 void SetUp() override
{
354 provider_
= TestContextProvider::Create();
355 output_surface_
.reset(new OverlayOutputSurface(provider_
));
356 EXPECT_TRUE(output_surface_
->BindToClient(&client_
));
357 output_surface_
->InitWithSingleOverlayValidator();
358 EXPECT_TRUE(output_surface_
->GetOverlayCandidateValidator() != NULL
);
360 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
361 resource_provider_
= FakeResourceProvider::Create(
362 output_surface_
.get(), shared_bitmap_manager_
.get());
364 overlay_processor_
.reset(
365 new SingleOverlayProcessor
<OverlayStrategyType
>(output_surface_
.get()));
366 overlay_processor_
->Initialize();
369 scoped_refptr
<TestContextProvider
> provider_
;
370 scoped_ptr
<OverlayOutputSurface
> output_surface_
;
371 FakeOutputSurfaceClient client_
;
372 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
373 scoped_ptr
<ResourceProvider
> resource_provider_
;
374 scoped_ptr
<SingleOverlayProcessor
<OverlayStrategyType
>> overlay_processor_
;
377 typedef OverlayTest
<OverlayStrategySingleOnTop
> SingleOverlayOnTopTest
;
378 typedef OverlayTest
<OverlayStrategyUnderlay
> UnderlayTest
;
380 class SandwichTest
: public testing::Test
{
382 void SetUp() override
{
383 provider_
= TestContextProvider::Create();
384 output_surface_
.reset(new OverlayOutputSurface(provider_
));
385 EXPECT_TRUE(output_surface_
->BindToClient(&client_
));
386 output_surface_
->InitWithSandwichOverlayValidator();
387 EXPECT_TRUE(output_surface_
->GetOverlayCandidateValidator() != NULL
);
389 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
390 resource_provider_
= FakeResourceProvider::Create(
391 output_surface_
.get(), shared_bitmap_manager_
.get());
393 overlay_processor_
.reset(new OverlayProcessor(output_surface_
.get()));
394 overlay_processor_
->Initialize();
397 scoped_refptr
<TestContextProvider
> provider_
;
398 scoped_ptr
<OverlayOutputSurface
> output_surface_
;
399 FakeOutputSurfaceClient client_
;
400 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
401 scoped_ptr
<ResourceProvider
> resource_provider_
;
402 scoped_ptr
<OverlayProcessor
> overlay_processor_
;
405 TEST_F(SandwichTest
, SuccessfulSingleOverlay
) {
406 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
407 TextureDrawQuad
* original_quad
= CreateFullscreenCandidateQuad(
408 resource_provider_
.get(), pass
->shared_quad_state_list
.back(),
410 unsigned original_resource_id
= original_quad
->resource_id();
412 // Add something behind it.
413 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
414 pass
->shared_quad_state_list
.back(), pass
.get());
415 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
416 pass
->shared_quad_state_list
.back(), pass
.get());
418 RenderPassList pass_list
;
419 pass_list
.push_back(pass
.Pass());
421 // Check for potential candidates.
422 OverlayCandidateList candidate_list
;
423 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
425 ASSERT_EQ(1U, pass_list
.size());
426 ASSERT_EQ(2U, candidate_list
.size());
428 RenderPass
* main_pass
= pass_list
.back();
429 // Check that the quad is gone.
430 EXPECT_EQ(2U, main_pass
->quad_list
.size());
431 const QuadList
& quad_list
= main_pass
->quad_list
;
432 for (QuadList::ConstBackToFrontIterator it
= quad_list
.BackToFrontBegin();
433 it
!= quad_list
.BackToFrontEnd(); ++it
) {
434 EXPECT_NE(DrawQuad::TEXTURE_CONTENT
, it
->material
);
437 // Check that the right resource id got extracted.
438 EXPECT_EQ(original_resource_id
, candidate_list
.back().resource_id
);
441 TEST_F(SandwichTest
, SuccessfulTwoOverlays
) {
442 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
444 // Add two non-overlapping candidates.
445 CreateCandidateQuadAt(resource_provider_
.get(),
446 pass
->shared_quad_state_list
.back(), pass
.get(),
447 kOverlayTopLeftRect
);
448 CreateCandidateQuadAt(resource_provider_
.get(),
449 pass
->shared_quad_state_list
.back(), pass
.get(),
450 kOverlayBottomRightRect
);
452 // Add something behind it.
453 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
454 pass
->shared_quad_state_list
.back(), pass
.get());
456 RenderPassList pass_list
;
457 pass_list
.push_back(pass
.Pass());
458 OverlayCandidateList candidate_list
;
459 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
461 // Both candidates should become overlays.
462 EXPECT_EQ(1u, pass_list
.size());
463 EXPECT_EQ(3u, candidate_list
.size());
464 EXPECT_EQ(gfx::RectF(kOverlayTopLeftRect
), candidate_list
[1].display_rect
);
465 EXPECT_EQ(gfx::RectF(kOverlayBottomRightRect
),
466 candidate_list
[2].display_rect
);
468 // The overlay quads should be gone.
469 const QuadList
& quad_list
= pass_list
.back()->quad_list
;
470 EXPECT_EQ(1u, quad_list
.size());
471 EXPECT_EQ(DrawQuad::SOLID_COLOR
, quad_list
.front()->material
);
474 TEST_F(SandwichTest
, OverlappingOverlays
) {
475 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
477 // Add two overlapping candidates.
478 CreateCandidateQuadAt(resource_provider_
.get(),
479 pass
->shared_quad_state_list
.back(), pass
.get(),
480 kOverlayTopLeftRect
);
481 CreateCandidateQuadAt(resource_provider_
.get(),
482 pass
->shared_quad_state_list
.back(), pass
.get(),
485 // Add something behind it.
486 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
487 pass
->shared_quad_state_list
.back(), pass
.get());
489 RenderPassList pass_list
;
490 pass_list
.push_back(pass
.Pass());
491 OverlayCandidateList candidate_list
;
492 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
494 // Only one of the candidates should become an overlay.
495 EXPECT_EQ(1u, pass_list
.size());
496 EXPECT_EQ(2u, candidate_list
.size());
497 EXPECT_EQ(gfx::RectF(kOverlayTopLeftRect
), candidate_list
[1].display_rect
);
499 // One of the overlay quads should be gone.
500 const QuadList
& quad_list
= pass_list
.back()->quad_list
;
501 EXPECT_EQ(2u, quad_list
.size());
502 EXPECT_EQ(DrawQuad::TEXTURE_CONTENT
, quad_list
.front()->material
);
503 EXPECT_EQ(DrawQuad::SOLID_COLOR
, quad_list
.back()->material
);
506 TEST_F(SandwichTest
, SuccessfulSandwichOverlay
) {
507 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
509 CreateOpaqueQuadAt(resource_provider_
.get(),
510 pass
->shared_quad_state_list
.back(), pass
.get(),
511 gfx::Rect(16, 16, 32, 32));
512 unsigned candidate_id
=
513 CreateCandidateQuadAt(resource_provider_
.get(),
514 pass
->shared_quad_state_list
.back(), pass
.get(),
515 gfx::Rect(32, 32, 32, 32))
517 CreateOpaqueQuadAt(resource_provider_
.get(),
518 pass
->shared_quad_state_list
.back(), pass
.get(),
519 gfx::Rect(kDisplaySize
));
521 RenderPassList pass_list
;
522 pass_list
.push_back(pass
.Pass());
524 // Check for potential candidates.
525 OverlayCandidateList candidate_list
;
526 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
528 ASSERT_EQ(1U, pass_list
.size());
529 ASSERT_EQ(3U, candidate_list
.size());
531 RenderPass
* main_pass
= pass_list
.back();
532 // Check that the quad is gone.
533 EXPECT_EQ(3U, main_pass
->quad_list
.size());
534 const QuadList
& quad_list
= main_pass
->quad_list
;
535 for (QuadList::ConstBackToFrontIterator it
= quad_list
.BackToFrontBegin();
536 it
!= quad_list
.BackToFrontEnd(); ++it
) {
537 EXPECT_NE(DrawQuad::TEXTURE_CONTENT
, it
->material
);
540 EXPECT_FALSE(candidate_list
[0].use_output_surface_for_resource
);
541 EXPECT_EQ(candidate_id
, candidate_list
[1].resource_id
);
542 EXPECT_EQ(gfx::RectF(32.f
, 32.f
, 32.f
, 32.f
), candidate_list
[1].display_rect
);
543 EXPECT_TRUE(candidate_list
[2].use_output_surface_for_resource
);
544 EXPECT_EQ(gfx::RectF(32.f
, 32.f
, 16.f
, 16.f
), candidate_list
[2].display_rect
);
545 EXPECT_EQ(gfx::RectF(32.f
/ 256.f
, 32.f
/ 256.f
, 16.f
/ 256.f
, 16.f
/ 256.f
),
546 candidate_list
[2].uv_rect
);
549 TEST_F(SandwichTest
, GrowTopOverlayForToAlignWithDIP
) {
550 output_surface_
->SetScaleFactor(2);
551 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
553 // The opaque quad on top is not DIP aligned, so it should be enlarged to
554 // include the surrounding DIP.
555 CreateOpaqueQuadAt(resource_provider_
.get(),
556 pass
->shared_quad_state_list
.back(), pass
.get(),
557 gfx::Rect(16, 16, 33, 33));
558 unsigned candidate_id
=
559 CreateCandidateQuadAt(resource_provider_
.get(),
560 pass
->shared_quad_state_list
.back(), pass
.get(),
561 gfx::Rect(32, 32, 32, 32))
563 CreateOpaqueQuadAt(resource_provider_
.get(),
564 pass
->shared_quad_state_list
.back(), pass
.get(),
565 gfx::Rect(kDisplaySize
));
567 RenderPassList pass_list
;
568 pass_list
.push_back(pass
.Pass());
570 // Check for potential candidates.
571 OverlayCandidateList candidate_list
;
572 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
573 ASSERT_EQ(1U, pass_list
.size());
574 ASSERT_EQ(3U, candidate_list
.size());
576 // Check that the quad is gone.
577 RenderPass
* main_pass
= pass_list
.back();
578 EXPECT_EQ(3U, main_pass
->quad_list
.size());
579 const QuadList
& quad_list
= main_pass
->quad_list
;
580 for (QuadList::ConstBackToFrontIterator it
= quad_list
.BackToFrontBegin();
581 it
!= quad_list
.BackToFrontEnd(); ++it
) {
582 EXPECT_NE(DrawQuad::TEXTURE_CONTENT
, it
->material
);
585 EXPECT_FALSE(candidate_list
[0].use_output_surface_for_resource
);
586 EXPECT_EQ(candidate_id
, candidate_list
[1].resource_id
);
587 EXPECT_EQ(gfx::RectF(32.f
, 32.f
, 32.f
, 32.f
), candidate_list
[1].display_rect
);
588 EXPECT_TRUE(candidate_list
[2].use_output_surface_for_resource
);
589 EXPECT_EQ(gfx::RectF(32.f
, 32.f
, 18.f
, 18.f
), candidate_list
[2].display_rect
);
590 EXPECT_EQ(gfx::RectF(32.f
/ 256.f
, 32.f
/ 256.f
, 18.f
/ 256.f
, 18.f
/ 256.f
),
591 candidate_list
[2].uv_rect
);
594 TEST_F(SandwichTest
, MisalignedOverlay
) {
595 output_surface_
->SetScaleFactor(2);
596 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
598 // We can't create an overlay for a candidate that is not DIP aligned.
599 CreateCandidateQuadAt(resource_provider_
.get(),
600 pass
->shared_quad_state_list
.back(), pass
.get(),
601 gfx::Rect(32, 32, 33, 33))
603 CreateOpaqueQuadAt(resource_provider_
.get(),
604 pass
->shared_quad_state_list
.back(), pass
.get(),
605 gfx::Rect(kDisplaySize
));
607 RenderPassList pass_list
;
608 pass_list
.push_back(pass
.Pass());
610 OverlayCandidateList candidate_list
;
611 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
613 ASSERT_EQ(1U, pass_list
.size());
614 ASSERT_EQ(0U, candidate_list
.size());
617 TEST_F(SandwichTest
, MultiQuadOverlay
) {
618 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
620 // Put two non-intersecting quads on top.
621 const gfx::Rect
rect1(gfx::Rect(0, 0, 32, 32));
622 const gfx::Rect
rect2(gfx::Rect(32, 32, 32, 32));
623 Region covered_region
;
624 covered_region
.Union(rect1
);
625 covered_region
.Union(rect2
);
626 CreateOpaqueQuadAt(resource_provider_
.get(),
627 pass
->shared_quad_state_list
.back(), pass
.get(), rect1
);
628 CreateOpaqueQuadAt(resource_provider_
.get(),
629 pass
->shared_quad_state_list
.back(), pass
.get(), rect2
);
631 // Then a candidate that we'll turn into an overlay.
632 unsigned candidate_id
=
633 CreateCandidateQuadAt(resource_provider_
.get(),
634 pass
->shared_quad_state_list
.back(), pass
.get(),
635 gfx::Rect(0, 0, 64, 64))
638 // Then some opaque background.
639 CreateOpaqueQuadAt(resource_provider_
.get(),
640 pass
->shared_quad_state_list
.back(), pass
.get(),
641 gfx::Rect(kDisplaySize
));
643 RenderPassList pass_list
;
644 pass_list
.push_back(pass
.Pass());
646 // Run the overlay strategy on that input.
647 RenderPass
* main_pass
= pass_list
.back();
648 OverlayCandidateList candidate_list
;
649 EXPECT_EQ(4U, main_pass
->quad_list
.size());
650 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
651 ASSERT_EQ(1U, pass_list
.size());
652 ASSERT_EQ(4U, candidate_list
.size());
654 // Check that the candidate quad is gone and that we now have two transparent
655 // quads for the same region that was covered on the overlay.
656 EXPECT_EQ(5U, main_pass
->quad_list
.size());
657 const QuadList
& quad_list
= main_pass
->quad_list
;
658 Region transparent_quad_region
;
659 for (QuadList::ConstBackToFrontIterator it
= quad_list
.BackToFrontBegin();
660 it
!= quad_list
.BackToFrontEnd(); ++it
) {
661 EXPECT_NE(DrawQuad::TEXTURE_CONTENT
, it
->material
);
662 if (it
->material
== DrawQuad::SOLID_COLOR
) {
663 const SolidColorDrawQuad
* solid_color_quad
=
664 SolidColorDrawQuad::MaterialCast(*it
);
665 if (solid_color_quad
->color
== SK_ColorTRANSPARENT
)
666 transparent_quad_region
.Union(solid_color_quad
->rect
);
669 DCHECK(covered_region
== transparent_quad_region
);
671 // Check that overlays cover the same region that the quads covered.
672 EXPECT_FALSE(candidate_list
[0].use_output_surface_for_resource
);
673 EXPECT_EQ(candidate_id
, candidate_list
[1].resource_id
);
674 EXPECT_EQ(gfx::RectF(64.f
, 64.f
), candidate_list
[1].display_rect
);
675 EXPECT_TRUE(candidate_list
[2].use_output_surface_for_resource
);
676 EXPECT_TRUE(candidate_list
[3].use_output_surface_for_resource
);
677 Region overlay_region
;
678 overlay_region
.Union(gfx::ToEnclosingRect(candidate_list
[2].display_rect
));
679 overlay_region
.Union(gfx::ToEnclosingRect(candidate_list
[3].display_rect
));
680 DCHECK(covered_region
== overlay_region
);
683 TEST_F(SingleOverlayOnTopTest
, SuccessfullOverlay
) {
684 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
685 TextureDrawQuad
* original_quad
=
686 CreateFullscreenCandidateQuad(resource_provider_
.get(),
687 pass
->shared_quad_state_list
.back(),
689 unsigned original_resource_id
= original_quad
->resource_id();
691 // Add something behind it.
692 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
693 pass
->shared_quad_state_list
.back(), pass
.get());
694 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
695 pass
->shared_quad_state_list
.back(), pass
.get());
697 RenderPassList pass_list
;
698 pass_list
.push_back(pass
.Pass());
700 // Check for potential candidates.
701 OverlayCandidateList candidate_list
;
702 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
704 ASSERT_EQ(1U, pass_list
.size());
705 ASSERT_EQ(2U, candidate_list
.size());
707 RenderPass
* main_pass
= pass_list
.back();
708 // Check that the quad is gone.
709 EXPECT_EQ(2U, main_pass
->quad_list
.size());
710 const QuadList
& quad_list
= main_pass
->quad_list
;
711 for (QuadList::ConstBackToFrontIterator it
= quad_list
.BackToFrontBegin();
712 it
!= quad_list
.BackToFrontEnd();
714 EXPECT_NE(DrawQuad::TEXTURE_CONTENT
, it
->material
);
717 // Check that the right resource id got extracted.
718 EXPECT_EQ(original_resource_id
, candidate_list
.back().resource_id
);
721 TEST_F(SingleOverlayOnTopTest
, NoCandidates
) {
722 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
723 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
724 pass
->shared_quad_state_list
.back(), pass
.get());
725 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
726 pass
->shared_quad_state_list
.back(), pass
.get());
728 RenderPassList pass_list
;
729 pass_list
.push_back(pass
.Pass());
731 RenderPassList original_pass_list
;
732 RenderPass::CopyAll(pass_list
, &original_pass_list
);
734 OverlayCandidateList candidate_list
;
735 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
736 EXPECT_EQ(0U, candidate_list
.size());
737 // There should be nothing new here.
738 CompareRenderPassLists(pass_list
, original_pass_list
);
741 TEST_F(SingleOverlayOnTopTest
, OccludedCandidates
) {
742 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
743 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
744 pass
->shared_quad_state_list
.back(), pass
.get());
745 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
746 pass
->shared_quad_state_list
.back(), pass
.get());
748 CreateFullscreenCandidateQuad(resource_provider_
.get(),
749 pass
->shared_quad_state_list
.back(),
752 RenderPassList pass_list
;
753 pass_list
.push_back(pass
.Pass());
755 RenderPassList original_pass_list
;
756 RenderPass::CopyAll(pass_list
, &original_pass_list
);
758 OverlayCandidateList candidate_list
;
759 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
760 EXPECT_EQ(0U, candidate_list
.size());
761 // There should be nothing new here.
762 CompareRenderPassLists(pass_list
, original_pass_list
);
765 // Test with multiple render passes.
766 TEST_F(SingleOverlayOnTopTest
, MultipleRenderPasses
) {
767 RenderPassList pass_list
;
768 pass_list
.push_back(CreateRenderPass());
770 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
771 CreateFullscreenCandidateQuad(resource_provider_
.get(),
772 pass
->shared_quad_state_list
.back(),
775 // Add something behind it.
776 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
777 pass
->shared_quad_state_list
.back(), pass
.get());
778 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
779 pass
->shared_quad_state_list
.back(), pass
.get());
781 pass_list
.push_back(pass
.Pass());
783 RenderPassList original_pass_list
;
784 RenderPass::CopyAll(pass_list
, &original_pass_list
);
786 // Check for potential candidates.
787 OverlayCandidateList candidate_list
;
788 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
789 EXPECT_EQ(2U, candidate_list
.size());
791 // This should be the same.
792 ASSERT_EQ(2U, pass_list
.size());
795 TEST_F(SingleOverlayOnTopTest
, RejectPremultipliedAlpha
) {
796 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
797 TextureDrawQuad
* quad
=
798 CreateFullscreenCandidateQuad(resource_provider_
.get(),
799 pass
->shared_quad_state_list
.back(),
801 quad
->premultiplied_alpha
= true;
803 RenderPassList pass_list
;
804 pass_list
.push_back(pass
.Pass());
805 OverlayCandidateList candidate_list
;
806 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
807 EXPECT_EQ(1U, pass_list
.size());
808 EXPECT_EQ(0U, candidate_list
.size());
811 TEST_F(SingleOverlayOnTopTest
, RejectBlending
) {
812 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
813 TextureDrawQuad
* quad
=
814 CreateFullscreenCandidateQuad(resource_provider_
.get(),
815 pass
->shared_quad_state_list
.back(),
817 quad
->needs_blending
= true;
819 RenderPassList pass_list
;
820 pass_list
.push_back(pass
.Pass());
821 OverlayCandidateList candidate_list
;
822 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
823 ASSERT_EQ(1U, pass_list
.size());
824 EXPECT_EQ(0U, candidate_list
.size());
827 TEST_F(SingleOverlayOnTopTest
, RejectBackgroundColor
) {
828 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
829 TextureDrawQuad
* quad
=
830 CreateFullscreenCandidateQuad(resource_provider_
.get(),
831 pass
->shared_quad_state_list
.back(),
833 quad
->background_color
= SK_ColorBLACK
;
835 RenderPassList pass_list
;
836 pass_list
.push_back(pass
.Pass());
837 OverlayCandidateList candidate_list
;
838 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
839 ASSERT_EQ(1U, pass_list
.size());
840 EXPECT_EQ(0U, candidate_list
.size());
843 TEST_F(SingleOverlayOnTopTest
, RejectBlendMode
) {
844 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
845 CreateFullscreenCandidateQuad(resource_provider_
.get(),
846 pass
->shared_quad_state_list
.back(),
848 pass
->shared_quad_state_list
.back()->blend_mode
= SkXfermode::kScreen_Mode
;
850 RenderPassList pass_list
;
851 pass_list
.push_back(pass
.Pass());
852 OverlayCandidateList candidate_list
;
853 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
854 ASSERT_EQ(1U, pass_list
.size());
855 EXPECT_EQ(0U, candidate_list
.size());
858 TEST_F(SingleOverlayOnTopTest
, RejectOpacity
) {
859 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
860 CreateFullscreenCandidateQuad(resource_provider_
.get(),
861 pass
->shared_quad_state_list
.back(),
863 pass
->shared_quad_state_list
.back()->opacity
= 0.5f
;
865 RenderPassList pass_list
;
866 pass_list
.push_back(pass
.Pass());
867 OverlayCandidateList candidate_list
;
868 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
869 ASSERT_EQ(1U, pass_list
.size());
870 EXPECT_EQ(0U, candidate_list
.size());
873 TEST_F(SingleOverlayOnTopTest
, RejectNonAxisAlignedTransform
) {
874 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
875 CreateFullscreenCandidateQuad(resource_provider_
.get(),
876 pass
->shared_quad_state_list
.back(),
878 pass
->shared_quad_state_list
.back()
879 ->quad_to_target_transform
.RotateAboutXAxis(45.f
);
881 RenderPassList pass_list
;
882 pass_list
.push_back(pass
.Pass());
883 OverlayCandidateList candidate_list
;
884 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
885 ASSERT_EQ(1U, pass_list
.size());
886 EXPECT_EQ(0U, candidate_list
.size());
889 TEST_F(SingleOverlayOnTopTest
, AllowClipped
) {
890 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
891 CreateFullscreenCandidateQuad(resource_provider_
.get(),
892 pass
->shared_quad_state_list
.back(),
894 pass
->shared_quad_state_list
.back()->is_clipped
= true;
895 pass
->shared_quad_state_list
.back()->clip_rect
= kOverlayClipRect
;
897 RenderPassList pass_list
;
898 pass_list
.push_back(pass
.Pass());
899 OverlayCandidateList candidate_list
;
900 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
901 ASSERT_EQ(1U, pass_list
.size());
902 EXPECT_EQ(2U, candidate_list
.size());
905 TEST_F(SingleOverlayOnTopTest
, AllowVerticalFlip
) {
906 gfx::Rect rect
= kOverlayRect
;
907 rect
.set_width(rect
.width() / 2);
908 rect
.Offset(0, -rect
.height());
909 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
910 CreateCandidateQuadAt(resource_provider_
.get(),
911 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
912 pass
->shared_quad_state_list
.back()->quad_to_target_transform
.Scale(2.0f
,
915 RenderPassList pass_list
;
916 pass_list
.push_back(pass
.Pass());
917 OverlayCandidateList candidate_list
;
918 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
919 ASSERT_EQ(1U, pass_list
.size());
920 ASSERT_EQ(2U, candidate_list
.size());
921 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
,
922 candidate_list
.back().transform
);
925 TEST_F(SingleOverlayOnTopTest
, AllowHorizontalFlip
) {
926 gfx::Rect rect
= kOverlayRect
;
927 rect
.set_height(rect
.height() / 2);
928 rect
.Offset(-rect
.width(), 0);
929 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
930 CreateCandidateQuadAt(resource_provider_
.get(),
931 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
932 pass
->shared_quad_state_list
.back()->quad_to_target_transform
.Scale(-1.0f
,
935 RenderPassList pass_list
;
936 pass_list
.push_back(pass
.Pass());
937 OverlayCandidateList candidate_list
;
938 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
939 ASSERT_EQ(1U, pass_list
.size());
940 ASSERT_EQ(2U, candidate_list
.size());
941 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
,
942 candidate_list
.back().transform
);
945 TEST_F(SingleOverlayOnTopTest
, AllowPositiveScaleTransform
) {
946 gfx::Rect rect
= kOverlayRect
;
947 rect
.set_width(rect
.width() / 2);
948 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
949 CreateCandidateQuadAt(resource_provider_
.get(),
950 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
951 pass
->shared_quad_state_list
.back()->quad_to_target_transform
.Scale(2.0f
,
954 RenderPassList pass_list
;
955 pass_list
.push_back(pass
.Pass());
956 OverlayCandidateList candidate_list
;
957 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
958 ASSERT_EQ(1U, pass_list
.size());
959 EXPECT_EQ(2U, candidate_list
.size());
962 TEST_F(SingleOverlayOnTopTest
, Allow90DegreeRotation
) {
963 gfx::Rect rect
= kOverlayRect
;
964 rect
.Offset(0, -rect
.height());
965 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
966 CreateCandidateQuadAt(resource_provider_
.get(),
967 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
968 pass
->shared_quad_state_list
.back()
969 ->quad_to_target_transform
.RotateAboutZAxis(90.f
);
971 RenderPassList pass_list
;
972 pass_list
.push_back(pass
.Pass());
973 OverlayCandidateList candidate_list
;
974 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
975 ASSERT_EQ(1U, pass_list
.size());
976 ASSERT_EQ(2U, candidate_list
.size());
977 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_90
, candidate_list
.back().transform
);
980 TEST_F(SingleOverlayOnTopTest
, Allow180DegreeRotation
) {
981 gfx::Rect rect
= kOverlayRect
;
982 rect
.Offset(-rect
.width(), -rect
.height());
983 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
984 CreateCandidateQuadAt(resource_provider_
.get(),
985 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
986 pass
->shared_quad_state_list
.back()
987 ->quad_to_target_transform
.RotateAboutZAxis(180.f
);
989 RenderPassList pass_list
;
990 pass_list
.push_back(pass
.Pass());
991 OverlayCandidateList candidate_list
;
992 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
993 ASSERT_EQ(1U, pass_list
.size());
994 ASSERT_EQ(2U, candidate_list
.size());
995 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_180
, candidate_list
.back().transform
);
998 TEST_F(SingleOverlayOnTopTest
, Allow270DegreeRotation
) {
999 gfx::Rect rect
= kOverlayRect
;
1000 rect
.Offset(-rect
.width(), 0);
1001 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1002 CreateCandidateQuadAt(resource_provider_
.get(),
1003 pass
->shared_quad_state_list
.back(), pass
.get(), rect
);
1004 pass
->shared_quad_state_list
.back()
1005 ->quad_to_target_transform
.RotateAboutZAxis(270.f
);
1007 RenderPassList pass_list
;
1008 pass_list
.push_back(pass
.Pass());
1009 OverlayCandidateList candidate_list
;
1010 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1011 ASSERT_EQ(1U, pass_list
.size());
1012 ASSERT_EQ(2U, candidate_list
.size());
1013 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_270
, candidate_list
.back().transform
);
1016 TEST_F(SingleOverlayOnTopTest
, AllowNotTopIfNotOccluded
) {
1017 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1018 CreateOpaqueQuadAt(resource_provider_
.get(),
1019 pass
->shared_quad_state_list
.back(), pass
.get(),
1020 kOverlayTopLeftRect
);
1021 CreateCandidateQuadAt(resource_provider_
.get(),
1022 pass
->shared_quad_state_list
.back(),
1024 kOverlayBottomRightRect
);
1026 RenderPassList pass_list
;
1027 pass_list
.push_back(pass
.Pass());
1029 RenderPassList original_pass_list
;
1030 RenderPass::CopyAll(pass_list
, &original_pass_list
);
1032 OverlayCandidateList candidate_list
;
1033 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1034 EXPECT_EQ(1U, pass_list
.size());
1035 EXPECT_EQ(2U, candidate_list
.size());
1038 TEST_F(SingleOverlayOnTopTest
, AllowTransparentOnTop
) {
1039 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1040 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
1041 shared_state
->opacity
= 0.f
;
1042 CreateSolidColorQuadAt(shared_state
, SK_ColorBLACK
, pass
.get(),
1043 kOverlayBottomRightRect
);
1044 shared_state
= pass
->CreateAndAppendSharedQuadState();
1045 shared_state
->opacity
= 1.f
;
1046 CreateCandidateQuadAt(resource_provider_
.get(), shared_state
, pass
.get(),
1047 kOverlayBottomRightRect
);
1049 RenderPassList pass_list
;
1050 pass_list
.push_back(pass
.Pass());
1052 RenderPassList original_pass_list
;
1053 RenderPass::CopyAll(pass_list
, &original_pass_list
);
1055 OverlayCandidateList candidate_list
;
1056 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1057 EXPECT_EQ(1U, pass_list
.size());
1058 EXPECT_EQ(2U, candidate_list
.size());
1061 TEST_F(SingleOverlayOnTopTest
, AllowTransparentColorOnTop
) {
1062 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1063 CreateSolidColorQuadAt(pass
->shared_quad_state_list
.back(),
1064 SK_ColorTRANSPARENT
, pass
.get(),
1065 kOverlayBottomRightRect
);
1066 CreateCandidateQuadAt(resource_provider_
.get(),
1067 pass
->shared_quad_state_list
.back(), pass
.get(),
1068 kOverlayBottomRightRect
);
1070 RenderPassList pass_list
;
1071 pass_list
.push_back(pass
.Pass());
1073 RenderPassList original_pass_list
;
1074 RenderPass::CopyAll(pass_list
, &original_pass_list
);
1076 OverlayCandidateList candidate_list
;
1077 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1078 EXPECT_EQ(1U, pass_list
.size());
1079 EXPECT_EQ(2U, candidate_list
.size());
1082 TEST_F(SingleOverlayOnTopTest
, RejectOpaqueColorOnTop
) {
1083 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1084 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
1085 shared_state
->opacity
= 0.5f
;
1086 CreateSolidColorQuadAt(shared_state
, SK_ColorBLACK
, pass
.get(),
1087 kOverlayBottomRightRect
);
1088 shared_state
= pass
->CreateAndAppendSharedQuadState();
1089 shared_state
->opacity
= 1.f
;
1090 CreateCandidateQuadAt(resource_provider_
.get(), shared_state
, pass
.get(),
1091 kOverlayBottomRightRect
);
1093 RenderPassList pass_list
;
1094 pass_list
.push_back(pass
.Pass());
1096 RenderPassList original_pass_list
;
1097 RenderPass::CopyAll(pass_list
, &original_pass_list
);
1099 OverlayCandidateList candidate_list
;
1100 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1101 EXPECT_EQ(1U, pass_list
.size());
1102 EXPECT_EQ(0U, candidate_list
.size());
1105 TEST_F(SingleOverlayOnTopTest
, RejectTransparentColorOnTopWithoutBlending
) {
1106 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1107 SharedQuadState
* shared_state
= pass
->CreateAndAppendSharedQuadState();
1108 CreateSolidColorQuadAt(shared_state
, SK_ColorTRANSPARENT
, pass
.get(),
1109 kOverlayBottomRightRect
)->opaque_rect
=
1110 kOverlayBottomRightRect
;
1111 CreateCandidateQuadAt(resource_provider_
.get(), shared_state
, pass
.get(),
1112 kOverlayBottomRightRect
);
1114 RenderPassList pass_list
;
1115 pass_list
.push_back(pass
.Pass());
1117 RenderPassList original_pass_list
;
1118 RenderPass::CopyAll(pass_list
, &original_pass_list
);
1120 OverlayCandidateList candidate_list
;
1121 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1122 EXPECT_EQ(1U, pass_list
.size());
1123 EXPECT_EQ(0U, candidate_list
.size());
1126 TEST_F(SingleOverlayOnTopTest
, RejectVideoSwapTransform
) {
1127 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1128 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
1129 pass
->shared_quad_state_list
.back(),
1130 pass
.get(), kSwapTransform
);
1132 RenderPassList pass_list
;
1133 pass_list
.push_back(pass
.Pass());
1134 OverlayCandidateList candidate_list
;
1135 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1136 ASSERT_EQ(1U, pass_list
.size());
1137 EXPECT_EQ(0U, candidate_list
.size());
1140 TEST_F(SingleOverlayOnTopTest
, AllowVideoXMirrorTransform
) {
1141 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1142 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
1143 pass
->shared_quad_state_list
.back(),
1144 pass
.get(), kXMirrorTransform
);
1146 RenderPassList pass_list
;
1147 pass_list
.push_back(pass
.Pass());
1148 OverlayCandidateList candidate_list
;
1149 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1150 ASSERT_EQ(1U, pass_list
.size());
1151 EXPECT_EQ(2U, candidate_list
.size());
1154 TEST_F(SingleOverlayOnTopTest
, AllowVideoBothMirrorTransform
) {
1155 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1156 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
1157 pass
->shared_quad_state_list
.back(),
1158 pass
.get(), kBothMirrorTransform
);
1160 RenderPassList pass_list
;
1161 pass_list
.push_back(pass
.Pass());
1162 OverlayCandidateList candidate_list
;
1163 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1164 ASSERT_EQ(1U, pass_list
.size());
1165 EXPECT_EQ(2U, candidate_list
.size());
1168 TEST_F(SingleOverlayOnTopTest
, AllowVideoNormalTransform
) {
1169 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1170 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
1171 pass
->shared_quad_state_list
.back(),
1172 pass
.get(), kNormalTransform
);
1174 RenderPassList pass_list
;
1175 pass_list
.push_back(pass
.Pass());
1176 OverlayCandidateList candidate_list
;
1177 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1178 ASSERT_EQ(1U, pass_list
.size());
1179 EXPECT_EQ(2U, candidate_list
.size());
1182 TEST_F(SingleOverlayOnTopTest
, AllowVideoYMirrorTransform
) {
1183 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1184 CreateFullscreenCandidateVideoQuad(resource_provider_
.get(),
1185 pass
->shared_quad_state_list
.back(),
1186 pass
.get(), kYMirrorTransform
);
1188 RenderPassList pass_list
;
1189 pass_list
.push_back(pass
.Pass());
1190 OverlayCandidateList candidate_list
;
1191 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1192 ASSERT_EQ(1U, pass_list
.size());
1193 EXPECT_EQ(2U, candidate_list
.size());
1196 TEST_F(UnderlayTest
, OverlayLayerUnderMainLayer
) {
1197 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1198 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1199 pass
->shared_quad_state_list
.back(), pass
.get());
1200 CreateCandidateQuadAt(resource_provider_
.get(),
1201 pass
->shared_quad_state_list
.back(), pass
.get(),
1202 kOverlayBottomRightRect
);
1204 RenderPassList pass_list
;
1205 pass_list
.push_back(pass
.Pass());
1207 OverlayCandidateList candidate_list
;
1208 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1209 EXPECT_EQ(1U, pass_list
.size());
1210 ASSERT_EQ(2U, candidate_list
.size());
1211 EXPECT_EQ(0, candidate_list
[0].plane_z_order
);
1212 EXPECT_EQ(-1, candidate_list
[1].plane_z_order
);
1213 EXPECT_EQ(2U, pass_list
[0]->quad_list
.size());
1214 // The overlay quad should have changed to a SOLID_COLOR quad.
1215 EXPECT_EQ(pass_list
[0]->quad_list
.back()->material
, DrawQuad::SOLID_COLOR
);
1218 TEST_F(UnderlayTest
, AllowOnTop
) {
1219 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1220 CreateFullscreenCandidateQuad(resource_provider_
.get(),
1221 pass
->shared_quad_state_list
.back(),
1223 pass
->CreateAndAppendSharedQuadState()->opacity
= 0.5f
;
1224 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1225 pass
->shared_quad_state_list
.back(), pass
.get());
1227 RenderPassList pass_list
;
1228 pass_list
.push_back(pass
.Pass());
1230 OverlayCandidateList candidate_list
;
1231 overlay_processor_
->ProcessForOverlays(&pass_list
, &candidate_list
);
1232 EXPECT_EQ(1U, pass_list
.size());
1233 ASSERT_EQ(2U, candidate_list
.size());
1234 EXPECT_EQ(0, candidate_list
[0].plane_z_order
);
1235 EXPECT_EQ(-1, candidate_list
[1].plane_z_order
);
1236 // The overlay quad should have changed to a SOLID_COLOR quad.
1237 EXPECT_EQ(pass_list
[0]->quad_list
.front()->material
, DrawQuad::SOLID_COLOR
);
1240 class OverlayInfoRendererGL
: public GLRenderer
{
1242 OverlayInfoRendererGL(RendererClient
* client
,
1243 const RendererSettings
* settings
,
1244 OutputSurface
* output_surface
,
1245 ResourceProvider
* resource_provider
)
1246 : GLRenderer(client
,
1252 expect_overlays_(false) {}
1254 MOCK_METHOD3(DoDrawQuad
,
1255 void(DrawingFrame
* frame
,
1256 const DrawQuad
* quad
,
1257 const gfx::QuadF
* draw_region
));
1259 using GLRenderer::BeginDrawingFrame
;
1261 void FinishDrawingFrame(DrawingFrame
* frame
) override
{
1262 GLRenderer::FinishDrawingFrame(frame
);
1264 if (!expect_overlays_
) {
1265 EXPECT_EQ(0U, frame
->overlay_list
.size());
1269 ASSERT_EQ(2U, frame
->overlay_list
.size());
1270 EXPECT_NE(0U, frame
->overlay_list
.back().resource_id
);
1273 void set_expect_overlays(bool expect_overlays
) {
1274 expect_overlays_
= expect_overlays
;
1278 bool expect_overlays_
;
1281 class FakeRendererClient
: public RendererClient
{
1283 // RendererClient methods.
1284 void SetFullRootLayerDamage() override
{}
1287 class MockOverlayScheduler
{
1289 MOCK_METHOD5(Schedule
,
1290 void(int plane_z_order
,
1291 gfx::OverlayTransform plane_transform
,
1292 unsigned overlay_texture_id
,
1293 const gfx::Rect
& display_bounds
,
1294 const gfx::RectF
& uv_rect
));
1297 class GLRendererWithOverlaysTest
: public testing::Test
{
1299 GLRendererWithOverlaysTest() {
1300 provider_
= TestContextProvider::Create();
1301 output_surface_
.reset(new OverlayOutputSurface(provider_
));
1302 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
1303 resource_provider_
=
1304 FakeResourceProvider::Create(output_surface_
.get(), nullptr);
1306 provider_
->support()->SetScheduleOverlayPlaneCallback(base::Bind(
1307 &MockOverlayScheduler::Schedule
, base::Unretained(&scheduler_
)));
1310 void Init(bool use_validator
) {
1312 output_surface_
->InitWithSingleOverlayValidator();
1315 make_scoped_ptr(new OverlayInfoRendererGL(&renderer_client_
,
1317 output_surface_
.get(),
1318 resource_provider_
.get()));
1321 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
1323 RendererSettings settings_
;
1324 FakeOutputSurfaceClient output_surface_client_
;
1325 scoped_ptr
<OverlayOutputSurface
> output_surface_
;
1326 FakeRendererClient renderer_client_
;
1327 scoped_ptr
<ResourceProvider
> resource_provider_
;
1328 scoped_ptr
<OverlayInfoRendererGL
> renderer_
;
1329 scoped_refptr
<TestContextProvider
> provider_
;
1330 MockOverlayScheduler scheduler_
;
1333 TEST_F(GLRendererWithOverlaysTest
, OverlayQuadNotDrawn
) {
1334 bool use_validator
= true;
1335 Init(use_validator
);
1336 renderer_
->set_expect_overlays(true);
1337 gfx::Rect
viewport_rect(16, 16);
1339 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1341 CreateFullscreenCandidateQuad(resource_provider_
.get(),
1342 pass
->shared_quad_state_list
.back(),
1345 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1346 pass
->shared_quad_state_list
.back(), pass
.get());
1347 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1348 pass
->shared_quad_state_list
.back(), pass
.get());
1350 RenderPassList pass_list
;
1351 pass_list
.push_back(pass
.Pass());
1353 // Candidate pass was taken out and extra skipped pass added,
1354 // so only draw 2 quads.
1355 EXPECT_CALL(*renderer_
, DoDrawQuad(_
, _
, _
)).Times(2);
1356 EXPECT_CALL(scheduler_
,
1358 gfx::OVERLAY_TRANSFORM_NONE
,
1361 BoundingRect(kUVTopLeft
, kUVBottomRight
))).Times(1);
1362 renderer_
->DrawFrame(&pass_list
, 1.f
, viewport_rect
, viewport_rect
, false);
1366 Mock::VerifyAndClearExpectations(renderer_
.get());
1367 Mock::VerifyAndClearExpectations(&scheduler_
);
1370 TEST_F(GLRendererWithOverlaysTest
, OccludedQuadInUnderlay
) {
1371 bool use_validator
= true;
1372 Init(use_validator
);
1373 renderer_
->set_expect_overlays(true);
1374 gfx::Rect
viewport_rect(16, 16);
1376 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1378 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1379 pass
->shared_quad_state_list
.back(), pass
.get());
1380 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1381 pass
->shared_quad_state_list
.back(), pass
.get());
1383 CreateFullscreenCandidateQuad(resource_provider_
.get(),
1384 pass
->shared_quad_state_list
.back(),
1387 RenderPassList pass_list
;
1388 pass_list
.push_back(pass
.Pass());
1390 // Candidate quad should fail to be overlaid on top because of occlusion.
1391 // Expect to be replaced with transparent hole quad and placed in underlay.
1392 EXPECT_CALL(*renderer_
, DoDrawQuad(_
, _
, _
)).Times(3);
1393 EXPECT_CALL(scheduler_
,
1394 Schedule(-1, gfx::OVERLAY_TRANSFORM_NONE
, _
, kOverlayRect
,
1395 BoundingRect(kUVTopLeft
, kUVBottomRight
))).Times(1);
1396 renderer_
->DrawFrame(&pass_list
, 1.f
, viewport_rect
, viewport_rect
, false);
1400 Mock::VerifyAndClearExpectations(renderer_
.get());
1401 Mock::VerifyAndClearExpectations(&scheduler_
);
1404 TEST_F(GLRendererWithOverlaysTest
, NoValidatorNoOverlay
) {
1405 bool use_validator
= false;
1406 Init(use_validator
);
1407 renderer_
->set_expect_overlays(false);
1408 gfx::Rect
viewport_rect(16, 16);
1410 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1412 CreateFullscreenCandidateQuad(resource_provider_
.get(),
1413 pass
->shared_quad_state_list
.back(),
1416 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1417 pass
->shared_quad_state_list
.back(), pass
.get());
1418 CreateFullscreenOpaqueQuad(resource_provider_
.get(),
1419 pass
->shared_quad_state_list
.back(), pass
.get());
1421 RenderPassList pass_list
;
1422 pass_list
.push_back(pass
.Pass());
1424 // Should see no overlays.
1425 EXPECT_CALL(*renderer_
, DoDrawQuad(_
, _
, _
)).Times(3);
1426 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1427 renderer_
->DrawFrame(&pass_list
, 1.f
, viewport_rect
, viewport_rect
, false);
1431 Mock::VerifyAndClearExpectations(renderer_
.get());
1432 Mock::VerifyAndClearExpectations(&scheduler_
);
1435 TEST_F(GLRendererWithOverlaysTest
, ResourcesExportedAndReturned
) {
1436 bool use_validator
= true;
1437 Init(use_validator
);
1438 renderer_
->set_expect_overlays(true);
1440 ResourceId resource1
= CreateResource(resource_provider_
.get());
1441 ResourceId resource2
= CreateResource(resource_provider_
.get());
1443 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1444 RenderPassList pass_list
;
1445 pass_list
.push_back(pass
.Pass());
1447 DirectRenderer::DrawingFrame frame1
;
1448 frame1
.render_passes_in_draw_order
= &pass_list
;
1449 frame1
.overlay_list
.resize(2);
1450 OverlayCandidate
& overlay1
= frame1
.overlay_list
.back();
1451 overlay1
.resource_id
= resource1
;
1452 overlay1
.plane_z_order
= 1;
1454 DirectRenderer::DrawingFrame frame2
;
1455 frame2
.render_passes_in_draw_order
= &pass_list
;
1456 frame2
.overlay_list
.resize(2);
1457 OverlayCandidate
& overlay2
= frame2
.overlay_list
.back();
1458 overlay2
.resource_id
= resource2
;
1459 overlay2
.plane_z_order
= 1;
1461 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1462 renderer_
->BeginDrawingFrame(&frame1
);
1463 renderer_
->FinishDrawingFrame(&frame1
);
1464 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1465 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1467 Mock::VerifyAndClearExpectations(&scheduler_
);
1469 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1470 renderer_
->BeginDrawingFrame(&frame2
);
1471 renderer_
->FinishDrawingFrame(&frame2
);
1472 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1473 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource2
));
1475 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1476 Mock::VerifyAndClearExpectations(&scheduler_
);
1478 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1479 renderer_
->BeginDrawingFrame(&frame1
);
1480 renderer_
->FinishDrawingFrame(&frame1
);
1481 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1482 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource2
));
1484 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1485 Mock::VerifyAndClearExpectations(&scheduler_
);
1487 // No overlays, release the resource.
1488 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1489 DirectRenderer::DrawingFrame frame3
;
1490 frame3
.render_passes_in_draw_order
= &pass_list
;
1491 renderer_
->set_expect_overlays(false);
1492 renderer_
->BeginDrawingFrame(&frame3
);
1493 renderer_
->FinishDrawingFrame(&frame3
);
1494 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1495 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1497 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1498 Mock::VerifyAndClearExpectations(&scheduler_
);
1500 // Use the same buffer twice.
1501 renderer_
->set_expect_overlays(true);
1502 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1503 renderer_
->BeginDrawingFrame(&frame1
);
1504 renderer_
->FinishDrawingFrame(&frame1
);
1505 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1507 Mock::VerifyAndClearExpectations(&scheduler_
);
1509 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1510 renderer_
->BeginDrawingFrame(&frame1
);
1511 renderer_
->FinishDrawingFrame(&frame1
);
1512 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1514 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1515 Mock::VerifyAndClearExpectations(&scheduler_
);
1517 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1518 renderer_
->set_expect_overlays(false);
1519 renderer_
->BeginDrawingFrame(&frame3
);
1520 renderer_
->FinishDrawingFrame(&frame3
);
1521 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1523 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1524 Mock::VerifyAndClearExpectations(&scheduler_
);
1527 TEST_F(GLRendererWithOverlaysTest
, ResourcesExportedAndReturnedWithDelay
) {
1528 bool use_validator
= true;
1529 settings_
.delay_releasing_overlay_resources
= true;
1530 Init(use_validator
);
1531 renderer_
->set_expect_overlays(true);
1533 ResourceId resource1
= CreateResource(resource_provider_
.get());
1534 ResourceId resource2
= CreateResource(resource_provider_
.get());
1535 ResourceId resource3
= CreateResource(resource_provider_
.get());
1537 scoped_ptr
<RenderPass
> pass
= CreateRenderPass();
1538 RenderPassList pass_list
;
1539 pass_list
.push_back(pass
.Pass());
1541 DirectRenderer::DrawingFrame frame1
;
1542 frame1
.render_passes_in_draw_order
= &pass_list
;
1543 frame1
.overlay_list
.resize(2);
1544 OverlayCandidate
& overlay1
= frame1
.overlay_list
.back();
1545 overlay1
.resource_id
= resource1
;
1546 overlay1
.plane_z_order
= 1;
1548 DirectRenderer::DrawingFrame frame2
;
1549 frame2
.render_passes_in_draw_order
= &pass_list
;
1550 frame2
.overlay_list
.resize(2);
1551 OverlayCandidate
& overlay2
= frame2
.overlay_list
.back();
1552 overlay2
.resource_id
= resource2
;
1553 overlay2
.plane_z_order
= 1;
1555 DirectRenderer::DrawingFrame frame3
;
1556 frame3
.render_passes_in_draw_order
= &pass_list
;
1557 frame3
.overlay_list
.resize(2);
1558 OverlayCandidate
& overlay3
= frame3
.overlay_list
.back();
1559 overlay3
.resource_id
= resource3
;
1560 overlay3
.plane_z_order
= 1;
1562 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1563 renderer_
->BeginDrawingFrame(&frame1
);
1564 renderer_
->FinishDrawingFrame(&frame1
);
1565 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1566 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1568 Mock::VerifyAndClearExpectations(&scheduler_
);
1570 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1571 renderer_
->BeginDrawingFrame(&frame2
);
1572 renderer_
->FinishDrawingFrame(&frame2
);
1573 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1574 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource2
));
1576 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1577 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource2
));
1578 Mock::VerifyAndClearExpectations(&scheduler_
);
1580 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1581 renderer_
->BeginDrawingFrame(&frame3
);
1582 renderer_
->FinishDrawingFrame(&frame3
);
1583 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1584 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource2
));
1585 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource3
));
1587 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1588 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource2
));
1589 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource3
));
1590 Mock::VerifyAndClearExpectations(&scheduler_
);
1592 // No overlays, release the resource.
1593 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1594 DirectRenderer::DrawingFrame frame_no_overlays
;
1595 frame_no_overlays
.render_passes_in_draw_order
= &pass_list
;
1596 renderer_
->set_expect_overlays(false);
1597 renderer_
->BeginDrawingFrame(&frame_no_overlays
);
1598 renderer_
->FinishDrawingFrame(&frame_no_overlays
);
1599 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1600 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource2
));
1601 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource3
));
1603 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1604 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource2
));
1605 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource3
));
1606 Mock::VerifyAndClearExpectations(&scheduler_
);
1608 // Use the same buffer twice.
1609 renderer_
->set_expect_overlays(true);
1610 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1611 renderer_
->BeginDrawingFrame(&frame1
);
1612 renderer_
->FinishDrawingFrame(&frame1
);
1613 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1615 Mock::VerifyAndClearExpectations(&scheduler_
);
1617 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(1);
1618 renderer_
->BeginDrawingFrame(&frame1
);
1619 renderer_
->FinishDrawingFrame(&frame1
);
1620 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1622 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1623 Mock::VerifyAndClearExpectations(&scheduler_
);
1625 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1626 renderer_
->set_expect_overlays(false);
1627 renderer_
->BeginDrawingFrame(&frame_no_overlays
);
1628 renderer_
->FinishDrawingFrame(&frame_no_overlays
);
1629 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1631 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1632 Mock::VerifyAndClearExpectations(&scheduler_
);
1634 EXPECT_CALL(scheduler_
, Schedule(_
, _
, _
, _
, _
)).Times(0);
1635 renderer_
->set_expect_overlays(false);
1636 renderer_
->BeginDrawingFrame(&frame_no_overlays
);
1637 renderer_
->FinishDrawingFrame(&frame_no_overlays
);
1638 EXPECT_TRUE(resource_provider_
->InUseByConsumer(resource1
));
1640 EXPECT_FALSE(resource_provider_
->InUseByConsumer(resource1
));
1641 Mock::VerifyAndClearExpectations(&scheduler_
);