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::PointF kUVTopLeft(0.1f, 0.2f);
32const gfx::PointF kUVBottomRight(1.0f, 1.0f);
33
34void MailboxReleased(unsigned sync_point, bool lost_resource) {}
35
36class SingleOverlayValidator : public OverlayCandidateValidator {
37 public:
38  virtual void CheckOverlaySupport(OverlayCandidateList* surfaces) OVERRIDE;
39};
40
41void 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
52class 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
60SingleOverlayProcessor::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
68void 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
76class DefaultOverlayProcessor : public OverlayProcessor {
77 public:
78  DefaultOverlayProcessor(OutputSurface* surface,
79                          ResourceProvider* resource_provider);
80  size_t GetStrategyCount();
81};
82
83DefaultOverlayProcessor::DefaultOverlayProcessor(
84    OutputSurface* surface,
85    ResourceProvider* resource_provider)
86    : OverlayProcessor(surface, resource_provider) {}
87
88size_t DefaultOverlayProcessor::GetStrategyCount() {
89  return strategies_.size();
90}
91
92class 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
102scoped_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
119ResourceProvider::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
132scoped_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
156scoped_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
166static 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
195TEST(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
204TEST(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
223class 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
250TEST_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
287TEST_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
307TEST_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.
333TEST_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
363TEST_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
378TEST_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
393TEST_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
408TEST_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
423TEST_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
438TEST_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
454class 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
490class 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
497class 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
507class 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
544TEST_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
582TEST_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
614TEST_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
646TEST_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