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