Roll src/third_party/WebKit d10c917:a1123a1 (svn 198729:198730)
[chromium-blink-merge.git] / cc / output / overlay_unittest.cc
blob6ac9b1c64c8d849d5758c1b0df53e41f93bafa7a
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/base/scoped_ptr_vector.h"
6 #include "cc/output/compositor_frame_metadata.h"
7 #include "cc/output/gl_renderer.h"
8 #include "cc/output/output_surface.h"
9 #include "cc/output/output_surface_client.h"
10 #include "cc/output/overlay_candidate_validator.h"
11 #include "cc/output/overlay_processor.h"
12 #include "cc/output/overlay_strategy_single_on_top.h"
13 #include "cc/output/overlay_strategy_underlay.h"
14 #include "cc/quads/checkerboard_draw_quad.h"
15 #include "cc/quads/render_pass.h"
16 #include "cc/quads/stream_video_draw_quad.h"
17 #include "cc/quads/texture_draw_quad.h"
18 #include "cc/resources/resource_provider.h"
19 #include "cc/resources/texture_mailbox.h"
20 #include "cc/test/fake_output_surface_client.h"
21 #include "cc/test/fake_resource_provider.h"
22 #include "cc/test/geometry_test_utils.h"
23 #include "cc/test/test_context_provider.h"
24 #include "cc/test/test_shared_bitmap_manager.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
28 using testing::_;
29 using testing::Mock;
31 namespace cc {
32 namespace {
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,
51 bool lost_resource,
52 BlockingTaskRunner* main_thread_task_runner) {
55 class SingleOverlayValidator : public OverlayCandidateValidator {
56 public:
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);
67 } else {
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 {
80 public:
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 {
97 public:
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 {
111 public:
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();
126 private:
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();
141 pass->SetAll(id,
142 output_rect,
143 output_rect,
144 gfx::Transform(),
145 has_transparent_background);
147 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
148 shared_state->opacity = 1.f;
149 return pass.Pass();
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,
165 SkColor color,
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);
171 return quad;
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,
189 rect,
190 rect,
191 rect,
192 resource_id,
193 premultiplied_alpha,
194 kUVTopLeft,
195 kUVBottomRight,
196 SK_ColorTRANSPARENT,
197 vertex_opacity,
198 flipped,
199 nearest_neighbor);
200 overlay_quad->set_allow_overlay(allow_overlay);
201 overlay_quad->set_resource_size_in_pixels(resource_size_in_pixels);
203 return overlay_quad;
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);
221 return overlay_quad;
224 TextureDrawQuad* CreateFullscreenCandidateQuad(
225 ResourceProvider* resource_provider,
226 const SharedQuadState* shared_quad_state,
227 RenderPass* render_pass) {
228 return CreateCandidateQuadAt(
229 resource_provider, shared_quad_state, render_pass, kOverlayRect);
232 StreamVideoDrawQuad* CreateFullscreenCandidateVideoQuad(
233 ResourceProvider* resource_provider,
234 const SharedQuadState* shared_quad_state,
235 RenderPass* render_pass,
236 const gfx::Transform& transform) {
237 return CreateCandidateVideoQuadAt(resource_provider, shared_quad_state,
238 render_pass, kOverlayRect, transform);
241 void CreateCheckeredQuadAt(ResourceProvider* resource_provider,
242 const SharedQuadState* shared_quad_state,
243 RenderPass* render_pass,
244 const gfx::Rect& rect) {
245 CheckerboardDrawQuad* checkerboard_quad =
246 render_pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
247 checkerboard_quad->SetNew(shared_quad_state, rect, rect, SkColor(), 1.f);
250 void CreateFullscreenCheckeredQuad(ResourceProvider* resource_provider,
251 const SharedQuadState* shared_quad_state,
252 RenderPass* render_pass) {
253 CreateCheckeredQuadAt(
254 resource_provider, shared_quad_state, render_pass, kOverlayRect);
257 static void CompareRenderPassLists(const RenderPassList& expected_list,
258 const RenderPassList& actual_list) {
259 EXPECT_EQ(expected_list.size(), actual_list.size());
260 for (size_t i = 0; i < actual_list.size(); ++i) {
261 RenderPass* expected = expected_list[i];
262 RenderPass* actual = actual_list[i];
264 EXPECT_EQ(expected->id, actual->id);
265 EXPECT_EQ(expected->output_rect, actual->output_rect);
266 EXPECT_EQ(expected->transform_to_root_target,
267 actual->transform_to_root_target);
268 EXPECT_EQ(expected->damage_rect, actual->damage_rect);
269 EXPECT_EQ(expected->has_transparent_background,
270 actual->has_transparent_background);
272 EXPECT_EQ(expected->shared_quad_state_list.size(),
273 actual->shared_quad_state_list.size());
274 EXPECT_EQ(expected->quad_list.size(), actual->quad_list.size());
276 for (auto exp_iter = expected->quad_list.cbegin(),
277 act_iter = actual->quad_list.cbegin();
278 exp_iter != expected->quad_list.cend();
279 ++exp_iter, ++act_iter) {
280 EXPECT_EQ(exp_iter->rect.ToString(), act_iter->rect.ToString());
281 EXPECT_EQ(exp_iter->shared_quad_state->quad_layer_bounds.ToString(),
282 act_iter->shared_quad_state->quad_layer_bounds.ToString());
287 TEST(OverlayTest, NoOverlaysByDefault) {
288 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
289 OverlayOutputSurface output_surface(provider);
290 EXPECT_EQ(NULL, output_surface.GetOverlayCandidateValidator());
292 output_surface.InitWithSingleOverlayValidator();
293 EXPECT_TRUE(output_surface.GetOverlayCandidateValidator() != NULL);
296 TEST(OverlayTest, OverlaysProcessorHasStrategy) {
297 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
298 OverlayOutputSurface output_surface(provider);
299 FakeOutputSurfaceClient client;
300 EXPECT_TRUE(output_surface.BindToClient(&client));
301 output_surface.InitWithSingleOverlayValidator();
302 EXPECT_TRUE(output_surface.GetOverlayCandidateValidator() != NULL);
304 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
305 new TestSharedBitmapManager());
306 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
307 &output_surface, shared_bitmap_manager.get());
309 scoped_ptr<DefaultOverlayProcessor> overlay_processor(
310 new DefaultOverlayProcessor(&output_surface));
311 overlay_processor->Initialize();
312 EXPECT_GE(2U, overlay_processor->GetStrategyCount());
315 template <typename OverlayStrategyType>
316 class OverlayTest : public testing::Test {
317 protected:
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(),
350 pass.get());
351 unsigned original_resource_id = original_quad->resource_id();
353 // Add something behind it.
354 CreateFullscreenCheckeredQuad(resource_provider_.get(),
355 pass->shared_quad_state_list.back(),
356 pass.get());
357 CreateFullscreenCheckeredQuad(resource_provider_.get(),
358 pass->shared_quad_state_list.back(),
359 pass.get());
361 RenderPassList pass_list;
362 pass_list.push_back(pass.Pass());
364 // Check for potential candidates.
365 OverlayCandidateList candidate_list;
366 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
368 ASSERT_EQ(1U, pass_list.size());
369 ASSERT_EQ(2U, candidate_list.size());
371 RenderPass* main_pass = pass_list.back();
372 // Check that the quad is gone.
373 EXPECT_EQ(2U, main_pass->quad_list.size());
374 const QuadList& quad_list = main_pass->quad_list;
375 for (QuadList::ConstBackToFrontIterator it = quad_list.BackToFrontBegin();
376 it != quad_list.BackToFrontEnd();
377 ++it) {
378 EXPECT_NE(DrawQuad::TEXTURE_CONTENT, it->material);
381 // Check that the right resource id got extracted.
382 EXPECT_EQ(original_resource_id, candidate_list.back().resource_id);
385 TEST_F(SingleOverlayOnTopTest, NoCandidates) {
386 scoped_ptr<RenderPass> pass = CreateRenderPass();
387 CreateFullscreenCheckeredQuad(resource_provider_.get(),
388 pass->shared_quad_state_list.back(),
389 pass.get());
390 CreateFullscreenCheckeredQuad(resource_provider_.get(),
391 pass->shared_quad_state_list.back(),
392 pass.get());
394 RenderPassList pass_list;
395 pass_list.push_back(pass.Pass());
397 RenderPassList original_pass_list;
398 RenderPass::CopyAll(pass_list, &original_pass_list);
400 OverlayCandidateList candidate_list;
401 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
402 EXPECT_EQ(0U, candidate_list.size());
403 // There should be nothing new here.
404 CompareRenderPassLists(pass_list, original_pass_list);
407 TEST_F(SingleOverlayOnTopTest, OccludedCandidates) {
408 scoped_ptr<RenderPass> pass = CreateRenderPass();
409 CreateFullscreenCheckeredQuad(resource_provider_.get(),
410 pass->shared_quad_state_list.back(),
411 pass.get());
412 CreateFullscreenCheckeredQuad(resource_provider_.get(),
413 pass->shared_quad_state_list.back(),
414 pass.get());
416 CreateFullscreenCandidateQuad(resource_provider_.get(),
417 pass->shared_quad_state_list.back(),
418 pass.get());
420 RenderPassList pass_list;
421 pass_list.push_back(pass.Pass());
423 RenderPassList original_pass_list;
424 RenderPass::CopyAll(pass_list, &original_pass_list);
426 OverlayCandidateList candidate_list;
427 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
428 EXPECT_EQ(0U, candidate_list.size());
429 // There should be nothing new here.
430 CompareRenderPassLists(pass_list, original_pass_list);
433 // Test with multiple render passes.
434 TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) {
435 RenderPassList pass_list;
436 pass_list.push_back(CreateRenderPass());
438 scoped_ptr<RenderPass> pass = CreateRenderPass();
439 CreateFullscreenCandidateQuad(resource_provider_.get(),
440 pass->shared_quad_state_list.back(),
441 pass.get());
443 // Add something behind it.
444 CreateFullscreenCheckeredQuad(resource_provider_.get(),
445 pass->shared_quad_state_list.back(),
446 pass.get());
447 CreateFullscreenCheckeredQuad(resource_provider_.get(),
448 pass->shared_quad_state_list.back(),
449 pass.get());
451 pass_list.push_back(pass.Pass());
453 RenderPassList original_pass_list;
454 RenderPass::CopyAll(pass_list, &original_pass_list);
456 // Check for potential candidates.
457 OverlayCandidateList candidate_list;
458 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
459 EXPECT_EQ(2U, candidate_list.size());
461 // This should be the same.
462 ASSERT_EQ(2U, pass_list.size());
465 TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) {
466 scoped_ptr<RenderPass> pass = CreateRenderPass();
467 TextureDrawQuad* quad =
468 CreateFullscreenCandidateQuad(resource_provider_.get(),
469 pass->shared_quad_state_list.back(),
470 pass.get());
471 quad->premultiplied_alpha = true;
473 RenderPassList pass_list;
474 pass_list.push_back(pass.Pass());
475 OverlayCandidateList candidate_list;
476 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
477 EXPECT_EQ(1U, pass_list.size());
478 EXPECT_EQ(0U, candidate_list.size());
481 TEST_F(SingleOverlayOnTopTest, RejectBlending) {
482 scoped_ptr<RenderPass> pass = CreateRenderPass();
483 TextureDrawQuad* quad =
484 CreateFullscreenCandidateQuad(resource_provider_.get(),
485 pass->shared_quad_state_list.back(),
486 pass.get());
487 quad->needs_blending = true;
489 RenderPassList pass_list;
490 pass_list.push_back(pass.Pass());
491 OverlayCandidateList candidate_list;
492 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
493 ASSERT_EQ(1U, pass_list.size());
494 EXPECT_EQ(0U, candidate_list.size());
497 TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) {
498 scoped_ptr<RenderPass> pass = CreateRenderPass();
499 TextureDrawQuad* quad =
500 CreateFullscreenCandidateQuad(resource_provider_.get(),
501 pass->shared_quad_state_list.back(),
502 pass.get());
503 quad->background_color = SK_ColorBLACK;
505 RenderPassList pass_list;
506 pass_list.push_back(pass.Pass());
507 OverlayCandidateList candidate_list;
508 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
509 ASSERT_EQ(1U, pass_list.size());
510 EXPECT_EQ(0U, candidate_list.size());
513 TEST_F(SingleOverlayOnTopTest, RejectBlendMode) {
514 scoped_ptr<RenderPass> pass = CreateRenderPass();
515 CreateFullscreenCandidateQuad(resource_provider_.get(),
516 pass->shared_quad_state_list.back(),
517 pass.get());
518 pass->shared_quad_state_list.back()->blend_mode = SkXfermode::kScreen_Mode;
520 RenderPassList pass_list;
521 pass_list.push_back(pass.Pass());
522 OverlayCandidateList candidate_list;
523 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
524 ASSERT_EQ(1U, pass_list.size());
525 EXPECT_EQ(0U, candidate_list.size());
528 TEST_F(SingleOverlayOnTopTest, RejectOpacity) {
529 scoped_ptr<RenderPass> pass = CreateRenderPass();
530 CreateFullscreenCandidateQuad(resource_provider_.get(),
531 pass->shared_quad_state_list.back(),
532 pass.get());
533 pass->shared_quad_state_list.back()->opacity = 0.5f;
535 RenderPassList pass_list;
536 pass_list.push_back(pass.Pass());
537 OverlayCandidateList candidate_list;
538 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
539 ASSERT_EQ(1U, pass_list.size());
540 EXPECT_EQ(0U, candidate_list.size());
543 TEST_F(SingleOverlayOnTopTest, RejectNonAxisAlignedTransform) {
544 scoped_ptr<RenderPass> pass = CreateRenderPass();
545 CreateFullscreenCandidateQuad(resource_provider_.get(),
546 pass->shared_quad_state_list.back(),
547 pass.get());
548 pass->shared_quad_state_list.back()
549 ->quad_to_target_transform.RotateAboutXAxis(45.f);
551 RenderPassList pass_list;
552 pass_list.push_back(pass.Pass());
553 OverlayCandidateList candidate_list;
554 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
555 ASSERT_EQ(1U, pass_list.size());
556 EXPECT_EQ(0U, candidate_list.size());
559 TEST_F(SingleOverlayOnTopTest, AllowVerticalFlip) {
560 gfx::Rect rect = kOverlayRect;
561 rect.set_width(rect.width() / 2);
562 rect.Offset(0, -rect.height());
563 scoped_ptr<RenderPass> pass = CreateRenderPass();
564 CreateCandidateQuadAt(resource_provider_.get(),
565 pass->shared_quad_state_list.back(), pass.get(), rect);
566 pass->shared_quad_state_list.back()->quad_to_target_transform.Scale(2.0f,
567 -1.0f);
569 RenderPassList pass_list;
570 pass_list.push_back(pass.Pass());
571 OverlayCandidateList candidate_list;
572 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
573 ASSERT_EQ(1U, pass_list.size());
574 ASSERT_EQ(2U, candidate_list.size());
575 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL,
576 candidate_list.back().transform);
579 TEST_F(SingleOverlayOnTopTest, AllowHorizontalFlip) {
580 gfx::Rect rect = kOverlayRect;
581 rect.set_height(rect.height() / 2);
582 rect.Offset(-rect.width(), 0);
583 scoped_ptr<RenderPass> pass = CreateRenderPass();
584 CreateCandidateQuadAt(resource_provider_.get(),
585 pass->shared_quad_state_list.back(), pass.get(), rect);
586 pass->shared_quad_state_list.back()->quad_to_target_transform.Scale(-1.0f,
587 2.0f);
589 RenderPassList pass_list;
590 pass_list.push_back(pass.Pass());
591 OverlayCandidateList candidate_list;
592 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
593 ASSERT_EQ(1U, pass_list.size());
594 ASSERT_EQ(2U, candidate_list.size());
595 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL,
596 candidate_list.back().transform);
599 TEST_F(SingleOverlayOnTopTest, AllowPositiveScaleTransform) {
600 gfx::Rect rect = kOverlayRect;
601 rect.set_width(rect.width() / 2);
602 scoped_ptr<RenderPass> pass = CreateRenderPass();
603 CreateCandidateQuadAt(resource_provider_.get(),
604 pass->shared_quad_state_list.back(), pass.get(), rect);
605 pass->shared_quad_state_list.back()->quad_to_target_transform.Scale(2.0f,
606 1.0f);
608 RenderPassList pass_list;
609 pass_list.push_back(pass.Pass());
610 OverlayCandidateList candidate_list;
611 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
612 ASSERT_EQ(1U, pass_list.size());
613 EXPECT_EQ(2U, candidate_list.size());
616 TEST_F(SingleOverlayOnTopTest, Allow90DegreeRotation) {
617 gfx::Rect rect = kOverlayRect;
618 rect.Offset(0, -rect.height());
619 scoped_ptr<RenderPass> pass = CreateRenderPass();
620 CreateCandidateQuadAt(resource_provider_.get(),
621 pass->shared_quad_state_list.back(), pass.get(), rect);
622 pass->shared_quad_state_list.back()
623 ->quad_to_target_transform.RotateAboutZAxis(90.f);
625 RenderPassList pass_list;
626 pass_list.push_back(pass.Pass());
627 OverlayCandidateList candidate_list;
628 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
629 ASSERT_EQ(1U, pass_list.size());
630 ASSERT_EQ(2U, candidate_list.size());
631 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_90, candidate_list.back().transform);
634 TEST_F(SingleOverlayOnTopTest, Allow180DegreeRotation) {
635 gfx::Rect rect = kOverlayRect;
636 rect.Offset(-rect.width(), -rect.height());
637 scoped_ptr<RenderPass> pass = CreateRenderPass();
638 CreateCandidateQuadAt(resource_provider_.get(),
639 pass->shared_quad_state_list.back(), pass.get(), rect);
640 pass->shared_quad_state_list.back()
641 ->quad_to_target_transform.RotateAboutZAxis(180.f);
643 RenderPassList pass_list;
644 pass_list.push_back(pass.Pass());
645 OverlayCandidateList candidate_list;
646 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
647 ASSERT_EQ(1U, pass_list.size());
648 ASSERT_EQ(2U, candidate_list.size());
649 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_180, candidate_list.back().transform);
652 TEST_F(SingleOverlayOnTopTest, Allow270DegreeRotation) {
653 gfx::Rect rect = kOverlayRect;
654 rect.Offset(-rect.width(), 0);
655 scoped_ptr<RenderPass> pass = CreateRenderPass();
656 CreateCandidateQuadAt(resource_provider_.get(),
657 pass->shared_quad_state_list.back(), pass.get(), rect);
658 pass->shared_quad_state_list.back()
659 ->quad_to_target_transform.RotateAboutZAxis(270.f);
661 RenderPassList pass_list;
662 pass_list.push_back(pass.Pass());
663 OverlayCandidateList candidate_list;
664 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
665 ASSERT_EQ(1U, pass_list.size());
666 ASSERT_EQ(2U, candidate_list.size());
667 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_270, candidate_list.back().transform);
670 TEST_F(SingleOverlayOnTopTest, AllowNotTopIfNotOccluded) {
671 scoped_ptr<RenderPass> pass = CreateRenderPass();
672 CreateCheckeredQuadAt(resource_provider_.get(),
673 pass->shared_quad_state_list.back(),
674 pass.get(),
675 kOverlayTopLeftRect);
676 CreateCandidateQuadAt(resource_provider_.get(),
677 pass->shared_quad_state_list.back(),
678 pass.get(),
679 kOverlayBottomRightRect);
681 RenderPassList pass_list;
682 pass_list.push_back(pass.Pass());
684 RenderPassList original_pass_list;
685 RenderPass::CopyAll(pass_list, &original_pass_list);
687 OverlayCandidateList candidate_list;
688 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
689 EXPECT_EQ(1U, pass_list.size());
690 EXPECT_EQ(2U, candidate_list.size());
693 TEST_F(SingleOverlayOnTopTest, AllowTransparentOnTop) {
694 scoped_ptr<RenderPass> pass = CreateRenderPass();
695 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
696 shared_state->opacity = 0.f;
697 CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(),
698 kOverlayBottomRightRect);
699 shared_state = pass->CreateAndAppendSharedQuadState();
700 shared_state->opacity = 1.f;
701 CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
702 kOverlayBottomRightRect);
704 RenderPassList pass_list;
705 pass_list.push_back(pass.Pass());
707 RenderPassList original_pass_list;
708 RenderPass::CopyAll(pass_list, &original_pass_list);
710 OverlayCandidateList candidate_list;
711 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
712 EXPECT_EQ(1U, pass_list.size());
713 EXPECT_EQ(2U, candidate_list.size());
716 TEST_F(SingleOverlayOnTopTest, AllowTransparentColorOnTop) {
717 scoped_ptr<RenderPass> pass = CreateRenderPass();
718 CreateSolidColorQuadAt(pass->shared_quad_state_list.back(),
719 SK_ColorTRANSPARENT, pass.get(),
720 kOverlayBottomRightRect);
721 CreateCandidateQuadAt(resource_provider_.get(),
722 pass->shared_quad_state_list.back(), pass.get(),
723 kOverlayBottomRightRect);
725 RenderPassList pass_list;
726 pass_list.push_back(pass.Pass());
728 RenderPassList original_pass_list;
729 RenderPass::CopyAll(pass_list, &original_pass_list);
731 OverlayCandidateList candidate_list;
732 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
733 EXPECT_EQ(1U, pass_list.size());
734 EXPECT_EQ(2U, candidate_list.size());
737 TEST_F(SingleOverlayOnTopTest, RejectOpaqueColorOnTop) {
738 scoped_ptr<RenderPass> pass = CreateRenderPass();
739 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
740 shared_state->opacity = 0.5f;
741 CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(),
742 kOverlayBottomRightRect);
743 shared_state = pass->CreateAndAppendSharedQuadState();
744 shared_state->opacity = 1.f;
745 CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
746 kOverlayBottomRightRect);
748 RenderPassList pass_list;
749 pass_list.push_back(pass.Pass());
751 RenderPassList original_pass_list;
752 RenderPass::CopyAll(pass_list, &original_pass_list);
754 OverlayCandidateList candidate_list;
755 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
756 EXPECT_EQ(1U, pass_list.size());
757 EXPECT_EQ(0U, candidate_list.size());
760 TEST_F(SingleOverlayOnTopTest, RejectTransparentColorOnTopWithoutBlending) {
761 scoped_ptr<RenderPass> pass = CreateRenderPass();
762 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
763 CreateSolidColorQuadAt(shared_state, SK_ColorTRANSPARENT, pass.get(),
764 kOverlayBottomRightRect)->opaque_rect =
765 kOverlayBottomRightRect;
766 CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
767 kOverlayBottomRightRect);
769 RenderPassList pass_list;
770 pass_list.push_back(pass.Pass());
772 RenderPassList original_pass_list;
773 RenderPass::CopyAll(pass_list, &original_pass_list);
775 OverlayCandidateList candidate_list;
776 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
777 EXPECT_EQ(1U, pass_list.size());
778 EXPECT_EQ(0U, candidate_list.size());
781 TEST_F(SingleOverlayOnTopTest, RejectVideoSwapTransform) {
782 scoped_ptr<RenderPass> pass = CreateRenderPass();
783 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
784 pass->shared_quad_state_list.back(),
785 pass.get(), kSwapTransform);
787 RenderPassList pass_list;
788 pass_list.push_back(pass.Pass());
789 OverlayCandidateList candidate_list;
790 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
791 ASSERT_EQ(1U, pass_list.size());
792 EXPECT_EQ(0U, candidate_list.size());
795 TEST_F(SingleOverlayOnTopTest, AllowVideoXMirrorTransform) {
796 scoped_ptr<RenderPass> pass = CreateRenderPass();
797 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
798 pass->shared_quad_state_list.back(),
799 pass.get(), kXMirrorTransform);
801 RenderPassList pass_list;
802 pass_list.push_back(pass.Pass());
803 OverlayCandidateList candidate_list;
804 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
805 ASSERT_EQ(1U, pass_list.size());
806 EXPECT_EQ(2U, candidate_list.size());
809 TEST_F(SingleOverlayOnTopTest, AllowVideoBothMirrorTransform) {
810 scoped_ptr<RenderPass> pass = CreateRenderPass();
811 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
812 pass->shared_quad_state_list.back(),
813 pass.get(), kBothMirrorTransform);
815 RenderPassList pass_list;
816 pass_list.push_back(pass.Pass());
817 OverlayCandidateList candidate_list;
818 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
819 ASSERT_EQ(1U, pass_list.size());
820 EXPECT_EQ(2U, candidate_list.size());
823 TEST_F(SingleOverlayOnTopTest, AllowVideoNormalTransform) {
824 scoped_ptr<RenderPass> pass = CreateRenderPass();
825 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
826 pass->shared_quad_state_list.back(),
827 pass.get(), kNormalTransform);
829 RenderPassList pass_list;
830 pass_list.push_back(pass.Pass());
831 OverlayCandidateList candidate_list;
832 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
833 ASSERT_EQ(1U, pass_list.size());
834 EXPECT_EQ(2U, candidate_list.size());
837 TEST_F(SingleOverlayOnTopTest, AllowVideoYMirrorTransform) {
838 scoped_ptr<RenderPass> pass = CreateRenderPass();
839 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
840 pass->shared_quad_state_list.back(),
841 pass.get(), kYMirrorTransform);
843 RenderPassList pass_list;
844 pass_list.push_back(pass.Pass());
845 OverlayCandidateList candidate_list;
846 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
847 ASSERT_EQ(1U, pass_list.size());
848 EXPECT_EQ(2U, candidate_list.size());
851 TEST_F(UnderlayTest, OverlayLayerUnderMainLayer) {
852 scoped_ptr<RenderPass> pass = CreateRenderPass();
853 CreateFullscreenCheckeredQuad(resource_provider_.get(),
854 pass->shared_quad_state_list.back(),
855 pass.get());
856 CreateCandidateQuadAt(resource_provider_.get(),
857 pass->shared_quad_state_list.back(), pass.get(),
858 kOverlayBottomRightRect);
860 RenderPassList pass_list;
861 pass_list.push_back(pass.Pass());
863 OverlayCandidateList candidate_list;
864 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
865 EXPECT_EQ(1U, pass_list.size());
866 ASSERT_EQ(2U, candidate_list.size());
867 EXPECT_EQ(0, candidate_list[0].plane_z_order);
868 EXPECT_EQ(-1, candidate_list[1].plane_z_order);
869 EXPECT_EQ(2U, pass_list[0]->quad_list.size());
870 // The overlay quad should have changed to a SOLID_COLOR quad.
871 EXPECT_EQ(pass_list[0]->quad_list.back()->material, DrawQuad::SOLID_COLOR);
874 TEST_F(UnderlayTest, AllowOnTop) {
875 scoped_ptr<RenderPass> pass = CreateRenderPass();
876 CreateFullscreenCandidateQuad(resource_provider_.get(),
877 pass->shared_quad_state_list.back(),
878 pass.get());
879 pass->CreateAndAppendSharedQuadState()->opacity = 0.5f;
880 CreateFullscreenCheckeredQuad(resource_provider_.get(),
881 pass->shared_quad_state_list.back(),
882 pass.get());
884 RenderPassList pass_list;
885 pass_list.push_back(pass.Pass());
887 OverlayCandidateList candidate_list;
888 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
889 EXPECT_EQ(1U, pass_list.size());
890 ASSERT_EQ(2U, candidate_list.size());
891 EXPECT_EQ(0, candidate_list[0].plane_z_order);
892 EXPECT_EQ(-1, candidate_list[1].plane_z_order);
893 // The overlay quad should have changed to a SOLID_COLOR quad.
894 EXPECT_EQ(pass_list[0]->quad_list.front()->material, DrawQuad::SOLID_COLOR);
897 class OverlayInfoRendererGL : public GLRenderer {
898 public:
899 OverlayInfoRendererGL(RendererClient* client,
900 const RendererSettings* settings,
901 OutputSurface* output_surface,
902 ResourceProvider* resource_provider)
903 : GLRenderer(client,
904 settings,
905 output_surface,
906 resource_provider,
907 NULL,
909 expect_overlays_(false) {}
911 MOCK_METHOD3(DoDrawQuad,
912 void(DrawingFrame* frame,
913 const DrawQuad* quad,
914 const gfx::QuadF* draw_region));
916 using GLRenderer::BeginDrawingFrame;
918 void FinishDrawingFrame(DrawingFrame* frame) override {
919 GLRenderer::FinishDrawingFrame(frame);
921 if (!expect_overlays_) {
922 EXPECT_EQ(0U, frame->overlay_list.size());
923 return;
926 ASSERT_EQ(2U, frame->overlay_list.size());
927 EXPECT_NE(0U, frame->overlay_list.back().resource_id);
930 void set_expect_overlays(bool expect_overlays) {
931 expect_overlays_ = expect_overlays;
934 private:
935 bool expect_overlays_;
938 class FakeRendererClient : public RendererClient {
939 public:
940 // RendererClient methods.
941 void SetFullRootLayerDamage() override {}
944 class MockOverlayScheduler {
945 public:
946 MOCK_METHOD5(Schedule,
947 void(int plane_z_order,
948 gfx::OverlayTransform plane_transform,
949 unsigned overlay_texture_id,
950 const gfx::Rect& display_bounds,
951 const gfx::RectF& uv_rect));
954 class GLRendererWithOverlaysTest : public testing::Test {
955 protected:
956 GLRendererWithOverlaysTest() {
957 provider_ = TestContextProvider::Create();
958 output_surface_.reset(new OverlayOutputSurface(provider_));
959 CHECK(output_surface_->BindToClient(&output_surface_client_));
960 resource_provider_ =
961 FakeResourceProvider::Create(output_surface_.get(), nullptr);
963 provider_->support()->SetScheduleOverlayPlaneCallback(base::Bind(
964 &MockOverlayScheduler::Schedule, base::Unretained(&scheduler_)));
967 void Init(bool use_validator) {
968 if (use_validator)
969 output_surface_->InitWithSingleOverlayValidator();
971 renderer_ =
972 make_scoped_ptr(new OverlayInfoRendererGL(&renderer_client_,
973 &settings_,
974 output_surface_.get(),
975 resource_provider_.get()));
978 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
980 RendererSettings settings_;
981 FakeOutputSurfaceClient output_surface_client_;
982 scoped_ptr<OverlayOutputSurface> output_surface_;
983 FakeRendererClient renderer_client_;
984 scoped_ptr<ResourceProvider> resource_provider_;
985 scoped_ptr<OverlayInfoRendererGL> renderer_;
986 scoped_refptr<TestContextProvider> provider_;
987 MockOverlayScheduler scheduler_;
990 TEST_F(GLRendererWithOverlaysTest, OverlayQuadNotDrawn) {
991 bool use_validator = true;
992 Init(use_validator);
993 renderer_->set_expect_overlays(true);
994 gfx::Rect viewport_rect(16, 16);
996 scoped_ptr<RenderPass> pass = CreateRenderPass();
998 CreateFullscreenCandidateQuad(resource_provider_.get(),
999 pass->shared_quad_state_list.back(),
1000 pass.get());
1002 CreateFullscreenCheckeredQuad(resource_provider_.get(),
1003 pass->shared_quad_state_list.back(),
1004 pass.get());
1005 CreateFullscreenCheckeredQuad(resource_provider_.get(),
1006 pass->shared_quad_state_list.back(),
1007 pass.get());
1009 RenderPassList pass_list;
1010 pass_list.push_back(pass.Pass());
1012 // Candidate pass was taken out and extra skipped pass added,
1013 // so only draw 2 quads.
1014 EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(2);
1015 EXPECT_CALL(scheduler_,
1016 Schedule(1,
1017 gfx::OVERLAY_TRANSFORM_NONE,
1019 kOverlayRect,
1020 BoundingRect(kUVTopLeft, kUVBottomRight))).Times(1);
1021 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
1023 SwapBuffers();
1025 Mock::VerifyAndClearExpectations(renderer_.get());
1026 Mock::VerifyAndClearExpectations(&scheduler_);
1029 TEST_F(GLRendererWithOverlaysTest, OccludedQuadInUnderlay) {
1030 bool use_validator = true;
1031 Init(use_validator);
1032 renderer_->set_expect_overlays(true);
1033 gfx::Rect viewport_rect(16, 16);
1035 scoped_ptr<RenderPass> pass = CreateRenderPass();
1037 CreateFullscreenCheckeredQuad(resource_provider_.get(),
1038 pass->shared_quad_state_list.back(),
1039 pass.get());
1040 CreateFullscreenCheckeredQuad(resource_provider_.get(),
1041 pass->shared_quad_state_list.back(),
1042 pass.get());
1044 CreateFullscreenCandidateQuad(resource_provider_.get(),
1045 pass->shared_quad_state_list.back(),
1046 pass.get());
1048 RenderPassList pass_list;
1049 pass_list.push_back(pass.Pass());
1051 // Candidate quad should fail to be overlaid on top because of occlusion.
1052 // Expect to be replaced with transparent hole quad and placed in underlay.
1053 EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(3);
1054 EXPECT_CALL(scheduler_,
1055 Schedule(-1, gfx::OVERLAY_TRANSFORM_NONE, _, kOverlayRect,
1056 BoundingRect(kUVTopLeft, kUVBottomRight))).Times(1);
1057 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
1059 SwapBuffers();
1061 Mock::VerifyAndClearExpectations(renderer_.get());
1062 Mock::VerifyAndClearExpectations(&scheduler_);
1065 TEST_F(GLRendererWithOverlaysTest, NoValidatorNoOverlay) {
1066 bool use_validator = false;
1067 Init(use_validator);
1068 renderer_->set_expect_overlays(false);
1069 gfx::Rect viewport_rect(16, 16);
1071 scoped_ptr<RenderPass> pass = CreateRenderPass();
1073 CreateFullscreenCandidateQuad(resource_provider_.get(),
1074 pass->shared_quad_state_list.back(),
1075 pass.get());
1077 CreateFullscreenCheckeredQuad(resource_provider_.get(),
1078 pass->shared_quad_state_list.back(),
1079 pass.get());
1080 CreateFullscreenCheckeredQuad(resource_provider_.get(),
1081 pass->shared_quad_state_list.back(),
1082 pass.get());
1084 RenderPassList pass_list;
1085 pass_list.push_back(pass.Pass());
1087 // Should see no overlays.
1088 EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(3);
1089 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
1090 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
1092 SwapBuffers();
1094 Mock::VerifyAndClearExpectations(renderer_.get());
1095 Mock::VerifyAndClearExpectations(&scheduler_);
1098 TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturned) {
1099 bool use_validator = true;
1100 Init(use_validator);
1101 renderer_->set_expect_overlays(true);
1103 ResourceId resource1 = CreateResource(resource_provider_.get());
1104 ResourceId resource2 = CreateResource(resource_provider_.get());
1106 scoped_ptr<RenderPass> pass = CreateRenderPass();
1107 RenderPassList pass_list;
1108 pass_list.push_back(pass.Pass());
1110 DirectRenderer::DrawingFrame frame1;
1111 frame1.render_passes_in_draw_order = &pass_list;
1112 frame1.overlay_list.resize(2);
1113 OverlayCandidate& overlay1 = frame1.overlay_list.back();
1114 overlay1.resource_id = resource1;
1115 overlay1.plane_z_order = 1;
1117 DirectRenderer::DrawingFrame frame2;
1118 frame2.render_passes_in_draw_order = &pass_list;
1119 frame2.overlay_list.resize(2);
1120 OverlayCandidate& overlay2 = frame2.overlay_list.back();
1121 overlay2.resource_id = resource2;
1122 overlay2.plane_z_order = 1;
1124 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1125 renderer_->BeginDrawingFrame(&frame1);
1126 renderer_->FinishDrawingFrame(&frame1);
1127 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1128 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
1129 SwapBuffers();
1130 Mock::VerifyAndClearExpectations(&scheduler_);
1132 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1133 renderer_->BeginDrawingFrame(&frame2);
1134 renderer_->FinishDrawingFrame(&frame2);
1135 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1136 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
1137 SwapBuffers();
1138 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
1139 Mock::VerifyAndClearExpectations(&scheduler_);
1141 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1142 renderer_->BeginDrawingFrame(&frame1);
1143 renderer_->FinishDrawingFrame(&frame1);
1144 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1145 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
1146 SwapBuffers();
1147 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
1148 Mock::VerifyAndClearExpectations(&scheduler_);
1150 // No overlays, release the resource.
1151 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
1152 DirectRenderer::DrawingFrame frame3;
1153 frame3.render_passes_in_draw_order = &pass_list;
1154 renderer_->set_expect_overlays(false);
1155 renderer_->BeginDrawingFrame(&frame3);
1156 renderer_->FinishDrawingFrame(&frame3);
1157 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1158 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
1159 SwapBuffers();
1160 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
1161 Mock::VerifyAndClearExpectations(&scheduler_);
1163 // Use the same buffer twice.
1164 renderer_->set_expect_overlays(true);
1165 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1166 renderer_->BeginDrawingFrame(&frame1);
1167 renderer_->FinishDrawingFrame(&frame1);
1168 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1169 SwapBuffers();
1170 Mock::VerifyAndClearExpectations(&scheduler_);
1172 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1173 renderer_->BeginDrawingFrame(&frame1);
1174 renderer_->FinishDrawingFrame(&frame1);
1175 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1176 SwapBuffers();
1177 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1178 Mock::VerifyAndClearExpectations(&scheduler_);
1180 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
1181 renderer_->set_expect_overlays(false);
1182 renderer_->BeginDrawingFrame(&frame3);
1183 renderer_->FinishDrawingFrame(&frame3);
1184 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1185 SwapBuffers();
1186 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
1187 Mock::VerifyAndClearExpectations(&scheduler_);
1190 } // namespace
1191 } // namespace cc