Home | History | Annotate | Download | only in output
      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