layer_tree_host_unittest.cc revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
1// Copyright 2011 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/trees/layer_tree_host.h"
6
7#include <algorithm>
8
9#include "base/auto_reset.h"
10#include "base/synchronization/lock.h"
11#include "cc/animation/timing_function.h"
12#include "cc/debug/frame_rate_counter.h"
13#include "cc/layers/content_layer.h"
14#include "cc/layers/content_layer_client.h"
15#include "cc/layers/io_surface_layer.h"
16#include "cc/layers/layer_impl.h"
17#include "cc/layers/painted_scrollbar_layer.h"
18#include "cc/layers/picture_layer.h"
19#include "cc/layers/solid_color_layer.h"
20#include "cc/layers/video_layer.h"
21#include "cc/output/begin_frame_args.h"
22#include "cc/output/copy_output_request.h"
23#include "cc/output/copy_output_result.h"
24#include "cc/output/output_surface.h"
25#include "cc/resources/prioritized_resource.h"
26#include "cc/resources/prioritized_resource_manager.h"
27#include "cc/resources/resource_update_queue.h"
28#include "cc/scheduler/frame_rate_controller.h"
29#include "cc/test/fake_content_layer.h"
30#include "cc/test/fake_content_layer_client.h"
31#include "cc/test/fake_content_layer_impl.h"
32#include "cc/test/fake_layer_tree_host_client.h"
33#include "cc/test/fake_output_surface.h"
34#include "cc/test/fake_painted_scrollbar_layer.h"
35#include "cc/test/fake_picture_layer.h"
36#include "cc/test/fake_picture_layer_impl.h"
37#include "cc/test/fake_proxy.h"
38#include "cc/test/fake_scoped_ui_resource.h"
39#include "cc/test/fake_video_frame_provider.h"
40#include "cc/test/geometry_test_utils.h"
41#include "cc/test/layer_tree_test.h"
42#include "cc/test/occlusion_tracker_test_common.h"
43#include "cc/test/test_web_graphics_context_3d.h"
44#include "cc/trees/layer_tree_host_impl.h"
45#include "cc/trees/layer_tree_impl.h"
46#include "cc/trees/single_thread_proxy.h"
47#include "cc/trees/thread_proxy.h"
48#include "gpu/GLES2/gl2extchromium.h"
49#include "skia/ext/refptr.h"
50#include "testing/gmock/include/gmock/gmock.h"
51#include "third_party/khronos/GLES2/gl2.h"
52#include "third_party/khronos/GLES2/gl2ext.h"
53#include "third_party/skia/include/core/SkPicture.h"
54#include "ui/gfx/frame_time.h"
55#include "ui/gfx/point_conversions.h"
56#include "ui/gfx/size_conversions.h"
57#include "ui/gfx/vector2d_conversions.h"
58
59using testing::_;
60using testing::AnyNumber;
61using testing::AtLeast;
62using testing::Mock;
63
64namespace cc {
65namespace {
66
67class LayerTreeHostTest : public LayerTreeTest {
68};
69
70// Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
71// draw with frame 0.
72class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
73 public:
74  LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
75
76  virtual void BeginTest() OVERRIDE {
77    PostSetNeedsCommitToMainThread();
78    PostSetNeedsCommitToMainThread();
79  }
80
81  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
82    num_draws_++;
83    if (!impl->active_tree()->source_frame_number())
84      EndTest();
85  }
86
87  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
88    num_commits_++;
89  }
90
91  virtual void AfterTest() OVERRIDE {
92    EXPECT_GE(1, num_commits_);
93    EXPECT_GE(1, num_draws_);
94  }
95
96 private:
97  int num_commits_;
98  int num_draws_;
99};
100
101SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
102
103// A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
104// first committed frame draws should lead to another commit.
105class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
106 public:
107  LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
108
109  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
110
111  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
112    ++num_draws_;
113  }
114
115  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
116    ++num_commits_;
117    switch (num_commits_) {
118      case 1:
119        PostSetNeedsCommitToMainThread();
120        break;
121      case 2:
122        EndTest();
123        break;
124      default:
125        NOTREACHED();
126    }
127  }
128
129  virtual void AfterTest() OVERRIDE {
130    EXPECT_EQ(2, num_commits_);
131    EXPECT_LE(1, num_draws_);
132  }
133
134 private:
135  int num_commits_;
136  int num_draws_;
137};
138
139MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
140
141// Verify that we pass property values in PushPropertiesTo.
142class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
143 protected:
144  virtual void SetupTree() OVERRIDE {
145    scoped_refptr<Layer> root = Layer::Create();
146    root->SetBounds(gfx::Size(10, 10));
147    layer_tree_host()->SetRootLayer(root);
148    LayerTreeHostTest::SetupTree();
149  }
150
151  enum Properties {
152    STARTUP,
153    BOUNDS,
154    HIDE_LAYER_AND_SUBTREE,
155    DRAWS_CONTENT,
156    DONE,
157  };
158
159  virtual void BeginTest() OVERRIDE {
160    index_ = STARTUP;
161    PostSetNeedsCommitToMainThread();
162  }
163
164  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
165    VerifyAfterValues(impl->active_tree()->root_layer());
166  }
167
168  virtual void DidCommitAndDrawFrame() OVERRIDE {
169    SetBeforeValues(layer_tree_host()->root_layer());
170    VerifyBeforeValues(layer_tree_host()->root_layer());
171
172    ++index_;
173    if (index_ == DONE) {
174      EndTest();
175      return;
176    }
177
178    SetAfterValues(layer_tree_host()->root_layer());
179  }
180
181  virtual void AfterTest() OVERRIDE {}
182
183  void VerifyBeforeValues(Layer* layer) {
184    EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString());
185    EXPECT_FALSE(layer->hide_layer_and_subtree());
186    EXPECT_FALSE(layer->DrawsContent());
187  }
188
189  void SetBeforeValues(Layer* layer) {
190    layer->SetBounds(gfx::Size(10, 10));
191    layer->SetHideLayerAndSubtree(false);
192    layer->SetIsDrawable(false);
193  }
194
195  void VerifyAfterValues(LayerImpl* layer) {
196    switch (static_cast<Properties>(index_)) {
197      case STARTUP:
198      case DONE:
199        break;
200      case BOUNDS:
201        EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString());
202        break;
203      case HIDE_LAYER_AND_SUBTREE:
204        EXPECT_TRUE(layer->hide_layer_and_subtree());
205        break;
206      case DRAWS_CONTENT:
207        EXPECT_TRUE(layer->DrawsContent());
208        break;
209    }
210  }
211
212  void SetAfterValues(Layer* layer) {
213    switch (static_cast<Properties>(index_)) {
214      case STARTUP:
215      case DONE:
216        break;
217      case BOUNDS:
218        layer->SetBounds(gfx::Size(20, 20));
219        break;
220      case HIDE_LAYER_AND_SUBTREE:
221        layer->SetHideLayerAndSubtree(true);
222        break;
223      case DRAWS_CONTENT:
224        layer->SetIsDrawable(true);
225        break;
226    }
227  }
228
229  int index_;
230};
231
232SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo);
233
234// 1 setNeedsRedraw after the first commit has completed should lead to 1
235// additional draw.
236class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
237 public:
238  LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
239
240  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
241
242  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
243    EXPECT_EQ(0, impl->active_tree()->source_frame_number());
244    if (!num_draws_) {
245      // Redraw again to verify that the second redraw doesn't commit.
246      PostSetNeedsRedrawToMainThread();
247    } else {
248      EndTest();
249    }
250    num_draws_++;
251  }
252
253  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
254    EXPECT_EQ(0, num_draws_);
255    num_commits_++;
256  }
257
258  virtual void AfterTest() OVERRIDE {
259    EXPECT_GE(2, num_draws_);
260    EXPECT_EQ(1, num_commits_);
261  }
262
263 private:
264  int num_commits_;
265  int num_draws_;
266};
267
268MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw);
269
270// After setNeedsRedrawRect(invalid_rect) the final damage_rect
271// must contain invalid_rect.
272class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
273 public:
274  LayerTreeHostTestSetNeedsRedrawRect()
275      : num_draws_(0),
276        bounds_(50, 50),
277        invalid_rect_(10, 10, 20, 20),
278        root_layer_(ContentLayer::Create(&client_)) {
279  }
280
281  virtual void BeginTest() OVERRIDE {
282    root_layer_->SetIsDrawable(true);
283    root_layer_->SetBounds(bounds_);
284    layer_tree_host()->SetRootLayer(root_layer_);
285    layer_tree_host()->SetViewportSize(bounds_);
286    PostSetNeedsCommitToMainThread();
287  }
288
289  virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
290                                     LayerTreeHostImpl::FrameData* frame_data,
291                                     bool result) OVERRIDE {
292    EXPECT_TRUE(result);
293
294    gfx::RectF root_damage_rect;
295    if (!frame_data->render_passes.empty())
296      root_damage_rect = frame_data->render_passes.back()->damage_rect;
297
298    if (!num_draws_) {
299      // If this is the first frame, expect full frame damage.
300      EXPECT_RECT_EQ(root_damage_rect, gfx::Rect(bounds_));
301    } else {
302      // Check that invalid_rect_ is indeed repainted.
303      EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
304    }
305
306    return result;
307  }
308
309  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
310    if (!num_draws_) {
311      PostSetNeedsRedrawRectToMainThread(invalid_rect_);
312    } else {
313      EndTest();
314    }
315    num_draws_++;
316  }
317
318  virtual void AfterTest() OVERRIDE {
319    EXPECT_EQ(2, num_draws_);
320  }
321
322 private:
323  int num_draws_;
324  const gfx::Size bounds_;
325  const gfx::Rect invalid_rect_;
326  FakeContentLayerClient client_;
327  scoped_refptr<ContentLayer> root_layer_;
328};
329
330SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
331
332class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
333 public:
334  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
335    settings->layer_transforms_should_scale_layer_contents = true;
336  }
337
338  virtual void SetupTree() OVERRIDE {
339    root_layer_ = Layer::Create();
340    root_layer_->SetBounds(gfx::Size(10, 20));
341
342    scaled_layer_ = FakeContentLayer::Create(&client_);
343    scaled_layer_->SetBounds(gfx::Size(1, 1));
344    root_layer_->AddChild(scaled_layer_);
345
346    layer_tree_host()->SetRootLayer(root_layer_);
347    LayerTreeHostTest::SetupTree();
348  }
349
350  virtual void BeginTest() OVERRIDE {
351    PostSetNeedsCommitToMainThread();
352  }
353
354  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
355    if (host_impl->active_tree()->source_frame_number() == 1)
356      EndTest();
357  }
358
359  virtual void DidCommit() OVERRIDE {
360    switch (layer_tree_host()->source_frame_number()) {
361      case 1:
362        // Changing the device scale factor causes a commit. It also changes
363        // the content bounds of |scaled_layer_|, which should not generate
364        // a second commit as a result.
365        layer_tree_host()->SetDeviceScaleFactor(4.f);
366        break;
367      default:
368        // No extra commits.
369        EXPECT_EQ(2, layer_tree_host()->source_frame_number());
370    }
371  }
372
373  virtual void AfterTest() OVERRIDE {
374    EXPECT_EQ(gfx::Size(4, 4).ToString(),
375              scaled_layer_->content_bounds().ToString());
376  }
377
378 private:
379  FakeContentLayerClient client_;
380  scoped_refptr<Layer> root_layer_;
381  scoped_refptr<FakeContentLayer> scaled_layer_;
382};
383
384SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
385
386class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
387    : public LayerTreeHostTest {
388 public:
389  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
390    settings->layer_transforms_should_scale_layer_contents = true;
391  }
392
393  virtual void SetupTree() OVERRIDE {
394    root_layer_ = Layer::Create();
395    root_layer_->SetBounds(gfx::Size(10, 20));
396
397    bool paint_scrollbar = true;
398    bool has_thumb = false;
399    scrollbar_ = FakePaintedScrollbarLayer::Create(
400        paint_scrollbar, has_thumb, root_layer_->id());
401    scrollbar_->SetPosition(gfx::Point(0, 10));
402    scrollbar_->SetBounds(gfx::Size(10, 10));
403
404    root_layer_->AddChild(scrollbar_);
405
406    layer_tree_host()->SetRootLayer(root_layer_);
407    LayerTreeHostTest::SetupTree();
408  }
409
410  virtual void BeginTest() OVERRIDE {
411    PostSetNeedsCommitToMainThread();
412  }
413
414  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
415    if (host_impl->active_tree()->source_frame_number() == 1)
416      EndTest();
417  }
418
419  virtual void DidCommit() OVERRIDE {
420    switch (layer_tree_host()->source_frame_number()) {
421      case 1:
422        // Changing the device scale factor causes a commit. It also changes
423        // the content bounds of |scrollbar_|, which should not generate
424        // a second commit as a result.
425        layer_tree_host()->SetDeviceScaleFactor(4.f);
426        break;
427      default:
428        // No extra commits.
429        EXPECT_EQ(2, layer_tree_host()->source_frame_number());
430    }
431  }
432
433  virtual void AfterTest() OVERRIDE {
434    EXPECT_EQ(gfx::Size(40, 40).ToString(),
435              scrollbar_->content_bounds().ToString());
436  }
437
438 private:
439  FakeContentLayerClient client_;
440  scoped_refptr<Layer> root_layer_;
441  scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
442};
443
444SINGLE_AND_MULTI_THREAD_TEST_F(
445    LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
446
447class LayerTreeHostTestCompositeAndReadback : public LayerTreeHostTest {
448 public:
449  LayerTreeHostTestCompositeAndReadback() : num_commits_(0) {}
450
451  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
452
453  virtual void DidCommit() OVERRIDE {
454    num_commits_++;
455    if (num_commits_ == 1) {
456      char pixels[4];
457      layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
458    } else if (num_commits_ == 2) {
459      // This is inside the readback. We should get another commit after it.
460    } else if (num_commits_ == 3) {
461      EndTest();
462    } else {
463      NOTREACHED();
464    }
465  }
466
467  virtual void AfterTest() OVERRIDE {}
468
469 private:
470  int num_commits_;
471};
472
473MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadback);
474
475class LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
476    : public LayerTreeHostTest {
477 public:
478  LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws()
479      : num_commits_(0) {}
480
481  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
482
483  virtual void DidCommit() OVERRIDE {
484    num_commits_++;
485    if (num_commits_ == 1) {
486      layer_tree_host()->SetNeedsCommit();
487    } else if (num_commits_ == 2) {
488      char pixels[4];
489      layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
490    } else if (num_commits_ == 3) {
491      // This is inside the readback. We should get another commit after it.
492    } else if (num_commits_ == 4) {
493      EndTest();
494    } else {
495      NOTREACHED();
496    }
497  }
498
499  virtual void AfterTest() OVERRIDE {}
500
501 private:
502  int num_commits_;
503};
504
505MULTI_THREAD_TEST_F(
506    LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws);
507
508class LayerTreeHostTestCompositeAndReadbackDuringForcedDraw
509    : public LayerTreeHostTest {
510 protected:
511  static const int kFirstCommitSourceFrameNumber = 0;
512  static const int kReadbackSourceFrameNumber = 1;
513  static const int kReadbackReplacementAndForcedDrawSourceFrameNumber = 2;
514
515  LayerTreeHostTestCompositeAndReadbackDuringForcedDraw()
516      : did_post_readback_(false) {}
517
518  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
519    // This enables forced draws after a single prepare to draw failure.
520    settings->timeout_and_draw_when_animation_checkerboards = true;
521    settings->maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
522  }
523
524  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
525
526  virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
527                                     LayerTreeHostImpl::FrameData* frame_data,
528                                     bool result) OVERRIDE {
529    int sfn = host_impl->active_tree()->source_frame_number();
530    EXPECT_TRUE(sfn == kFirstCommitSourceFrameNumber ||
531                sfn == kReadbackSourceFrameNumber ||
532                sfn == kReadbackReplacementAndForcedDrawSourceFrameNumber)
533        << sfn;
534
535    // Before we react to the failed draw by initiating the forced draw
536    // sequence, start a readback on the main thread.
537    if (sfn == kFirstCommitSourceFrameNumber && !did_post_readback_) {
538      did_post_readback_ = true;
539      PostReadbackToMainThread();
540    }
541
542    // Returning false will result in a forced draw.
543    return false;
544  }
545
546  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
547    // We should only draw for the readback and the forced draw.
548    int sfn = host_impl->active_tree()->source_frame_number();
549    EXPECT_TRUE(sfn == kReadbackSourceFrameNumber ||
550                sfn == kReadbackReplacementAndForcedDrawSourceFrameNumber)
551        << sfn;
552  }
553
554  virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
555                                   bool result) OVERRIDE {
556    // We should only swap for the forced draw.
557    int sfn = host_impl->active_tree()->source_frame_number();
558    EXPECT_TRUE(sfn == kReadbackReplacementAndForcedDrawSourceFrameNumber)
559        << sfn;
560    EndTest();
561  }
562
563  virtual void AfterTest() OVERRIDE {}
564
565  bool did_post_readback_;
566};
567
568MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackDuringForcedDraw);
569
570class LayerTreeHostTestCompositeAndReadbackAfterForcedDraw
571    : public LayerTreeHostTest {
572 protected:
573  static const int kFirstCommitSourceFrameNumber = 0;
574  static const int kForcedDrawSourceFrameNumber = 1;
575  static const int kReadbackSourceFrameNumber = 2;
576  static const int kReadbackReplacementSourceFrameNumber = 3;
577
578  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
579    // This enables forced draws after a single prepare to draw failure.
580    settings->timeout_and_draw_when_animation_checkerboards = true;
581    settings->maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
582  }
583
584  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
585
586  virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
587                                     LayerTreeHostImpl::FrameData* frame_data,
588                                     bool result) OVERRIDE {
589    int sfn = host_impl->active_tree()->source_frame_number();
590    EXPECT_TRUE(sfn == kFirstCommitSourceFrameNumber ||
591                sfn == kForcedDrawSourceFrameNumber ||
592                sfn == kReadbackSourceFrameNumber ||
593                sfn == kReadbackReplacementSourceFrameNumber)
594        << sfn;
595
596    // Returning false will result in a forced draw.
597    return false;
598  }
599
600  virtual void DidCommit() OVERRIDE {
601    if (layer_tree_host()->source_frame_number() ==
602        kForcedDrawSourceFrameNumber) {
603      // Avoid aborting the forced draw commit so source_frame_number
604      // increments.
605      layer_tree_host()->SetNeedsCommit();
606    } else if (layer_tree_host()->source_frame_number() ==
607               kReadbackSourceFrameNumber) {
608      // Perform a readback immediately after the forced draw's commit.
609      char pixels[4];
610      layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
611    }
612  }
613
614  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
615    // We should only draw for the the forced draw, readback, and
616    // replacement commit.
617    int sfn = host_impl->active_tree()->source_frame_number();
618    EXPECT_TRUE(sfn == kForcedDrawSourceFrameNumber ||
619                sfn == kReadbackSourceFrameNumber ||
620                sfn == kReadbackReplacementSourceFrameNumber)
621        << sfn;
622  }
623
624  virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
625                                   bool result) OVERRIDE {
626    // We should only swap for the forced draw and replacement commit.
627    int sfn = host_impl->active_tree()->source_frame_number();
628    EXPECT_TRUE(sfn == kForcedDrawSourceFrameNumber ||
629                sfn == kReadbackReplacementSourceFrameNumber)
630        << sfn;
631
632    if (sfn == kReadbackReplacementSourceFrameNumber)
633      EndTest();
634  }
635
636  virtual void AfterTest() OVERRIDE {}
637};
638
639MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackAfterForcedDraw);
640
641class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
642 public:
643  LayerTreeHostTestSetNextCommitForcesRedraw()
644      : num_draws_(0),
645        bounds_(50, 50),
646        invalid_rect_(10, 10, 20, 20),
647        root_layer_(ContentLayer::Create(&client_)) {
648  }
649
650  virtual void BeginTest() OVERRIDE {
651    root_layer_->SetIsDrawable(true);
652    root_layer_->SetBounds(bounds_);
653    layer_tree_host()->SetRootLayer(root_layer_);
654    layer_tree_host()->SetViewportSize(bounds_);
655    PostSetNeedsCommitToMainThread();
656  }
657
658  virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
659    if (num_draws_ == 3 && host_impl->settings().impl_side_painting)
660      host_impl->SetNeedsRedrawRect(invalid_rect_);
661  }
662
663  virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
664                                     LayerTreeHostImpl::FrameData* frame_data,
665                                     bool result) OVERRIDE {
666    EXPECT_TRUE(result);
667
668    gfx::RectF root_damage_rect;
669    if (!frame_data->render_passes.empty())
670      root_damage_rect = frame_data->render_passes.back()->damage_rect;
671
672    switch (num_draws_) {
673      case 0:
674        EXPECT_RECT_EQ(gfx::Rect(bounds_), root_damage_rect);
675        break;
676      case 1:
677      case 2:
678        EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root_damage_rect);
679        break;
680      case 3:
681        EXPECT_RECT_EQ(invalid_rect_, root_damage_rect);
682        break;
683      case 4:
684        EXPECT_RECT_EQ(gfx::Rect(bounds_), root_damage_rect);
685        break;
686      default:
687        NOTREACHED();
688    }
689
690    return result;
691  }
692
693  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
694    switch (num_draws_) {
695      case 0:
696      case 1:
697        // Cycle through a couple of empty commits to ensure we're observing the
698        // right behavior
699        PostSetNeedsCommitToMainThread();
700        break;
701      case 2:
702        // Should force full frame damage on the next commit
703        PostSetNextCommitForcesRedrawToMainThread();
704        PostSetNeedsCommitToMainThread();
705        if (host_impl->settings().impl_side_painting)
706          host_impl->BlockNotifyReadyToActivateForTesting(true);
707        else
708          num_draws_++;
709        break;
710      case 3:
711        host_impl->BlockNotifyReadyToActivateForTesting(false);
712        break;
713      default:
714        EndTest();
715        break;
716    }
717    num_draws_++;
718  }
719
720  virtual void AfterTest() OVERRIDE {
721    EXPECT_EQ(5, num_draws_);
722  }
723
724 private:
725  int num_draws_;
726  const gfx::Size bounds_;
727  const gfx::Rect invalid_rect_;
728  FakeContentLayerClient client_;
729  scoped_refptr<ContentLayer> root_layer_;
730};
731
732SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNextCommitForcesRedraw);
733
734// Tests that if a layer is not drawn because of some reason in the parent then
735// its damage is preserved until the next time it is drawn.
736class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
737 public:
738  LayerTreeHostTestUndrawnLayersDamageLater()
739      : root_layer_(ContentLayer::Create(&client_)) {
740  }
741
742  virtual void SetupTree() OVERRIDE {
743    root_layer_->SetIsDrawable(true);
744    root_layer_->SetBounds(gfx::Size(50, 50));
745    layer_tree_host()->SetRootLayer(root_layer_);
746
747    // The initially transparent layer has a larger child layer, which is
748    // not initially drawn because of the this (parent) layer.
749    parent_layer_ = FakeContentLayer::Create(&client_);
750    parent_layer_->SetBounds(gfx::Size(15, 15));
751    parent_layer_->SetOpacity(0.0f);
752    root_layer_->AddChild(parent_layer_);
753
754    child_layer_ = FakeContentLayer::Create(&client_);
755    child_layer_->SetBounds(gfx::Size(25, 25));
756    parent_layer_->AddChild(child_layer_);
757
758    LayerTreeHostTest::SetupTree();
759  }
760
761  virtual void BeginTest() OVERRIDE {
762    PostSetNeedsCommitToMainThread();
763  }
764
765  virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
766                                     LayerTreeHostImpl::FrameData* frame_data,
767                                     bool result) OVERRIDE {
768    EXPECT_TRUE(result);
769
770    gfx::RectF root_damage_rect;
771    if (!frame_data->render_passes.empty())
772      root_damage_rect = frame_data->render_passes.back()->damage_rect;
773
774    // The first time, the whole view needs be drawn.
775    // Afterwards, just the opacity of surface_layer1 is changed a few times,
776    // and each damage should be the bounding box of it and its child. If this
777    // was working improperly, the damage might not include its childs bounding
778    // box.
779    switch (layer_tree_host()->source_frame_number()) {
780      case 1:
781        EXPECT_RECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
782        break;
783      case 2:
784      case 3:
785      case 4:
786        EXPECT_RECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect);
787        break;
788      default:
789        NOTREACHED();
790    }
791
792    return result;
793  }
794
795  virtual void DidCommitAndDrawFrame() OVERRIDE {
796    switch (layer_tree_host()->source_frame_number()) {
797      case 1:
798        // Test not owning the surface.
799        parent_layer_->SetOpacity(1.0f);
800        break;
801      case 2:
802        parent_layer_->SetOpacity(0.0f);
803        break;
804      case 3:
805        // Test owning the surface.
806        parent_layer_->SetOpacity(0.5f);
807        parent_layer_->SetForceRenderSurface(true);
808        break;
809      case 4:
810        EndTest();
811        break;
812      default:
813        NOTREACHED();
814    }
815  }
816
817
818  virtual void AfterTest() OVERRIDE {}
819
820 private:
821  FakeContentLayerClient client_;
822  scoped_refptr<ContentLayer> root_layer_;
823  scoped_refptr<FakeContentLayer> parent_layer_;
824  scoped_refptr<FakeContentLayer> child_layer_;
825};
826
827SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
828
829// If the layerTreeHost says it can't draw, Then we should not try to draw.
830class LayerTreeHostTestCanDrawBlocksDrawing : public LayerTreeHostTest {
831 public:
832  LayerTreeHostTestCanDrawBlocksDrawing() : num_commits_(0), done_(false) {}
833
834  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
835
836  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
837    if (done_)
838      return;
839    // Only the initial draw should bring us here.
840    EXPECT_TRUE(impl->CanDraw());
841    EXPECT_EQ(0, impl->active_tree()->source_frame_number());
842  }
843
844  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
845    if (done_)
846      return;
847    if (num_commits_ >= 1) {
848      // After the first commit, we should not be able to draw.
849      EXPECT_FALSE(impl->CanDraw());
850    }
851  }
852
853  virtual void DidCommit() OVERRIDE {
854    num_commits_++;
855    if (num_commits_ == 1) {
856      // Make the viewport empty so the host says it can't draw.
857      layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
858    } else if (num_commits_ == 2) {
859      char pixels[4];
860      layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
861    } else if (num_commits_ == 3) {
862      // Let it draw so we go idle and end the test.
863      layer_tree_host()->SetViewportSize(gfx::Size(1, 1));
864      done_ = true;
865      EndTest();
866    }
867  }
868
869  virtual void AfterTest() OVERRIDE {}
870
871 private:
872  int num_commits_;
873  bool done_;
874};
875
876SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing);
877
878// beginLayerWrite should prevent draws from executing until a commit occurs
879class LayerTreeHostTestWriteLayersRedraw : public LayerTreeHostTest {
880 public:
881  LayerTreeHostTestWriteLayersRedraw() : num_commits_(0), num_draws_(0) {}
882
883  virtual void BeginTest() OVERRIDE {
884    PostAcquireLayerTextures();
885    PostSetNeedsRedrawToMainThread();  // should be inhibited without blocking
886    PostSetNeedsCommitToMainThread();
887  }
888
889  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
890    num_draws_++;
891    EXPECT_EQ(num_draws_, num_commits_);
892  }
893
894  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
895    num_commits_++;
896    EndTest();
897  }
898
899  virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_commits_); }
900
901 private:
902  int num_commits_;
903  int num_draws_;
904};
905
906MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersRedraw);
907
908// Verify that when resuming visibility, Requesting layer write permission
909// will not deadlock the main thread even though there are not yet any
910// scheduled redraws. This behavior is critical for reliably surviving tab
911// switching. There are no failure conditions to this test, it just passes
912// by not timing out.
913class LayerTreeHostTestWriteLayersAfterVisible : public LayerTreeHostTest {
914 public:
915  LayerTreeHostTestWriteLayersAfterVisible() : num_commits_(0) {}
916
917  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
918
919  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
920    num_commits_++;
921    if (num_commits_ == 2)
922      EndTest();
923    else if (num_commits_ < 2) {
924      PostSetVisibleToMainThread(false);
925      PostSetVisibleToMainThread(true);
926      PostAcquireLayerTextures();
927      PostSetNeedsCommitToMainThread();
928    }
929  }
930
931  virtual void AfterTest() OVERRIDE {}
932
933 private:
934  int num_commits_;
935};
936
937MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersAfterVisible);
938
939// A compositeAndReadback while invisible should force a normal commit without
940// assertion.
941class LayerTreeHostTestCompositeAndReadbackWhileInvisible
942    : public LayerTreeHostTest {
943 public:
944  LayerTreeHostTestCompositeAndReadbackWhileInvisible() : num_commits_(0) {}
945
946  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
947
948  virtual void DidCommitAndDrawFrame() OVERRIDE {
949    num_commits_++;
950    if (num_commits_ == 1) {
951      layer_tree_host()->SetVisible(false);
952      layer_tree_host()->SetNeedsCommit();
953      layer_tree_host()->SetNeedsCommit();
954      char pixels[4];
955      layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
956    } else {
957      EndTest();
958    }
959  }
960
961  virtual void AfterTest() OVERRIDE {}
962
963 private:
964  int num_commits_;
965};
966
967MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackWhileInvisible);
968
969class LayerTreeHostTestAbortFrameWhenInvisible : public LayerTreeHostTest {
970 public:
971  LayerTreeHostTestAbortFrameWhenInvisible() {}
972
973  virtual void BeginTest() OVERRIDE {
974    // Request a commit (from the main thread), Which will trigger the commit
975    // flow from the impl side.
976    layer_tree_host()->SetNeedsCommit();
977    // Then mark ourselves as not visible before processing any more messages
978    // on the main thread.
979    layer_tree_host()->SetVisible(false);
980    // If we make it without kicking a frame, we pass!
981    EndTestAfterDelay(1);
982  }
983
984  virtual void Layout() OVERRIDE {
985    ASSERT_FALSE(true);
986    EndTest();
987  }
988
989  virtual void AfterTest() OVERRIDE {}
990};
991
992MULTI_THREAD_TEST_F(LayerTreeHostTestAbortFrameWhenInvisible);
993
994// This test verifies that properties on the layer tree host are commited
995// to the impl side.
996class LayerTreeHostTestCommit : public LayerTreeHostTest {
997 public:
998  LayerTreeHostTestCommit() {}
999
1000  virtual void BeginTest() OVERRIDE {
1001    layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1002    layer_tree_host()->set_background_color(SK_ColorGRAY);
1003
1004    PostSetNeedsCommitToMainThread();
1005  }
1006
1007  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1008    EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize());
1009    EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
1010
1011    EndTest();
1012  }
1013
1014  virtual void AfterTest() OVERRIDE {}
1015};
1016
1017MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
1018
1019// This test verifies that LayerTreeHostImpl's current frame time gets
1020// updated in consecutive frames when it doesn't draw due to tree
1021// activation failure.
1022class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
1023    : public LayerTreeHostTest {
1024 public:
1025  LayerTreeHostTestFrameTimeUpdatesAfterActivationFails()
1026      : frame_count_with_pending_tree_(0) {}
1027
1028  virtual void BeginTest() OVERRIDE {
1029    layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1030    layer_tree_host()->set_background_color(SK_ColorGRAY);
1031
1032    PostSetNeedsCommitToMainThread();
1033  }
1034
1035  virtual void BeginCommitOnThread(LayerTreeHostImpl *impl) OVERRIDE {
1036    EXPECT_EQ(frame_count_with_pending_tree_, 0);
1037    impl->BlockNotifyReadyToActivateForTesting(true);
1038  }
1039
1040  virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
1041                                          const BeginFrameArgs& args) OVERRIDE {
1042    if (impl->pending_tree())
1043      frame_count_with_pending_tree_++;
1044
1045    if (frame_count_with_pending_tree_ == 2)
1046      impl->BlockNotifyReadyToActivateForTesting(false);
1047  }
1048
1049  virtual void DidBeginImplFrameOnThread(LayerTreeHostImpl* impl,
1050                                         const BeginFrameArgs& args) OVERRIDE {
1051    if (frame_count_with_pending_tree_ == 1) {
1052      EXPECT_EQ(first_frame_time_.ToInternalValue(), 0);
1053      first_frame_time_ = impl->CurrentFrameTimeTicks();
1054    }
1055  }
1056
1057  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1058    if (frame_count_with_pending_tree_ > 1) {
1059      EXPECT_NE(first_frame_time_.ToInternalValue(), 0);
1060      EXPECT_NE(first_frame_time_.ToInternalValue(),
1061                impl->CurrentFrameTimeTicks().ToInternalValue());
1062      EndTest();
1063      return;
1064    }
1065
1066    EXPECT_FALSE(impl->settings().impl_side_painting);
1067    EndTest();
1068  }
1069  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1070    if (impl->settings().impl_side_painting)
1071      EXPECT_NE(frame_count_with_pending_tree_, 1);
1072  }
1073
1074  virtual void AfterTest() OVERRIDE {}
1075
1076 private:
1077  int frame_count_with_pending_tree_;
1078  base::TimeTicks first_frame_time_;
1079};
1080
1081SINGLE_AND_MULTI_THREAD_TEST_F(
1082    LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
1083
1084// This test verifies that LayerTreeHostImpl's current frame time gets
1085// updated in consecutive frames when it draws in each frame.
1086class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
1087 public:
1088  LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
1089
1090  virtual void BeginTest() OVERRIDE {
1091    layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
1092    layer_tree_host()->set_background_color(SK_ColorGRAY);
1093
1094    PostSetNeedsCommitToMainThread();
1095  }
1096
1097  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1098    frame_++;
1099    if (frame_ == 1) {
1100      first_frame_time_ = impl->CurrentFrameTimeTicks();
1101      impl->SetNeedsRedraw();
1102
1103      // Since we might use a low-resolution clock on Windows, we need to
1104      // make sure that the clock has incremented past first_frame_time_.
1105      while (first_frame_time_ == gfx::FrameTime::Now()) {}
1106
1107      return;
1108    }
1109
1110    EXPECT_NE(first_frame_time_, impl->CurrentFrameTimeTicks());
1111    EndTest();
1112  }
1113
1114  virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1115    // Ensure there isn't a commit between the two draws, to ensure that a
1116    // commit isn't required for updating the current frame time. We can
1117    // only check for this in the multi-threaded case, since in the single-
1118    // threaded case there will always be a commit between consecutive draws.
1119    if (HasImplThread())
1120      EXPECT_EQ(0, frame_);
1121  }
1122
1123  virtual void AfterTest() OVERRIDE {}
1124
1125 private:
1126  int frame_;
1127  base::TimeTicks first_frame_time_;
1128};
1129
1130SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
1131
1132// Verifies that StartPageScaleAnimation events propagate correctly
1133// from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
1134class LayerTreeHostTestStartPageScaleAnimation
1135    : public LayerTreeHostTest {
1136 public:
1137  LayerTreeHostTestStartPageScaleAnimation() {}
1138
1139  virtual void SetupTree() OVERRIDE {
1140    LayerTreeHostTest::SetupTree();
1141
1142    if (layer_tree_host()->settings().impl_side_painting) {
1143      scoped_refptr<FakePictureLayer> layer =
1144          FakePictureLayer::Create(&client_);
1145      layer->set_always_update_resources(true);
1146      scroll_layer_ = layer;
1147    } else {
1148      scroll_layer_ = FakeContentLayer::Create(&client_);
1149    }
1150
1151    scroll_layer_->SetScrollable(true);
1152    scroll_layer_->SetScrollOffset(gfx::Vector2d());
1153    layer_tree_host()->root_layer()->AddChild(scroll_layer_);
1154    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
1155  }
1156
1157  virtual void BeginTest() OVERRIDE {
1158    PostSetNeedsCommitToMainThread();
1159  }
1160
1161  virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta, float scale)
1162      OVERRIDE {
1163    gfx::Vector2d offset = scroll_layer_->scroll_offset();
1164    scroll_layer_->SetScrollOffset(offset + scroll_delta);
1165    layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
1166  }
1167
1168  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1169    // We get one commit before the first draw, and the animation doesn't happen
1170    // until the second draw.
1171    switch (impl->active_tree()->source_frame_number()) {
1172      case 0:
1173        EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
1174        // We'll start an animation when we get back to the main thread.
1175        break;
1176      case 1:
1177        EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
1178        break;
1179      case 2:
1180        EXPECT_EQ(1.25f, impl->active_tree()->page_scale_factor());
1181        EndTest();
1182        break;
1183      default:
1184        NOTREACHED();
1185    }
1186  }
1187
1188  virtual void DidCommitAndDrawFrame() OVERRIDE {
1189    switch (layer_tree_host()->source_frame_number()) {
1190      case 1:
1191        layer_tree_host()->StartPageScaleAnimation(
1192            gfx::Vector2d(), false, 1.25f, base::TimeDelta());
1193        break;
1194    }
1195  }
1196
1197  virtual void AfterTest() OVERRIDE {}
1198
1199  FakeContentLayerClient client_;
1200  scoped_refptr<Layer> scroll_layer_;
1201};
1202
1203MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
1204
1205class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
1206 public:
1207  LayerTreeHostTestSetVisible() : num_draws_(0) {}
1208
1209  virtual void BeginTest() OVERRIDE {
1210    PostSetNeedsCommitToMainThread();
1211    PostSetVisibleToMainThread(false);
1212    // This is suppressed while we're invisible.
1213    PostSetNeedsRedrawToMainThread();
1214    // Triggers the redraw.
1215    PostSetVisibleToMainThread(true);
1216  }
1217
1218  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1219    EXPECT_TRUE(impl->visible());
1220    ++num_draws_;
1221    EndTest();
1222  }
1223
1224  virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_draws_); }
1225
1226 private:
1227  int num_draws_;
1228};
1229
1230MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
1231
1232class TestOpacityChangeLayerDelegate : public ContentLayerClient {
1233 public:
1234  TestOpacityChangeLayerDelegate() : test_layer_(0) {}
1235
1236  void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
1237
1238  virtual void PaintContents(SkCanvas*, gfx::Rect, gfx::RectF*) OVERRIDE {
1239    // Set layer opacity to 0.
1240    if (test_layer_)
1241      test_layer_->SetOpacity(0.f);
1242  }
1243  virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
1244
1245 private:
1246  Layer* test_layer_;
1247};
1248
1249class ContentLayerWithUpdateTracking : public ContentLayer {
1250 public:
1251  static scoped_refptr<ContentLayerWithUpdateTracking> Create(
1252      ContentLayerClient* client) {
1253    return make_scoped_refptr(new ContentLayerWithUpdateTracking(client));
1254  }
1255
1256  int PaintContentsCount() { return paint_contents_count_; }
1257  void ResetPaintContentsCount() { paint_contents_count_ = 0; }
1258
1259  virtual bool Update(ResourceUpdateQueue* queue,
1260                      const OcclusionTracker* occlusion) OVERRIDE {
1261    bool updated = ContentLayer::Update(queue, occlusion);
1262    paint_contents_count_++;
1263    return updated;
1264  }
1265
1266 private:
1267  explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
1268      : ContentLayer(client), paint_contents_count_(0) {
1269    SetAnchorPoint(gfx::PointF(0.f, 0.f));
1270    SetBounds(gfx::Size(10, 10));
1271    SetIsDrawable(true);
1272  }
1273  virtual ~ContentLayerWithUpdateTracking() {}
1274
1275  int paint_contents_count_;
1276};
1277
1278// Layer opacity change during paint should not prevent compositor resources
1279// from being updated during commit.
1280class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
1281 public:
1282  LayerTreeHostTestOpacityChange()
1283      : test_opacity_change_delegate_(),
1284        update_check_layer_(ContentLayerWithUpdateTracking::Create(
1285            &test_opacity_change_delegate_)) {
1286    test_opacity_change_delegate_.SetTestLayer(update_check_layer_.get());
1287  }
1288
1289  virtual void BeginTest() OVERRIDE {
1290    layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1291    layer_tree_host()->root_layer()->AddChild(update_check_layer_);
1292
1293    PostSetNeedsCommitToMainThread();
1294  }
1295
1296  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1297    EndTest();
1298  }
1299
1300  virtual void AfterTest() OVERRIDE {
1301    // Update() should have been called once.
1302    EXPECT_EQ(1, update_check_layer_->PaintContentsCount());
1303  }
1304
1305 private:
1306  TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
1307  scoped_refptr<ContentLayerWithUpdateTracking> update_check_layer_;
1308};
1309
1310MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
1311
1312class NoScaleContentLayer : public ContentLayer {
1313 public:
1314  static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) {
1315    return make_scoped_refptr(new NoScaleContentLayer(client));
1316  }
1317
1318  virtual void CalculateContentsScale(float ideal_contents_scale,
1319                                      float device_scale_factor,
1320                                      float page_scale_factor,
1321                                      bool animating_transform_to_screen,
1322                                      float* contents_scale_x,
1323                                      float* contents_scale_y,
1324                                      gfx::Size* contentBounds) OVERRIDE {
1325    // Skip over the ContentLayer's method to the base Layer class.
1326    Layer::CalculateContentsScale(ideal_contents_scale,
1327                                  device_scale_factor,
1328                                  page_scale_factor,
1329                                  animating_transform_to_screen,
1330                                  contents_scale_x,
1331                                  contents_scale_y,
1332                                  contentBounds);
1333  }
1334
1335 private:
1336  explicit NoScaleContentLayer(ContentLayerClient* client)
1337      : ContentLayer(client) {}
1338  virtual ~NoScaleContentLayer() {}
1339};
1340
1341class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1342    : public LayerTreeHostTest {
1343 public:
1344  LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
1345      : root_layer_(NoScaleContentLayer::Create(&client_)),
1346        child_layer_(ContentLayer::Create(&client_)) {}
1347
1348  virtual void BeginTest() OVERRIDE {
1349    layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1350    layer_tree_host()->SetDeviceScaleFactor(1.5);
1351    EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
1352
1353    root_layer_->AddChild(child_layer_);
1354
1355    root_layer_->SetIsDrawable(true);
1356    root_layer_->SetBounds(gfx::Size(30, 30));
1357    root_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1358
1359    child_layer_->SetIsDrawable(true);
1360    child_layer_->SetPosition(gfx::Point(2, 2));
1361    child_layer_->SetBounds(gfx::Size(10, 10));
1362    child_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1363
1364    layer_tree_host()->SetRootLayer(root_layer_);
1365
1366    PostSetNeedsCommitToMainThread();
1367  }
1368
1369  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1370    // Should only do one commit.
1371    EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1372    // Device scale factor should come over to impl.
1373    EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
1374
1375    // Both layers are on impl.
1376    ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
1377
1378    // Device viewport is scaled.
1379    EXPECT_EQ(gfx::Size(60, 60), impl->DrawViewportSize());
1380
1381    LayerImpl* root = impl->active_tree()->root_layer();
1382    LayerImpl* child = impl->active_tree()->root_layer()->children()[0];
1383
1384    // Positions remain in layout pixels.
1385    EXPECT_EQ(gfx::Point(0, 0), root->position());
1386    EXPECT_EQ(gfx::Point(2, 2), child->position());
1387
1388    // Compute all the layer transforms for the frame.
1389    LayerTreeHostImpl::FrameData frame_data;
1390    impl->PrepareToDraw(&frame_data, gfx::Rect());
1391    impl->DidDrawAllLayers(frame_data);
1392
1393    const LayerImplList& render_surface_layer_list =
1394        *frame_data.render_surface_layer_list;
1395
1396    // Both layers should be drawing into the root render surface.
1397    ASSERT_EQ(1u, render_surface_layer_list.size());
1398    ASSERT_EQ(root->render_surface(),
1399              render_surface_layer_list[0]->render_surface());
1400    ASSERT_EQ(2u, root->render_surface()->layer_list().size());
1401
1402    // The root render surface is the size of the viewport.
1403    EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60),
1404                   root->render_surface()->content_rect());
1405
1406    // The content bounds of the child should be scaled.
1407    gfx::Size child_bounds_scaled =
1408        gfx::ToCeiledSize(gfx::ScaleSize(child->bounds(), 1.5));
1409    EXPECT_EQ(child_bounds_scaled, child->content_bounds());
1410
1411    gfx::Transform scale_transform;
1412    scale_transform.Scale(impl->device_scale_factor(),
1413                          impl->device_scale_factor());
1414
1415    // The root layer is scaled by 2x.
1416    gfx::Transform root_screen_space_transform = scale_transform;
1417    gfx::Transform root_draw_transform = scale_transform;
1418
1419    EXPECT_EQ(root_draw_transform, root->draw_transform());
1420    EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
1421
1422    // The child is at position 2,2, which is transformed to 3,3 after the scale
1423    gfx::Transform child_screen_space_transform;
1424    child_screen_space_transform.Translate(3.f, 3.f);
1425    gfx::Transform child_draw_transform = child_screen_space_transform;
1426
1427    EXPECT_TRANSFORMATION_MATRIX_EQ(child_draw_transform,
1428                                    child->draw_transform());
1429    EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform,
1430                                    child->screen_space_transform());
1431
1432    EndTest();
1433  }
1434
1435  virtual void AfterTest() OVERRIDE {}
1436
1437 private:
1438  FakeContentLayerClient client_;
1439  scoped_refptr<NoScaleContentLayer> root_layer_;
1440  scoped_refptr<ContentLayer> child_layer_;
1441};
1442
1443MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
1444
1445// Verify atomicity of commits and reuse of textures.
1446class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest {
1447 public:
1448  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1449    settings->texture_id_allocation_chunk_size = 1;
1450    // Make sure partial texture updates are turned off.
1451    settings->max_partial_texture_updates = 0;
1452    // Linear fade animator prevents scrollbars from drawing immediately.
1453    settings->scrollbar_animator = LayerTreeSettings::NoAnimator;
1454  }
1455
1456  virtual void SetupTree() OVERRIDE {
1457    layer_ = FakeContentLayer::Create(&client_);
1458    layer_->SetBounds(gfx::Size(10, 20));
1459
1460    bool paint_scrollbar = true;
1461    bool has_thumb = false;
1462    scrollbar_ = FakePaintedScrollbarLayer::Create(
1463        paint_scrollbar, has_thumb, layer_->id());
1464    scrollbar_->SetPosition(gfx::Point(0, 10));
1465    scrollbar_->SetBounds(gfx::Size(10, 10));
1466
1467    layer_->AddChild(scrollbar_);
1468
1469    layer_tree_host()->SetRootLayer(layer_);
1470    LayerTreeHostTest::SetupTree();
1471  }
1472
1473  virtual void BeginTest() OVERRIDE {
1474    drew_frame_ = -1;
1475    PostSetNeedsCommitToMainThread();
1476  }
1477
1478  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1479    ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1480
1481    TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1482        impl->output_surface()->context_provider()->Context3d());
1483
1484    switch (impl->active_tree()->source_frame_number()) {
1485      case 0:
1486        // Number of textures should be one for each layer
1487        ASSERT_EQ(2u, context->NumTextures());
1488        // Number of textures used for commit should be one for each layer.
1489        EXPECT_EQ(2u, context->NumUsedTextures());
1490        // Verify that used texture is correct.
1491        EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1492        EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1493
1494        context->ResetUsedTextures();
1495        PostSetNeedsCommitToMainThread();
1496        break;
1497      case 1:
1498        // Number of textures should be one for scrollbar layer since it was
1499        // requested and deleted on the impl-thread, and double for the content
1500        // layer since its first texture is used by impl thread and cannot by
1501        // used for update.
1502        ASSERT_EQ(3u, context->NumTextures());
1503        // Number of textures used for commit should be one for each layer.
1504        EXPECT_EQ(2u, context->NumUsedTextures());
1505        // First textures should not have been used.
1506        EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1507        EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1508        // New textures should have been used.
1509        EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1510        context->ResetUsedTextures();
1511        PostSetNeedsCommitToMainThread();
1512        break;
1513      case 2:
1514        EndTest();
1515        break;
1516      default:
1517        NOTREACHED();
1518        break;
1519    }
1520  }
1521
1522  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1523    TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1524        impl->output_surface()->context_provider()->Context3d());
1525
1526    if (drew_frame_ == impl->active_tree()->source_frame_number()) {
1527      EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
1528      return;
1529    }
1530    drew_frame_ = impl->active_tree()->source_frame_number();
1531
1532    // We draw/ship one texture each frame for each layer.
1533    EXPECT_EQ(2u, context->NumUsedTextures());
1534    context->ResetUsedTextures();
1535  }
1536
1537  virtual void Layout() OVERRIDE {
1538    layer_->SetNeedsDisplay();
1539    scrollbar_->SetNeedsDisplay();
1540  }
1541
1542  virtual void AfterTest() OVERRIDE {}
1543
1544 protected:
1545  FakeContentLayerClient client_;
1546  scoped_refptr<FakeContentLayer> layer_;
1547  scoped_refptr<FakePaintedScrollbarLayer> scrollbar_;
1548  int drew_frame_;
1549};
1550
1551MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1552    LayerTreeHostTestDirectRendererAtomicCommit);
1553
1554class LayerTreeHostTestDelegatingRendererAtomicCommit
1555    : public LayerTreeHostTestDirectRendererAtomicCommit {
1556 public:
1557  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1558    ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1559
1560    TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1561        impl->output_surface()->context_provider()->Context3d());
1562
1563    switch (impl->active_tree()->source_frame_number()) {
1564      case 0:
1565        // Number of textures should be one for each layer
1566        ASSERT_EQ(2u, context->NumTextures());
1567        // Number of textures used for commit should be one for each layer.
1568        EXPECT_EQ(2u, context->NumUsedTextures());
1569        // Verify that used texture is correct.
1570        EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1571        EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1572        context->ResetUsedTextures();
1573        PostSetNeedsCommitToMainThread();
1574        break;
1575      case 1:
1576        // Number of textures should be doubled as the first context layer
1577        // texture is being used by the impl-thread and cannot be used for
1578        // update.  The scrollbar behavior is different direct renderer because
1579        // UI resource deletion with delegating renderer occurs after tree
1580        // activation.
1581        ASSERT_EQ(4u, context->NumTextures());
1582        // Number of textures used for commit should still be
1583        // one for each layer.
1584        EXPECT_EQ(2u, context->NumUsedTextures());
1585        // First textures should not have been used.
1586        EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1587        EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1588        // New textures should have been used.
1589        EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1590        EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1591        context->ResetUsedTextures();
1592        PostSetNeedsCommitToMainThread();
1593        break;
1594      case 2:
1595        EndTest();
1596        break;
1597      default:
1598        NOTREACHED();
1599        break;
1600    }
1601  }
1602};
1603
1604MULTI_THREAD_DELEGATING_RENDERER_NOIMPL_TEST_F(
1605    LayerTreeHostTestDelegatingRendererAtomicCommit);
1606
1607static void SetLayerPropertiesForTesting(Layer* layer,
1608                                         Layer* parent,
1609                                         const gfx::Transform& transform,
1610                                         gfx::PointF anchor,
1611                                         gfx::PointF position,
1612                                         gfx::Size bounds,
1613                                         bool opaque) {
1614  layer->RemoveAllChildren();
1615  if (parent)
1616    parent->AddChild(layer);
1617  layer->SetTransform(transform);
1618  layer->SetAnchorPoint(anchor);
1619  layer->SetPosition(position);
1620  layer->SetBounds(bounds);
1621  layer->SetContentsOpaque(opaque);
1622}
1623
1624class LayerTreeHostTestAtomicCommitWithPartialUpdate
1625    : public LayerTreeHostTest {
1626 public:
1627  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1628    settings->texture_id_allocation_chunk_size = 1;
1629    // Allow one partial texture update.
1630    settings->max_partial_texture_updates = 1;
1631    // No partial updates when impl side painting is enabled.
1632    settings->impl_side_painting = false;
1633  }
1634
1635  virtual void SetupTree() OVERRIDE {
1636    parent_ = FakeContentLayer::Create(&client_);
1637    parent_->SetBounds(gfx::Size(10, 20));
1638
1639    child_ = FakeContentLayer::Create(&client_);
1640    child_->SetPosition(gfx::Point(0, 10));
1641    child_->SetBounds(gfx::Size(3, 10));
1642
1643    parent_->AddChild(child_);
1644
1645    layer_tree_host()->SetRootLayer(parent_);
1646    LayerTreeHostTest::SetupTree();
1647  }
1648
1649  virtual void BeginTest() OVERRIDE {
1650    PostSetNeedsCommitToMainThread();
1651  }
1652
1653  virtual void DidCommitAndDrawFrame() OVERRIDE {
1654    switch (layer_tree_host()->source_frame_number()) {
1655      case 1:
1656        parent_->SetNeedsDisplay();
1657        child_->SetNeedsDisplay();
1658        break;
1659      case 2:
1660        // Damage part of layers.
1661        parent_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1662        child_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1663        break;
1664      case 3:
1665        child_->SetNeedsDisplay();
1666        layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1667        break;
1668      case 4:
1669        layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1670        break;
1671      case 5:
1672        EndTest();
1673        break;
1674      default:
1675        NOTREACHED() << layer_tree_host()->source_frame_number();
1676        break;
1677    }
1678  }
1679
1680  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1681    ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates);
1682
1683    TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1684        impl->output_surface()->context_provider()->Context3d());
1685
1686    switch (impl->active_tree()->source_frame_number()) {
1687      case 0:
1688        // Number of textures should be one for each layer.
1689        ASSERT_EQ(2u, context->NumTextures());
1690        // Number of textures used for commit should be one for each layer.
1691        EXPECT_EQ(2u, context->NumUsedTextures());
1692        // Verify that used textures are correct.
1693        EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1694        EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1695        context->ResetUsedTextures();
1696        break;
1697      case 1:
1698        if (HasImplThread()) {
1699          // Number of textures should be two for each content layer.
1700          ASSERT_EQ(4u, context->NumTextures());
1701        } else {
1702          // In single thread we can always do partial updates, so the limit has
1703          // no effect.
1704          ASSERT_EQ(2u, context->NumTextures());
1705        }
1706        // Number of textures used for commit should be one for each content
1707        // layer.
1708        EXPECT_EQ(2u, context->NumUsedTextures());
1709
1710        if (HasImplThread()) {
1711          // First content textures should not have been used.
1712          EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1713          EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1714          // New textures should have been used.
1715          EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1716          EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1717        } else {
1718          // In single thread we can always do partial updates, so the limit has
1719          // no effect.
1720          EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1721          EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1722        }
1723
1724        context->ResetUsedTextures();
1725        break;
1726      case 2:
1727        if (HasImplThread()) {
1728          // Number of textures should be two for each content layer.
1729          ASSERT_EQ(4u, context->NumTextures());
1730        } else {
1731          // In single thread we can always do partial updates, so the limit has
1732          // no effect.
1733          ASSERT_EQ(2u, context->NumTextures());
1734        }
1735        // Number of textures used for commit should be one for each content
1736        // layer.
1737        EXPECT_EQ(2u, context->NumUsedTextures());
1738
1739        if (HasImplThread()) {
1740          // One content layer does a partial update also.
1741          EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1742          EXPECT_FALSE(context->UsedTexture(context->TextureAt(3)));
1743        } else {
1744          // In single thread we can always do partial updates, so the limit has
1745          // no effect.
1746          EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1747          EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1748        }
1749
1750        context->ResetUsedTextures();
1751        break;
1752      case 3:
1753        // No textures should be used for commit.
1754        EXPECT_EQ(0u, context->NumUsedTextures());
1755
1756        context->ResetUsedTextures();
1757        break;
1758      case 4:
1759        // Number of textures used for commit should be one, for the
1760        // content layer.
1761        EXPECT_EQ(1u, context->NumUsedTextures());
1762
1763        context->ResetUsedTextures();
1764        break;
1765      default:
1766        NOTREACHED();
1767        break;
1768    }
1769  }
1770
1771  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1772    EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
1773
1774    TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1775        impl->output_surface()->context_provider()->Context3d());
1776
1777    // Number of textures used for drawing should one per layer except for
1778    // frame 3 where the viewport only contains one layer.
1779    if (impl->active_tree()->source_frame_number() == 3) {
1780      EXPECT_EQ(1u, context->NumUsedTextures());
1781    } else {
1782      EXPECT_EQ(2u, context->NumUsedTextures()) <<
1783        "For frame " << impl->active_tree()->source_frame_number();
1784    }
1785
1786    context->ResetUsedTextures();
1787  }
1788
1789  virtual void AfterTest() OVERRIDE {}
1790
1791 private:
1792  FakeContentLayerClient client_;
1793  scoped_refptr<FakeContentLayer> parent_;
1794  scoped_refptr<FakeContentLayer> child_;
1795};
1796
1797// Partial updates are not possible with a delegating renderer.
1798SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1799    LayerTreeHostTestAtomicCommitWithPartialUpdate);
1800
1801class LayerTreeHostTestFinishAllRendering : public LayerTreeHostTest {
1802 public:
1803  LayerTreeHostTestFinishAllRendering() : once_(false), draw_count_(0) {}
1804
1805  virtual void BeginTest() OVERRIDE {
1806    layer_tree_host()->SetNeedsRedraw();
1807    PostSetNeedsCommitToMainThread();
1808  }
1809
1810  virtual void DidCommitAndDrawFrame() OVERRIDE {
1811    if (once_)
1812      return;
1813    once_ = true;
1814    layer_tree_host()->SetNeedsRedraw();
1815    layer_tree_host()->AcquireLayerTextures();
1816    {
1817      base::AutoLock lock(lock_);
1818      draw_count_ = 0;
1819    }
1820    layer_tree_host()->FinishAllRendering();
1821    {
1822      base::AutoLock lock(lock_);
1823      EXPECT_EQ(0, draw_count_);
1824    }
1825    EndTest();
1826  }
1827
1828  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1829    base::AutoLock lock(lock_);
1830    ++draw_count_;
1831  }
1832
1833  virtual void AfterTest() OVERRIDE {}
1834
1835 private:
1836  bool once_;
1837  base::Lock lock_;
1838  int draw_count_;
1839};
1840
1841SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering);
1842
1843class LayerTreeHostTestCompositeAndReadbackCleanup : public LayerTreeHostTest {
1844 public:
1845  virtual void BeginTest() OVERRIDE {
1846    Layer* root_layer = layer_tree_host()->root_layer();
1847
1848    char pixels[4];
1849    layer_tree_host()->CompositeAndReadback(static_cast<void*>(&pixels),
1850                                            gfx::Rect(0, 0, 1, 1));
1851    EXPECT_FALSE(root_layer->render_surface());
1852
1853    EndTest();
1854  }
1855
1856  virtual void AfterTest() OVERRIDE {}
1857};
1858
1859SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackCleanup);
1860
1861class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1862    : public LayerTreeHostTest {
1863 protected:
1864  virtual void SetupTree() OVERRIDE {
1865    root_layer_ = FakeContentLayer::Create(&client_);
1866    root_layer_->SetBounds(gfx::Size(100, 100));
1867
1868    surface_layer1_ = FakeContentLayer::Create(&client_);
1869    surface_layer1_->SetBounds(gfx::Size(100, 100));
1870    surface_layer1_->SetForceRenderSurface(true);
1871    surface_layer1_->SetOpacity(0.5f);
1872    root_layer_->AddChild(surface_layer1_);
1873
1874    surface_layer2_ = FakeContentLayer::Create(&client_);
1875    surface_layer2_->SetBounds(gfx::Size(100, 100));
1876    surface_layer2_->SetForceRenderSurface(true);
1877    surface_layer2_->SetOpacity(0.5f);
1878    surface_layer1_->AddChild(surface_layer2_);
1879
1880    replica_layer1_ = FakeContentLayer::Create(&client_);
1881    surface_layer1_->SetReplicaLayer(replica_layer1_.get());
1882
1883    replica_layer2_ = FakeContentLayer::Create(&client_);
1884    surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1885
1886    layer_tree_host()->SetRootLayer(root_layer_);
1887    LayerTreeHostTest::SetupTree();
1888  }
1889
1890  virtual void BeginTest() OVERRIDE {
1891    PostSetNeedsCommitToMainThread();
1892  }
1893
1894  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1895    Renderer* renderer = host_impl->renderer();
1896    RenderPass::Id surface1_render_pass_id = host_impl->active_tree()
1897        ->root_layer()->children()[0]->render_surface()->RenderPassId();
1898    RenderPass::Id surface2_render_pass_id =
1899        host_impl->active_tree()->root_layer()->children()[0]->children()[0]
1900        ->render_surface()->RenderPassId();
1901
1902    switch (host_impl->active_tree()->source_frame_number()) {
1903      case 0:
1904        EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting(
1905            surface1_render_pass_id));
1906        EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting(
1907            surface2_render_pass_id));
1908
1909        // Reduce the memory limit to only fit the root layer and one render
1910        // surface. This prevents any contents drawing into surfaces
1911        // from being allocated.
1912        host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
1913        break;
1914      case 1:
1915        EXPECT_FALSE(renderer->HasAllocatedResourcesForTesting(
1916            surface1_render_pass_id));
1917        EXPECT_FALSE(renderer->HasAllocatedResourcesForTesting(
1918            surface2_render_pass_id));
1919
1920        EndTest();
1921        break;
1922    }
1923  }
1924
1925  virtual void DidCommitAndDrawFrame() OVERRIDE {
1926    if (layer_tree_host()->source_frame_number() < 2)
1927      root_layer_->SetNeedsDisplay();
1928  }
1929
1930  virtual void AfterTest() OVERRIDE {
1931    EXPECT_LE(2u, root_layer_->update_count());
1932    EXPECT_LE(2u, surface_layer1_->update_count());
1933    EXPECT_LE(2u, surface_layer2_->update_count());
1934  }
1935
1936  FakeContentLayerClient client_;
1937  scoped_refptr<FakeContentLayer> root_layer_;
1938  scoped_refptr<FakeContentLayer> surface_layer1_;
1939  scoped_refptr<FakeContentLayer> replica_layer1_;
1940  scoped_refptr<FakeContentLayer> surface_layer2_;
1941  scoped_refptr<FakeContentLayer> replica_layer2_;
1942};
1943
1944// Surfaces don't exist with a delegated renderer.
1945SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
1946    LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
1947
1948class EvictionTestLayer : public Layer {
1949 public:
1950  static scoped_refptr<EvictionTestLayer> Create() {
1951    return make_scoped_refptr(new EvictionTestLayer());
1952  }
1953
1954  virtual bool Update(ResourceUpdateQueue*,
1955                      const OcclusionTracker*) OVERRIDE;
1956  virtual bool DrawsContent() const OVERRIDE { return true; }
1957
1958  virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
1959      OVERRIDE;
1960  virtual void PushPropertiesTo(LayerImpl* impl) OVERRIDE;
1961  virtual void SetTexturePriorities(const PriorityCalculator&) OVERRIDE;
1962
1963  bool HaveBackingTexture() const {
1964    return texture_.get() ? texture_->have_backing_texture() : false;
1965  }
1966
1967 private:
1968  EvictionTestLayer() : Layer() {}
1969  virtual ~EvictionTestLayer() {}
1970
1971  void CreateTextureIfNeeded() {
1972    if (texture_)
1973      return;
1974    texture_ = PrioritizedResource::Create(
1975        layer_tree_host()->contents_texture_manager());
1976    texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888);
1977    bitmap_.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
1978    bitmap_.allocPixels();
1979  }
1980
1981  scoped_ptr<PrioritizedResource> texture_;
1982  SkBitmap bitmap_;
1983};
1984
1985class EvictionTestLayerImpl : public LayerImpl {
1986 public:
1987  static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
1988                                                  int id) {
1989    return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
1990  }
1991  virtual ~EvictionTestLayerImpl() {}
1992
1993  virtual void AppendQuads(QuadSink* quad_sink,
1994                           AppendQuadsData* append_quads_data) OVERRIDE {
1995    ASSERT_TRUE(has_texture_);
1996    ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
1997  }
1998
1999  void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
2000
2001 private:
2002  EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
2003      : LayerImpl(tree_impl, id), has_texture_(false) {}
2004
2005  bool has_texture_;
2006};
2007
2008void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
2009  CreateTextureIfNeeded();
2010  if (!texture_)
2011    return;
2012  texture_->set_request_priority(PriorityCalculator::UIPriority(true));
2013}
2014
2015bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
2016                               const OcclusionTracker*) {
2017  CreateTextureIfNeeded();
2018  if (!texture_)
2019    return false;
2020
2021  gfx::Rect full_rect(0, 0, 10, 10);
2022  ResourceUpdate upload = ResourceUpdate::Create(
2023      texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
2024  queue->AppendFullUpload(upload);
2025  return true;
2026}
2027
2028scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
2029    LayerTreeImpl* tree_impl) {
2030  return EvictionTestLayerImpl::Create(tree_impl, layer_id_)
2031      .PassAs<LayerImpl>();
2032}
2033
2034void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
2035  Layer::PushPropertiesTo(layer_impl);
2036
2037  EvictionTestLayerImpl* test_layer_impl =
2038      static_cast<EvictionTestLayerImpl*>(layer_impl);
2039  test_layer_impl->SetHasTexture(texture_->have_backing_texture());
2040}
2041
2042class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
2043 public:
2044  LayerTreeHostTestEvictTextures()
2045      : layer_(EvictionTestLayer::Create()),
2046        impl_for_evict_textures_(0),
2047        num_commits_(0) {}
2048
2049  virtual void BeginTest() OVERRIDE {
2050    layer_tree_host()->SetRootLayer(layer_);
2051    layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
2052
2053    gfx::Transform identity_matrix;
2054    SetLayerPropertiesForTesting(layer_.get(),
2055                                 0,
2056                                 identity_matrix,
2057                                 gfx::PointF(0.f, 0.f),
2058                                 gfx::PointF(0.f, 0.f),
2059                                 gfx::Size(10, 20),
2060                                 true);
2061
2062    PostSetNeedsCommitToMainThread();
2063  }
2064
2065  void PostEvictTextures() {
2066    ImplThreadTaskRunner()->PostTask(
2067        FROM_HERE,
2068        base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
2069                   base::Unretained(this)));
2070  }
2071
2072  void EvictTexturesOnImplThread() {
2073    DCHECK(impl_for_evict_textures_);
2074    impl_for_evict_textures_->EvictTexturesForTesting();
2075  }
2076
2077  // Commit 1: Just commit and draw normally, then post an eviction at the end
2078  // that will trigger a commit.
2079  // Commit 2: Triggered by the eviction, let it go through and then set
2080  // needsCommit.
2081  // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
2082  // task, which will be handled before the commit. Don't set needsCommit, it
2083  // should have been posted. A frame should not be drawn (note,
2084  // didCommitAndDrawFrame may be called anyway).
2085  // Commit 4: Triggered by the eviction, let it go through and then set
2086  // needsCommit.
2087  // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
2088  // Layout(), a frame should not be drawn but a commit will be posted.
2089  // Commit 6: Triggered by the eviction, post an eviction task in
2090  // Layout(), which will be a noop, letting the commit (which recreates the
2091  // textures) go through and draw a frame, then end the test.
2092  //
2093  // Commits 1+2 test the eviction recovery path where eviction happens outside
2094  // of the beginFrame/commit pair.
2095  // Commits 3+4 test the eviction recovery path where eviction happens inside
2096  // the beginFrame/commit pair.
2097  // Commits 5+6 test the path where an eviction happens during the eviction
2098  // recovery path.
2099  virtual void DidCommit() OVERRIDE {
2100    switch (num_commits_) {
2101      case 1:
2102        EXPECT_TRUE(layer_->HaveBackingTexture());
2103        PostEvictTextures();
2104        break;
2105      case 2:
2106        EXPECT_TRUE(layer_->HaveBackingTexture());
2107        layer_tree_host()->SetNeedsCommit();
2108        break;
2109      case 3:
2110        break;
2111      case 4:
2112        EXPECT_TRUE(layer_->HaveBackingTexture());
2113        layer_tree_host()->SetNeedsCommit();
2114        break;
2115      case 5:
2116        break;
2117      case 6:
2118        EXPECT_TRUE(layer_->HaveBackingTexture());
2119        EndTest();
2120        break;
2121      default:
2122        NOTREACHED();
2123        break;
2124    }
2125  }
2126
2127  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2128    impl_for_evict_textures_ = impl;
2129  }
2130
2131  virtual void Layout() OVERRIDE {
2132    ++num_commits_;
2133    switch (num_commits_) {
2134      case 1:
2135      case 2:
2136        break;
2137      case 3:
2138        PostEvictTextures();
2139        break;
2140      case 4:
2141        // We couldn't check in didCommitAndDrawFrame on commit 3,
2142        // so check here.
2143        EXPECT_FALSE(layer_->HaveBackingTexture());
2144        break;
2145      case 5:
2146        PostEvictTextures();
2147        break;
2148      case 6:
2149        // We couldn't check in didCommitAndDrawFrame on commit 5,
2150        // so check here.
2151        EXPECT_FALSE(layer_->HaveBackingTexture());
2152        PostEvictTextures();
2153        break;
2154      default:
2155        NOTREACHED();
2156        break;
2157    }
2158  }
2159
2160  virtual void AfterTest() OVERRIDE {}
2161
2162 private:
2163  FakeContentLayerClient client_;
2164  scoped_refptr<EvictionTestLayer> layer_;
2165  LayerTreeHostImpl* impl_for_evict_textures_;
2166  int num_commits_;
2167};
2168
2169MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures);
2170
2171class LayerTreeHostTestContinuousCommit : public LayerTreeHostTest {
2172 public:
2173  LayerTreeHostTestContinuousCommit()
2174      : num_commit_complete_(0), num_draw_layers_(0) {}
2175
2176  virtual void BeginTest() OVERRIDE {
2177    layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
2178    layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
2179
2180    PostSetNeedsCommitToMainThread();
2181  }
2182
2183  virtual void DidCommit() OVERRIDE {
2184    if (num_draw_layers_ == 2)
2185      return;
2186    layer_tree_host()->SetNeedsCommit();
2187  }
2188
2189  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2190    if (num_draw_layers_ == 1)
2191      num_commit_complete_++;
2192  }
2193
2194  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2195    num_draw_layers_++;
2196    if (num_draw_layers_ == 2)
2197      EndTest();
2198  }
2199
2200  virtual void AfterTest() OVERRIDE {
2201    // Check that we didn't commit twice between first and second draw.
2202    EXPECT_EQ(1, num_commit_complete_);
2203  }
2204
2205 private:
2206  int num_commit_complete_;
2207  int num_draw_layers_;
2208};
2209
2210MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousCommit);
2211
2212class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
2213 public:
2214  LayerTreeHostTestContinuousInvalidate()
2215      : num_commit_complete_(0), num_draw_layers_(0) {}
2216
2217  virtual void BeginTest() OVERRIDE {
2218    layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
2219    layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
2220
2221    content_layer_ = ContentLayer::Create(&client_);
2222    content_layer_->SetBounds(gfx::Size(10, 10));
2223    content_layer_->SetPosition(gfx::PointF(0.f, 0.f));
2224    content_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
2225    content_layer_->SetIsDrawable(true);
2226    layer_tree_host()->root_layer()->AddChild(content_layer_);
2227
2228    PostSetNeedsCommitToMainThread();
2229  }
2230
2231  virtual void DidCommitAndDrawFrame() OVERRIDE {
2232    if (num_draw_layers_ == 2)
2233      return;
2234    content_layer_->SetNeedsDisplay();
2235  }
2236
2237  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2238    if (num_draw_layers_ == 1)
2239      num_commit_complete_++;
2240  }
2241
2242  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2243    num_draw_layers_++;
2244    if (num_draw_layers_ == 2)
2245      EndTest();
2246  }
2247
2248  virtual void AfterTest() OVERRIDE {
2249    // Check that we didn't commit twice between first and second draw.
2250    EXPECT_EQ(1, num_commit_complete_);
2251  }
2252
2253 private:
2254  FakeContentLayerClient client_;
2255  scoped_refptr<Layer> content_layer_;
2256  int num_commit_complete_;
2257  int num_draw_layers_;
2258};
2259
2260MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestContinuousInvalidate);
2261
2262class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
2263 public:
2264  LayerTreeHostTestDeferCommits()
2265      : num_commits_deferred_(0), num_complete_commits_(0) {}
2266
2267  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2268
2269  virtual void DidDeferCommit() OVERRIDE {
2270    num_commits_deferred_++;
2271    layer_tree_host()->SetDeferCommits(false);
2272  }
2273
2274  virtual void DidCommit() OVERRIDE {
2275    num_complete_commits_++;
2276    switch (num_complete_commits_) {
2277      case 1:
2278        EXPECT_EQ(0, num_commits_deferred_);
2279        layer_tree_host()->SetDeferCommits(true);
2280        PostSetNeedsCommitToMainThread();
2281        break;
2282      case 2:
2283        EndTest();
2284        break;
2285      default:
2286        NOTREACHED();
2287        break;
2288    }
2289  }
2290
2291  virtual void AfterTest() OVERRIDE {
2292    EXPECT_EQ(1, num_commits_deferred_);
2293    EXPECT_EQ(2, num_complete_commits_);
2294  }
2295
2296 private:
2297  int num_commits_deferred_;
2298  int num_complete_commits_;
2299};
2300
2301MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
2302
2303class LayerTreeHostWithProxy : public LayerTreeHost {
2304 public:
2305  LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
2306                         const LayerTreeSettings& settings,
2307                         scoped_ptr<FakeProxy> proxy)
2308      : LayerTreeHost(client, NULL, settings) {
2309    proxy->SetLayerTreeHost(this);
2310    EXPECT_TRUE(InitializeForTesting(proxy.PassAs<Proxy>()));
2311  }
2312};
2313
2314TEST(LayerTreeHostTest, LimitPartialUpdates) {
2315  // When partial updates are not allowed, max updates should be 0.
2316  {
2317    FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2318
2319    scoped_ptr<FakeProxy> proxy(new FakeProxy);
2320    proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
2321    proxy->SetMaxPartialTextureUpdates(5);
2322
2323    LayerTreeSettings settings;
2324    settings.max_partial_texture_updates = 10;
2325
2326    LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2327    EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
2328
2329    EXPECT_EQ(0u, host.MaxPartialTextureUpdates());
2330  }
2331
2332  // When partial updates are allowed,
2333  // max updates should be limited by the proxy.
2334  {
2335    FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2336
2337    scoped_ptr<FakeProxy> proxy(new FakeProxy);
2338    proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2339    proxy->SetMaxPartialTextureUpdates(5);
2340
2341    LayerTreeSettings settings;
2342    settings.max_partial_texture_updates = 10;
2343
2344    LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2345    EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
2346
2347    EXPECT_EQ(5u, host.MaxPartialTextureUpdates());
2348  }
2349
2350  // When partial updates are allowed,
2351  // max updates should also be limited by the settings.
2352  {
2353    FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2354
2355    scoped_ptr<FakeProxy> proxy(new FakeProxy);
2356    proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
2357    proxy->SetMaxPartialTextureUpdates(20);
2358
2359    LayerTreeSettings settings;
2360    settings.max_partial_texture_updates = 10;
2361
2362    LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
2363    EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
2364
2365    EXPECT_EQ(10u, host.MaxPartialTextureUpdates());
2366  }
2367}
2368
2369TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
2370  FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2371
2372  LayerTreeSettings settings;
2373  settings.max_partial_texture_updates = 4;
2374
2375  scoped_ptr<LayerTreeHost> host =
2376      LayerTreeHost::Create(&client, NULL, settings, NULL);
2377  EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2378  EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2379}
2380
2381TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
2382  FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
2383
2384  LayerTreeSettings settings;
2385  settings.max_partial_texture_updates = 4;
2386
2387  scoped_ptr<LayerTreeHost> host =
2388      LayerTreeHost::Create(&client, NULL, settings, NULL);
2389  EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2390  EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2391}
2392
2393TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
2394  FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
2395
2396  LayerTreeSettings settings;
2397  settings.max_partial_texture_updates = 4;
2398
2399  scoped_ptr<LayerTreeHost> host =
2400      LayerTreeHost::Create(&client, NULL, settings, NULL);
2401  EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2402  EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2403}
2404
2405TEST(LayerTreeHostTest,
2406     PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
2407  FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2408
2409  LayerTreeSettings settings;
2410  settings.max_partial_texture_updates = 4;
2411
2412  scoped_ptr<LayerTreeHost> host =
2413      LayerTreeHost::Create(&client, NULL, settings, NULL);
2414  EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2415  EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
2416}
2417
2418class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2419    : public LayerTreeHostTest {
2420 public:
2421  LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2422      : root_layer_(FakeContentLayer::Create(&client_)),
2423        child_layer1_(FakeContentLayer::Create(&client_)),
2424        child_layer2_(FakeContentLayer::Create(&client_)),
2425        num_commits_(0) {}
2426
2427  virtual void BeginTest() OVERRIDE {
2428    layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2429    root_layer_->SetBounds(gfx::Size(100, 100));
2430    child_layer1_->SetBounds(gfx::Size(100, 100));
2431    child_layer2_->SetBounds(gfx::Size(100, 100));
2432    root_layer_->AddChild(child_layer1_);
2433    root_layer_->AddChild(child_layer2_);
2434    layer_tree_host()->SetRootLayer(root_layer_);
2435    PostSetNeedsCommitToMainThread();
2436  }
2437
2438  virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2439                                       bool visible) OVERRIDE {
2440    if (visible) {
2441      // One backing should remain unevicted.
2442      EXPECT_EQ(
2443          100u * 100u * 4u * 1u,
2444          layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2445    } else {
2446      EXPECT_EQ(
2447          0u,
2448          layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2449    }
2450
2451    // Make sure that contents textures are marked as having been
2452    // purged.
2453    EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2454    // End the test in this state.
2455    EndTest();
2456  }
2457
2458  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2459    ++num_commits_;
2460    switch (num_commits_) {
2461      case 1:
2462        // All three backings should have memory.
2463        EXPECT_EQ(
2464            100u * 100u * 4u * 3u,
2465            layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2466        // Set a new policy that will kick out 1 of the 3 resources.
2467        // Because a resource was evicted, a commit will be kicked off.
2468        host_impl->SetMemoryPolicy(
2469            ManagedMemoryPolicy(100 * 100 * 4 * 2,
2470                                gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
2471                                1000));
2472        break;
2473      case 2:
2474        // Only two backings should have memory.
2475        EXPECT_EQ(
2476            100u * 100u * 4u * 2u,
2477            layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2478        // Become backgrounded, which will cause 1 more resource to be
2479        // evicted.
2480        PostSetVisibleToMainThread(false);
2481        break;
2482      default:
2483        // No further commits should happen because this is not visible
2484        // anymore.
2485        NOTREACHED();
2486        break;
2487    }
2488  }
2489
2490  virtual void AfterTest() OVERRIDE {}
2491
2492 private:
2493  FakeContentLayerClient client_;
2494  scoped_refptr<FakeContentLayer> root_layer_;
2495  scoped_refptr<FakeContentLayer> child_layer1_;
2496  scoped_refptr<FakeContentLayer> child_layer2_;
2497  int num_commits_;
2498};
2499
2500SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(
2501    LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2502
2503class LayerTreeHostTestLCDNotification : public LayerTreeHostTest {
2504 public:
2505  class NotificationClient : public ContentLayerClient {
2506   public:
2507    NotificationClient()
2508        : layer_(0), paint_count_(0), lcd_notification_count_(0) {}
2509
2510    void set_layer(Layer* layer) { layer_ = layer; }
2511    int paint_count() const { return paint_count_; }
2512    int lcd_notification_count() const { return lcd_notification_count_; }
2513
2514    virtual void PaintContents(SkCanvas* canvas,
2515                               gfx::Rect clip,
2516                               gfx::RectF* opaque) OVERRIDE {
2517      ++paint_count_;
2518    }
2519    virtual void DidChangeLayerCanUseLCDText() OVERRIDE {
2520      ++lcd_notification_count_;
2521      layer_->SetNeedsDisplay();
2522    }
2523
2524   private:
2525    Layer* layer_;
2526    int paint_count_;
2527    int lcd_notification_count_;
2528  };
2529
2530  virtual void SetupTree() OVERRIDE {
2531    scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2532    root_layer->SetIsDrawable(true);
2533    root_layer->SetBounds(gfx::Size(1, 1));
2534
2535    layer_tree_host()->SetRootLayer(root_layer);
2536    client_.set_layer(root_layer.get());
2537
2538    // The expecations are based on the assumption that the default
2539    // LCD settings are:
2540    EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2541    EXPECT_FALSE(root_layer->can_use_lcd_text());
2542
2543    LayerTreeHostTest::SetupTree();
2544  }
2545
2546  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2547  virtual void AfterTest() OVERRIDE {}
2548
2549  virtual void DidCommit() OVERRIDE {
2550    switch (layer_tree_host()->source_frame_number()) {
2551      case 1:
2552        // The first update consists one LCD notification and one paint.
2553        EXPECT_EQ(1, client_.lcd_notification_count());
2554        EXPECT_EQ(1, client_.paint_count());
2555        // LCD text must have been enabled on the layer.
2556        EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2557        PostSetNeedsCommitToMainThread();
2558        break;
2559      case 2:
2560        // Since nothing changed on layer, there should be no notification
2561        // or paint on the second update.
2562        EXPECT_EQ(1, client_.lcd_notification_count());
2563        EXPECT_EQ(1, client_.paint_count());
2564        // LCD text must not have changed.
2565        EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2566        // Change layer opacity that should trigger lcd notification.
2567        layer_tree_host()->root_layer()->SetOpacity(.5f);
2568        // No need to request a commit - setting opacity will do it.
2569        break;
2570      default:
2571        // Verify that there is not extra commit due to layer invalidation.
2572        EXPECT_EQ(3, layer_tree_host()->source_frame_number());
2573        // LCD notification count should have incremented due to
2574        // change in layer opacity.
2575        EXPECT_EQ(2, client_.lcd_notification_count());
2576        // Paint count should be incremented due to invalidation.
2577        EXPECT_EQ(2, client_.paint_count());
2578        // LCD text must have been disabled on the layer due to opacity.
2579        EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
2580        EndTest();
2581        break;
2582    }
2583  }
2584
2585 private:
2586  NotificationClient client_;
2587};
2588
2589SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification);
2590
2591// Verify that the BeginImplFrame notification is used to initiate rendering.
2592class LayerTreeHostTestBeginImplFrameNotification : public LayerTreeHostTest {
2593 public:
2594  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2595    settings->begin_impl_frame_scheduling_enabled = true;
2596  }
2597
2598  virtual void BeginTest() OVERRIDE {
2599    // This will trigger a SetNeedsBeginImplFrame which will trigger a
2600    // BeginImplFrame.
2601    PostSetNeedsCommitToMainThread();
2602  }
2603
2604  virtual bool PrepareToDrawOnThread(
2605      LayerTreeHostImpl* host_impl,
2606      LayerTreeHostImpl::FrameData* frame,
2607      bool result) OVERRIDE {
2608    EndTest();
2609    return true;
2610  }
2611
2612  virtual void AfterTest() OVERRIDE {}
2613
2614 private:
2615  base::TimeTicks frame_time_;
2616};
2617
2618MULTI_THREAD_TEST_F(LayerTreeHostTestBeginImplFrameNotification);
2619
2620class LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled
2621    : public LayerTreeHostTest {
2622 public:
2623  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2624    settings->begin_impl_frame_scheduling_enabled = true;
2625    settings->using_synchronous_renderer_compositor = true;
2626  }
2627
2628  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2629
2630  virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2631    // The BeginImplFrame notification is turned off now but will get enabled
2632    // once we return. End test while it's enabled.
2633    ImplThreadTaskRunner()->PostTask(
2634        FROM_HERE,
2635        base::Bind(&LayerTreeHostTestBeginImplFrameNotification::EndTest,
2636                   base::Unretained(this)));
2637  }
2638
2639  virtual void AfterTest() OVERRIDE {}
2640};
2641
2642MULTI_THREAD_TEST_F(
2643    LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled);
2644
2645class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
2646 protected:
2647  LayerTreeHostTestAbortedCommitDoesntStall()
2648      : commit_count_(0), commit_complete_count_(0) {}
2649
2650  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2651    settings->begin_impl_frame_scheduling_enabled = true;
2652  }
2653
2654  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2655
2656  virtual void DidCommit() OVERRIDE {
2657    commit_count_++;
2658    if (commit_count_ == 2) {
2659      // A commit was just aborted, request a real commit now to make sure a
2660      // real commit following an aborted commit will still complete and
2661      // end the test even when the Impl thread is idle.
2662      layer_tree_host()->SetNeedsCommit();
2663    }
2664  }
2665
2666  virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2667    commit_complete_count_++;
2668    if (commit_complete_count_ == 1) {
2669      // Initiate an aborted commit after the first commit.
2670      host_impl->SetNeedsCommit();
2671    } else {
2672      EndTest();
2673    }
2674  }
2675
2676  virtual void AfterTest() OVERRIDE {
2677    EXPECT_EQ(commit_count_, 3);
2678    EXPECT_EQ(commit_complete_count_, 2);
2679  }
2680
2681  int commit_count_;
2682  int commit_complete_count_;
2683};
2684
2685class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
2686    : public LayerTreeHostTestAbortedCommitDoesntStall {
2687  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2688    LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2689    settings->using_synchronous_renderer_compositor = true;
2690  }
2691};
2692
2693MULTI_THREAD_TEST_F(
2694    LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor);
2695
2696class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync
2697    : public LayerTreeHostTestAbortedCommitDoesntStall {
2698  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2699    LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings);
2700    settings->throttle_frame_production = false;
2701  }
2702};
2703
2704MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync);
2705
2706class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2707    : public LayerTreeHostTest {
2708 protected:
2709  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2710    settings->impl_side_painting = true;
2711  }
2712
2713  virtual void SetupTree() OVERRIDE {
2714    LayerTreeHostTest::SetupTree();
2715
2716    scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2717    layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2718    layer->SetBounds(gfx::Size(10, 10));
2719    layer_tree_host()->root_layer()->AddChild(layer);
2720  }
2721
2722  virtual void BeginTest() OVERRIDE {
2723    PostSetNeedsCommitToMainThread();
2724  }
2725
2726  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2727    EndTest();
2728  }
2729
2730  virtual void AfterTest() OVERRIDE {
2731  }
2732
2733  FakeContentLayerClient client_;
2734};
2735
2736MULTI_THREAD_TEST_F(
2737    LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2738
2739class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2740    : public LayerTreeHostTest {
2741 public:
2742  class SetBoundsClient : public ContentLayerClient {
2743   public:
2744    SetBoundsClient() : layer_(0) {}
2745
2746    void set_layer(Layer* layer) { layer_ = layer; }
2747
2748    virtual void PaintContents(SkCanvas* canvas,
2749                               gfx::Rect clip,
2750                               gfx::RectF* opaque) OVERRIDE {
2751      layer_->SetBounds(gfx::Size(2, 2));
2752    }
2753
2754    virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
2755
2756   private:
2757    Layer* layer_;
2758  };
2759
2760  LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2761
2762  virtual void SetupTree() OVERRIDE {
2763    scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2764    root_layer->SetIsDrawable(true);
2765    root_layer->SetBounds(gfx::Size(1, 1));
2766
2767    layer_tree_host()->SetRootLayer(root_layer);
2768    client_.set_layer(root_layer.get());
2769
2770    LayerTreeHostTest::SetupTree();
2771  }
2772
2773  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2774  virtual void AfterTest() OVERRIDE {}
2775
2776  virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2777    num_commits_++;
2778    if (num_commits_ == 1) {
2779      LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2780      EXPECT_SIZE_EQ(gfx::Size(1, 1), root_layer->bounds());
2781    } else {
2782      LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2783      EXPECT_SIZE_EQ(gfx::Size(2, 2), root_layer->bounds());
2784      EndTest();
2785    }
2786  }
2787
2788 private:
2789  SetBoundsClient client_;
2790  int num_commits_;
2791};
2792
2793SINGLE_THREAD_TEST_F(LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2794
2795class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
2796 public:
2797  MockIOSurfaceWebGraphicsContext3D() {
2798    test_capabilities_.iosurface = true;
2799    test_capabilities_.texture_rectangle = true;
2800  }
2801
2802  virtual WebKit::WebGLId createTexture() OVERRIDE {
2803    return 1;
2804  }
2805
2806  MOCK_METHOD1(activeTexture, void(WebKit::WGC3Denum texture));
2807  MOCK_METHOD2(bindTexture, void(WebKit::WGC3Denum target,
2808                                 WebKit::WebGLId texture_id));
2809  MOCK_METHOD3(texParameteri, void(WebKit::WGC3Denum target,
2810                                   WebKit::WGC3Denum pname,
2811                                   WebKit::WGC3Dint param));
2812  MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(WebKit::WGC3Denum target,
2813                                                 WebKit::WGC3Dint width,
2814                                                 WebKit::WGC3Dint height,
2815                                                 WebKit::WGC3Duint ioSurfaceId,
2816                                                 WebKit::WGC3Duint plane));
2817  MOCK_METHOD4(drawElements, void(WebKit::WGC3Denum mode,
2818                                  WebKit::WGC3Dsizei count,
2819                                  WebKit::WGC3Denum type,
2820                                  WebKit::WGC3Dintptr offset));
2821  MOCK_METHOD1(deleteTexture, void(WebKit::WGC3Denum texture));
2822};
2823
2824
2825class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2826 protected:
2827  virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
2828      OVERRIDE {
2829    scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
2830        new MockIOSurfaceWebGraphicsContext3D);
2831    mock_context_ = mock_context_owned.get();
2832
2833    scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
2834        mock_context_owned.PassAs<TestWebGraphicsContext3D>()));
2835    return output_surface.Pass();
2836  }
2837
2838  virtual void SetupTree() OVERRIDE {
2839    LayerTreeHostTest::SetupTree();
2840
2841    layer_tree_host()->root_layer()->SetIsDrawable(false);
2842
2843    io_surface_id_ = 9;
2844    io_surface_size_ = gfx::Size(6, 7);
2845
2846    scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
2847    io_surface_layer->SetBounds(gfx::Size(10, 10));
2848    io_surface_layer->SetAnchorPoint(gfx::PointF());
2849    io_surface_layer->SetIsDrawable(true);
2850    io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
2851    layer_tree_host()->root_layer()->AddChild(io_surface_layer);
2852  }
2853
2854  virtual void BeginTest() OVERRIDE {
2855    PostSetNeedsCommitToMainThread();
2856  }
2857
2858  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2859    // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2860
2861    EXPECT_CALL(*mock_context_, activeTexture(_))
2862        .Times(0);
2863    EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2864        .Times(AtLeast(1));
2865    EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2866                                              GL_TEXTURE_MIN_FILTER,
2867                                              GL_LINEAR))
2868        .Times(1);
2869    EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2870                                              GL_TEXTURE_MAG_FILTER,
2871                                              GL_LINEAR))
2872        .Times(1);
2873    EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2874                                              GL_TEXTURE_WRAP_S,
2875                                              GL_CLAMP_TO_EDGE))
2876        .Times(1);
2877    EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2878                                              GL_TEXTURE_WRAP_T,
2879                                              GL_CLAMP_TO_EDGE))
2880        .Times(1);
2881
2882    EXPECT_CALL(*mock_context_, texImageIOSurface2DCHROMIUM(
2883        GL_TEXTURE_RECTANGLE_ARB,
2884        io_surface_size_.width(),
2885        io_surface_size_.height(),
2886        io_surface_id_,
2887        0))
2888        .Times(1);
2889
2890    EXPECT_CALL(*mock_context_, bindTexture(_, 0))
2891        .Times(AnyNumber());
2892  }
2893
2894  virtual bool PrepareToDrawOnThread(
2895      LayerTreeHostImpl* host_impl,
2896      LayerTreeHostImpl::FrameData* frame,
2897      bool result) OVERRIDE {
2898    Mock::VerifyAndClearExpectations(&mock_context_);
2899
2900    // The io surface layer's texture is drawn.
2901    EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0))
2902        .Times(AtLeast(1));
2903    EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2904        .Times(1);
2905    EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
2906        .Times(AtLeast(1));
2907
2908    return result;
2909  }
2910
2911  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2912    Mock::VerifyAndClearExpectations(&mock_context_);
2913
2914    EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(1);
2915    EndTest();
2916  }
2917
2918  virtual void AfterTest() OVERRIDE {}
2919
2920  int io_surface_id_;
2921  MockIOSurfaceWebGraphicsContext3D* mock_context_;
2922  gfx::Size io_surface_size_;
2923};
2924
2925// TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
2926SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2927    LayerTreeHostTestIOSurfaceDrawing);
2928
2929class LayerTreeHostTestAsyncReadback : public LayerTreeHostTest {
2930 protected:
2931  virtual void SetupTree() OVERRIDE {
2932    root = FakeContentLayer::Create(&client_);
2933    root->SetBounds(gfx::Size(20, 20));
2934
2935    child = FakeContentLayer::Create(&client_);
2936    child->SetBounds(gfx::Size(10, 10));
2937    root->AddChild(child);
2938
2939    layer_tree_host()->SetRootLayer(root);
2940    LayerTreeHostTest::SetupTree();
2941  }
2942
2943  virtual void BeginTest() OVERRIDE {
2944    PostSetNeedsCommitToMainThread();
2945  }
2946
2947  virtual void DidCommitAndDrawFrame() OVERRIDE {
2948    WaitForCallback();
2949  }
2950
2951  void WaitForCallback() {
2952    base::MessageLoop::current()->PostTask(
2953        FROM_HERE,
2954        base::Bind(
2955            &LayerTreeHostTestAsyncReadback::NextStep,
2956            base::Unretained(this)));
2957  }
2958
2959  void NextStep() {
2960    int frame = layer_tree_host()->source_frame_number();
2961    switch (frame) {
2962      case 1:
2963        child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2964            base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2965                       base::Unretained(this))));
2966        EXPECT_EQ(0u, callbacks_.size());
2967        break;
2968      case 2:
2969        if (callbacks_.size() < 1u) {
2970          WaitForCallback();
2971          return;
2972        }
2973        EXPECT_EQ(1u, callbacks_.size());
2974        EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[0].ToString());
2975
2976        child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2977            base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2978                       base::Unretained(this))));
2979        root->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2980            base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2981                       base::Unretained(this))));
2982        child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2983            base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2984                       base::Unretained(this))));
2985        EXPECT_EQ(1u, callbacks_.size());
2986        break;
2987      case 3:
2988        if (callbacks_.size() < 4u) {
2989          WaitForCallback();
2990          return;
2991        }
2992        EXPECT_EQ(4u, callbacks_.size());
2993        // The child was copied to a bitmap and passed back twice.
2994        EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[1].ToString());
2995        EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[2].ToString());
2996        // The root was copied to a bitmap and passed back also.
2997        EXPECT_EQ(gfx::Size(20, 20).ToString(), callbacks_[3].ToString());
2998        EndTest();
2999        break;
3000    }
3001  }
3002
3003  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3004    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3005    EXPECT_TRUE(result->HasBitmap());
3006    scoped_ptr<SkBitmap> bitmap = result->TakeBitmap().Pass();
3007    EXPECT_EQ(result->size().ToString(),
3008              gfx::Size(bitmap->width(), bitmap->height()).ToString());
3009    callbacks_.push_back(result->size());
3010  }
3011
3012  virtual void AfterTest() OVERRIDE {
3013    EXPECT_EQ(4u, callbacks_.size());
3014  }
3015
3016  virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
3017      OVERRIDE {
3018    scoped_ptr<FakeOutputSurface> output_surface;
3019    if (use_gl_renderer_) {
3020      output_surface = FakeOutputSurface::Create3d().Pass();
3021    } else {
3022      output_surface = FakeOutputSurface::CreateSoftware(
3023          make_scoped_ptr(new SoftwareOutputDevice)).Pass();
3024    }
3025    return output_surface.PassAs<OutputSurface>();
3026  }
3027
3028  bool use_gl_renderer_;
3029  std::vector<gfx::Size> callbacks_;
3030  FakeContentLayerClient client_;
3031  scoped_refptr<FakeContentLayer> root;
3032  scoped_refptr<FakeContentLayer> child;
3033};
3034
3035// Readback can't be done with a delegating renderer.
3036TEST_F(LayerTreeHostTestAsyncReadback, GLRenderer_RunSingleThread) {
3037  use_gl_renderer_ = true;
3038  RunTest(false, false, false);
3039}
3040
3041TEST_F(LayerTreeHostTestAsyncReadback,
3042       GLRenderer_RunMultiThread_MainThreadPainting) {
3043  use_gl_renderer_ = true;
3044  RunTest(true, false, false);
3045}
3046
3047TEST_F(LayerTreeHostTestAsyncReadback, SoftwareRenderer_RunSingleThread) {
3048  use_gl_renderer_ = false;
3049  RunTest(false, false, false);
3050}
3051
3052TEST_F(LayerTreeHostTestAsyncReadback,
3053       SoftwareRenderer_RunMultiThread_MainThreadPainting) {
3054  use_gl_renderer_ = false;
3055  RunTest(true, false, false);
3056}
3057
3058class LayerTreeHostTestAsyncReadbackLayerDestroyed : public LayerTreeHostTest {
3059 protected:
3060  virtual void SetupTree() OVERRIDE {
3061    root_ = FakeContentLayer::Create(&client_);
3062    root_->SetBounds(gfx::Size(20, 20));
3063
3064    main_destroyed_ = FakeContentLayer::Create(&client_);
3065    main_destroyed_->SetBounds(gfx::Size(15, 15));
3066    root_->AddChild(main_destroyed_);
3067
3068    impl_destroyed_ = FakeContentLayer::Create(&client_);
3069    impl_destroyed_->SetBounds(gfx::Size(10, 10));
3070    root_->AddChild(impl_destroyed_);
3071
3072    layer_tree_host()->SetRootLayer(root_);
3073    LayerTreeHostTest::SetupTree();
3074  }
3075
3076  virtual void BeginTest() OVERRIDE {
3077    callback_count_ = 0;
3078    PostSetNeedsCommitToMainThread();
3079  }
3080
3081  virtual void DidCommit() OVERRIDE {
3082    int frame = layer_tree_host()->source_frame_number();
3083    switch (frame) {
3084      case 1:
3085        main_destroyed_->RequestCopyOfOutput(
3086            CopyOutputRequest::CreateBitmapRequest(base::Bind(
3087                &LayerTreeHostTestAsyncReadbackLayerDestroyed::
3088                    CopyOutputCallback,
3089                base::Unretained(this))));
3090        impl_destroyed_->RequestCopyOfOutput(
3091            CopyOutputRequest::CreateBitmapRequest(base::Bind(
3092                &LayerTreeHostTestAsyncReadbackLayerDestroyed::
3093                    CopyOutputCallback,
3094                base::Unretained(this))));
3095        EXPECT_EQ(0, callback_count_);
3096
3097        // Destroy the main thread layer right away.
3098        main_destroyed_->RemoveFromParent();
3099        main_destroyed_ = NULL;
3100
3101        // Should callback with a NULL bitmap.
3102        EXPECT_EQ(1, callback_count_);
3103
3104        // Prevent drawing so we can't make a copy of the impl_destroyed layer.
3105        layer_tree_host()->SetViewportSize(gfx::Size());
3106        break;
3107      case 2:
3108        // Flush the message loops and make sure the callbacks run.
3109        layer_tree_host()->SetNeedsCommit();
3110        break;
3111      case 3:
3112        // No drawing means no readback yet.
3113        EXPECT_EQ(1, callback_count_);
3114
3115        // Destroy the impl thread layer.
3116        impl_destroyed_->RemoveFromParent();
3117        impl_destroyed_ = NULL;
3118
3119        // No callback yet because it's on the impl side.
3120        EXPECT_EQ(1, callback_count_);
3121        break;
3122      case 4:
3123        // Flush the message loops and make sure the callbacks run.
3124        layer_tree_host()->SetNeedsCommit();
3125        break;
3126      case 5:
3127        // We should get another callback with a NULL bitmap.
3128        EXPECT_EQ(2, callback_count_);
3129        EndTest();
3130        break;
3131    }
3132  }
3133
3134  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3135    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3136    EXPECT_TRUE(result->IsEmpty());
3137    ++callback_count_;
3138  }
3139
3140  virtual void AfterTest() OVERRIDE {}
3141
3142  int callback_count_;
3143  FakeContentLayerClient client_;
3144  scoped_refptr<FakeContentLayer> root_;
3145  scoped_refptr<FakeContentLayer> main_destroyed_;
3146  scoped_refptr<FakeContentLayer> impl_destroyed_;
3147};
3148
3149SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAsyncReadbackLayerDestroyed);
3150
3151class LayerTreeHostTestAsyncReadbackInHiddenSubtree : public LayerTreeHostTest {
3152 protected:
3153  virtual void SetupTree() OVERRIDE {
3154    root_ = FakeContentLayer::Create(&client_);
3155    root_->SetBounds(gfx::Size(20, 20));
3156
3157    grand_parent_layer_ = FakeContentLayer::Create(&client_);
3158    grand_parent_layer_->SetBounds(gfx::Size(15, 15));
3159    root_->AddChild(grand_parent_layer_);
3160
3161    // parent_layer_ owns a render surface.
3162    parent_layer_ = FakeContentLayer::Create(&client_);
3163    parent_layer_->SetBounds(gfx::Size(15, 15));
3164    parent_layer_->SetForceRenderSurface(true);
3165    grand_parent_layer_->AddChild(parent_layer_);
3166
3167    copy_layer_ = FakeContentLayer::Create(&client_);
3168    copy_layer_->SetBounds(gfx::Size(10, 10));
3169    parent_layer_->AddChild(copy_layer_);
3170
3171    layer_tree_host()->SetRootLayer(root_);
3172    LayerTreeHostTest::SetupTree();
3173  }
3174
3175  void AddCopyRequest(Layer* layer) {
3176    layer->RequestCopyOfOutput(
3177        CopyOutputRequest::CreateBitmapRequest(base::Bind(
3178            &LayerTreeHostTestAsyncReadbackInHiddenSubtree::CopyOutputCallback,
3179            base::Unretained(this))));
3180  }
3181
3182  virtual void BeginTest() OVERRIDE {
3183    callback_count_ = 0;
3184    PostSetNeedsCommitToMainThread();
3185
3186    AddCopyRequest(copy_layer_.get());
3187  }
3188
3189  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3190    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3191    EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
3192    ++callback_count_;
3193
3194    switch (callback_count_) {
3195      case 1:
3196        // Hide the copy request layer.
3197        grand_parent_layer_->SetHideLayerAndSubtree(false);
3198        parent_layer_->SetHideLayerAndSubtree(false);
3199        copy_layer_->SetHideLayerAndSubtree(true);
3200        AddCopyRequest(copy_layer_.get());
3201        break;
3202      case 2:
3203        // Hide the copy request layer's parent only.
3204        grand_parent_layer_->SetHideLayerAndSubtree(false);
3205        parent_layer_->SetHideLayerAndSubtree(true);
3206        copy_layer_->SetHideLayerAndSubtree(false);
3207        AddCopyRequest(copy_layer_.get());
3208        break;
3209      case 3:
3210        // Hide the copy request layer's grand parent only.
3211        grand_parent_layer_->SetHideLayerAndSubtree(true);
3212        parent_layer_->SetHideLayerAndSubtree(false);
3213        copy_layer_->SetHideLayerAndSubtree(false);
3214        AddCopyRequest(copy_layer_.get());
3215        break;
3216      case 4:
3217        // Hide the copy request layer's parent and grandparent.
3218        grand_parent_layer_->SetHideLayerAndSubtree(true);
3219        parent_layer_->SetHideLayerAndSubtree(true);
3220        copy_layer_->SetHideLayerAndSubtree(false);
3221        AddCopyRequest(copy_layer_.get());
3222        break;
3223      case 5:
3224        // Hide the copy request layer as well as its parent and grandparent.
3225        grand_parent_layer_->SetHideLayerAndSubtree(true);
3226        parent_layer_->SetHideLayerAndSubtree(true);
3227        copy_layer_->SetHideLayerAndSubtree(true);
3228        AddCopyRequest(copy_layer_.get());
3229        break;
3230      case 6:
3231        EndTest();
3232        break;
3233    }
3234  }
3235
3236  virtual void AfterTest() OVERRIDE {}
3237
3238  int callback_count_;
3239  FakeContentLayerClient client_;
3240  scoped_refptr<FakeContentLayer> root_;
3241  scoped_refptr<FakeContentLayer> grand_parent_layer_;
3242  scoped_refptr<FakeContentLayer> parent_layer_;
3243  scoped_refptr<FakeContentLayer> copy_layer_;
3244};
3245
3246// No output to copy for delegated renderers.
3247SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
3248    LayerTreeHostTestAsyncReadbackInHiddenSubtree);
3249
3250class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
3251    : public LayerTreeHostTest {
3252 protected:
3253  virtual void SetupTree() OVERRIDE {
3254    root_ = FakeContentLayer::Create(&client_);
3255    root_->SetBounds(gfx::Size(20, 20));
3256
3257    grand_parent_layer_ = FakeContentLayer::Create(&client_);
3258    grand_parent_layer_->SetBounds(gfx::Size(15, 15));
3259    grand_parent_layer_->SetHideLayerAndSubtree(true);
3260    root_->AddChild(grand_parent_layer_);
3261
3262    // parent_layer_ owns a render surface.
3263    parent_layer_ = FakeContentLayer::Create(&client_);
3264    parent_layer_->SetBounds(gfx::Size(15, 15));
3265    parent_layer_->SetForceRenderSurface(true);
3266    grand_parent_layer_->AddChild(parent_layer_);
3267
3268    copy_layer_ = FakeContentLayer::Create(&client_);
3269    copy_layer_->SetBounds(gfx::Size(10, 10));
3270    parent_layer_->AddChild(copy_layer_);
3271
3272    layer_tree_host()->SetRootLayer(root_);
3273    LayerTreeHostTest::SetupTree();
3274  }
3275
3276  virtual void BeginTest() OVERRIDE {
3277    did_draw_ = false;
3278    PostSetNeedsCommitToMainThread();
3279
3280    copy_layer_->RequestCopyOfOutput(
3281        CopyOutputRequest::CreateBitmapRequest(base::Bind(
3282            &LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest::
3283                CopyOutputCallback,
3284            base::Unretained(this))));
3285  }
3286
3287  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3288    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3289    EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
3290    EndTest();
3291  }
3292
3293  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
3294    Renderer* renderer = host_impl->renderer();
3295
3296    LayerImpl* root = host_impl->active_tree()->root_layer();
3297    LayerImpl* grand_parent = root->children()[0];
3298    LayerImpl* parent = grand_parent->children()[0];
3299    LayerImpl* copy_layer = parent->children()[0];
3300
3301    // |parent| owns a surface, but it was hidden and not part of the copy
3302    // request so it should not allocate any resource.
3303    EXPECT_FALSE(renderer->HasAllocatedResourcesForTesting(
3304        parent->render_surface()->RenderPassId()));
3305
3306    // |copy_layer| should have been rendered to a texture since it was needed
3307    // for a copy request.
3308    EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting(
3309        copy_layer->render_surface()->RenderPassId()));
3310
3311    did_draw_ = true;
3312  }
3313
3314  virtual void AfterTest() OVERRIDE { EXPECT_TRUE(did_draw_); }
3315
3316  FakeContentLayerClient client_;
3317  bool did_draw_;
3318  scoped_refptr<FakeContentLayer> root_;
3319  scoped_refptr<FakeContentLayer> grand_parent_layer_;
3320  scoped_refptr<FakeContentLayer> parent_layer_;
3321  scoped_refptr<FakeContentLayer> copy_layer_;
3322};
3323
3324// No output to copy for delegated renderers.
3325SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
3326      LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest);
3327
3328class LayerTreeHostTestAsyncReadbackClippedOut : public LayerTreeHostTest {
3329 protected:
3330  virtual void SetupTree() OVERRIDE {
3331    root_ = FakeContentLayer::Create(&client_);
3332    root_->SetBounds(gfx::Size(20, 20));
3333
3334    parent_layer_ = FakeContentLayer::Create(&client_);
3335    parent_layer_->SetBounds(gfx::Size(15, 15));
3336    parent_layer_->SetMasksToBounds(true);
3337    root_->AddChild(parent_layer_);
3338
3339    copy_layer_ = FakeContentLayer::Create(&client_);
3340    copy_layer_->SetPosition(gfx::Point(15, 15));
3341    copy_layer_->SetBounds(gfx::Size(10, 10));
3342    parent_layer_->AddChild(copy_layer_);
3343
3344    layer_tree_host()->SetRootLayer(root_);
3345    LayerTreeHostTest::SetupTree();
3346  }
3347
3348  virtual void BeginTest() OVERRIDE {
3349    PostSetNeedsCommitToMainThread();
3350
3351    copy_layer_->RequestCopyOfOutput(
3352        CopyOutputRequest::CreateBitmapRequest(base::Bind(
3353            &LayerTreeHostTestAsyncReadbackClippedOut::CopyOutputCallback,
3354            base::Unretained(this))));
3355  }
3356
3357  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3358    // We should still get a callback with no output if the copy requested layer
3359    // was completely clipped away.
3360    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3361    EXPECT_EQ(gfx::Size().ToString(), result->size().ToString());
3362    EndTest();
3363  }
3364
3365  virtual void AfterTest() OVERRIDE {}
3366
3367  FakeContentLayerClient client_;
3368  scoped_refptr<FakeContentLayer> root_;
3369  scoped_refptr<FakeContentLayer> parent_layer_;
3370  scoped_refptr<FakeContentLayer> copy_layer_;
3371};
3372
3373// No output to copy for delegated renderers.
3374SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
3375    LayerTreeHostTestAsyncReadbackClippedOut);
3376
3377class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw : public LayerTreeHostTest {
3378 protected:
3379  virtual void SetupTree() OVERRIDE {
3380    root_ = FakeContentLayer::Create(&client_);
3381    root_->SetBounds(gfx::Size(20, 20));
3382
3383    copy_layer_ = FakeContentLayer::Create(&client_);
3384    copy_layer_->SetBounds(gfx::Size(10, 10));
3385    root_->AddChild(copy_layer_);
3386
3387    layer_tree_host()->SetRootLayer(root_);
3388    LayerTreeHostTest::SetupTree();
3389  }
3390
3391  void AddCopyRequest(Layer* layer) {
3392    layer->RequestCopyOfOutput(
3393        CopyOutputRequest::CreateBitmapRequest(base::Bind(
3394            &LayerTreeHostTestAsyncTwoReadbacksWithoutDraw::CopyOutputCallback,
3395            base::Unretained(this))));
3396  }
3397
3398  virtual void BeginTest() OVERRIDE {
3399    saw_copy_request_ = false;
3400    callback_count_ = 0;
3401    PostSetNeedsCommitToMainThread();
3402
3403    // Prevent drawing.
3404    layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
3405
3406    AddCopyRequest(copy_layer_.get());
3407  }
3408
3409  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3410    if (impl->active_tree()->source_frame_number() == 0) {
3411      LayerImpl* root = impl->active_tree()->root_layer();
3412      EXPECT_TRUE(root->children()[0]->HasCopyRequest());
3413      saw_copy_request_ = true;
3414    }
3415  }
3416
3417  virtual void DidCommit() OVERRIDE {
3418    if (layer_tree_host()->source_frame_number() == 1) {
3419      // Allow drawing.
3420      layer_tree_host()->SetViewportSize(gfx::Size(root_->bounds()));
3421
3422      AddCopyRequest(copy_layer_.get());
3423    }
3424  }
3425
3426  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3427    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3428    EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
3429    ++callback_count_;
3430
3431    if (callback_count_ == 2)
3432      EndTest();
3433  }
3434
3435  virtual void AfterTest() OVERRIDE { EXPECT_TRUE(saw_copy_request_); }
3436
3437  bool saw_copy_request_;
3438  int callback_count_;
3439  FakeContentLayerClient client_;
3440  scoped_refptr<FakeContentLayer> root_;
3441  scoped_refptr<FakeContentLayer> copy_layer_;
3442};
3443
3444// No output to copy for delegated renderers.
3445SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
3446    LayerTreeHostTestAsyncTwoReadbacksWithoutDraw);
3447
3448class LayerTreeHostTestAsyncReadbackLostOutputSurface
3449    : public LayerTreeHostTest {
3450 protected:
3451  virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
3452      OVERRIDE {
3453    if (!first_context_provider_.get()) {
3454      first_context_provider_ = TestContextProvider::Create();
3455      return FakeOutputSurface::Create3d(first_context_provider_)
3456          .PassAs<OutputSurface>();
3457    }
3458
3459    EXPECT_FALSE(second_context_provider_.get());
3460    second_context_provider_ = TestContextProvider::Create();
3461    return FakeOutputSurface::Create3d(second_context_provider_)
3462        .PassAs<OutputSurface>();
3463  }
3464
3465  virtual void SetupTree() OVERRIDE {
3466    root_ = FakeContentLayer::Create(&client_);
3467    root_->SetBounds(gfx::Size(20, 20));
3468
3469    copy_layer_ = FakeContentLayer::Create(&client_);
3470    copy_layer_->SetBounds(gfx::Size(10, 10));
3471    root_->AddChild(copy_layer_);
3472
3473    layer_tree_host()->SetRootLayer(root_);
3474    LayerTreeHostTest::SetupTree();
3475  }
3476
3477  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
3478
3479  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3480    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3481    EXPECT_EQ(gfx::Size(10, 10).ToString(), result->size().ToString());
3482    EXPECT_TRUE(result->HasTexture());
3483
3484    // Save the result for later.
3485    EXPECT_FALSE(result_);
3486    result_ = result.Pass();
3487
3488    // Post a commit to lose the output surface.
3489    layer_tree_host()->SetNeedsCommit();
3490  }
3491
3492  virtual void DidCommitAndDrawFrame() OVERRIDE {
3493    switch (layer_tree_host()->source_frame_number()) {
3494      case 1:
3495        // The layers have been pushed to the impl side. The layer textures have
3496        // been allocated.
3497
3498        // Request a copy of the layer. This will use another texture.
3499        copy_layer_->RequestCopyOfOutput(
3500            CopyOutputRequest::CreateRequest(base::Bind(
3501                &LayerTreeHostTestAsyncReadbackLostOutputSurface::
3502                CopyOutputCallback,
3503                base::Unretained(this))));
3504        break;
3505      case 4:
3506        // With SingleThreadProxy it takes two commits to finally swap after a
3507        // context loss.
3508      case 5:
3509        // Now destroy the CopyOutputResult, releasing the texture inside back
3510        // to the compositor.
3511        EXPECT_TRUE(result_);
3512        result_.reset();
3513
3514        // Check that it is released.
3515        ImplThreadTaskRunner()->PostTask(
3516            FROM_HERE,
3517            base::Bind(&LayerTreeHostTestAsyncReadbackLostOutputSurface::
3518                            CheckNumTextures,
3519                       base::Unretained(this),
3520                       num_textures_after_loss_ - 1));
3521        break;
3522    }
3523  }
3524
3525  virtual void SwapBuffersOnThread(LayerTreeHostImpl *impl, bool result)
3526      OVERRIDE {
3527    switch (impl->active_tree()->source_frame_number()) {
3528      case 0:
3529        // The layers have been drawn, so their textures have been allocated.
3530        EXPECT_FALSE(result_);
3531        num_textures_without_readback_ =
3532            first_context_provider_->TestContext3d()->NumTextures();
3533        break;
3534      case 1:
3535        // We did a readback, so there will be a readback texture around now.
3536        EXPECT_LT(num_textures_without_readback_,
3537                  first_context_provider_->TestContext3d()->NumTextures());
3538        break;
3539      case 2:
3540        // The readback texture is collected.
3541        EXPECT_TRUE(result_);
3542
3543        // Lose the output surface.
3544        first_context_provider_->TestContext3d()->loseContextCHROMIUM(
3545            GL_GUILTY_CONTEXT_RESET_ARB,
3546            GL_INNOCENT_CONTEXT_RESET_ARB);
3547        break;
3548      case 3:
3549        // With SingleThreadProxy it takes two commits to finally swap after a
3550        // context loss.
3551      case 4:
3552        // The output surface has been recreated.
3553        EXPECT_TRUE(second_context_provider_.get());
3554
3555        num_textures_after_loss_ =
3556            first_context_provider_->TestContext3d()->NumTextures();
3557        break;
3558    }
3559  }
3560
3561  void CheckNumTextures(size_t expected_num_textures) {
3562    EXPECT_EQ(expected_num_textures,
3563              first_context_provider_->TestContext3d()->NumTextures());
3564    EndTest();
3565  }
3566
3567  virtual void AfterTest() OVERRIDE {}
3568
3569  scoped_refptr<TestContextProvider> first_context_provider_;
3570  scoped_refptr<TestContextProvider> second_context_provider_;
3571  size_t num_textures_without_readback_;
3572  size_t num_textures_after_loss_;
3573  FakeContentLayerClient client_;
3574  scoped_refptr<FakeContentLayer> root_;
3575  scoped_refptr<FakeContentLayer> copy_layer_;
3576  scoped_ptr<CopyOutputResult> result_;
3577};
3578
3579// No output to copy for delegated renderers.
3580SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
3581    LayerTreeHostTestAsyncReadbackLostOutputSurface);
3582
3583class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
3584 public:
3585  virtual void BeginTest() OVERRIDE {
3586    frame_ = 0;
3587    PostSetNeedsCommitToMainThread();
3588  }
3589
3590  // Round 1: commit + draw
3591  // Round 2: commit only (no draw/swap)
3592  // Round 3: draw only (no commit)
3593  // Round 4: composite & readback (2 commits, no draw/swap)
3594  // Round 5: commit + draw
3595
3596  virtual void DidCommit() OVERRIDE {
3597    int commit = layer_tree_host()->source_frame_number();
3598    switch (commit) {
3599      case 2:
3600        // Round 2 done.
3601        EXPECT_EQ(1, frame_);
3602        layer_tree_host()->SetNeedsRedraw();
3603        break;
3604      case 3:
3605        // CompositeAndReadback in Round 4, first commit.
3606        EXPECT_EQ(2, frame_);
3607        break;
3608      case 4:
3609        // Round 4 done.
3610        EXPECT_EQ(2, frame_);
3611        layer_tree_host()->SetNeedsCommit();
3612        layer_tree_host()->SetNeedsRedraw();
3613        break;
3614    }
3615  }
3616
3617  virtual void DidCompleteSwapBuffers() OVERRIDE {
3618    int commit = layer_tree_host()->source_frame_number();
3619    ++frame_;
3620    char pixels[4] = {0};
3621    switch (frame_) {
3622      case 1:
3623        // Round 1 done.
3624        EXPECT_EQ(1, commit);
3625        layer_tree_host()->SetNeedsCommit();
3626        break;
3627      case 2:
3628        // Round 3 done.
3629        EXPECT_EQ(2, commit);
3630        layer_tree_host()->CompositeAndReadback(pixels, gfx::Rect(0, 0, 1, 1));
3631        break;
3632      case 3:
3633        // Round 5 done.
3634        EXPECT_EQ(5, commit);
3635        EndTest();
3636        break;
3637    }
3638  }
3639
3640  virtual void AfterTest() OVERRIDE {}
3641
3642 protected:
3643  int frame_;
3644};
3645
3646TEST_F(LayerTreeHostTestNumFramesPending, DelegatingRenderer) {
3647  RunTest(true, true, true);
3648}
3649
3650TEST_F(LayerTreeHostTestNumFramesPending, GLRenderer) {
3651  RunTest(true, false, true);
3652}
3653
3654class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest {
3655 public:
3656  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
3657    // PictureLayer can only be used with impl side painting enabled.
3658    settings->impl_side_painting = true;
3659  }
3660
3661  virtual void SetupTree() OVERRIDE {
3662    layer_ = FakePictureLayer::Create(&client_);
3663    // Force commits to not be aborted so new frames get drawn, otherwise
3664    // the renderer gets deferred initialized but nothing new needs drawing.
3665    layer_->set_always_update_resources(true);
3666    layer_tree_host()->SetRootLayer(layer_);
3667    LayerTreeHostTest::SetupTree();
3668  }
3669
3670  virtual void BeginTest() OVERRIDE {
3671    did_initialize_gl_ = false;
3672    did_release_gl_ = false;
3673    last_source_frame_number_drawn_ = -1;  // Never drawn.
3674    PostSetNeedsCommitToMainThread();
3675  }
3676
3677  virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
3678      OVERRIDE {
3679    scoped_ptr<TestWebGraphicsContext3D> context3d(
3680        TestWebGraphicsContext3D::Create());
3681    context3d->set_support_swapbuffers_complete_callback(false);
3682
3683    return FakeOutputSurface::CreateDeferredGL(
3684        scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice))
3685        .PassAs<OutputSurface>();
3686  }
3687
3688  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
3689    ASSERT_TRUE(host_impl->RootLayer());
3690    FakePictureLayerImpl* layer_impl =
3691        static_cast<FakePictureLayerImpl*>(host_impl->RootLayer());
3692
3693    // The same frame can be draw multiple times if new visible tiles are
3694    // rasterized. But we want to make sure we only post DeferredInitialize
3695    // and ReleaseGL once, so early out if the same frame is drawn again.
3696    if (last_source_frame_number_drawn_ ==
3697        host_impl->active_tree()->source_frame_number())
3698      return;
3699
3700    last_source_frame_number_drawn_ =
3701        host_impl->active_tree()->source_frame_number();
3702
3703    if (!did_initialize_gl_) {
3704      EXPECT_LE(1u, layer_impl->append_quads_count());
3705      ImplThreadTaskRunner()->PostTask(
3706          FROM_HERE,
3707          base::Bind(
3708              &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw,
3709              base::Unretained(this),
3710              base::Unretained(host_impl)));
3711    } else if (did_initialize_gl_ && !did_release_gl_) {
3712      EXPECT_LE(2u, layer_impl->append_quads_count());
3713      ImplThreadTaskRunner()->PostTask(
3714          FROM_HERE,
3715          base::Bind(
3716              &LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw,
3717              base::Unretained(this),
3718              base::Unretained(host_impl)));
3719    } else if (did_initialize_gl_ && did_release_gl_) {
3720      EXPECT_LE(3u, layer_impl->append_quads_count());
3721      EndTest();
3722    }
3723  }
3724
3725  void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) {
3726    EXPECT_FALSE(did_initialize_gl_);
3727    // SetAndInitializeContext3D calls SetNeedsCommit.
3728    FakeOutputSurface* fake_output_surface =
3729        static_cast<FakeOutputSurface*>(host_impl->output_surface());
3730    scoped_refptr<TestContextProvider> context_provider =
3731        TestContextProvider::Create();  // Not bound to thread.
3732    EXPECT_TRUE(fake_output_surface->InitializeAndSetContext3d(
3733        context_provider, NULL));
3734    did_initialize_gl_ = true;
3735  }
3736
3737  void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) {
3738    EXPECT_TRUE(did_initialize_gl_);
3739    EXPECT_FALSE(did_release_gl_);
3740    // ReleaseGL calls SetNeedsCommit.
3741    static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL();
3742    did_release_gl_ = true;
3743  }
3744
3745  virtual void AfterTest() OVERRIDE {
3746    EXPECT_TRUE(did_initialize_gl_);
3747    EXPECT_TRUE(did_release_gl_);
3748  }
3749
3750 private:
3751  FakeContentLayerClient client_;
3752  scoped_refptr<FakePictureLayer> layer_;
3753  bool did_initialize_gl_;
3754  bool did_release_gl_;
3755  int last_source_frame_number_drawn_;
3756};
3757
3758MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize);
3759
3760// Test for UI Resource management.
3761class LayerTreeHostTestUIResource : public LayerTreeHostTest {
3762 public:
3763  LayerTreeHostTestUIResource() : num_ui_resources_(0), num_commits_(0) {}
3764
3765  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
3766    settings->texture_id_allocation_chunk_size = 1;
3767  }
3768
3769  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
3770
3771  virtual void DidCommit() OVERRIDE {
3772    int frame = num_commits_;
3773    switch (frame) {
3774      case 1:
3775        CreateResource();
3776        CreateResource();
3777        PostSetNeedsCommitToMainThread();
3778        break;
3779      case 2:
3780        // Usually ScopedUIResource are deleted from the manager in their
3781        // destructor.  Here we just want to test that a direct call to
3782        // DeleteUIResource works.
3783        layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3784        PostSetNeedsCommitToMainThread();
3785        break;
3786      case 3:
3787        // DeleteUIResource can be called with an invalid id.
3788        layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
3789        PostSetNeedsCommitToMainThread();
3790        break;
3791      case 4:
3792        CreateResource();
3793        CreateResource();
3794        PostSetNeedsCommitToMainThread();
3795        break;
3796      case 5:
3797        ClearResources();
3798        EndTest();
3799        break;
3800    }
3801  }
3802
3803  void PerformTest(LayerTreeHostImpl* impl) {
3804    TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
3805        impl->output_surface()->context_provider()->Context3d());
3806
3807    int frame = num_commits_;
3808    switch (frame) {
3809      case 1:
3810        ASSERT_EQ(0u, context->NumTextures());
3811        break;
3812      case 2:
3813        // Created two textures.
3814        ASSERT_EQ(2u, context->NumTextures());
3815        break;
3816      case 3:
3817        // One texture left after one deletion.
3818        ASSERT_EQ(1u, context->NumTextures());
3819        break;
3820      case 4:
3821        // Resource manager state should not change when delete is called on an
3822        // invalid id.
3823        ASSERT_EQ(1u, context->NumTextures());
3824        break;
3825      case 5:
3826        // Creation after deletion: two more creates should total up to
3827        // three textures.
3828        ASSERT_EQ(3u, context->NumTextures());
3829        break;
3830    }
3831  }
3832
3833  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3834    ++num_commits_;
3835    if (!layer_tree_host()->settings().impl_side_painting)
3836      PerformTest(impl);
3837  }
3838
3839  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
3840    if (layer_tree_host()->settings().impl_side_painting)
3841      PerformTest(impl);
3842  }
3843
3844  virtual void AfterTest() OVERRIDE {}
3845
3846 private:
3847  // Must clear all resources before exiting.
3848  void ClearResources() {
3849    for (int i = 0; i < num_ui_resources_; i++)
3850      ui_resources_[i].reset();
3851  }
3852
3853  void CreateResource() {
3854    ui_resources_[num_ui_resources_++] =
3855        FakeScopedUIResource::Create(layer_tree_host());
3856  }
3857
3858  scoped_ptr<FakeScopedUIResource> ui_resources_[5];
3859  int num_ui_resources_;
3860  int num_commits_;
3861};
3862
3863MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
3864
3865class PushPropertiesCountingLayer : public Layer {
3866 public:
3867  static scoped_refptr<PushPropertiesCountingLayer> Create() {
3868    return new PushPropertiesCountingLayer();
3869  }
3870
3871  virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE {
3872    Layer::PushPropertiesTo(layer);
3873    push_properties_count_++;
3874    if (persist_needs_push_properties_)
3875      needs_push_properties_ = true;
3876  }
3877
3878  size_t push_properties_count() const { return push_properties_count_; }
3879  void reset_push_properties_count() { push_properties_count_ = 0; }
3880
3881  void set_persist_needs_push_properties(bool persist) {
3882    persist_needs_push_properties_ = persist;
3883  }
3884
3885 private:
3886  PushPropertiesCountingLayer()
3887      : push_properties_count_(0),
3888        persist_needs_push_properties_(false) {
3889    SetAnchorPoint(gfx::PointF());
3890    SetBounds(gfx::Size(1, 1));
3891    SetIsDrawable(true);
3892  }
3893  virtual ~PushPropertiesCountingLayer() {}
3894
3895  size_t push_properties_count_;
3896  bool persist_needs_push_properties_;
3897};
3898
3899class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
3900 protected:
3901  virtual void BeginTest() OVERRIDE {
3902    num_commits_ = 0;
3903    expected_push_properties_root_ = 0;
3904    expected_push_properties_child_ = 0;
3905    expected_push_properties_grandchild_ = 0;
3906    expected_push_properties_child2_ = 0;
3907    expected_push_properties_other_root_ = 0;
3908    expected_push_properties_leaf_layer_ = 0;
3909    PostSetNeedsCommitToMainThread();
3910  }
3911
3912  virtual void SetupTree() OVERRIDE {
3913    root_ = PushPropertiesCountingLayer::Create();
3914    child_ = PushPropertiesCountingLayer::Create();
3915    child2_ = PushPropertiesCountingLayer::Create();
3916    grandchild_ = PushPropertiesCountingLayer::Create();
3917    leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
3918    leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
3919
3920    root_->AddChild(child_);
3921    root_->AddChild(child2_);
3922    child_->AddChild(grandchild_);
3923    child2_->AddChild(leaf_always_pushing_layer_);
3924
3925    other_root_ = PushPropertiesCountingLayer::Create();
3926
3927    // Don't set the root layer here.
3928    LayerTreeHostTest::SetupTree();
3929  }
3930
3931  virtual void DidCommitAndDrawFrame() OVERRIDE {
3932    ++num_commits_;
3933
3934    EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
3935    EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
3936    EXPECT_EQ(expected_push_properties_grandchild_,
3937              grandchild_->push_properties_count());
3938    EXPECT_EQ(expected_push_properties_child2_,
3939              child2_->push_properties_count());
3940    EXPECT_EQ(expected_push_properties_other_root_,
3941              other_root_->push_properties_count());
3942    EXPECT_EQ(expected_push_properties_leaf_layer_,
3943              leaf_always_pushing_layer_->push_properties_count());
3944
3945    // The scrollbar layer always needs to be pushed.
3946    if (root_->layer_tree_host()) {
3947      EXPECT_TRUE(root_->descendant_needs_push_properties());
3948      EXPECT_FALSE(root_->needs_push_properties());
3949    }
3950    if (child2_->layer_tree_host()) {
3951      EXPECT_TRUE(child2_->descendant_needs_push_properties());
3952      EXPECT_FALSE(child2_->needs_push_properties());
3953    }
3954    if (leaf_always_pushing_layer_->layer_tree_host()) {
3955      EXPECT_FALSE(
3956          leaf_always_pushing_layer_->descendant_needs_push_properties());
3957      EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
3958    }
3959
3960    // child_ and grandchild_ don't persist their need to push properties.
3961    if (child_->layer_tree_host()) {
3962      EXPECT_FALSE(child_->descendant_needs_push_properties());
3963      EXPECT_FALSE(child_->needs_push_properties());
3964    }
3965    if (grandchild_->layer_tree_host()) {
3966      EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3967      EXPECT_FALSE(grandchild_->needs_push_properties());
3968    }
3969
3970    if (other_root_->layer_tree_host()) {
3971      EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3972      EXPECT_FALSE(other_root_->needs_push_properties());
3973    }
3974
3975    switch (num_commits_) {
3976      case 1:
3977        layer_tree_host()->SetRootLayer(root_);
3978        // Layers added to the tree get committed.
3979        ++expected_push_properties_root_;
3980        ++expected_push_properties_child_;
3981        ++expected_push_properties_grandchild_;
3982        ++expected_push_properties_child2_;
3983        break;
3984      case 2:
3985        layer_tree_host()->SetNeedsCommit();
3986        // No layers need commit.
3987        break;
3988      case 3:
3989        layer_tree_host()->SetRootLayer(other_root_);
3990        // Layers added to the tree get committed.
3991        ++expected_push_properties_other_root_;
3992        break;
3993      case 4:
3994        layer_tree_host()->SetRootLayer(root_);
3995        // Layers added to the tree get committed.
3996        ++expected_push_properties_root_;
3997        ++expected_push_properties_child_;
3998        ++expected_push_properties_grandchild_;
3999        ++expected_push_properties_child2_;
4000        break;
4001      case 5:
4002        layer_tree_host()->SetNeedsCommit();
4003        // No layers need commit.
4004        break;
4005      case 6:
4006        child_->RemoveFromParent();
4007        // No layers need commit.
4008        break;
4009      case 7:
4010        root_->AddChild(child_);
4011        // Layers added to the tree get committed.
4012        ++expected_push_properties_child_;
4013        ++expected_push_properties_grandchild_;
4014        break;
4015      case 8:
4016        grandchild_->RemoveFromParent();
4017        // No layers need commit.
4018        break;
4019      case 9:
4020        child_->AddChild(grandchild_);
4021        // Layers added to the tree get committed.
4022        ++expected_push_properties_grandchild_;
4023        break;
4024      case 10:
4025        layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
4026        // No layers need commit.
4027        break;
4028      case 11:
4029        layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
4030        // No layers need commit.
4031        break;
4032      case 12:
4033        child_->SetPosition(gfx::Point(1, 1));
4034        // The modified layer needs commit
4035        ++expected_push_properties_child_;
4036        break;
4037      case 13:
4038        child2_->SetPosition(gfx::Point(1, 1));
4039        // The modified layer needs commit
4040        ++expected_push_properties_child2_;
4041        break;
4042      case 14:
4043        child_->RemoveFromParent();
4044        root_->AddChild(child_);
4045        // Layers added to the tree get committed.
4046        ++expected_push_properties_child_;
4047        ++expected_push_properties_grandchild_;
4048        break;
4049      case 15:
4050        grandchild_->SetPosition(gfx::Point(1, 1));
4051        // The modified layer needs commit
4052        ++expected_push_properties_grandchild_;
4053        break;
4054      case 16:
4055        // SetNeedsDisplay does not always set needs commit (so call it
4056        // explicitly), but is a property change.
4057        child_->SetNeedsDisplay();
4058        ++expected_push_properties_child_;
4059        layer_tree_host()->SetNeedsCommit();
4060        break;
4061      case 17:
4062        EndTest();
4063        break;
4064    }
4065
4066    // The leaf layer always pushes.
4067    if (leaf_always_pushing_layer_->layer_tree_host())
4068      ++expected_push_properties_leaf_layer_;
4069  }
4070
4071  virtual void AfterTest() OVERRIDE {}
4072
4073  int num_commits_;
4074  FakeContentLayerClient client_;
4075  scoped_refptr<PushPropertiesCountingLayer> root_;
4076  scoped_refptr<PushPropertiesCountingLayer> child_;
4077  scoped_refptr<PushPropertiesCountingLayer> child2_;
4078  scoped_refptr<PushPropertiesCountingLayer> grandchild_;
4079  scoped_refptr<PushPropertiesCountingLayer> other_root_;
4080  scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
4081  size_t expected_push_properties_root_;
4082  size_t expected_push_properties_child_;
4083  size_t expected_push_properties_child2_;
4084  size_t expected_push_properties_grandchild_;
4085  size_t expected_push_properties_other_root_;
4086  size_t expected_push_properties_leaf_layer_;
4087};
4088
4089MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
4090
4091class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
4092    : public LayerTreeHostTest {
4093 protected:
4094  virtual void BeginTest() OVERRIDE {
4095    PostSetNeedsCommitToMainThread();
4096  }
4097
4098  virtual void SetupTree() OVERRIDE {
4099    root_ = Layer::Create();
4100    root_->SetBounds(gfx::Size(1, 1));
4101
4102    bool paint_scrollbar = true;
4103    bool has_thumb = false;
4104    scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
4105        paint_scrollbar, has_thumb, root_->id());
4106
4107    root_->AddChild(scrollbar_layer_);
4108
4109    layer_tree_host()->SetRootLayer(root_);
4110    LayerTreeHostTest::SetupTree();
4111  }
4112
4113  virtual void DidCommitAndDrawFrame() OVERRIDE {
4114    switch (layer_tree_host()->source_frame_number()) {
4115      case 0:
4116        break;
4117      case 1: {
4118        // During update, the ignore_set_needs_commit_ bit is set to true to
4119        // avoid causing a second commit to be scheduled. If a property change
4120        // is made during this, however, it needs to be pushed in the upcoming
4121        // commit.
4122        scoped_ptr<base::AutoReset<bool> > ignore =
4123            scrollbar_layer_->IgnoreSetNeedsCommit();
4124
4125        scrollbar_layer_->SetBounds(gfx::Size(30, 30));
4126
4127        EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
4128        EXPECT_TRUE(root_->descendant_needs_push_properties());
4129        layer_tree_host()->SetNeedsCommit();
4130
4131        scrollbar_layer_->reset_push_properties_count();
4132        EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
4133        break;
4134      }
4135      case 2:
4136        EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
4137        EndTest();
4138        break;
4139    }
4140  }
4141
4142  virtual void AfterTest() OVERRIDE {}
4143
4144  scoped_refptr<Layer> root_;
4145  scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
4146};
4147
4148MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
4149
4150class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
4151    : public LayerTreeHostTest {
4152 protected:
4153  virtual void BeginTest() OVERRIDE {
4154    expected_push_properties_root_ = 0;
4155    expected_push_properties_child_ = 0;
4156    expected_push_properties_grandchild1_ = 0;
4157    expected_push_properties_grandchild2_ = 0;
4158    expected_push_properties_grandchild3_ = 0;
4159    PostSetNeedsCommitToMainThread();
4160  }
4161
4162  virtual void SetupTree() OVERRIDE {
4163    root_ = PushPropertiesCountingLayer::Create();
4164    child_ = PushPropertiesCountingLayer::Create();
4165    grandchild1_ = PushPropertiesCountingLayer::Create();
4166    grandchild2_ = PushPropertiesCountingLayer::Create();
4167    grandchild3_ = PushPropertiesCountingLayer::Create();
4168
4169    root_->AddChild(child_);
4170    child_->AddChild(grandchild1_);
4171    child_->AddChild(grandchild2_);
4172    child_->AddChild(grandchild3_);
4173
4174    // Don't set the root layer here.
4175    LayerTreeHostTest::SetupTree();
4176  }
4177
4178  virtual void AfterTest() OVERRIDE {}
4179
4180  FakeContentLayerClient client_;
4181  scoped_refptr<PushPropertiesCountingLayer> root_;
4182  scoped_refptr<PushPropertiesCountingLayer> child_;
4183  scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
4184  scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
4185  scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
4186  size_t expected_push_properties_root_;
4187  size_t expected_push_properties_child_;
4188  size_t expected_push_properties_grandchild1_;
4189  size_t expected_push_properties_grandchild2_;
4190  size_t expected_push_properties_grandchild3_;
4191};
4192
4193class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
4194    : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4195 protected:
4196  virtual void DidCommitAndDrawFrame() OVERRIDE {
4197    int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4198    switch (last_source_frame_number) {
4199      case 0:
4200        EXPECT_FALSE(root_->needs_push_properties());
4201        EXPECT_FALSE(root_->descendant_needs_push_properties());
4202        EXPECT_FALSE(child_->needs_push_properties());
4203        EXPECT_FALSE(child_->descendant_needs_push_properties());
4204        EXPECT_FALSE(grandchild1_->needs_push_properties());
4205        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4206        EXPECT_FALSE(grandchild2_->needs_push_properties());
4207        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4208        EXPECT_FALSE(grandchild3_->needs_push_properties());
4209        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4210
4211        layer_tree_host()->SetRootLayer(root_);
4212
4213        EXPECT_TRUE(root_->needs_push_properties());
4214        EXPECT_TRUE(root_->descendant_needs_push_properties());
4215        EXPECT_TRUE(child_->needs_push_properties());
4216        EXPECT_TRUE(child_->descendant_needs_push_properties());
4217        EXPECT_TRUE(grandchild1_->needs_push_properties());
4218        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4219        EXPECT_TRUE(grandchild2_->needs_push_properties());
4220        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4221        EXPECT_TRUE(grandchild3_->needs_push_properties());
4222        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4223        break;
4224      case 1:
4225        EndTest();
4226        break;
4227    }
4228  }
4229};
4230
4231MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
4232
4233class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
4234    : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4235 protected:
4236  virtual void DidCommitAndDrawFrame() OVERRIDE {
4237    int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4238    switch (last_source_frame_number) {
4239      case 0:
4240        layer_tree_host()->SetRootLayer(root_);
4241        break;
4242      case 1:
4243        EXPECT_FALSE(root_->needs_push_properties());
4244        EXPECT_FALSE(root_->descendant_needs_push_properties());
4245        EXPECT_FALSE(child_->needs_push_properties());
4246        EXPECT_FALSE(child_->descendant_needs_push_properties());
4247        EXPECT_FALSE(grandchild1_->needs_push_properties());
4248        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4249        EXPECT_FALSE(grandchild2_->needs_push_properties());
4250        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4251        EXPECT_FALSE(grandchild3_->needs_push_properties());
4252        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4253
4254        grandchild1_->RemoveFromParent();
4255        grandchild1_->SetPosition(gfx::Point(1, 1));
4256
4257        EXPECT_FALSE(root_->needs_push_properties());
4258        EXPECT_FALSE(root_->descendant_needs_push_properties());
4259        EXPECT_FALSE(child_->needs_push_properties());
4260        EXPECT_FALSE(child_->descendant_needs_push_properties());
4261        EXPECT_FALSE(grandchild2_->needs_push_properties());
4262        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4263        EXPECT_FALSE(grandchild3_->needs_push_properties());
4264        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4265
4266        child_->AddChild(grandchild1_);
4267
4268        EXPECT_FALSE(root_->needs_push_properties());
4269        EXPECT_TRUE(root_->descendant_needs_push_properties());
4270        EXPECT_FALSE(child_->needs_push_properties());
4271        EXPECT_TRUE(child_->descendant_needs_push_properties());
4272        EXPECT_TRUE(grandchild1_->needs_push_properties());
4273        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4274        EXPECT_FALSE(grandchild2_->needs_push_properties());
4275        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4276        EXPECT_FALSE(grandchild3_->needs_push_properties());
4277        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4278
4279        grandchild2_->SetPosition(gfx::Point(1, 1));
4280
4281        EXPECT_FALSE(root_->needs_push_properties());
4282        EXPECT_TRUE(root_->descendant_needs_push_properties());
4283        EXPECT_FALSE(child_->needs_push_properties());
4284        EXPECT_TRUE(child_->descendant_needs_push_properties());
4285        EXPECT_TRUE(grandchild1_->needs_push_properties());
4286        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4287        EXPECT_TRUE(grandchild2_->needs_push_properties());
4288        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4289        EXPECT_FALSE(grandchild3_->needs_push_properties());
4290        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4291
4292        // grandchild2_ will still need a push properties.
4293        grandchild1_->RemoveFromParent();
4294
4295        EXPECT_FALSE(root_->needs_push_properties());
4296        EXPECT_TRUE(root_->descendant_needs_push_properties());
4297        EXPECT_FALSE(child_->needs_push_properties());
4298        EXPECT_TRUE(child_->descendant_needs_push_properties());
4299
4300        // grandchild3_ does not need a push properties, so recursing should
4301        // no longer be needed.
4302        grandchild2_->RemoveFromParent();
4303
4304        EXPECT_FALSE(root_->needs_push_properties());
4305        EXPECT_FALSE(root_->descendant_needs_push_properties());
4306        EXPECT_FALSE(child_->needs_push_properties());
4307        EXPECT_FALSE(child_->descendant_needs_push_properties());
4308        EndTest();
4309        break;
4310    }
4311  }
4312};
4313
4314MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
4315
4316class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
4317    : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4318 protected:
4319  virtual void DidCommitAndDrawFrame() OVERRIDE {
4320    int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4321    switch (last_source_frame_number) {
4322      case 0:
4323        layer_tree_host()->SetRootLayer(root_);
4324        grandchild1_->set_persist_needs_push_properties(true);
4325        grandchild2_->set_persist_needs_push_properties(true);
4326        break;
4327      case 1:
4328        EXPECT_FALSE(root_->needs_push_properties());
4329        EXPECT_TRUE(root_->descendant_needs_push_properties());
4330        EXPECT_FALSE(child_->needs_push_properties());
4331        EXPECT_TRUE(child_->descendant_needs_push_properties());
4332        EXPECT_TRUE(grandchild1_->needs_push_properties());
4333        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4334        EXPECT_TRUE(grandchild2_->needs_push_properties());
4335        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4336        EXPECT_FALSE(grandchild3_->needs_push_properties());
4337        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4338
4339        // grandchild2_ will still need a push properties.
4340        grandchild1_->RemoveFromParent();
4341
4342        EXPECT_FALSE(root_->needs_push_properties());
4343        EXPECT_TRUE(root_->descendant_needs_push_properties());
4344        EXPECT_FALSE(child_->needs_push_properties());
4345        EXPECT_TRUE(child_->descendant_needs_push_properties());
4346
4347        // grandchild3_ does not need a push properties, so recursing should
4348        // no longer be needed.
4349        grandchild2_->RemoveFromParent();
4350
4351        EXPECT_FALSE(root_->needs_push_properties());
4352        EXPECT_FALSE(root_->descendant_needs_push_properties());
4353        EXPECT_FALSE(child_->needs_push_properties());
4354        EXPECT_FALSE(child_->descendant_needs_push_properties());
4355        EndTest();
4356        break;
4357    }
4358  }
4359};
4360
4361MULTI_THREAD_TEST_F(
4362    LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
4363
4364class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
4365    : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4366 protected:
4367  virtual void DidCommitAndDrawFrame() OVERRIDE {
4368    int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4369    switch (last_source_frame_number) {
4370      case 0:
4371        layer_tree_host()->SetRootLayer(root_);
4372        break;
4373      case 1:
4374        EXPECT_FALSE(root_->needs_push_properties());
4375        EXPECT_FALSE(root_->descendant_needs_push_properties());
4376        EXPECT_FALSE(child_->needs_push_properties());
4377        EXPECT_FALSE(child_->descendant_needs_push_properties());
4378        EXPECT_FALSE(grandchild1_->needs_push_properties());
4379        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4380        EXPECT_FALSE(grandchild2_->needs_push_properties());
4381        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4382        EXPECT_FALSE(grandchild3_->needs_push_properties());
4383        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4384
4385        // Change grandchildren while their parent is not in the tree.
4386        child_->RemoveFromParent();
4387        grandchild1_->SetPosition(gfx::Point(1, 1));
4388        grandchild2_->SetPosition(gfx::Point(1, 1));
4389        root_->AddChild(child_);
4390
4391        EXPECT_FALSE(root_->needs_push_properties());
4392        EXPECT_TRUE(root_->descendant_needs_push_properties());
4393        EXPECT_TRUE(child_->needs_push_properties());
4394        EXPECT_TRUE(child_->descendant_needs_push_properties());
4395        EXPECT_TRUE(grandchild1_->needs_push_properties());
4396        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4397        EXPECT_TRUE(grandchild2_->needs_push_properties());
4398        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4399        EXPECT_TRUE(grandchild3_->needs_push_properties());
4400        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4401
4402        grandchild1_->RemoveFromParent();
4403
4404        EXPECT_FALSE(root_->needs_push_properties());
4405        EXPECT_TRUE(root_->descendant_needs_push_properties());
4406        EXPECT_TRUE(child_->needs_push_properties());
4407        EXPECT_TRUE(child_->descendant_needs_push_properties());
4408
4409        grandchild2_->RemoveFromParent();
4410
4411        EXPECT_FALSE(root_->needs_push_properties());
4412        EXPECT_TRUE(root_->descendant_needs_push_properties());
4413        EXPECT_TRUE(child_->needs_push_properties());
4414        EXPECT_TRUE(child_->descendant_needs_push_properties());
4415
4416        grandchild3_->RemoveFromParent();
4417
4418        EXPECT_FALSE(root_->needs_push_properties());
4419        EXPECT_TRUE(root_->descendant_needs_push_properties());
4420        EXPECT_TRUE(child_->needs_push_properties());
4421        EXPECT_FALSE(child_->descendant_needs_push_properties());
4422
4423        EndTest();
4424        break;
4425    }
4426  }
4427};
4428
4429MULTI_THREAD_TEST_F(
4430    LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
4431
4432class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
4433    : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4434 protected:
4435  virtual void DidCommitAndDrawFrame() OVERRIDE {
4436    int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4437    switch (last_source_frame_number) {
4438      case 0:
4439        layer_tree_host()->SetRootLayer(root_);
4440        break;
4441      case 1:
4442        EXPECT_FALSE(root_->needs_push_properties());
4443        EXPECT_FALSE(root_->descendant_needs_push_properties());
4444        EXPECT_FALSE(child_->needs_push_properties());
4445        EXPECT_FALSE(child_->descendant_needs_push_properties());
4446        EXPECT_FALSE(grandchild1_->needs_push_properties());
4447        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4448        EXPECT_FALSE(grandchild2_->needs_push_properties());
4449        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4450        EXPECT_FALSE(grandchild3_->needs_push_properties());
4451        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4452
4453        child_->SetPosition(gfx::Point(1, 1));
4454        grandchild1_->SetPosition(gfx::Point(1, 1));
4455        grandchild2_->SetPosition(gfx::Point(1, 1));
4456
4457        EXPECT_FALSE(root_->needs_push_properties());
4458        EXPECT_TRUE(root_->descendant_needs_push_properties());
4459        EXPECT_TRUE(child_->needs_push_properties());
4460        EXPECT_TRUE(child_->descendant_needs_push_properties());
4461        EXPECT_TRUE(grandchild1_->needs_push_properties());
4462        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4463        EXPECT_TRUE(grandchild2_->needs_push_properties());
4464        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4465        EXPECT_FALSE(grandchild3_->needs_push_properties());
4466        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4467
4468        grandchild1_->RemoveFromParent();
4469
4470        EXPECT_FALSE(root_->needs_push_properties());
4471        EXPECT_TRUE(root_->descendant_needs_push_properties());
4472        EXPECT_TRUE(child_->needs_push_properties());
4473        EXPECT_TRUE(child_->descendant_needs_push_properties());
4474
4475        grandchild2_->RemoveFromParent();
4476
4477        EXPECT_FALSE(root_->needs_push_properties());
4478        EXPECT_TRUE(root_->descendant_needs_push_properties());
4479        EXPECT_TRUE(child_->needs_push_properties());
4480        EXPECT_FALSE(child_->descendant_needs_push_properties());
4481
4482        child_->RemoveFromParent();
4483
4484        EXPECT_FALSE(root_->needs_push_properties());
4485        EXPECT_FALSE(root_->descendant_needs_push_properties());
4486
4487        EndTest();
4488        break;
4489    }
4490  }
4491};
4492
4493MULTI_THREAD_TEST_F(
4494    LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
4495
4496class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
4497    : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
4498 protected:
4499  virtual void DidCommitAndDrawFrame() OVERRIDE {
4500    int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
4501    switch (last_source_frame_number) {
4502      case 0:
4503        layer_tree_host()->SetRootLayer(root_);
4504        break;
4505      case 1:
4506        EXPECT_FALSE(root_->needs_push_properties());
4507        EXPECT_FALSE(root_->descendant_needs_push_properties());
4508        EXPECT_FALSE(child_->needs_push_properties());
4509        EXPECT_FALSE(child_->descendant_needs_push_properties());
4510        EXPECT_FALSE(grandchild1_->needs_push_properties());
4511        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4512        EXPECT_FALSE(grandchild2_->needs_push_properties());
4513        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4514        EXPECT_FALSE(grandchild3_->needs_push_properties());
4515        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4516
4517        grandchild1_->SetPosition(gfx::Point(1, 1));
4518        grandchild2_->SetPosition(gfx::Point(1, 1));
4519        child_->SetPosition(gfx::Point(1, 1));
4520
4521        EXPECT_FALSE(root_->needs_push_properties());
4522        EXPECT_TRUE(root_->descendant_needs_push_properties());
4523        EXPECT_TRUE(child_->needs_push_properties());
4524        EXPECT_TRUE(child_->descendant_needs_push_properties());
4525        EXPECT_TRUE(grandchild1_->needs_push_properties());
4526        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
4527        EXPECT_TRUE(grandchild2_->needs_push_properties());
4528        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
4529        EXPECT_FALSE(grandchild3_->needs_push_properties());
4530        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
4531
4532        grandchild1_->RemoveFromParent();
4533
4534        EXPECT_FALSE(root_->needs_push_properties());
4535        EXPECT_TRUE(root_->descendant_needs_push_properties());
4536        EXPECT_TRUE(child_->needs_push_properties());
4537        EXPECT_TRUE(child_->descendant_needs_push_properties());
4538
4539        grandchild2_->RemoveFromParent();
4540
4541        EXPECT_FALSE(root_->needs_push_properties());
4542        EXPECT_TRUE(root_->descendant_needs_push_properties());
4543        EXPECT_TRUE(child_->needs_push_properties());
4544        EXPECT_FALSE(child_->descendant_needs_push_properties());
4545
4546        child_->RemoveFromParent();
4547
4548        EXPECT_FALSE(root_->needs_push_properties());
4549        EXPECT_FALSE(root_->descendant_needs_push_properties());
4550
4551        EndTest();
4552        break;
4553    }
4554  }
4555};
4556
4557MULTI_THREAD_TEST_F(
4558    LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
4559
4560// This test verifies that the tree activation callback is invoked correctly.
4561class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
4562 public:
4563  LayerTreeHostTestTreeActivationCallback()
4564      : num_commits_(0), callback_count_(0) {}
4565
4566  virtual void BeginTest() OVERRIDE {
4567    EXPECT_TRUE(HasImplThread());
4568    PostSetNeedsCommitToMainThread();
4569  }
4570
4571  virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
4572                                     LayerTreeHostImpl::FrameData* frame_data,
4573                                     bool result) OVERRIDE {
4574    ++num_commits_;
4575    switch (num_commits_) {
4576      case 1:
4577        EXPECT_EQ(0, callback_count_);
4578        callback_count_ = 0;
4579        SetCallback(true);
4580        PostSetNeedsCommitToMainThread();
4581        break;
4582      case 2:
4583        EXPECT_EQ(1, callback_count_);
4584        callback_count_ = 0;
4585        SetCallback(false);
4586        PostSetNeedsCommitToMainThread();
4587        break;
4588      case 3:
4589        EXPECT_EQ(0, callback_count_);
4590        callback_count_ = 0;
4591        EndTest();
4592        break;
4593      default:
4594        ADD_FAILURE() << num_commits_;
4595        EndTest();
4596        break;
4597    }
4598    return LayerTreeHostTest::PrepareToDrawOnThread(host_impl, frame_data,
4599                                                    result);
4600  }
4601
4602  virtual void AfterTest() OVERRIDE {
4603    EXPECT_EQ(3, num_commits_);
4604  }
4605
4606  void SetCallback(bool enable) {
4607    output_surface()->SetTreeActivationCallback(enable ?
4608        base::Bind(&LayerTreeHostTestTreeActivationCallback::ActivationCallback,
4609                   base::Unretained(this)) :
4610        base::Closure());
4611  }
4612
4613  void ActivationCallback() {
4614    ++callback_count_;
4615  }
4616
4617  int num_commits_;
4618  int callback_count_;
4619};
4620
4621TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
4622  RunTest(true, false, true);
4623}
4624
4625TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
4626  RunTest(true, true, true);
4627}
4628
4629class LayerInvalidateCausesDraw : public LayerTreeHostTest {
4630 public:
4631  LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
4632
4633  virtual void BeginTest() OVERRIDE {
4634    ASSERT_TRUE(!!invalidate_layer_)
4635        << "Derived tests must set this in SetupTree";
4636
4637    // One initial commit.
4638    PostSetNeedsCommitToMainThread();
4639  }
4640
4641  virtual void DidCommitAndDrawFrame() OVERRIDE {
4642    // After commit, invalidate the layer.  This should cause a commit.
4643    if (layer_tree_host()->source_frame_number() == 1)
4644     invalidate_layer_->SetNeedsDisplay();
4645  }
4646
4647  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4648    num_draws_++;
4649    if (impl->active_tree()->source_frame_number() == 1)
4650      EndTest();
4651  }
4652
4653  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4654    num_commits_++;
4655  }
4656
4657  virtual void AfterTest() OVERRIDE {
4658    EXPECT_GE(2, num_commits_);
4659    EXPECT_GE(2, num_draws_);
4660  }
4661
4662 protected:
4663  scoped_refptr<Layer> invalidate_layer_;
4664
4665 private:
4666  int num_commits_;
4667  int num_draws_;
4668};
4669
4670// VideoLayer must support being invalidated and then passing that along
4671// to the compositor thread, even though no resources are updated in
4672// response to that invalidation.
4673class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
4674 public:
4675  virtual void SetupTree() OVERRIDE {
4676    LayerTreeHostTest::SetupTree();
4677    scoped_refptr<VideoLayer> video_layer = VideoLayer::Create(&provider_);
4678    video_layer->SetBounds(gfx::Size(10, 10));
4679    video_layer->SetIsDrawable(true);
4680    layer_tree_host()->root_layer()->AddChild(video_layer);
4681
4682    invalidate_layer_ = video_layer;
4683  }
4684
4685 private:
4686  FakeVideoFrameProvider provider_;
4687};
4688
4689SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
4690
4691// IOSurfaceLayer must support being invalidated and then passing that along
4692// to the compositor thread, even though no resources are updated in
4693// response to that invalidation.
4694class LayerTreeHostTestIOSurfaceLayerInvalidate
4695    : public LayerInvalidateCausesDraw {
4696 public:
4697  virtual void SetupTree() OVERRIDE {
4698    LayerTreeHostTest::SetupTree();
4699    scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
4700    layer->SetBounds(gfx::Size(10, 10));
4701    uint32_t fake_io_surface_id = 7;
4702    layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
4703    layer->SetIsDrawable(true);
4704    layer_tree_host()->root_layer()->AddChild(layer);
4705
4706    invalidate_layer_ = layer;
4707  }
4708};
4709
4710// TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
4711SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
4712    LayerTreeHostTestIOSurfaceLayerInvalidate);
4713
4714class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
4715 protected:
4716  virtual void SetupTree() OVERRIDE {
4717    root_layer_ = Layer::Create();
4718    root_layer_->SetAnchorPoint(gfx::PointF());
4719    root_layer_->SetPosition(gfx::Point());
4720    root_layer_->SetBounds(gfx::Size(10, 10));
4721
4722    parent_layer_ = SolidColorLayer::Create();
4723    parent_layer_->SetAnchorPoint(gfx::PointF());
4724    parent_layer_->SetPosition(gfx::Point());
4725    parent_layer_->SetBounds(gfx::Size(10, 10));
4726    parent_layer_->SetIsDrawable(true);
4727    root_layer_->AddChild(parent_layer_);
4728
4729    child_layer_ = SolidColorLayer::Create();
4730    child_layer_->SetAnchorPoint(gfx::PointF());
4731    child_layer_->SetPosition(gfx::Point());
4732    child_layer_->SetBounds(gfx::Size(10, 10));
4733    child_layer_->SetIsDrawable(true);
4734    parent_layer_->AddChild(child_layer_);
4735
4736    layer_tree_host()->SetRootLayer(root_layer_);
4737    LayerTreeHostTest::SetupTree();
4738  }
4739
4740  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4741
4742  virtual void DidCommitAndDrawFrame() OVERRIDE {
4743    switch (layer_tree_host()->source_frame_number()) {
4744      case 1:
4745        // The layer type used does not need to push properties every frame.
4746        EXPECT_FALSE(child_layer_->needs_push_properties());
4747
4748        // Change the bounds of the child layer, but make it skipped
4749        // by CalculateDrawProperties.
4750        parent_layer_->SetOpacity(0.f);
4751        child_layer_->SetBounds(gfx::Size(5, 5));
4752        break;
4753      case 2:
4754        // The bounds of the child layer were pushed to the impl side.
4755        EXPECT_FALSE(child_layer_->needs_push_properties());
4756
4757        EndTest();
4758        break;
4759    }
4760  }
4761
4762  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4763    LayerImpl* root = impl->active_tree()->root_layer();
4764    LayerImpl* parent = root->children()[0];
4765    LayerImpl* child = parent->children()[0];
4766
4767    switch (impl->active_tree()->source_frame_number()) {
4768      case 1:
4769        EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
4770        break;
4771    }
4772  }
4773
4774  virtual void AfterTest() OVERRIDE {}
4775
4776  scoped_refptr<Layer> root_layer_;
4777  scoped_refptr<SolidColorLayer> parent_layer_;
4778  scoped_refptr<SolidColorLayer> child_layer_;
4779};
4780
4781SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
4782
4783class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
4784 protected:
4785  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4786    settings->impl_side_painting = true;
4787  }
4788
4789  virtual void SetupTree() OVERRIDE {
4790    root_layer_ = FakePictureLayer::Create(&client_);
4791    root_layer_->SetAnchorPoint(gfx::PointF());
4792    root_layer_->SetBounds(gfx::Size(10, 10));
4793
4794    layer_tree_host()->SetRootLayer(root_layer_);
4795    LayerTreeHostTest::SetupTree();
4796  }
4797
4798  virtual void BeginTest() OVERRIDE {
4799    // The viewport is empty, but we still need to update layers on the main
4800    // thread.
4801    layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
4802    PostSetNeedsCommitToMainThread();
4803  }
4804
4805  virtual void DidCommit() OVERRIDE {
4806    // The layer should be updated even though the viewport is empty, so we
4807    // are capable of drawing it on the impl tree.
4808    EXPECT_GT(root_layer_->update_count(), 0u);
4809    EndTest();
4810  }
4811
4812  virtual void AfterTest() OVERRIDE {}
4813
4814  FakeContentLayerClient client_;
4815  scoped_refptr<FakePictureLayer> root_layer_;
4816};
4817
4818MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
4819
4820class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
4821 public:
4822  LayerTreeHostTestAbortEvictedTextures()
4823      : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
4824
4825 protected:
4826  virtual void SetupTree() OVERRIDE {
4827    scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
4828    root_layer->SetBounds(gfx::Size(200, 200));
4829    root_layer->SetIsDrawable(true);
4830
4831    layer_tree_host()->SetRootLayer(root_layer);
4832    LayerTreeHostTest::SetupTree();
4833  }
4834
4835  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4836
4837  virtual void WillBeginMainFrame() OVERRIDE {
4838    num_will_begin_main_frames_++;
4839    switch (num_will_begin_main_frames_) {
4840      case 2:
4841        // Send a redraw to the compositor thread.  This will (wrongly) be
4842        // ignored unless aborting resets the texture state.
4843        layer_tree_host()->SetNeedsRedraw();
4844        break;
4845    }
4846  }
4847
4848  virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4849    num_impl_commits_++;
4850  }
4851
4852  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4853    switch (impl->SourceAnimationFrameNumber()) {
4854      case 1:
4855        // Prevent draws until commit.
4856        impl->active_tree()->SetContentsTexturesPurged();
4857        EXPECT_FALSE(impl->CanDraw());
4858        // Trigger an abortable commit.
4859        impl->SetNeedsCommit();
4860        break;
4861      case 2:
4862        EndTest();
4863        break;
4864    }
4865  }
4866
4867  virtual void AfterTest() OVERRIDE {
4868    // Ensure that the commit was truly aborted.
4869    EXPECT_EQ(2, num_will_begin_main_frames_);
4870    EXPECT_EQ(1, num_impl_commits_);
4871  }
4872
4873 private:
4874  int num_will_begin_main_frames_;
4875  int num_impl_commits_;
4876};
4877
4878// Commits can only be aborted when using the thread proxy.
4879MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
4880
4881class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
4882 protected:
4883  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
4884    settings->impl_side_painting = true;
4885  }
4886
4887  virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
4888      OVERRIDE {
4889    scoped_refptr<TestContextProvider> context_provider =
4890        TestContextProvider::Create();
4891    context_provider->SetMaxTransferBufferUsageBytes(1024 * 1024);
4892    return FakeOutputSurface::Create3d(context_provider)
4893        .PassAs<OutputSurface>();
4894  }
4895
4896  virtual void SetupTree() OVERRIDE {
4897    scoped_refptr<FakePictureLayer> root_layer =
4898        FakePictureLayer::Create(&client_);
4899    root_layer->SetBounds(gfx::Size(6000, 6000));
4900    root_layer->SetIsDrawable(true);
4901
4902    layer_tree_host()->SetRootLayer(root_layer);
4903    LayerTreeHostTest::SetupTree();
4904  }
4905
4906  virtual void BeginTest() OVERRIDE {
4907    PostSetNeedsCommitToMainThread();
4908  }
4909
4910  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4911    TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
4912        impl->output_surface()->context_provider()->Context3d());
4913
4914    // Expect that the transfer buffer memory used is equal to the
4915    // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
4916    EXPECT_EQ(1024 * 1024u,
4917              context->GetTransferBufferMemoryUsedBytes());
4918    EndTest();
4919  }
4920
4921  virtual void AfterTest() OVERRIDE {}
4922
4923 private:
4924  FakeContentLayerClient client_;
4925};
4926
4927// Impl-side painting is a multi-threaded compositor feature.
4928MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
4929
4930// Test ensuring that memory limits are sent to the prioritized resource
4931// manager.
4932class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
4933 public:
4934  LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
4935
4936  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
4937
4938  virtual void DidCommit() OVERRIDE {
4939    int frame = num_commits_;
4940    switch (frame) {
4941      case 0:
4942        // Verify default values.
4943        EXPECT_EQ(
4944            PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4945            layer_tree_host()->contents_texture_manager()->
4946                MaxMemoryLimitBytes());
4947        EXPECT_EQ(
4948            PriorityCalculator::AllowEverythingCutoff(),
4949            layer_tree_host()->contents_texture_manager()->
4950                ExternalPriorityCutoff());
4951        PostSetNeedsCommitToMainThread();
4952        break;
4953      case 1:
4954        // The values should remain the same until the commit after the policy
4955        // is changed.
4956        EXPECT_EQ(
4957            PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
4958            layer_tree_host()->contents_texture_manager()->
4959                MaxMemoryLimitBytes());
4960        EXPECT_EQ(
4961            PriorityCalculator::AllowEverythingCutoff(),
4962            layer_tree_host()->contents_texture_manager()->
4963                ExternalPriorityCutoff());
4964        break;
4965      case 2:
4966        // Verify values were correctly passed.
4967        EXPECT_EQ(
4968            16u*1024u*1024u,
4969            layer_tree_host()->contents_texture_manager()->
4970                MaxMemoryLimitBytes());
4971        EXPECT_EQ(
4972            PriorityCalculator::AllowVisibleAndNearbyCutoff(),
4973            layer_tree_host()->contents_texture_manager()->
4974                ExternalPriorityCutoff());
4975        EndTest();
4976        break;
4977      case 3:
4978        // Make sure no extra commits happen.
4979        NOTREACHED();
4980        break;
4981    }
4982
4983    ++num_commits_;
4984  }
4985
4986  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
4987    int frame = num_commits_;
4988    switch (frame) {
4989      case 0:
4990        break;
4991      case 1:
4992        // This will trigger a commit because the priority cutoff has changed.
4993        impl->SetMemoryPolicy(ManagedMemoryPolicy(
4994            16u*1024u*1024u,
4995            gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
4996            1000));
4997        break;
4998      case 2:
4999        // This will not trigger a commit because the priority cutoff has not
5000        // changed, and there is already enough memory for all allocations.
5001        impl->SetMemoryPolicy(ManagedMemoryPolicy(
5002            32u*1024u*1024u,
5003            gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
5004            1000));
5005        break;
5006      case 3:
5007        NOTREACHED();
5008        break;
5009    }
5010  }
5011
5012  virtual void AfterTest() OVERRIDE {}
5013
5014 private:
5015  int num_commits_;
5016};
5017
5018SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
5019
5020class LayerSetsNeedsFilterContext : public Layer {
5021 public:
5022  static scoped_refptr<LayerSetsNeedsFilterContext> Create() {
5023    return make_scoped_refptr(new LayerSetsNeedsFilterContext());
5024  }
5025
5026  virtual bool Update(ResourceUpdateQueue* queue,
5027                      const OcclusionTracker* occlusion) OVERRIDE {
5028    bool updated = Layer::Update(queue, occlusion);
5029    if (needs_context_) {
5030      layer_tree_host()->set_needs_filter_context();
5031      return true;
5032    }
5033    return updated;
5034  }
5035
5036  void set_needs_context(bool need) { needs_context_ = need; }
5037
5038 private:
5039  LayerSetsNeedsFilterContext() : needs_context_(false) {}
5040  virtual ~LayerSetsNeedsFilterContext() {}
5041
5042  bool needs_context_;
5043};
5044
5045class LayerTreeHostTestOffscreenContext : public LayerTreeHostTest {
5046 protected:
5047  virtual void SetupTree() OVERRIDE {
5048    scoped_refptr<LayerSetsNeedsFilterContext> root =
5049        LayerSetsNeedsFilterContext::Create();
5050    root->SetIsDrawable(true);
5051    root->SetAnchorPoint(gfx::PointF());
5052    root->SetBounds(gfx::Size(10, 10));
5053    root->set_needs_context(with_context_);
5054    layer_tree_host()->SetRootLayer(root);
5055    LayerTreeHostTest::SetupTree();
5056  }
5057
5058  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
5059
5060  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
5061    bool expect_context = with_context_;
5062    if (delegating_renderer())
5063      expect_context = false;
5064    EXPECT_EQ(expect_context, !!host_impl->offscreen_context_provider());
5065    EndTest();
5066  }
5067
5068  virtual void AfterTest() OVERRIDE {}
5069
5070  bool with_context_;
5071};
5072
5073class LayerTreeHostTestOffscreenContext_NoContext
5074    : public LayerTreeHostTestOffscreenContext {
5075 protected:
5076  LayerTreeHostTestOffscreenContext_NoContext() { with_context_ = false; }
5077};
5078
5079SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestOffscreenContext_NoContext);
5080
5081class LayerTreeHostTestOffscreenContext_WithContext
5082    : public LayerTreeHostTestOffscreenContext {
5083 protected:
5084  LayerTreeHostTestOffscreenContext_WithContext() { with_context_ = true; }
5085};
5086
5087SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestOffscreenContext_WithContext);
5088
5089class LayerTreeHostTestNoQuadsForEmptyLayer : public LayerTreeHostTest {
5090 protected:
5091  virtual void SetupTree() OVERRIDE {
5092    LayerTreeHostTest::SetupTree();
5093    root_layer_ = FakeContentLayer::Create(&client_);
5094    root_layer_->SetBounds(gfx::Size(10, 10));
5095    root_layer_->SetIsDrawable(false);
5096    root_layer_->SetHaveWheelEventHandlers(true);
5097    layer_tree_host()->SetRootLayer(root_layer_);
5098    LayerTreeHostTest::SetupTree();
5099  }
5100
5101  virtual void BeginTest() OVERRIDE {
5102    PostSetNeedsCommitToMainThread();
5103  }
5104
5105  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
5106    FakeContentLayerImpl* layer_impl =
5107          static_cast<FakeContentLayerImpl*>(impl->RootLayer());
5108    EXPECT_FALSE(layer_impl->DrawsContent());
5109    EXPECT_EQ(0u, layer_impl->append_quads_count());
5110  }
5111
5112  virtual void DidCommit() OVERRIDE {
5113    // The layer is not drawable, so it should not be updated.
5114    EXPECT_EQ(0u, root_layer_->update_count());
5115    EndTest();
5116  }
5117  virtual void AfterTest() OVERRIDE {}
5118
5119 private:
5120  FakeContentLayerClient client_;
5121  scoped_refptr<FakeContentLayer> root_layer_;
5122};
5123
5124SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoQuadsForEmptyLayer);
5125
5126
5127}  // namespace
5128
5129class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
5130    : public LayerTreeHostTest {
5131 protected:
5132  LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
5133      : first_output_surface_memory_limit_(4321234),
5134        second_output_surface_memory_limit_(1234321) {}
5135
5136  virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
5137      OVERRIDE {
5138    if (!first_context_provider_) {
5139      first_context_provider_ = TestContextProvider::Create();
5140    } else {
5141      EXPECT_FALSE(second_context_provider_);
5142      second_context_provider_ = TestContextProvider::Create();
5143    }
5144
5145    scoped_ptr<FakeOutputSurface> output_surface(
5146        FakeOutputSurface::Create3d(
5147            second_context_provider_ ?
5148                second_context_provider_ :
5149                first_context_provider_));
5150    output_surface->SetMemoryPolicyToSetAtBind(make_scoped_ptr(
5151        new ManagedMemoryPolicy(
5152            second_context_provider_ ?
5153                second_output_surface_memory_limit_ :
5154                first_output_surface_memory_limit_,
5155            gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
5156            ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
5157    return output_surface.PassAs<OutputSurface>();
5158  }
5159
5160  virtual void SetupTree() OVERRIDE {
5161    root_ = FakeContentLayer::Create(&client_);
5162    root_->SetBounds(gfx::Size(20, 20));
5163    layer_tree_host()->SetRootLayer(root_);
5164    LayerTreeHostTest::SetupTree();
5165  }
5166
5167  virtual void BeginTest() OVERRIDE {
5168    PostSetNeedsCommitToMainThread();
5169  }
5170
5171  virtual void DidCommitAndDrawFrame() OVERRIDE {
5172    // Lost context sometimes takes two frames to recreate. The third frame
5173    // is sometimes aborted, so wait until the fourth frame to verify that
5174    // the memory has been set, and the fifth frame to end the test.
5175    if (layer_tree_host()->source_frame_number() < 5) {
5176      layer_tree_host()->SetNeedsCommit();
5177    } else if (layer_tree_host()->source_frame_number() == 5) {
5178      EndTest();
5179    }
5180  }
5181
5182  virtual void SwapBuffersOnThread(LayerTreeHostImpl *impl, bool result)
5183      OVERRIDE {
5184    switch (impl->active_tree()->source_frame_number()) {
5185      case 1:
5186        EXPECT_EQ(first_output_surface_memory_limit_,
5187                  impl->memory_allocation_limit_bytes());
5188        // Lose the output surface.
5189        first_context_provider_->TestContext3d()->loseContextCHROMIUM(
5190            GL_GUILTY_CONTEXT_RESET_ARB,
5191            GL_INNOCENT_CONTEXT_RESET_ARB);
5192        break;
5193      case 4:
5194        EXPECT_EQ(second_output_surface_memory_limit_,
5195                  impl->memory_allocation_limit_bytes());
5196        break;
5197    }
5198  }
5199
5200  virtual void AfterTest() OVERRIDE {}
5201
5202  scoped_refptr<TestContextProvider> first_context_provider_;
5203  scoped_refptr<TestContextProvider> second_context_provider_;
5204  size_t first_output_surface_memory_limit_;
5205  size_t second_output_surface_memory_limit_;
5206  FakeContentLayerClient client_;
5207  scoped_refptr<FakeContentLayer> root_;
5208};
5209
5210// No output to copy for delegated renderers.
5211SINGLE_AND_MULTI_THREAD_TEST_F(
5212    LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);
5213
5214}  // namespace cc
5215