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. 4 5 #include "cc/base/scoped_ptr_vector.h" 6 #include "cc/output/gl_renderer.h" 7 #include "cc/output/output_surface.h" 8 #include "cc/output/output_surface_client.h" 9 #include "cc/output/overlay_candidate_validator.h" 10 #include "cc/output/overlay_processor.h" 11 #include "cc/output/overlay_strategy_single_on_top.h" 12 #include "cc/quads/checkerboard_draw_quad.h" 13 #include "cc/quads/render_pass.h" 14 #include "cc/quads/texture_draw_quad.h" 15 #include "cc/resources/resource_provider.h" 16 #include "cc/resources/texture_mailbox.h" 17 #include "cc/test/fake_output_surface_client.h" 18 #include "cc/test/geometry_test_utils.h" 19 #include "cc/test/test_context_provider.h" 20 #include "cc/test/test_shared_bitmap_manager.h" 21 #include "testing/gmock/include/gmock/gmock.h" 22 #include "testing/gtest/include/gtest/gtest.h" 23 24 using testing::_; 25 using testing::Mock; 26 27 namespace cc { 28 namespace { 29 30 const gfx::Rect kOverlayRect(0, 0, 128, 128); 31 const gfx::PointF kUVTopLeft(0.1f, 0.2f); 32 const gfx::PointF kUVBottomRight(1.0f, 1.0f); 33 34 void MailboxReleased(unsigned sync_point, bool lost_resource) {} 35 36 class SingleOverlayValidator : public OverlayCandidateValidator { 37 public: 38 virtual void CheckOverlaySupport(OverlayCandidateList* surfaces) OVERRIDE; 39 }; 40 41 void SingleOverlayValidator::CheckOverlaySupport( 42 OverlayCandidateList* surfaces) { 43 ASSERT_EQ(2U, surfaces->size()); 44 45 OverlayCandidate& candidate = surfaces->back(); 46 EXPECT_EQ(kOverlayRect.ToString(), candidate.display_rect.ToString()); 47 EXPECT_EQ(BoundingRect(kUVTopLeft, kUVBottomRight).ToString(), 48 candidate.uv_rect.ToString()); 49 candidate.overlay_handled = true; 50 } 51 52 class SingleOverlayProcessor : public OverlayProcessor { 53 public: 54 SingleOverlayProcessor(OutputSurface* surface, 55 ResourceProvider* resource_provider); 56 // Virtual to allow testing different strategies. 57 virtual void Initialize() OVERRIDE; 58 }; 59 60 SingleOverlayProcessor::SingleOverlayProcessor( 61 OutputSurface* surface, 62 ResourceProvider* resource_provider) 63 : OverlayProcessor(surface, resource_provider) { 64 EXPECT_EQ(surface, surface_); 65 EXPECT_EQ(resource_provider, resource_provider_); 66 } 67 68 void SingleOverlayProcessor::Initialize() { 69 OverlayCandidateValidator* candidates = 70 surface_->overlay_candidate_validator(); 71 ASSERT_TRUE(candidates != NULL); 72 strategies_.push_back(scoped_ptr<Strategy>( 73 new OverlayStrategySingleOnTop(candidates, resource_provider_))); 74 } 75 76 class DefaultOverlayProcessor : public OverlayProcessor { 77 public: 78 DefaultOverlayProcessor(OutputSurface* surface, 79 ResourceProvider* resource_provider); 80 size_t GetStrategyCount(); 81 }; 82 83 DefaultOverlayProcessor::DefaultOverlayProcessor( 84 OutputSurface* surface, 85 ResourceProvider* resource_provider) 86 : OverlayProcessor(surface, resource_provider) {} 87 88 size_t DefaultOverlayProcessor::GetStrategyCount() { 89 return strategies_.size(); 90 } 91 92 class OverlayOutputSurface : public OutputSurface { 93 public: 94 explicit OverlayOutputSurface(scoped_refptr<ContextProvider> context_provider) 95 : OutputSurface(context_provider) {} 96 97 void InitWithSingleOverlayValidator() { 98 overlay_candidate_validator_.reset(new SingleOverlayValidator); 99 } 100 }; 101 102 scoped_ptr<RenderPass> CreateRenderPass() { 103 RenderPass::Id id(1, 0); 104 gfx::Rect output_rect(0, 0, 256, 256); 105 bool has_transparent_background = true; 106 107 scoped_ptr<RenderPass> pass = RenderPass::Create(); 108 pass->SetAll(id, 109 output_rect, 110 output_rect, 111 gfx::Transform(), 112 has_transparent_background); 113 114 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState(); 115 shared_state->opacity = 1.f; 116 return pass.Pass(); 117 } 118 119 ResourceProvider::ResourceId CreateResource( 120 ResourceProvider* resource_provider) { 121 unsigned sync_point = 0; 122 TextureMailbox mailbox = 123 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point); 124 mailbox.set_allow_overlay(true); 125 scoped_ptr<SingleReleaseCallback> release_callback = 126 SingleReleaseCallback::Create(base::Bind(&MailboxReleased)); 127 128 return resource_provider->CreateResourceFromTextureMailbox( 129 mailbox, release_callback.Pass()); 130 } 131 132 scoped_ptr<TextureDrawQuad> CreateCandidateQuad( 133 ResourceProvider* resource_provider, 134 const SharedQuadState* shared_quad_state) { 135 ResourceProvider::ResourceId resource_id = CreateResource(resource_provider); 136 bool premultiplied_alpha = false; 137 bool flipped = false; 138 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; 139 140 scoped_ptr<TextureDrawQuad> overlay_quad = TextureDrawQuad::Create(); 141 overlay_quad->SetNew(shared_quad_state, 142 kOverlayRect, 143 kOverlayRect, 144 kOverlayRect, 145 resource_id, 146 premultiplied_alpha, 147 kUVTopLeft, 148 kUVBottomRight, 149 SK_ColorTRANSPARENT, 150 vertex_opacity, 151 flipped); 152 153 return overlay_quad.Pass(); 154 } 155 156 scoped_ptr<DrawQuad> CreateCheckeredQuad( 157 ResourceProvider* resource_provider, 158 const SharedQuadState* shared_quad_state) { 159 scoped_ptr<CheckerboardDrawQuad> checkerboard_quad = 160 CheckerboardDrawQuad::Create(); 161 checkerboard_quad->SetNew( 162 shared_quad_state, kOverlayRect, kOverlayRect, SkColor()); 163 return checkerboard_quad.PassAs<DrawQuad>(); 164 } 165 166 static void CompareRenderPassLists(const RenderPassList& expected_list, 167 const RenderPassList& actual_list) { 168 EXPECT_EQ(expected_list.size(), actual_list.size()); 169 for (size_t i = 0; i < actual_list.size(); ++i) { 170 RenderPass* expected = expected_list[i]; 171 RenderPass* actual = actual_list[i]; 172 173 EXPECT_EQ(expected->id, actual->id); 174 EXPECT_RECT_EQ(expected->output_rect, actual->output_rect); 175 EXPECT_EQ(expected->transform_to_root_target, 176 actual->transform_to_root_target); 177 EXPECT_RECT_EQ(expected->damage_rect, actual->damage_rect); 178 EXPECT_EQ(expected->has_transparent_background, 179 actual->has_transparent_background); 180 181 EXPECT_EQ(expected->shared_quad_state_list.size(), 182 actual->shared_quad_state_list.size()); 183 EXPECT_EQ(expected->quad_list.size(), actual->quad_list.size()); 184 185 for (size_t i = 0; i < expected->quad_list.size(); ++i) { 186 EXPECT_EQ(expected->quad_list[i]->rect.ToString(), 187 actual->quad_list[i]->rect.ToString()); 188 EXPECT_EQ( 189 expected->quad_list[i]->shared_quad_state->content_bounds.ToString(), 190 actual->quad_list[i]->shared_quad_state->content_bounds.ToString()); 191 } 192 } 193 } 194 195 TEST(OverlayTest, NoOverlaysByDefault) { 196 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create(); 197 OverlayOutputSurface output_surface(provider); 198 EXPECT_EQ(NULL, output_surface.overlay_candidate_validator()); 199 200 output_surface.InitWithSingleOverlayValidator(); 201 EXPECT_TRUE(output_surface.overlay_candidate_validator() != NULL); 202 } 203 204 TEST(OverlayTest, OverlaysProcessorHasStrategy) { 205 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create(); 206 OverlayOutputSurface output_surface(provider); 207 FakeOutputSurfaceClient client; 208 EXPECT_TRUE(output_surface.BindToClient(&client)); 209 output_surface.InitWithSingleOverlayValidator(); 210 EXPECT_TRUE(output_surface.overlay_candidate_validator() != NULL); 211 212 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 213 new TestSharedBitmapManager()); 214 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( 215 &output_surface, shared_bitmap_manager.get(), 0, false, 1, false)); 216 217 scoped_ptr<DefaultOverlayProcessor> overlay_processor( 218 new DefaultOverlayProcessor(&output_surface, resource_provider.get())); 219 overlay_processor->Initialize(); 220 EXPECT_GE(1U, overlay_processor->GetStrategyCount()); 221 } 222 223 class SingleOverlayOnTopTest : public testing::Test { 224 protected: 225 virtual void SetUp() { 226 provider_ = TestContextProvider::Create(); 227 output_surface_.reset(new OverlayOutputSurface(provider_)); 228 EXPECT_TRUE(output_surface_->BindToClient(&client_)); 229 output_surface_->InitWithSingleOverlayValidator(); 230 EXPECT_TRUE(output_surface_->overlay_candidate_validator() != NULL); 231 232 shared_bitmap_manager_.reset(new TestSharedBitmapManager()); 233 resource_provider_ = ResourceProvider::Create( 234 output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, 235 false); 236 237 overlay_processor_.reset(new SingleOverlayProcessor( 238 output_surface_.get(), resource_provider_.get())); 239 overlay_processor_->Initialize(); 240 } 241 242 scoped_refptr<TestContextProvider> provider_; 243 scoped_ptr<OverlayOutputSurface> output_surface_; 244 FakeOutputSurfaceClient client_; 245 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; 246 scoped_ptr<ResourceProvider> resource_provider_; 247 scoped_ptr<SingleOverlayProcessor> overlay_processor_; 248 }; 249 250 TEST_F(SingleOverlayOnTopTest, SuccessfullOverlay) { 251 scoped_ptr<RenderPass> pass = CreateRenderPass(); 252 scoped_ptr<TextureDrawQuad> original_quad = CreateCandidateQuad( 253 resource_provider_.get(), pass->shared_quad_state_list.back()); 254 255 pass->quad_list.push_back( 256 original_quad->Copy(pass->shared_quad_state_list.back())); 257 // Add something behind it. 258 pass->quad_list.push_back(CreateCheckeredQuad( 259 resource_provider_.get(), pass->shared_quad_state_list.back())); 260 pass->quad_list.push_back(CreateCheckeredQuad( 261 resource_provider_.get(), pass->shared_quad_state_list.back())); 262 263 RenderPassList pass_list; 264 pass_list.push_back(pass.Pass()); 265 266 // Check for potential candidates. 267 OverlayCandidateList candidate_list; 268 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); 269 270 ASSERT_EQ(1U, pass_list.size()); 271 ASSERT_EQ(2U, candidate_list.size()); 272 273 RenderPass* main_pass = pass_list.back(); 274 // Check that the quad is gone. 275 EXPECT_EQ(2U, main_pass->quad_list.size()); 276 const QuadList& quad_list = main_pass->quad_list; 277 for (QuadList::ConstBackToFrontIterator it = quad_list.BackToFrontBegin(); 278 it != quad_list.BackToFrontEnd(); 279 ++it) { 280 EXPECT_NE(DrawQuad::TEXTURE_CONTENT, (*it)->material); 281 } 282 283 // Check that the right resource id got extracted. 284 EXPECT_EQ(original_quad->resource_id, candidate_list.back().resource_id); 285 } 286 287 TEST_F(SingleOverlayOnTopTest, NoCandidates) { 288 scoped_ptr<RenderPass> pass = CreateRenderPass(); 289 pass->quad_list.push_back(CreateCheckeredQuad( 290 resource_provider_.get(), pass->shared_quad_state_list.back())); 291 pass->quad_list.push_back(CreateCheckeredQuad( 292 resource_provider_.get(), pass->shared_quad_state_list.back())); 293 294 RenderPassList pass_list; 295 pass_list.push_back(pass.Pass()); 296 297 RenderPassList original_pass_list; 298 RenderPass::CopyAll(pass_list, &original_pass_list); 299 300 OverlayCandidateList candidate_list; 301 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); 302 EXPECT_EQ(0U, candidate_list.size()); 303 // There should be nothing new here. 304 CompareRenderPassLists(pass_list, original_pass_list); 305 } 306 307 TEST_F(SingleOverlayOnTopTest, OccludedCandidates) { 308 scoped_ptr<RenderPass> pass = CreateRenderPass(); 309 pass->quad_list.push_back(CreateCheckeredQuad( 310 resource_provider_.get(), pass->shared_quad_state_list.back())); 311 pass->quad_list.push_back(CreateCheckeredQuad( 312 resource_provider_.get(), pass->shared_quad_state_list.back())); 313 314 pass->quad_list.push_back( 315 CreateCandidateQuad(resource_provider_.get(), 316 pass->shared_quad_state_list.back()) 317 .PassAs<DrawQuad>()); 318 319 RenderPassList pass_list; 320 pass_list.push_back(pass.Pass()); 321 322 RenderPassList original_pass_list; 323 RenderPass::CopyAll(pass_list, &original_pass_list); 324 325 OverlayCandidateList candidate_list; 326 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); 327 EXPECT_EQ(0U, candidate_list.size()); 328 // There should be nothing new here. 329 CompareRenderPassLists(pass_list, original_pass_list); 330 } 331 332 // Test with multiple render passes. 333 TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) { 334 RenderPassList pass_list; 335 pass_list.push_back(CreateRenderPass()); 336 337 scoped_ptr<RenderPass> pass = CreateRenderPass(); 338 scoped_ptr<TextureDrawQuad> original_quad = CreateCandidateQuad( 339 resource_provider_.get(), pass->shared_quad_state_list.back()); 340 341 pass->quad_list.push_back( 342 original_quad->Copy(pass->shared_quad_state_list.back())); 343 // Add something behind it. 344 pass->quad_list.push_back(CreateCheckeredQuad( 345 resource_provider_.get(), pass->shared_quad_state_list.back())); 346 pass->quad_list.push_back(CreateCheckeredQuad( 347 resource_provider_.get(), pass->shared_quad_state_list.back())); 348 349 pass_list.push_back(pass.Pass()); 350 351 RenderPassList original_pass_list; 352 RenderPass::CopyAll(pass_list, &original_pass_list); 353 354 // Check for potential candidates. 355 OverlayCandidateList candidate_list; 356 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); 357 EXPECT_EQ(2U, candidate_list.size()); 358 359 // This should be the same. 360 ASSERT_EQ(2U, pass_list.size()); 361 } 362 363 TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) { 364 scoped_ptr<RenderPass> pass = CreateRenderPass(); 365 scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad( 366 resource_provider_.get(), pass->shared_quad_state_list.back()); 367 quad->premultiplied_alpha = true; 368 369 pass->quad_list.push_back(quad.PassAs<DrawQuad>()); 370 RenderPassList pass_list; 371 pass_list.push_back(pass.Pass()); 372 OverlayCandidateList candidate_list; 373 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); 374 EXPECT_EQ(1U, pass_list.size()); 375 EXPECT_EQ(0U, candidate_list.size()); 376 } 377 378 TEST_F(SingleOverlayOnTopTest, RejectBlending) { 379 scoped_ptr<RenderPass> pass = CreateRenderPass(); 380 scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad( 381 resource_provider_.get(), pass->shared_quad_state_list.back()); 382 quad->needs_blending = true; 383 384 pass->quad_list.push_back(quad.PassAs<DrawQuad>()); 385 RenderPassList pass_list; 386 pass_list.push_back(pass.Pass()); 387 OverlayCandidateList candidate_list; 388 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); 389 ASSERT_EQ(1U, pass_list.size()); 390 EXPECT_EQ(0U, candidate_list.size()); 391 } 392 393 TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) { 394 scoped_ptr<RenderPass> pass = CreateRenderPass(); 395 scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad( 396 resource_provider_.get(), pass->shared_quad_state_list.back()); 397 quad->background_color = SK_ColorBLACK; 398 399 pass->quad_list.push_back(quad.PassAs<DrawQuad>()); 400 RenderPassList pass_list; 401 pass_list.push_back(pass.Pass()); 402 OverlayCandidateList candidate_list; 403 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); 404 ASSERT_EQ(1U, pass_list.size()); 405 EXPECT_EQ(0U, candidate_list.size()); 406 } 407 408 TEST_F(SingleOverlayOnTopTest, RejectBlendMode) { 409 scoped_ptr<RenderPass> pass = CreateRenderPass(); 410 scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad( 411 resource_provider_.get(), pass->shared_quad_state_list.back()); 412 pass->shared_quad_state_list.back()->blend_mode = SkXfermode::kScreen_Mode; 413 414 pass->quad_list.push_back(quad.PassAs<DrawQuad>()); 415 RenderPassList pass_list; 416 pass_list.push_back(pass.Pass()); 417 OverlayCandidateList candidate_list; 418 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); 419 ASSERT_EQ(1U, pass_list.size()); 420 EXPECT_EQ(0U, candidate_list.size()); 421 } 422 423 TEST_F(SingleOverlayOnTopTest, RejectOpacity) { 424 scoped_ptr<RenderPass> pass = CreateRenderPass(); 425 scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad( 426 resource_provider_.get(), pass->shared_quad_state_list.back()); 427 pass->shared_quad_state_list.back()->opacity = 0.5f; 428 429 pass->quad_list.push_back(quad.PassAs<DrawQuad>()); 430 RenderPassList pass_list; 431 pass_list.push_back(pass.Pass()); 432 OverlayCandidateList candidate_list; 433 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); 434 ASSERT_EQ(1U, pass_list.size()); 435 EXPECT_EQ(0U, candidate_list.size()); 436 } 437 438 TEST_F(SingleOverlayOnTopTest, RejectTransform) { 439 scoped_ptr<RenderPass> pass = CreateRenderPass(); 440 scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad( 441 resource_provider_.get(), pass->shared_quad_state_list.back()); 442 pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.f, 443 2.f); 444 445 pass->quad_list.push_back(quad.PassAs<DrawQuad>()); 446 RenderPassList pass_list; 447 pass_list.push_back(pass.Pass()); 448 OverlayCandidateList candidate_list; 449 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); 450 ASSERT_EQ(1U, pass_list.size()); 451 EXPECT_EQ(0U, candidate_list.size()); 452 } 453 454 class OverlayInfoRendererGL : public GLRenderer { 455 public: 456 OverlayInfoRendererGL(RendererClient* client, 457 const LayerTreeSettings* settings, 458 OutputSurface* output_surface, 459 ResourceProvider* resource_provider) 460 : GLRenderer(client, 461 settings, 462 output_surface, 463 resource_provider, 464 NULL, 465 0), 466 expect_overlays_(false) {} 467 468 MOCK_METHOD2(DoDrawQuad, void(DrawingFrame* frame, const DrawQuad* quad)); 469 470 virtual void FinishDrawingFrame(DrawingFrame* frame) OVERRIDE { 471 GLRenderer::FinishDrawingFrame(frame); 472 473 if (!expect_overlays_) { 474 EXPECT_EQ(0U, frame->overlay_list.size()); 475 return; 476 } 477 478 ASSERT_EQ(2U, frame->overlay_list.size()); 479 EXPECT_NE(0U, frame->overlay_list.back().resource_id); 480 } 481 482 void set_expect_overlays(bool expect_overlays) { 483 expect_overlays_ = expect_overlays; 484 } 485 486 private: 487 bool expect_overlays_; 488 }; 489 490 class FakeRendererClient : public RendererClient { 491 public: 492 // RendererClient methods. 493 virtual void SetFullRootLayerDamage() OVERRIDE {} 494 virtual void RunOnDemandRasterTask(Task* on_demand_raster_task) OVERRIDE {} 495 }; 496 497 class MockOverlayScheduler { 498 public: 499 MOCK_METHOD5(Schedule, 500 void(int plane_z_order, 501 gfx::OverlayTransform plane_transform, 502 unsigned overlay_texture_id, 503 const gfx::Rect& display_bounds, 504 const gfx::RectF& uv_rect)); 505 }; 506 507 class GLRendererWithOverlaysTest : public testing::Test { 508 protected: 509 GLRendererWithOverlaysTest() { 510 provider_ = TestContextProvider::Create(); 511 output_surface_.reset(new OverlayOutputSurface(provider_)); 512 CHECK(output_surface_->BindToClient(&output_surface_client_)); 513 resource_provider_ = 514 ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1, 515 false); 516 517 provider_->support()->SetScheduleOverlayPlaneCallback(base::Bind( 518 &MockOverlayScheduler::Schedule, base::Unretained(&scheduler_))); 519 } 520 521 void Init(bool use_validator) { 522 if (use_validator) 523 output_surface_->InitWithSingleOverlayValidator(); 524 525 renderer_ = 526 make_scoped_ptr(new OverlayInfoRendererGL(&renderer_client_, 527 &settings_, 528 output_surface_.get(), 529 resource_provider_.get())); 530 } 531 532 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); } 533 534 LayerTreeSettings settings_; 535 FakeOutputSurfaceClient output_surface_client_; 536 scoped_ptr<OverlayOutputSurface> output_surface_; 537 FakeRendererClient renderer_client_; 538 scoped_ptr<ResourceProvider> resource_provider_; 539 scoped_ptr<OverlayInfoRendererGL> renderer_; 540 scoped_refptr<TestContextProvider> provider_; 541 MockOverlayScheduler scheduler_; 542 }; 543 544 TEST_F(GLRendererWithOverlaysTest, OverlayQuadNotDrawn) { 545 bool use_validator = true; 546 Init(use_validator); 547 renderer_->set_expect_overlays(true); 548 gfx::Rect viewport_rect(16, 16); 549 550 scoped_ptr<RenderPass> pass = CreateRenderPass(); 551 552 pass->quad_list.push_back( 553 CreateCandidateQuad(resource_provider_.get(), 554 pass->shared_quad_state_list.back()) 555 .PassAs<DrawQuad>()); 556 557 pass->quad_list.push_back(CreateCheckeredQuad( 558 resource_provider_.get(), pass->shared_quad_state_list.back())); 559 pass->quad_list.push_back(CreateCheckeredQuad( 560 resource_provider_.get(), pass->shared_quad_state_list.back())); 561 562 RenderPassList pass_list; 563 pass_list.push_back(pass.Pass()); 564 565 // Candidate pass was taken out and extra skipped pass added, 566 // so only draw 2 quads. 567 EXPECT_CALL(*renderer_, DoDrawQuad(_, _)).Times(2); 568 EXPECT_CALL(scheduler_, 569 Schedule(1, 570 gfx::OVERLAY_TRANSFORM_NONE, 571 _, 572 kOverlayRect, 573 BoundingRect(kUVTopLeft, kUVBottomRight))).Times(1); 574 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false); 575 576 SwapBuffers(); 577 578 Mock::VerifyAndClearExpectations(renderer_.get()); 579 Mock::VerifyAndClearExpectations(&scheduler_); 580 } 581 582 TEST_F(GLRendererWithOverlaysTest, OccludedQuadDrawn) { 583 bool use_validator = true; 584 Init(use_validator); 585 renderer_->set_expect_overlays(false); 586 gfx::Rect viewport_rect(16, 16); 587 588 scoped_ptr<RenderPass> pass = CreateRenderPass(); 589 590 pass->quad_list.push_back(CreateCheckeredQuad( 591 resource_provider_.get(), pass->shared_quad_state_list.back())); 592 pass->quad_list.push_back(CreateCheckeredQuad( 593 resource_provider_.get(), pass->shared_quad_state_list.back())); 594 595 pass->quad_list.push_back( 596 CreateCandidateQuad(resource_provider_.get(), 597 pass->shared_quad_state_list.back()) 598 .PassAs<DrawQuad>()); 599 600 RenderPassList pass_list; 601 pass_list.push_back(pass.Pass()); 602 603 // 3 quads in the pass, all should draw. 604 EXPECT_CALL(*renderer_, DoDrawQuad(_, _)).Times(3); 605 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0); 606 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false); 607 608 SwapBuffers(); 609 610 Mock::VerifyAndClearExpectations(renderer_.get()); 611 Mock::VerifyAndClearExpectations(&scheduler_); 612 } 613 614 TEST_F(GLRendererWithOverlaysTest, NoValidatorNoOverlay) { 615 bool use_validator = false; 616 Init(use_validator); 617 renderer_->set_expect_overlays(false); 618 gfx::Rect viewport_rect(16, 16); 619 620 scoped_ptr<RenderPass> pass = CreateRenderPass(); 621 622 pass->quad_list.push_back( 623 CreateCandidateQuad(resource_provider_.get(), 624 pass->shared_quad_state_list.back()) 625 .PassAs<DrawQuad>()); 626 627 pass->quad_list.push_back(CreateCheckeredQuad( 628 resource_provider_.get(), pass->shared_quad_state_list.back())); 629 pass->quad_list.push_back(CreateCheckeredQuad( 630 resource_provider_.get(), pass->shared_quad_state_list.back())); 631 632 RenderPassList pass_list; 633 pass_list.push_back(pass.Pass()); 634 635 // Should see no overlays. 636 EXPECT_CALL(*renderer_, DoDrawQuad(_, _)).Times(3); 637 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0); 638 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false); 639 640 SwapBuffers(); 641 642 Mock::VerifyAndClearExpectations(renderer_.get()); 643 Mock::VerifyAndClearExpectations(&scheduler_); 644 } 645 646 TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturned) { 647 bool use_validator = true; 648 Init(use_validator); 649 renderer_->set_expect_overlays(true); 650 651 ResourceProvider::ResourceId resource1 = 652 CreateResource(resource_provider_.get()); 653 ResourceProvider::ResourceId resource2 = 654 CreateResource(resource_provider_.get()); 655 656 DirectRenderer::DrawingFrame frame1; 657 frame1.overlay_list.resize(2); 658 OverlayCandidate& overlay1 = frame1.overlay_list.back(); 659 overlay1.resource_id = resource1; 660 overlay1.plane_z_order = 1; 661 662 DirectRenderer::DrawingFrame frame2; 663 frame2.overlay_list.resize(2); 664 OverlayCandidate& overlay2 = frame2.overlay_list.back(); 665 overlay2.resource_id = resource2; 666 overlay2.plane_z_order = 1; 667 668 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1); 669 renderer_->FinishDrawingFrame(&frame1); 670 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1)); 671 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2)); 672 SwapBuffers(); 673 Mock::VerifyAndClearExpectations(&scheduler_); 674 675 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1); 676 renderer_->FinishDrawingFrame(&frame2); 677 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1)); 678 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2)); 679 SwapBuffers(); 680 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1)); 681 Mock::VerifyAndClearExpectations(&scheduler_); 682 683 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1); 684 renderer_->FinishDrawingFrame(&frame1); 685 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1)); 686 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2)); 687 SwapBuffers(); 688 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2)); 689 Mock::VerifyAndClearExpectations(&scheduler_); 690 691 // No overlays, release the resource. 692 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0); 693 DirectRenderer::DrawingFrame frame3; 694 renderer_->set_expect_overlays(false); 695 renderer_->FinishDrawingFrame(&frame3); 696 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1)); 697 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2)); 698 SwapBuffers(); 699 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1)); 700 Mock::VerifyAndClearExpectations(&scheduler_); 701 702 // Use the same buffer twice. 703 renderer_->set_expect_overlays(true); 704 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1); 705 renderer_->FinishDrawingFrame(&frame1); 706 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1)); 707 SwapBuffers(); 708 Mock::VerifyAndClearExpectations(&scheduler_); 709 710 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1); 711 renderer_->FinishDrawingFrame(&frame1); 712 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1)); 713 SwapBuffers(); 714 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1)); 715 Mock::VerifyAndClearExpectations(&scheduler_); 716 717 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0); 718 renderer_->set_expect_overlays(false); 719 renderer_->FinishDrawingFrame(&frame3); 720 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1)); 721 SwapBuffers(); 722 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1)); 723 Mock::VerifyAndClearExpectations(&scheduler_); 724 } 725 726 } // namespace 727 } // namespace cc 728