layer_tree_host_unittest.cc revision a3f7b4e666c476898878fa745f637129375cd889
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/picture_layer.h"
18#include "cc/layers/scrollbar_layer.h"
19#include "cc/output/begin_frame_args.h"
20#include "cc/output/copy_output_request.h"
21#include "cc/output/copy_output_result.h"
22#include "cc/output/output_surface.h"
23#include "cc/resources/prioritized_resource.h"
24#include "cc/resources/prioritized_resource_manager.h"
25#include "cc/resources/resource_update_queue.h"
26#include "cc/scheduler/frame_rate_controller.h"
27#include "cc/test/fake_content_layer.h"
28#include "cc/test/fake_content_layer_client.h"
29#include "cc/test/fake_layer_tree_host_client.h"
30#include "cc/test/fake_output_surface.h"
31#include "cc/test/fake_picture_layer.h"
32#include "cc/test/fake_picture_layer_impl.h"
33#include "cc/test/fake_proxy.h"
34#include "cc/test/fake_scrollbar_layer.h"
35#include "cc/test/geometry_test_utils.h"
36#include "cc/test/layer_tree_test.h"
37#include "cc/test/occlusion_tracker_test_common.h"
38#include "cc/trees/layer_tree_host_impl.h"
39#include "cc/trees/layer_tree_impl.h"
40#include "cc/trees/single_thread_proxy.h"
41#include "cc/trees/thread_proxy.h"
42#include "gpu/GLES2/gl2extchromium.h"
43#include "skia/ext/refptr.h"
44#include "testing/gmock/include/gmock/gmock.h"
45#include "third_party/khronos/GLES2/gl2.h"
46#include "third_party/khronos/GLES2/gl2ext.h"
47#include "third_party/skia/include/core/SkPicture.h"
48#include "ui/gfx/point_conversions.h"
49#include "ui/gfx/size_conversions.h"
50#include "ui/gfx/vector2d_conversions.h"
51
52using testing::_;
53using testing::AnyNumber;
54using testing::AtLeast;
55using testing::Mock;
56
57namespace cc {
58namespace {
59
60class LayerTreeHostTest : public LayerTreeTest {
61};
62
63// Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
64// draw with frame 0.
65class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
66 public:
67  LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {}
68
69  virtual void BeginTest() OVERRIDE {
70    PostSetNeedsCommitToMainThread();
71    PostSetNeedsCommitToMainThread();
72  }
73
74  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
75    num_draws_++;
76    if (!impl->active_tree()->source_frame_number())
77      EndTest();
78  }
79
80  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
81    num_commits_++;
82  }
83
84  virtual void AfterTest() OVERRIDE {
85    EXPECT_GE(1, num_commits_);
86    EXPECT_GE(1, num_draws_);
87  }
88
89 private:
90  int num_commits_;
91  int num_draws_;
92};
93
94SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
95
96// A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
97// first committed frame draws should lead to another commit.
98class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
99 public:
100  LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {}
101
102  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
103
104  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
105    ++num_draws_;
106  }
107
108  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
109    ++num_commits_;
110    switch (num_commits_) {
111      case 1:
112        PostSetNeedsCommitToMainThread();
113        break;
114      case 2:
115        EndTest();
116        break;
117      default:
118        NOTREACHED();
119    }
120  }
121
122  virtual void AfterTest() OVERRIDE {
123    EXPECT_EQ(2, num_commits_);
124    EXPECT_LE(1, num_draws_);
125  }
126
127 private:
128  int num_commits_;
129  int num_draws_;
130};
131
132MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2);
133
134// Verify that we pass property values in PushPropertiesTo.
135class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest {
136 protected:
137  virtual void SetupTree() OVERRIDE {
138    scoped_refptr<Layer> root = Layer::Create();
139    root->SetBounds(gfx::Size(10, 10));
140    layer_tree_host()->SetRootLayer(root);
141    LayerTreeHostTest::SetupTree();
142  }
143
144  enum Properties {
145    STARTUP,
146    BOUNDS,
147    HIDE_LAYER_AND_SUBTREE,
148    DRAWS_CONTENT,
149    DONE,
150  };
151
152  virtual void BeginTest() OVERRIDE {
153    index_ = STARTUP;
154    PostSetNeedsCommitToMainThread();
155  }
156
157  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
158    VerifyAfterValues(impl->active_tree()->root_layer());
159  }
160
161  virtual void DidCommitAndDrawFrame() OVERRIDE {
162    SetBeforeValues(layer_tree_host()->root_layer());
163    VerifyBeforeValues(layer_tree_host()->root_layer());
164
165    ++index_;
166    if (index_ == DONE) {
167      EndTest();
168      return;
169    }
170
171    SetAfterValues(layer_tree_host()->root_layer());
172  }
173
174  virtual void AfterTest() OVERRIDE {}
175
176  void VerifyBeforeValues(Layer* layer) {
177    EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString());
178    EXPECT_FALSE(layer->hide_layer_and_subtree());
179    EXPECT_FALSE(layer->DrawsContent());
180  }
181
182  void SetBeforeValues(Layer* layer) {
183    layer->SetBounds(gfx::Size(10, 10));
184    layer->SetHideLayerAndSubtree(false);
185    layer->SetIsDrawable(false);
186  }
187
188  void VerifyAfterValues(LayerImpl* layer) {
189    switch (static_cast<Properties>(index_)) {
190      case STARTUP:
191      case DONE:
192        break;
193      case BOUNDS:
194        EXPECT_EQ(gfx::Size(20, 20).ToString(), layer->bounds().ToString());
195        break;
196      case HIDE_LAYER_AND_SUBTREE:
197        EXPECT_TRUE(layer->hide_layer_and_subtree());
198        break;
199      case DRAWS_CONTENT:
200        EXPECT_TRUE(layer->DrawsContent());
201        break;
202    }
203  }
204
205  void SetAfterValues(Layer* layer) {
206    switch (static_cast<Properties>(index_)) {
207      case STARTUP:
208      case DONE:
209        break;
210      case BOUNDS:
211        layer->SetBounds(gfx::Size(20, 20));
212        break;
213      case HIDE_LAYER_AND_SUBTREE:
214        layer->SetHideLayerAndSubtree(true);
215        break;
216      case DRAWS_CONTENT:
217        layer->SetIsDrawable(true);
218        break;
219    }
220  }
221
222  int index_;
223};
224
225SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo);
226
227// 1 setNeedsRedraw after the first commit has completed should lead to 1
228// additional draw.
229class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest {
230 public:
231  LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {}
232
233  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
234
235  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
236    EXPECT_EQ(0, impl->active_tree()->source_frame_number());
237    if (!num_draws_) {
238      // Redraw again to verify that the second redraw doesn't commit.
239      PostSetNeedsRedrawToMainThread();
240    } else {
241      EndTest();
242    }
243    num_draws_++;
244  }
245
246  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
247    EXPECT_EQ(0, num_draws_);
248    num_commits_++;
249  }
250
251  virtual void AfterTest() OVERRIDE {
252    EXPECT_GE(2, num_draws_);
253    EXPECT_EQ(1, num_commits_);
254  }
255
256 private:
257  int num_commits_;
258  int num_draws_;
259};
260
261MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw);
262
263// After setNeedsRedrawRect(invalid_rect) the final damage_rect
264// must contain invalid_rect.
265class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest {
266 public:
267  LayerTreeHostTestSetNeedsRedrawRect()
268      : num_draws_(0),
269        bounds_(50, 50),
270        invalid_rect_(10, 10, 20, 20),
271        root_layer_(ContentLayer::Create(&client_)) {
272  }
273
274  virtual void BeginTest() OVERRIDE {
275    root_layer_->SetIsDrawable(true);
276    root_layer_->SetBounds(bounds_);
277    layer_tree_host()->SetRootLayer(root_layer_);
278    layer_tree_host()->SetViewportSize(bounds_);
279    PostSetNeedsCommitToMainThread();
280  }
281
282  virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
283                                     LayerTreeHostImpl::FrameData* frame_data,
284                                     bool result) OVERRIDE {
285    EXPECT_TRUE(result);
286
287    gfx::RectF root_damage_rect;
288    if (!frame_data->render_passes.empty())
289      root_damage_rect = frame_data->render_passes.back()->damage_rect;
290
291    if (!num_draws_) {
292      // If this is the first frame, expect full frame damage.
293      EXPECT_RECT_EQ(root_damage_rect, gfx::Rect(bounds_));
294    } else {
295      // Check that invalid_rect_ is indeed repainted.
296      EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
297    }
298
299    return result;
300  }
301
302  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
303    if (!num_draws_) {
304      PostSetNeedsRedrawRectToMainThread(invalid_rect_);
305    } else {
306      EndTest();
307    }
308    num_draws_++;
309  }
310
311  virtual void AfterTest() OVERRIDE {
312    EXPECT_EQ(2, num_draws_);
313  }
314
315 private:
316  int num_draws_;
317  const gfx::Size bounds_;
318  const gfx::Rect invalid_rect_;
319  FakeContentLayerClient client_;
320  scoped_refptr<ContentLayer> root_layer_;
321};
322
323SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect);
324
325class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest {
326 public:
327  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
328    settings->layer_transforms_should_scale_layer_contents = true;
329  }
330
331  virtual void SetupTree() OVERRIDE {
332    root_layer_ = Layer::Create();
333    root_layer_->SetBounds(gfx::Size(10, 20));
334
335    scaled_layer_ = FakeContentLayer::Create(&client_);
336    scaled_layer_->SetBounds(gfx::Size(1, 1));
337    root_layer_->AddChild(scaled_layer_);
338
339    layer_tree_host()->SetRootLayer(root_layer_);
340    LayerTreeHostTest::SetupTree();
341  }
342
343  virtual void BeginTest() OVERRIDE {
344    PostSetNeedsCommitToMainThread();
345  }
346
347  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
348    if (host_impl->active_tree()->source_frame_number() == 1)
349      EndTest();
350  }
351
352  virtual void DidCommit() OVERRIDE {
353    switch (layer_tree_host()->commit_number()) {
354      case 1:
355        // Changing the device scale factor causes a commit. It also changes
356        // the content bounds of |scaled_layer_|, which should not generate
357        // a second commit as a result.
358        layer_tree_host()->SetDeviceScaleFactor(4.f);
359        break;
360      default:
361        // No extra commits.
362        EXPECT_EQ(2, layer_tree_host()->commit_number());
363    }
364  }
365
366  virtual void AfterTest() OVERRIDE {
367    EXPECT_EQ(gfx::Size(4, 4).ToString(),
368              scaled_layer_->content_bounds().ToString());
369  }
370
371 private:
372  FakeContentLayerClient client_;
373  scoped_refptr<Layer> root_layer_;
374  scoped_refptr<FakeContentLayer> scaled_layer_;
375};
376
377SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate);
378
379class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
380    : public LayerTreeHostTest {
381 public:
382  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
383    settings->layer_transforms_should_scale_layer_contents = true;
384  }
385
386  virtual void SetupTree() OVERRIDE {
387    root_layer_ = Layer::Create();
388    root_layer_->SetBounds(gfx::Size(10, 20));
389
390    bool paint_scrollbar = true;
391    bool has_thumb = false;
392    scrollbar_ = FakeScrollbarLayer::Create(paint_scrollbar,
393                                            has_thumb,
394                                            root_layer_->id());
395    scrollbar_->SetPosition(gfx::Point(0, 10));
396    scrollbar_->SetBounds(gfx::Size(10, 10));
397
398    root_layer_->AddChild(scrollbar_);
399
400    layer_tree_host()->SetRootLayer(root_layer_);
401    LayerTreeHostTest::SetupTree();
402  }
403
404  virtual void BeginTest() OVERRIDE {
405    PostSetNeedsCommitToMainThread();
406  }
407
408  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
409    if (host_impl->active_tree()->source_frame_number() == 1)
410      EndTest();
411  }
412
413  virtual void DidCommit() OVERRIDE {
414    switch (layer_tree_host()->commit_number()) {
415      case 1:
416        // Changing the device scale factor causes a commit. It also changes
417        // the content bounds of |scrollbar_|, which should not generate
418        // a second commit as a result.
419        layer_tree_host()->SetDeviceScaleFactor(4.f);
420        break;
421      default:
422        // No extra commits.
423        EXPECT_EQ(2, layer_tree_host()->commit_number());
424    }
425  }
426
427  virtual void AfterTest() OVERRIDE {
428    EXPECT_EQ(gfx::Size(40, 40).ToString(),
429              scrollbar_->content_bounds().ToString());
430  }
431
432 private:
433  FakeContentLayerClient client_;
434  scoped_refptr<Layer> root_layer_;
435  scoped_refptr<FakeScrollbarLayer> scrollbar_;
436};
437
438SINGLE_AND_MULTI_THREAD_TEST_F(
439    LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate);
440
441class LayerTreeHostTestCompositeAndReadback : public LayerTreeHostTest {
442 public:
443  LayerTreeHostTestCompositeAndReadback() : num_commits_(0) {}
444
445  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
446
447  virtual void DidCommit() OVERRIDE {
448    num_commits_++;
449    if (num_commits_ == 1) {
450      char pixels[4];
451      layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
452    } else if (num_commits_ == 2) {
453      // This is inside the readback. We should get another commit after it.
454    } else if (num_commits_ == 3) {
455      EndTest();
456    } else {
457      NOTREACHED();
458    }
459  }
460
461  virtual void AfterTest() OVERRIDE {}
462
463 private:
464  int num_commits_;
465};
466
467MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadback);
468
469class LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws
470    : public LayerTreeHostTest {
471 public:
472  LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws()
473      : num_commits_(0) {}
474
475  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
476
477  virtual void DidCommit() OVERRIDE {
478    num_commits_++;
479    if (num_commits_ == 1) {
480      layer_tree_host()->SetNeedsCommit();
481    } else if (num_commits_ == 2) {
482      char pixels[4];
483      layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
484    } else if (num_commits_ == 3) {
485      // This is inside the readback. We should get another commit after it.
486    } else if (num_commits_ == 4) {
487      EndTest();
488    } else {
489      NOTREACHED();
490    }
491  }
492
493  virtual void AfterTest() OVERRIDE {}
494
495 private:
496  int num_commits_;
497};
498
499MULTI_THREAD_TEST_F(
500    LayerTreeHostTestCompositeAndReadbackBeforePreviousCommitDraws);
501
502// If the layerTreeHost says it can't draw, Then we should not try to draw.
503class LayerTreeHostTestCanDrawBlocksDrawing : public LayerTreeHostTest {
504 public:
505  LayerTreeHostTestCanDrawBlocksDrawing() : num_commits_(0), done_(false) {}
506
507  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
508
509  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
510    if (done_)
511      return;
512    // Only the initial draw should bring us here.
513    EXPECT_TRUE(impl->CanDraw());
514    EXPECT_EQ(0, impl->active_tree()->source_frame_number());
515  }
516
517  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
518    if (done_)
519      return;
520    if (num_commits_ >= 1) {
521      // After the first commit, we should not be able to draw.
522      EXPECT_FALSE(impl->CanDraw());
523    }
524  }
525
526  virtual void DidCommit() OVERRIDE {
527    num_commits_++;
528    if (num_commits_ == 1) {
529      // Make the viewport empty so the host says it can't draw.
530      layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
531    } else if (num_commits_ == 2) {
532      char pixels[4];
533      layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
534    } else if (num_commits_ == 3) {
535      // Let it draw so we go idle and end the test.
536      layer_tree_host()->SetViewportSize(gfx::Size(1, 1));
537      done_ = true;
538      EndTest();
539    }
540  }
541
542  virtual void AfterTest() OVERRIDE {}
543
544 private:
545  int num_commits_;
546  bool done_;
547};
548
549SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing);
550
551// beginLayerWrite should prevent draws from executing until a commit occurs
552class LayerTreeHostTestWriteLayersRedraw : public LayerTreeHostTest {
553 public:
554  LayerTreeHostTestWriteLayersRedraw() : num_commits_(0), num_draws_(0) {}
555
556  virtual void BeginTest() OVERRIDE {
557    PostAcquireLayerTextures();
558    PostSetNeedsRedrawToMainThread();  // should be inhibited without blocking
559    PostSetNeedsCommitToMainThread();
560  }
561
562  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
563    num_draws_++;
564    EXPECT_EQ(num_draws_, num_commits_);
565  }
566
567  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
568    num_commits_++;
569    EndTest();
570  }
571
572  virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_commits_); }
573
574 private:
575  int num_commits_;
576  int num_draws_;
577};
578
579MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersRedraw);
580
581// Verify that when resuming visibility, Requesting layer write permission
582// will not deadlock the main thread even though there are not yet any
583// scheduled redraws. This behavior is critical for reliably surviving tab
584// switching. There are no failure conditions to this test, it just passes
585// by not timing out.
586class LayerTreeHostTestWriteLayersAfterVisible : public LayerTreeHostTest {
587 public:
588  LayerTreeHostTestWriteLayersAfterVisible() : num_commits_(0) {}
589
590  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
591
592  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
593    num_commits_++;
594    if (num_commits_ == 2)
595      EndTest();
596    else if (num_commits_ < 2) {
597      PostSetVisibleToMainThread(false);
598      PostSetVisibleToMainThread(true);
599      PostAcquireLayerTextures();
600      PostSetNeedsCommitToMainThread();
601    }
602  }
603
604  virtual void AfterTest() OVERRIDE {}
605
606 private:
607  int num_commits_;
608};
609
610MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersAfterVisible);
611
612// A compositeAndReadback while invisible should force a normal commit without
613// assertion.
614class LayerTreeHostTestCompositeAndReadbackWhileInvisible
615    : public LayerTreeHostTest {
616 public:
617  LayerTreeHostTestCompositeAndReadbackWhileInvisible() : num_commits_(0) {}
618
619  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
620
621  virtual void DidCommitAndDrawFrame() OVERRIDE {
622    num_commits_++;
623    if (num_commits_ == 1) {
624      layer_tree_host()->SetVisible(false);
625      layer_tree_host()->SetNeedsCommit();
626      layer_tree_host()->SetNeedsCommit();
627      char pixels[4];
628      layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
629    } else {
630      EndTest();
631    }
632  }
633
634  virtual void AfterTest() OVERRIDE {}
635
636 private:
637  int num_commits_;
638};
639
640MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackWhileInvisible);
641
642class LayerTreeHostTestAbortFrameWhenInvisible : public LayerTreeHostTest {
643 public:
644  LayerTreeHostTestAbortFrameWhenInvisible() {}
645
646  virtual void BeginTest() OVERRIDE {
647    // Request a commit (from the main thread), Which will trigger the commit
648    // flow from the impl side.
649    layer_tree_host()->SetNeedsCommit();
650    // Then mark ourselves as not visible before processing any more messages
651    // on the main thread.
652    layer_tree_host()->SetVisible(false);
653    // If we make it without kicking a frame, we pass!
654    EndTestAfterDelay(1);
655  }
656
657  virtual void Layout() OVERRIDE {
658    ASSERT_FALSE(true);
659    EndTest();
660  }
661
662  virtual void AfterTest() OVERRIDE {}
663
664 private:
665};
666
667MULTI_THREAD_TEST_F(LayerTreeHostTestAbortFrameWhenInvisible);
668
669// This test verifies that properties on the layer tree host are commited
670// to the impl side.
671class LayerTreeHostTestCommit : public LayerTreeHostTest {
672 public:
673  LayerTreeHostTestCommit() {}
674
675  virtual void BeginTest() OVERRIDE {
676    layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
677    layer_tree_host()->set_background_color(SK_ColorGRAY);
678
679    PostSetNeedsCommitToMainThread();
680  }
681
682  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
683    EXPECT_EQ(gfx::Size(20, 20), impl->device_viewport_size());
684    EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
685
686    EndTest();
687  }
688
689  virtual void AfterTest() OVERRIDE {}
690};
691
692MULTI_THREAD_TEST_F(LayerTreeHostTestCommit);
693
694// This test verifies that LayerTreeHostImpl's current frame time gets
695// updated in consecutive frames when it doesn't draw due to tree
696// activation failure.
697class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
698    : public LayerTreeHostTest {
699 public:
700  LayerTreeHostTestFrameTimeUpdatesAfterActivationFails() : frame_(0) {}
701
702  virtual void BeginTest() OVERRIDE {
703    layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
704    layer_tree_host()->set_background_color(SK_ColorGRAY);
705
706    PostSetNeedsCommitToMainThread();
707  }
708
709  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
710    if (frame_ >= 1) {
711      EXPECT_NE(first_frame_time_, impl->CurrentFrameTimeTicks());
712      EndTest();
713      return;
714    }
715
716    EXPECT_FALSE(impl->settings().impl_side_painting);
717    EndTest();
718  }
719
720  virtual bool CanActivatePendingTree(LayerTreeHostImpl* impl) OVERRIDE {
721    if (frame_ >= 1)
722      return true;
723
724    return false;
725  }
726
727  virtual bool CanActivatePendingTreeIfNeeded(LayerTreeHostImpl* impl)
728      OVERRIDE {
729    frame_++;
730    if (frame_ == 1) {
731      first_frame_time_ = impl->CurrentFrameTimeTicks();
732
733      // Since base::TimeTicks::Now() uses a low-resolution clock on
734      // Windows, we need to make sure that the clock has incremented past
735      // first_frame_time_.
736      while (first_frame_time_ == base::TimeTicks::Now()) {}
737
738      return false;
739    }
740
741    return true;
742  }
743
744  virtual void AfterTest() OVERRIDE {}
745
746 private:
747  int frame_;
748  base::TimeTicks first_frame_time_;
749};
750
751SINGLE_AND_MULTI_THREAD_TEST_F(
752    LayerTreeHostTestFrameTimeUpdatesAfterActivationFails);
753
754// This test verifies that LayerTreeHostImpl's current frame time gets
755// updated in consecutive frames when it draws in each frame.
756class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
757 public:
758  LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {}
759
760  virtual void BeginTest() OVERRIDE {
761    layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
762    layer_tree_host()->set_background_color(SK_ColorGRAY);
763
764    PostSetNeedsCommitToMainThread();
765  }
766
767  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
768    frame_++;
769    if (frame_ == 1) {
770      first_frame_time_ = impl->CurrentFrameTimeTicks();
771      impl->SetNeedsRedraw();
772
773      // Since base::TimeTicks::Now() uses a low-resolution clock on
774      // Windows, we need to make sure that the clock has incremented past
775      // first_frame_time_.
776      while (first_frame_time_ == base::TimeTicks::Now()) {}
777
778      return;
779    }
780
781    EXPECT_NE(first_frame_time_, impl->CurrentFrameTimeTicks());
782    EndTest();
783  }
784
785  virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
786    // Ensure there isn't a commit between the two draws, to ensure that a
787    // commit isn't required for updating the current frame time. We can
788    // only check for this in the multi-threaded case, since in the single-
789    // threaded case there will always be a commit between consecutive draws.
790    if (HasImplThread())
791      EXPECT_EQ(0, frame_);
792  }
793
794  virtual void AfterTest() OVERRIDE {}
795
796 private:
797  int frame_;
798  base::TimeTicks first_frame_time_;
799};
800
801SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw);
802
803// Verifies that StartPageScaleAnimation events propagate correctly
804// from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
805class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
806 public:
807  LayerTreeHostTestStartPageScaleAnimation() {}
808
809  virtual void SetupTree() OVERRIDE {
810    LayerTreeHostTest::SetupTree();
811
812    scroll_layer_ = FakeContentLayer::Create(&client_);
813    scroll_layer_->SetScrollable(true);
814    scroll_layer_->SetScrollOffset(gfx::Vector2d());
815    layer_tree_host()->root_layer()->AddChild(scroll_layer_);
816  }
817
818  virtual void BeginTest() OVERRIDE {
819    PostSetNeedsCommitToMainThread();
820  }
821
822  virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta, float scale)
823      OVERRIDE {
824    gfx::Vector2d offset = scroll_layer_->scroll_offset();
825    scroll_layer_->SetScrollOffset(offset + scroll_delta);
826    layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
827  }
828
829  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
830    impl->ProcessScrollDeltas();
831    // We get one commit before the first draw, and the animation doesn't happen
832    // until the second draw.
833    switch (impl->active_tree()->source_frame_number()) {
834      case 0:
835        EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
836        // We'll start an animation when we get back to the main thread.
837        break;
838      case 1:
839        EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
840        PostSetNeedsRedrawToMainThread();
841        break;
842      case 2:
843        EXPECT_EQ(1.25f, impl->active_tree()->page_scale_factor());
844        EndTest();
845        break;
846      default:
847        NOTREACHED();
848    }
849  }
850
851  virtual void DidCommitAndDrawFrame() OVERRIDE {
852    switch (layer_tree_host()->commit_number()) {
853      case 1:
854        layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
855        layer_tree_host()->StartPageScaleAnimation(
856            gfx::Vector2d(), false, 1.25f, base::TimeDelta());
857        break;
858    }
859  }
860
861  virtual void AfterTest() OVERRIDE {}
862
863  FakeContentLayerClient client_;
864  scoped_refptr<FakeContentLayer> scroll_layer_;
865};
866
867MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
868
869class LayerTreeHostTestSetVisible : public LayerTreeHostTest {
870 public:
871  LayerTreeHostTestSetVisible() : num_draws_(0) {}
872
873  virtual void BeginTest() OVERRIDE {
874    PostSetNeedsCommitToMainThread();
875    PostSetVisibleToMainThread(false);
876    // This is suppressed while we're invisible.
877    PostSetNeedsRedrawToMainThread();
878    // Triggers the redraw.
879    PostSetVisibleToMainThread(true);
880  }
881
882  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
883    EXPECT_TRUE(impl->visible());
884    ++num_draws_;
885    EndTest();
886  }
887
888  virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_draws_); }
889
890 private:
891  int num_draws_;
892};
893
894MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible);
895
896class TestOpacityChangeLayerDelegate : public ContentLayerClient {
897 public:
898  TestOpacityChangeLayerDelegate() : test_layer_(0) {}
899
900  void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
901
902  virtual void PaintContents(SkCanvas*, gfx::Rect, gfx::RectF*) OVERRIDE {
903    // Set layer opacity to 0.
904    if (test_layer_)
905      test_layer_->SetOpacity(0.f);
906  }
907  virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
908
909 private:
910  Layer* test_layer_;
911};
912
913class ContentLayerWithUpdateTracking : public ContentLayer {
914 public:
915  static scoped_refptr<ContentLayerWithUpdateTracking> Create(
916      ContentLayerClient* client) {
917    return make_scoped_refptr(new ContentLayerWithUpdateTracking(client));
918  }
919
920  int PaintContentsCount() { return paint_contents_count_; }
921  void ResetPaintContentsCount() { paint_contents_count_ = 0; }
922
923  virtual bool Update(ResourceUpdateQueue* queue,
924                      const OcclusionTracker* occlusion) OVERRIDE {
925    bool updated = ContentLayer::Update(queue, occlusion);
926    paint_contents_count_++;
927    return updated;
928  }
929
930 private:
931  explicit ContentLayerWithUpdateTracking(ContentLayerClient* client)
932      : ContentLayer(client), paint_contents_count_(0) {
933    SetAnchorPoint(gfx::PointF(0.f, 0.f));
934    SetBounds(gfx::Size(10, 10));
935    SetIsDrawable(true);
936  }
937  virtual ~ContentLayerWithUpdateTracking() {}
938
939  int paint_contents_count_;
940};
941
942// Layer opacity change during paint should not prevent compositor resources
943// from being updated during commit.
944class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
945 public:
946  LayerTreeHostTestOpacityChange()
947      : test_opacity_change_delegate_(),
948        update_check_layer_(ContentLayerWithUpdateTracking::Create(
949            &test_opacity_change_delegate_)) {
950    test_opacity_change_delegate_.SetTestLayer(update_check_layer_.get());
951  }
952
953  virtual void BeginTest() OVERRIDE {
954    layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
955    layer_tree_host()->root_layer()->AddChild(update_check_layer_);
956
957    PostSetNeedsCommitToMainThread();
958  }
959
960  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
961    EndTest();
962  }
963
964  virtual void AfterTest() OVERRIDE {
965    // Update() should have been called once.
966    EXPECT_EQ(1, update_check_layer_->PaintContentsCount());
967  }
968
969 private:
970  TestOpacityChangeLayerDelegate test_opacity_change_delegate_;
971  scoped_refptr<ContentLayerWithUpdateTracking> update_check_layer_;
972};
973
974MULTI_THREAD_TEST_F(LayerTreeHostTestOpacityChange);
975
976class NoScaleContentLayer : public ContentLayer {
977 public:
978  static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) {
979    return make_scoped_refptr(new NoScaleContentLayer(client));
980  }
981
982  virtual void CalculateContentsScale(float ideal_contents_scale,
983                                      float device_scale_factor,
984                                      float page_scale_factor,
985                                      bool animating_transform_to_screen,
986                                      float* contents_scale_x,
987                                      float* contents_scale_y,
988                                      gfx::Size* contentBounds) OVERRIDE {
989    // Skip over the ContentLayer's method to the base Layer class.
990    Layer::CalculateContentsScale(ideal_contents_scale,
991                                  device_scale_factor,
992                                  page_scale_factor,
993                                  animating_transform_to_screen,
994                                  contents_scale_x,
995                                  contents_scale_y,
996                                  contentBounds);
997  }
998
999 private:
1000  explicit NoScaleContentLayer(ContentLayerClient* client)
1001      : ContentLayer(client) {}
1002  virtual ~NoScaleContentLayer() {}
1003};
1004
1005class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
1006    : public LayerTreeHostTest {
1007 public:
1008  LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
1009      : root_layer_(NoScaleContentLayer::Create(&client_)),
1010        child_layer_(ContentLayer::Create(&client_)) {}
1011
1012  virtual void BeginTest() OVERRIDE {
1013    layer_tree_host()->SetViewportSize(gfx::Size(60, 60));
1014    layer_tree_host()->SetDeviceScaleFactor(1.5);
1015    EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size());
1016
1017    root_layer_->AddChild(child_layer_);
1018
1019    root_layer_->SetIsDrawable(true);
1020    root_layer_->SetBounds(gfx::Size(30, 30));
1021    root_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1022
1023    child_layer_->SetIsDrawable(true);
1024    child_layer_->SetPosition(gfx::Point(2, 2));
1025    child_layer_->SetBounds(gfx::Size(10, 10));
1026    child_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1027
1028    layer_tree_host()->SetRootLayer(root_layer_);
1029
1030    PostSetNeedsCommitToMainThread();
1031  }
1032
1033  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1034    // Should only do one commit.
1035    EXPECT_EQ(0, impl->active_tree()->source_frame_number());
1036    // Device scale factor should come over to impl.
1037    EXPECT_NEAR(impl->device_scale_factor(), 1.5f, 0.00001f);
1038
1039    // Both layers are on impl.
1040    ASSERT_EQ(1u, impl->active_tree()->root_layer()->children().size());
1041
1042    // Device viewport is scaled.
1043    EXPECT_EQ(gfx::Size(60, 60), impl->device_viewport_size());
1044
1045    LayerImpl* root = impl->active_tree()->root_layer();
1046    LayerImpl* child = impl->active_tree()->root_layer()->children()[0];
1047
1048    // Positions remain in layout pixels.
1049    EXPECT_EQ(gfx::Point(0, 0), root->position());
1050    EXPECT_EQ(gfx::Point(2, 2), child->position());
1051
1052    // Compute all the layer transforms for the frame.
1053    LayerTreeHostImpl::FrameData frame_data;
1054    impl->PrepareToDraw(&frame_data, gfx::Rect());
1055    impl->DidDrawAllLayers(frame_data);
1056
1057    const LayerImplList& render_surface_layer_list =
1058        *frame_data.render_surface_layer_list;
1059
1060    // Both layers should be drawing into the root render surface.
1061    ASSERT_EQ(1u, render_surface_layer_list.size());
1062    ASSERT_EQ(root->render_surface(),
1063              render_surface_layer_list[0]->render_surface());
1064    ASSERT_EQ(2u, root->render_surface()->layer_list().size());
1065
1066    // The root render surface is the size of the viewport.
1067    EXPECT_RECT_EQ(gfx::Rect(0, 0, 60, 60),
1068                   root->render_surface()->content_rect());
1069
1070    // The content bounds of the child should be scaled.
1071    gfx::Size child_bounds_scaled =
1072        gfx::ToCeiledSize(gfx::ScaleSize(child->bounds(), 1.5));
1073    EXPECT_EQ(child_bounds_scaled, child->content_bounds());
1074
1075    gfx::Transform scale_transform;
1076    scale_transform.Scale(impl->device_scale_factor(),
1077                          impl->device_scale_factor());
1078
1079    // The root layer is scaled by 2x.
1080    gfx::Transform root_screen_space_transform = scale_transform;
1081    gfx::Transform root_draw_transform = scale_transform;
1082
1083    EXPECT_EQ(root_draw_transform, root->draw_transform());
1084    EXPECT_EQ(root_screen_space_transform, root->screen_space_transform());
1085
1086    // The child is at position 2,2, which is transformed to 3,3 after the scale
1087    gfx::Transform child_screen_space_transform;
1088    child_screen_space_transform.Translate(3.f, 3.f);
1089    gfx::Transform child_draw_transform = child_screen_space_transform;
1090
1091    EXPECT_TRANSFORMATION_MATRIX_EQ(child_draw_transform,
1092                                    child->draw_transform());
1093    EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform,
1094                                    child->screen_space_transform());
1095
1096    EndTest();
1097  }
1098
1099  virtual void AfterTest() OVERRIDE {}
1100
1101 private:
1102  FakeContentLayerClient client_;
1103  scoped_refptr<NoScaleContentLayer> root_layer_;
1104  scoped_refptr<ContentLayer> child_layer_;
1105};
1106
1107MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers);
1108
1109// Verify atomicity of commits and reuse of textures.
1110class LayerTreeHostTestAtomicCommit : public LayerTreeHostTest {
1111 public:
1112  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1113    // Make sure partial texture updates are turned off.
1114    settings->max_partial_texture_updates = 0;
1115    // Linear fade animator prevents scrollbars from drawing immediately.
1116    settings->use_linear_fade_scrollbar_animator = false;
1117  }
1118
1119  virtual void SetupTree() OVERRIDE {
1120    layer_ = FakeContentLayer::Create(&client_);
1121    layer_->SetBounds(gfx::Size(10, 20));
1122
1123    bool paint_scrollbar = true;
1124    bool has_thumb = false;
1125    scrollbar_ =
1126        FakeScrollbarLayer::Create(paint_scrollbar, has_thumb, layer_->id());
1127    scrollbar_->SetPosition(gfx::Point(0, 10));
1128    scrollbar_->SetBounds(gfx::Size(10, 10));
1129
1130    layer_->AddChild(scrollbar_);
1131
1132    layer_tree_host()->SetRootLayer(layer_);
1133    LayerTreeHostTest::SetupTree();
1134  }
1135
1136  virtual void BeginTest() OVERRIDE {
1137    drew_frame_ = -1;
1138    PostSetNeedsCommitToMainThread();
1139  }
1140
1141  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1142    ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
1143
1144    TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1145        impl->output_surface()->context3d());
1146
1147    switch (impl->active_tree()->source_frame_number()) {
1148      case 0:
1149        // Number of textures should be one for each layer
1150        ASSERT_EQ(2u, context->NumTextures());
1151        // Number of textures used for commit should be one for each layer.
1152        EXPECT_EQ(2u, context->NumUsedTextures());
1153        // Verify that used texture is correct.
1154        EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1155        EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1156
1157        context->ResetUsedTextures();
1158        PostSetNeedsCommitToMainThread();
1159        break;
1160      case 1:
1161        // Number of textures should be doubled as the first textures
1162        // are used by impl thread and cannot by used for update.
1163        ASSERT_EQ(4u, context->NumTextures());
1164        // Number of textures used for commit should still be
1165        // one for each layer.
1166        EXPECT_EQ(2u, context->NumUsedTextures());
1167        // First textures should not have been used.
1168        EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1169        EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1170        // New textures should have been used.
1171        EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1172        EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1173
1174        context->ResetUsedTextures();
1175        PostSetNeedsCommitToMainThread();
1176        break;
1177      case 2:
1178        EndTest();
1179        break;
1180      default:
1181        NOTREACHED();
1182        break;
1183    }
1184  }
1185
1186  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1187    TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1188        impl->output_surface()->context3d());
1189
1190    if (drew_frame_ == impl->active_tree()->source_frame_number()) {
1191      EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
1192      return;
1193    }
1194    drew_frame_ = impl->active_tree()->source_frame_number();
1195
1196    // We draw/ship one texture each frame for each layer.
1197    EXPECT_EQ(2u, context->NumUsedTextures());
1198    context->ResetUsedTextures();
1199  }
1200
1201  virtual void Layout() OVERRIDE {
1202    layer_->SetNeedsDisplay();
1203    scrollbar_->SetNeedsDisplay();
1204  }
1205
1206  virtual void AfterTest() OVERRIDE {}
1207
1208 private:
1209  FakeContentLayerClient client_;
1210  scoped_refptr<FakeContentLayer> layer_;
1211  scoped_refptr<FakeScrollbarLayer> scrollbar_;
1212  int drew_frame_;
1213};
1214
1215MULTI_THREAD_TEST_F(LayerTreeHostTestAtomicCommit);
1216
1217static void SetLayerPropertiesForTesting(Layer* layer,
1218                                         Layer* parent,
1219                                         const gfx::Transform& transform,
1220                                         gfx::PointF anchor,
1221                                         gfx::PointF position,
1222                                         gfx::Size bounds,
1223                                         bool opaque) {
1224  layer->RemoveAllChildren();
1225  if (parent)
1226    parent->AddChild(layer);
1227  layer->SetTransform(transform);
1228  layer->SetAnchorPoint(anchor);
1229  layer->SetPosition(position);
1230  layer->SetBounds(bounds);
1231  layer->SetContentsOpaque(opaque);
1232}
1233
1234class LayerTreeHostTestAtomicCommitWithPartialUpdate
1235    : public LayerTreeHostTest {
1236 public:
1237  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1238    // Allow one partial texture update.
1239    settings->max_partial_texture_updates = 1;
1240    // Linear fade animator prevents scrollbars from drawing immediately.
1241    settings->use_linear_fade_scrollbar_animator = false;
1242    // No partial updates when impl side painting is enabled.
1243    settings->impl_side_painting = false;
1244  }
1245
1246  virtual void SetupTree() OVERRIDE {
1247    parent_ = FakeContentLayer::Create(&client_);
1248    parent_->SetBounds(gfx::Size(10, 20));
1249
1250    child_ = FakeContentLayer::Create(&client_);
1251    child_->SetPosition(gfx::Point(0, 10));
1252    child_->SetBounds(gfx::Size(3, 10));
1253
1254    bool paint_scrollbar = true;
1255    bool has_thumb = false;
1256    scrollbar_with_paints_ =
1257        FakeScrollbarLayer::Create(paint_scrollbar, has_thumb, parent_->id());
1258    scrollbar_with_paints_->SetPosition(gfx::Point(3, 10));
1259    scrollbar_with_paints_->SetBounds(gfx::Size(3, 10));
1260
1261    paint_scrollbar = false;
1262    scrollbar_without_paints_ =
1263        FakeScrollbarLayer::Create(paint_scrollbar, has_thumb, parent_->id());
1264    scrollbar_without_paints_->SetPosition(gfx::Point(6, 10));
1265    scrollbar_without_paints_->SetBounds(gfx::Size(3, 10));
1266
1267    parent_->AddChild(child_);
1268    parent_->AddChild(scrollbar_with_paints_);
1269    parent_->AddChild(scrollbar_without_paints_);
1270
1271    layer_tree_host()->SetRootLayer(parent_);
1272    LayerTreeHostTest::SetupTree();
1273  }
1274
1275  virtual void BeginTest() OVERRIDE {
1276    PostSetNeedsCommitToMainThread();
1277  }
1278
1279  virtual void DidCommitAndDrawFrame() OVERRIDE {
1280    switch (layer_tree_host()->commit_number()) {
1281      case 1:
1282        parent_->SetNeedsDisplay();
1283        child_->SetNeedsDisplay();
1284        scrollbar_with_paints_->SetNeedsDisplay();
1285        scrollbar_without_paints_->SetNeedsDisplay();
1286        break;
1287      case 2:
1288        // Damage part of layers.
1289        parent_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1290        child_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f));
1291        scrollbar_with_paints_->SetNeedsDisplayRect(
1292            gfx::RectF(0.f, 0.f, 5.f, 5.f));
1293        scrollbar_without_paints_->SetNeedsDisplayRect(
1294            gfx::RectF(0.f, 0.f, 5.f, 5.f));
1295        break;
1296      case 3:
1297        child_->SetNeedsDisplay();
1298        scrollbar_with_paints_->SetNeedsDisplay();
1299        scrollbar_without_paints_->SetNeedsDisplay();
1300        layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1301        break;
1302      case 4:
1303        layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1304        break;
1305      case 5:
1306        EndTest();
1307        break;
1308      default:
1309        NOTREACHED() << layer_tree_host()->commit_number();
1310        break;
1311    }
1312  }
1313
1314  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1315    ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates);
1316
1317    TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1318        impl->output_surface()->context3d());
1319
1320    switch (impl->active_tree()->source_frame_number()) {
1321      case 0:
1322        // Number of textures should be one for each layer.
1323        ASSERT_EQ(4u, context->NumTextures());
1324        // Number of textures used for commit should be one for each layer.
1325        EXPECT_EQ(4u, context->NumUsedTextures());
1326        // Verify that used textures are correct.
1327        EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
1328        EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
1329        EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
1330        EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1331
1332        context->ResetUsedTextures();
1333        break;
1334      case 1:
1335        // Number of textures should be two for each content layer and one
1336        // for each scrollbar, since they always do a partial update.
1337        ASSERT_EQ(6u, context->NumTextures());
1338        // Number of textures used for commit should be one for each content
1339        // layer, and one for the scrollbar layer that paints.
1340        EXPECT_EQ(3u, context->NumUsedTextures());
1341
1342        // First content textures should not have been used.
1343        EXPECT_FALSE(context->UsedTexture(context->TextureAt(0)));
1344        EXPECT_FALSE(context->UsedTexture(context->TextureAt(1)));
1345        // The non-painting scrollbar's texture wasn't updated.
1346        EXPECT_FALSE(context->UsedTexture(context->TextureAt(2)));
1347        // The painting scrollbar's partial update texture was used.
1348        EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1349        // New textures should have been used.
1350        EXPECT_TRUE(context->UsedTexture(context->TextureAt(4)));
1351        EXPECT_TRUE(context->UsedTexture(context->TextureAt(5)));
1352
1353        context->ResetUsedTextures();
1354        break;
1355      case 2:
1356        // Number of textures should be two for each content layer and one
1357        // for each scrollbar, since they always do a partial update.
1358        ASSERT_EQ(6u, context->NumTextures());
1359        // Number of textures used for commit should be one for each content
1360        // layer, and one for the scrollbar layer that paints.
1361        EXPECT_EQ(3u, context->NumUsedTextures());
1362
1363        // The non-painting scrollbar's texture wasn't updated.
1364        EXPECT_FALSE(context->UsedTexture(context->TextureAt(2)));
1365        // The painting scrollbar does a partial update.
1366        EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
1367        // One content layer does a partial update also.
1368        EXPECT_TRUE(context->UsedTexture(context->TextureAt(4)));
1369        EXPECT_FALSE(context->UsedTexture(context->TextureAt(5)));
1370
1371        context->ResetUsedTextures();
1372        break;
1373      case 3:
1374        // No textures should be used for commit.
1375        EXPECT_EQ(0u, context->NumUsedTextures());
1376
1377        context->ResetUsedTextures();
1378        break;
1379      case 4:
1380        // Number of textures used for commit should be two. One for the
1381        // content layer, and one for the painting scrollbar. The
1382        // non-painting scrollbar doesn't update its texture.
1383        EXPECT_EQ(2u, context->NumUsedTextures());
1384
1385        context->ResetUsedTextures();
1386        break;
1387      default:
1388        NOTREACHED();
1389        break;
1390    }
1391  }
1392
1393  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1394    EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
1395
1396    TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
1397        impl->output_surface()->context3d());
1398
1399    // Number of textures used for drawing should one per layer except for
1400    // frame 3 where the viewport only contains one layer.
1401    if (impl->active_tree()->source_frame_number() == 3) {
1402      EXPECT_EQ(1u, context->NumUsedTextures());
1403    } else {
1404      EXPECT_EQ(4u, context->NumUsedTextures()) <<
1405          "For frame " << impl->active_tree()->source_frame_number();
1406    }
1407
1408    context->ResetUsedTextures();
1409  }
1410
1411  virtual void AfterTest() OVERRIDE {}
1412
1413 private:
1414  FakeContentLayerClient client_;
1415  scoped_refptr<FakeContentLayer> parent_;
1416  scoped_refptr<FakeContentLayer> child_;
1417  scoped_refptr<FakeScrollbarLayer> scrollbar_with_paints_;
1418  scoped_refptr<FakeScrollbarLayer> scrollbar_without_paints_;
1419};
1420
1421// Partial updates are not possible with a delegating renderer.
1422SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1423    LayerTreeHostTestAtomicCommitWithPartialUpdate);
1424
1425class LayerTreeHostTestFinishAllRendering : public LayerTreeHostTest {
1426 public:
1427  LayerTreeHostTestFinishAllRendering() : once_(false), draw_count_(0) {}
1428
1429  virtual void BeginTest() OVERRIDE {
1430    layer_tree_host()->SetNeedsRedraw();
1431    PostSetNeedsCommitToMainThread();
1432  }
1433
1434  virtual void DidCommitAndDrawFrame() OVERRIDE {
1435    if (once_)
1436      return;
1437    once_ = true;
1438    layer_tree_host()->SetNeedsRedraw();
1439    layer_tree_host()->AcquireLayerTextures();
1440    {
1441      base::AutoLock lock(lock_);
1442      draw_count_ = 0;
1443    }
1444    layer_tree_host()->FinishAllRendering();
1445    {
1446      base::AutoLock lock(lock_);
1447      EXPECT_EQ(0, draw_count_);
1448    }
1449    EndTest();
1450  }
1451
1452  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1453    base::AutoLock lock(lock_);
1454    ++draw_count_;
1455  }
1456
1457  virtual void AfterTest() OVERRIDE {}
1458
1459 private:
1460  bool once_;
1461  base::Lock lock_;
1462  int draw_count_;
1463};
1464
1465SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFinishAllRendering);
1466
1467class LayerTreeHostTestCompositeAndReadbackCleanup : public LayerTreeHostTest {
1468 public:
1469  virtual void BeginTest() OVERRIDE {
1470    Layer* root_layer = layer_tree_host()->root_layer();
1471
1472    char pixels[4];
1473    layer_tree_host()->CompositeAndReadback(static_cast<void*>(&pixels),
1474                                            gfx::Rect(0, 0, 1, 1));
1475    EXPECT_FALSE(root_layer->render_surface());
1476
1477    EndTest();
1478  }
1479
1480  virtual void AfterTest() OVERRIDE {}
1481};
1482
1483SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCompositeAndReadbackCleanup);
1484
1485class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
1486    : public LayerTreeHostTest {
1487 protected:
1488  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1489    settings->cache_render_pass_contents = true;
1490  }
1491
1492  virtual void SetupTree() OVERRIDE {
1493    root_layer_ = FakeContentLayer::Create(&client_);
1494    root_layer_->SetBounds(gfx::Size(100, 100));
1495
1496    surface_layer1_ = FakeContentLayer::Create(&client_);
1497    surface_layer1_->SetBounds(gfx::Size(100, 100));
1498    surface_layer1_->SetForceRenderSurface(true);
1499    surface_layer1_->SetOpacity(0.5f);
1500    root_layer_->AddChild(surface_layer1_);
1501
1502    surface_layer2_ = FakeContentLayer::Create(&client_);
1503    surface_layer2_->SetBounds(gfx::Size(100, 100));
1504    surface_layer2_->SetForceRenderSurface(true);
1505    surface_layer2_->SetOpacity(0.5f);
1506    surface_layer1_->AddChild(surface_layer2_);
1507
1508    replica_layer1_ = FakeContentLayer::Create(&client_);
1509    surface_layer1_->SetReplicaLayer(replica_layer1_.get());
1510
1511    replica_layer2_ = FakeContentLayer::Create(&client_);
1512    surface_layer2_->SetReplicaLayer(replica_layer2_.get());
1513
1514    layer_tree_host()->SetRootLayer(root_layer_);
1515    LayerTreeHostTest::SetupTree();
1516  }
1517
1518  virtual void BeginTest() OVERRIDE {
1519    PostSetNeedsCommitToMainThread();
1520  }
1521
1522  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1523    Renderer* renderer = host_impl->renderer();
1524    RenderPass::Id surface1_render_pass_id = host_impl->active_tree()
1525        ->root_layer()->children()[0]->render_surface()->RenderPassId();
1526    RenderPass::Id surface2_render_pass_id =
1527        host_impl->active_tree()->root_layer()->children()[0]->children()[0]
1528        ->render_surface()->RenderPassId();
1529
1530    switch (host_impl->active_tree()->source_frame_number()) {
1531      case 0:
1532        EXPECT_TRUE(renderer->HaveCachedResourcesForRenderPassId(
1533            surface1_render_pass_id));
1534        EXPECT_TRUE(renderer->HaveCachedResourcesForRenderPassId(
1535            surface2_render_pass_id));
1536
1537        // Reduce the memory limit to only fit the root layer and one render
1538        // surface. This prevents any contents drawing into surfaces
1539        // from being allocated.
1540        host_impl->SetMemoryPolicy(
1541            ManagedMemoryPolicy(100 * 100 * 4 * 2), true);
1542        break;
1543      case 1:
1544        EXPECT_FALSE(renderer->HaveCachedResourcesForRenderPassId(
1545            surface1_render_pass_id));
1546        EXPECT_FALSE(renderer->HaveCachedResourcesForRenderPassId(
1547            surface2_render_pass_id));
1548
1549        EndTest();
1550        break;
1551    }
1552  }
1553
1554  virtual void DidCommitAndDrawFrame() OVERRIDE {
1555    if (layer_tree_host()->commit_number() < 2)
1556      root_layer_->SetNeedsDisplay();
1557  }
1558
1559  virtual void AfterTest() OVERRIDE {
1560    EXPECT_LE(2u, root_layer_->update_count());
1561    EXPECT_LE(2u, surface_layer1_->update_count());
1562    EXPECT_LE(2u, surface_layer2_->update_count());
1563  }
1564
1565  FakeContentLayerClient client_;
1566  scoped_refptr<FakeContentLayer> root_layer_;
1567  scoped_refptr<FakeContentLayer> surface_layer1_;
1568  scoped_refptr<FakeContentLayer> replica_layer1_;
1569  scoped_refptr<FakeContentLayer> surface_layer2_;
1570  scoped_refptr<FakeContentLayer> replica_layer2_;
1571};
1572
1573// Surfaces don't exist with a delegated renderer.
1574SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1575    LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit);
1576
1577class EvictionTestLayer : public Layer {
1578 public:
1579  static scoped_refptr<EvictionTestLayer> Create() {
1580    return make_scoped_refptr(new EvictionTestLayer());
1581  }
1582
1583  virtual bool Update(ResourceUpdateQueue*,
1584                      const OcclusionTracker*) OVERRIDE;
1585  virtual bool DrawsContent() const OVERRIDE { return true; }
1586
1587  virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
1588      OVERRIDE;
1589  virtual void PushPropertiesTo(LayerImpl* impl) OVERRIDE;
1590  virtual void SetTexturePriorities(const PriorityCalculator&) OVERRIDE;
1591
1592  bool HaveBackingTexture() const {
1593    return texture_.get() ? texture_->have_backing_texture() : false;
1594  }
1595
1596 private:
1597  EvictionTestLayer() : Layer() {}
1598  virtual ~EvictionTestLayer() {}
1599
1600  void CreateTextureIfNeeded() {
1601    if (texture_)
1602      return;
1603    texture_ = PrioritizedResource::Create(
1604        layer_tree_host()->contents_texture_manager());
1605    texture_->SetDimensions(gfx::Size(10, 10), GL_RGBA);
1606    bitmap_.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
1607  }
1608
1609  scoped_ptr<PrioritizedResource> texture_;
1610  SkBitmap bitmap_;
1611};
1612
1613class EvictionTestLayerImpl : public LayerImpl {
1614 public:
1615  static scoped_ptr<EvictionTestLayerImpl> Create(LayerTreeImpl* tree_impl,
1616                                                  int id) {
1617    return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id));
1618  }
1619  virtual ~EvictionTestLayerImpl() {}
1620
1621  virtual void AppendQuads(QuadSink* quad_sink,
1622                           AppendQuadsData* append_quads_data) OVERRIDE {
1623    ASSERT_TRUE(has_texture_);
1624    ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources());
1625  }
1626
1627  void SetHasTexture(bool has_texture) { has_texture_ = has_texture; }
1628
1629 private:
1630  EvictionTestLayerImpl(LayerTreeImpl* tree_impl, int id)
1631      : LayerImpl(tree_impl, id), has_texture_(false) {}
1632
1633  bool has_texture_;
1634};
1635
1636void EvictionTestLayer::SetTexturePriorities(const PriorityCalculator&) {
1637  CreateTextureIfNeeded();
1638  if (!texture_)
1639    return;
1640  texture_->set_request_priority(PriorityCalculator::UIPriority(true));
1641}
1642
1643bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
1644                               const OcclusionTracker*) {
1645  CreateTextureIfNeeded();
1646  if (!texture_)
1647    return false;
1648
1649  gfx::Rect full_rect(0, 0, 10, 10);
1650  ResourceUpdate upload = ResourceUpdate::Create(
1651      texture_.get(), &bitmap_, full_rect, full_rect, gfx::Vector2d());
1652  queue->AppendFullUpload(upload);
1653  return true;
1654}
1655
1656scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl(
1657    LayerTreeImpl* tree_impl) {
1658  return EvictionTestLayerImpl::Create(tree_impl, layer_id_)
1659      .PassAs<LayerImpl>();
1660}
1661
1662void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) {
1663  Layer::PushPropertiesTo(layer_impl);
1664
1665  EvictionTestLayerImpl* test_layer_impl =
1666      static_cast<EvictionTestLayerImpl*>(layer_impl);
1667  test_layer_impl->SetHasTexture(texture_->have_backing_texture());
1668}
1669
1670class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
1671 public:
1672  LayerTreeHostTestEvictTextures()
1673      : layer_(EvictionTestLayer::Create()),
1674        impl_for_evict_textures_(0),
1675        num_commits_(0) {}
1676
1677  virtual void BeginTest() OVERRIDE {
1678    layer_tree_host()->SetRootLayer(layer_);
1679    layer_tree_host()->SetViewportSize(gfx::Size(10, 20));
1680
1681    gfx::Transform identity_matrix;
1682    SetLayerPropertiesForTesting(layer_.get(),
1683                                 0,
1684                                 identity_matrix,
1685                                 gfx::PointF(0.f, 0.f),
1686                                 gfx::PointF(0.f, 0.f),
1687                                 gfx::Size(10, 20),
1688                                 true);
1689
1690    PostSetNeedsCommitToMainThread();
1691  }
1692
1693  void PostEvictTextures() {
1694    DCHECK(HasImplThread());
1695    ImplThreadTaskRunner()->PostTask(
1696        FROM_HERE,
1697        base::Bind(&LayerTreeHostTestEvictTextures::EvictTexturesOnImplThread,
1698                   base::Unretained(this)));
1699  }
1700
1701  void EvictTexturesOnImplThread() {
1702    DCHECK(impl_for_evict_textures_);
1703    impl_for_evict_textures_->EvictTexturesForTesting();
1704  }
1705
1706  // Commit 1: Just commit and draw normally, then post an eviction at the end
1707  // that will trigger a commit.
1708  // Commit 2: Triggered by the eviction, let it go through and then set
1709  // needsCommit.
1710  // Commit 3: Triggered by the setNeedsCommit. In Layout(), post an eviction
1711  // task, which will be handled before the commit. Don't set needsCommit, it
1712  // should have been posted. A frame should not be drawn (note,
1713  // didCommitAndDrawFrame may be called anyway).
1714  // Commit 4: Triggered by the eviction, let it go through and then set
1715  // needsCommit.
1716  // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
1717  // Layout(), a frame should not be drawn but a commit will be posted.
1718  // Commit 6: Triggered by the eviction, post an eviction task in
1719  // Layout(), which will be a noop, letting the commit (which recreates the
1720  // textures) go through and draw a frame, then end the test.
1721  //
1722  // Commits 1+2 test the eviction recovery path where eviction happens outside
1723  // of the beginFrame/commit pair.
1724  // Commits 3+4 test the eviction recovery path where eviction happens inside
1725  // the beginFrame/commit pair.
1726  // Commits 5+6 test the path where an eviction happens during the eviction
1727  // recovery path.
1728  virtual void DidCommit() OVERRIDE {
1729    switch (num_commits_) {
1730      case 1:
1731        EXPECT_TRUE(layer_->HaveBackingTexture());
1732        PostEvictTextures();
1733        break;
1734      case 2:
1735        EXPECT_TRUE(layer_->HaveBackingTexture());
1736        layer_tree_host()->SetNeedsCommit();
1737        break;
1738      case 3:
1739        break;
1740      case 4:
1741        EXPECT_TRUE(layer_->HaveBackingTexture());
1742        layer_tree_host()->SetNeedsCommit();
1743        break;
1744      case 5:
1745        break;
1746      case 6:
1747        EXPECT_TRUE(layer_->HaveBackingTexture());
1748        EndTest();
1749        break;
1750      default:
1751        NOTREACHED();
1752        break;
1753    }
1754  }
1755
1756  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1757    impl_for_evict_textures_ = impl;
1758  }
1759
1760  virtual void Layout() OVERRIDE {
1761    ++num_commits_;
1762    switch (num_commits_) {
1763      case 1:
1764      case 2:
1765        break;
1766      case 3:
1767        PostEvictTextures();
1768        break;
1769      case 4:
1770        // We couldn't check in didCommitAndDrawFrame on commit 3,
1771        // so check here.
1772        EXPECT_FALSE(layer_->HaveBackingTexture());
1773        break;
1774      case 5:
1775        PostEvictTextures();
1776        break;
1777      case 6:
1778        // We couldn't check in didCommitAndDrawFrame on commit 5,
1779        // so check here.
1780        EXPECT_FALSE(layer_->HaveBackingTexture());
1781        PostEvictTextures();
1782        break;
1783      default:
1784        NOTREACHED();
1785        break;
1786    }
1787  }
1788
1789  virtual void AfterTest() OVERRIDE {}
1790
1791 private:
1792  FakeContentLayerClient client_;
1793  scoped_refptr<EvictionTestLayer> layer_;
1794  LayerTreeHostImpl* impl_for_evict_textures_;
1795  int num_commits_;
1796};
1797
1798MULTI_THREAD_TEST_F(LayerTreeHostTestEvictTextures);
1799
1800class LayerTreeHostTestContinuousCommit : public LayerTreeHostTest {
1801 public:
1802  LayerTreeHostTestContinuousCommit()
1803      : num_commit_complete_(0), num_draw_layers_(0) {}
1804
1805  virtual void BeginTest() OVERRIDE {
1806    layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1807    layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1808
1809    PostSetNeedsCommitToMainThread();
1810  }
1811
1812  virtual void DidCommit() OVERRIDE {
1813    if (num_draw_layers_ == 2)
1814      return;
1815    layer_tree_host()->root_layer()->SetNeedsDisplay();
1816  }
1817
1818  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1819    if (num_draw_layers_ == 1)
1820      num_commit_complete_++;
1821  }
1822
1823  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1824    num_draw_layers_++;
1825    if (num_draw_layers_ == 2)
1826      EndTest();
1827  }
1828
1829  virtual void AfterTest() OVERRIDE {
1830    // Check that we didn't commit twice between first and second draw.
1831    EXPECT_EQ(1, num_commit_complete_);
1832  }
1833
1834 private:
1835  int num_commit_complete_;
1836  int num_draw_layers_;
1837};
1838
1839MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousCommit);
1840
1841class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
1842 public:
1843  LayerTreeHostTestContinuousInvalidate()
1844      : num_commit_complete_(0), num_draw_layers_(0) {}
1845
1846  virtual void BeginTest() OVERRIDE {
1847    layer_tree_host()->SetViewportSize(gfx::Size(10, 10));
1848    layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
1849
1850    content_layer_ = ContentLayer::Create(&client_);
1851    content_layer_->SetBounds(gfx::Size(10, 10));
1852    content_layer_->SetPosition(gfx::PointF(0.f, 0.f));
1853    content_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
1854    content_layer_->SetIsDrawable(true);
1855    layer_tree_host()->root_layer()->AddChild(content_layer_);
1856
1857    PostSetNeedsCommitToMainThread();
1858  }
1859
1860  virtual void DidCommitAndDrawFrame() OVERRIDE {
1861    if (num_draw_layers_ == 2)
1862      return;
1863    content_layer_->SetNeedsDisplay();
1864  }
1865
1866  virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1867    if (num_draw_layers_ == 1)
1868      num_commit_complete_++;
1869  }
1870
1871  virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
1872    num_draw_layers_++;
1873    if (num_draw_layers_ == 2)
1874      EndTest();
1875  }
1876
1877  virtual void AfterTest() OVERRIDE {
1878    // Check that we didn't commit twice between first and second draw.
1879    EXPECT_EQ(1, num_commit_complete_);
1880  }
1881
1882 private:
1883  FakeContentLayerClient client_;
1884  scoped_refptr<Layer> content_layer_;
1885  int num_commit_complete_;
1886  int num_draw_layers_;
1887};
1888
1889MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate);
1890
1891class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
1892 public:
1893  LayerTreeHostTestDeferCommits()
1894      : num_commits_deferred_(0), num_complete_commits_(0) {}
1895
1896  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1897
1898  virtual void DidDeferCommit() OVERRIDE {
1899    num_commits_deferred_++;
1900    layer_tree_host()->SetDeferCommits(false);
1901  }
1902
1903  virtual void DidCommit() OVERRIDE {
1904    num_complete_commits_++;
1905    switch (num_complete_commits_) {
1906      case 1:
1907        EXPECT_EQ(0, num_commits_deferred_);
1908        layer_tree_host()->SetDeferCommits(true);
1909        PostSetNeedsCommitToMainThread();
1910        break;
1911      case 2:
1912        EndTest();
1913        break;
1914      default:
1915        NOTREACHED();
1916        break;
1917    }
1918  }
1919
1920  virtual void AfterTest() OVERRIDE {
1921    EXPECT_EQ(1, num_commits_deferred_);
1922    EXPECT_EQ(2, num_complete_commits_);
1923  }
1924
1925 private:
1926  int num_commits_deferred_;
1927  int num_complete_commits_;
1928};
1929
1930MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
1931
1932class LayerTreeHostWithProxy : public LayerTreeHost {
1933 public:
1934  LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
1935                         const LayerTreeSettings& settings,
1936                         scoped_ptr<FakeProxy> proxy)
1937      : LayerTreeHost(client, settings) {
1938        proxy->SetLayerTreeHost(this);
1939    EXPECT_TRUE(InitializeForTesting(proxy.PassAs<Proxy>()));
1940  }
1941};
1942
1943TEST(LayerTreeHostTest, LimitPartialUpdates) {
1944  // When partial updates are not allowed, max updates should be 0.
1945  {
1946    FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1947
1948    scoped_ptr<FakeProxy> proxy(new FakeProxy);
1949    proxy->GetRendererCapabilities().allow_partial_texture_updates = false;
1950    proxy->SetMaxPartialTextureUpdates(5);
1951
1952    LayerTreeSettings settings;
1953    settings.max_partial_texture_updates = 10;
1954
1955    LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1956    EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
1957
1958    EXPECT_EQ(0u, host.settings().max_partial_texture_updates);
1959  }
1960
1961  // When partial updates are allowed,
1962  // max updates should be limited by the proxy.
1963  {
1964    FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1965
1966    scoped_ptr<FakeProxy> proxy(new FakeProxy);
1967    proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
1968    proxy->SetMaxPartialTextureUpdates(5);
1969
1970    LayerTreeSettings settings;
1971    settings.max_partial_texture_updates = 10;
1972
1973    LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1974    EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
1975
1976    EXPECT_EQ(5u, host.settings().max_partial_texture_updates);
1977  }
1978
1979  // When partial updates are allowed,
1980  // max updates should also be limited by the settings.
1981  {
1982    FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
1983
1984    scoped_ptr<FakeProxy> proxy(new FakeProxy);
1985    proxy->GetRendererCapabilities().allow_partial_texture_updates = true;
1986    proxy->SetMaxPartialTextureUpdates(20);
1987
1988    LayerTreeSettings settings;
1989    settings.max_partial_texture_updates = 10;
1990
1991    LayerTreeHostWithProxy host(&client, settings, proxy.Pass());
1992    EXPECT_TRUE(host.InitializeOutputSurfaceIfNeeded());
1993
1994    EXPECT_EQ(10u, host.settings().max_partial_texture_updates);
1995  }
1996}
1997
1998TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
1999  FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
2000
2001  LayerTreeSettings settings;
2002  settings.max_partial_texture_updates = 4;
2003
2004  scoped_ptr<LayerTreeHost> host =
2005      LayerTreeHost::Create(&client, settings, NULL);
2006  EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2007  EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2008}
2009
2010TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
2011  FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_SOFTWARE);
2012
2013  LayerTreeSettings settings;
2014  settings.max_partial_texture_updates = 4;
2015
2016  scoped_ptr<LayerTreeHost> host =
2017      LayerTreeHost::Create(&client, settings, NULL);
2018  EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2019  EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
2020}
2021
2022TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
2023  FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_3D);
2024
2025  LayerTreeSettings settings;
2026  settings.max_partial_texture_updates = 4;
2027
2028  scoped_ptr<LayerTreeHost> host =
2029      LayerTreeHost::Create(&client, settings, NULL);
2030  EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2031  EXPECT_EQ(0u, host->settings().max_partial_texture_updates);
2032}
2033
2034TEST(LayerTreeHostTest,
2035     PartialUpdatesWithDelegatingRendererAndSoftwareContent) {
2036  FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DELEGATED_SOFTWARE);
2037
2038  LayerTreeSettings settings;
2039  settings.max_partial_texture_updates = 4;
2040
2041  scoped_ptr<LayerTreeHost> host =
2042      LayerTreeHost::Create(&client, settings, NULL);
2043  EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
2044  EXPECT_EQ(0u, host->settings().max_partial_texture_updates);
2045}
2046
2047class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
2048    : public LayerTreeHostTest {
2049 public:
2050  LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted()
2051      : root_layer_(FakeContentLayer::Create(&client_)),
2052        child_layer1_(FakeContentLayer::Create(&client_)),
2053        child_layer2_(FakeContentLayer::Create(&client_)),
2054        num_commits_(0) {}
2055
2056  virtual void BeginTest() OVERRIDE {
2057    layer_tree_host()->SetViewportSize(gfx::Size(100, 100));
2058    root_layer_->SetBounds(gfx::Size(100, 100));
2059    child_layer1_->SetBounds(gfx::Size(100, 100));
2060    child_layer2_->SetBounds(gfx::Size(100, 100));
2061    root_layer_->AddChild(child_layer1_);
2062    root_layer_->AddChild(child_layer2_);
2063    layer_tree_host()->SetRootLayer(root_layer_);
2064    PostSetNeedsCommitToMainThread();
2065  }
2066
2067  virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
2068                                       bool visible) OVERRIDE {
2069    // One backing should remain unevicted.
2070    EXPECT_EQ(100u * 100u * 4u * 1u,
2071              layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2072    // Make sure that contents textures are marked as having been
2073    // purged.
2074    EXPECT_TRUE(host_impl->active_tree()->ContentsTexturesPurged());
2075    // End the test in this state.
2076    EndTest();
2077  }
2078
2079  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2080    ++num_commits_;
2081    switch (num_commits_) {
2082      case 1:
2083        // All three backings should have memory.
2084        EXPECT_EQ(
2085            100u * 100u * 4u * 3u,
2086            layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2087        // Set a new policy that will kick out 1 of the 3 resources.
2088        // Because a resource was evicted, a commit will be kicked off.
2089        host_impl->SetMemoryPolicy(
2090            ManagedMemoryPolicy(100 * 100 * 4 * 2,
2091                                ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
2092                                100 * 100 * 4 * 1,
2093                                ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING),
2094            true);
2095        break;
2096      case 2:
2097        // Only two backings should have memory.
2098        EXPECT_EQ(
2099            100u * 100u * 4u * 2u,
2100            layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
2101        // Become backgrounded, which will cause 1 more resource to be
2102        // evicted.
2103        PostSetVisibleToMainThread(false);
2104        break;
2105      default:
2106        // No further commits should happen because this is not visible
2107        // anymore.
2108        NOTREACHED();
2109        break;
2110    }
2111  }
2112
2113  virtual void AfterTest() OVERRIDE {}
2114
2115 private:
2116  FakeContentLayerClient client_;
2117  scoped_refptr<FakeContentLayer> root_layer_;
2118  scoped_refptr<FakeContentLayer> child_layer1_;
2119  scoped_refptr<FakeContentLayer> child_layer2_;
2120  int num_commits_;
2121};
2122
2123SINGLE_AND_MULTI_THREAD_TEST_F(
2124    LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted);
2125
2126class LayerTreeHostTestLCDNotification : public LayerTreeHostTest {
2127 public:
2128  class NotificationClient : public ContentLayerClient {
2129   public:
2130    NotificationClient()
2131        : layer_(0), paint_count_(0), lcd_notification_count_(0) {}
2132
2133    void set_layer(Layer* layer) { layer_ = layer; }
2134    int paint_count() const { return paint_count_; }
2135    int lcd_notification_count() const { return lcd_notification_count_; }
2136
2137    virtual void PaintContents(SkCanvas* canvas,
2138                               gfx::Rect clip,
2139                               gfx::RectF* opaque) OVERRIDE {
2140      ++paint_count_;
2141    }
2142    virtual void DidChangeLayerCanUseLCDText() OVERRIDE {
2143      ++lcd_notification_count_;
2144      layer_->SetNeedsDisplay();
2145    }
2146
2147   private:
2148    Layer* layer_;
2149    int paint_count_;
2150    int lcd_notification_count_;
2151  };
2152
2153  virtual void SetupTree() OVERRIDE {
2154    scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2155    root_layer->SetIsDrawable(true);
2156    root_layer->SetBounds(gfx::Size(1, 1));
2157
2158    layer_tree_host()->SetRootLayer(root_layer);
2159    client_.set_layer(root_layer.get());
2160
2161    // The expecations are based on the assumption that the default
2162    // LCD settings are:
2163    EXPECT_TRUE(layer_tree_host()->settings().can_use_lcd_text);
2164    EXPECT_FALSE(root_layer->can_use_lcd_text());
2165
2166    LayerTreeHostTest::SetupTree();
2167  }
2168
2169  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2170  virtual void AfterTest() OVERRIDE {}
2171
2172  virtual void DidCommit() OVERRIDE {
2173    switch (layer_tree_host()->commit_number()) {
2174      case 1:
2175        // The first update consists one LCD notification and one paint.
2176        EXPECT_EQ(1, client_.lcd_notification_count());
2177        EXPECT_EQ(1, client_.paint_count());
2178        // LCD text must have been enabled on the layer.
2179        EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2180        PostSetNeedsCommitToMainThread();
2181        break;
2182      case 2:
2183        // Since nothing changed on layer, there should be no notification
2184        // or paint on the second update.
2185        EXPECT_EQ(1, client_.lcd_notification_count());
2186        EXPECT_EQ(1, client_.paint_count());
2187        // LCD text must not have changed.
2188        EXPECT_TRUE(layer_tree_host()->root_layer()->can_use_lcd_text());
2189        // Change layer opacity that should trigger lcd notification.
2190        layer_tree_host()->root_layer()->SetOpacity(.5f);
2191        // No need to request a commit - setting opacity will do it.
2192        break;
2193      default:
2194        // Verify that there is not extra commit due to layer invalidation.
2195        EXPECT_EQ(3, layer_tree_host()->commit_number());
2196        // LCD notification count should have incremented due to
2197        // change in layer opacity.
2198        EXPECT_EQ(2, client_.lcd_notification_count());
2199        // Paint count should be incremented due to invalidation.
2200        EXPECT_EQ(2, client_.paint_count());
2201        // LCD text must have been disabled on the layer due to opacity.
2202        EXPECT_FALSE(layer_tree_host()->root_layer()->can_use_lcd_text());
2203        EndTest();
2204        break;
2205    }
2206  }
2207
2208 private:
2209  NotificationClient client_;
2210};
2211
2212SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification);
2213
2214// Verify that the BeginFrame notification is used to initiate rendering.
2215class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
2216 public:
2217  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2218    settings->begin_frame_scheduling_enabled = true;
2219  }
2220
2221  virtual void BeginTest() OVERRIDE {
2222    // This will trigger a SetNeedsBeginFrame which will trigger a BeginFrame.
2223    PostSetNeedsCommitToMainThread();
2224  }
2225
2226  virtual bool PrepareToDrawOnThread(
2227      LayerTreeHostImpl* host_impl,
2228      LayerTreeHostImpl::FrameData* frame,
2229      bool result) OVERRIDE {
2230    EndTest();
2231    return true;
2232  }
2233
2234  virtual void AfterTest() OVERRIDE {}
2235
2236 private:
2237  base::TimeTicks frame_time_;
2238};
2239
2240MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
2241
2242class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
2243    : public LayerTreeHostTest {
2244 public:
2245  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2246    settings->begin_frame_scheduling_enabled = true;
2247    settings->using_synchronous_renderer_compositor = true;
2248  }
2249
2250  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2251
2252  virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2253    // The BeginFrame notification is turned off now but will get enabled
2254    // once we return. End test while it's enabled.
2255    ImplThreadTaskRunner()->PostTask(
2256        FROM_HERE,
2257        base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
2258                   base::Unretained(this)));
2259  }
2260
2261  virtual void AfterTest() OVERRIDE {}
2262};
2263
2264MULTI_THREAD_TEST_F(
2265    LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
2266
2267class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation
2268    : public LayerTreeHostTest {
2269 protected:
2270  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2271    settings->impl_side_painting = true;
2272  }
2273
2274  virtual void SetupTree() OVERRIDE {
2275    LayerTreeHostTest::SetupTree();
2276
2277    scoped_refptr<Layer> layer = PictureLayer::Create(&client_);
2278    layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
2279    layer->SetBounds(gfx::Size(10, 10));
2280    layer_tree_host()->root_layer()->AddChild(layer);
2281  }
2282
2283  virtual void BeginTest() OVERRIDE {
2284    PostSetNeedsCommitToMainThread();
2285  }
2286
2287  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2288    EndTest();
2289  }
2290
2291  virtual void AfterTest() OVERRIDE {
2292  }
2293
2294  FakeContentLayerClient client_;
2295};
2296
2297MULTI_THREAD_TEST_F(
2298    LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation);
2299
2300class LayerTreeHostTestChangeLayerPropertiesInPaintContents
2301    : public LayerTreeHostTest {
2302 public:
2303  class SetBoundsClient : public ContentLayerClient {
2304   public:
2305    SetBoundsClient() : layer_(0) {}
2306
2307    void set_layer(Layer* layer) { layer_ = layer; }
2308
2309    virtual void PaintContents(SkCanvas* canvas,
2310                               gfx::Rect clip,
2311                               gfx::RectF* opaque) OVERRIDE {
2312      layer_->SetBounds(gfx::Size(2, 2));
2313    }
2314
2315    virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
2316
2317   private:
2318    Layer* layer_;
2319  };
2320
2321  LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {}
2322
2323  virtual void SetupTree() OVERRIDE {
2324    scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_);
2325    root_layer->SetIsDrawable(true);
2326    root_layer->SetBounds(gfx::Size(1, 1));
2327
2328    layer_tree_host()->SetRootLayer(root_layer);
2329    client_.set_layer(root_layer.get());
2330
2331    LayerTreeHostTest::SetupTree();
2332  }
2333
2334  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
2335  virtual void AfterTest() OVERRIDE {}
2336
2337  virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2338    num_commits_++;
2339    if (num_commits_ == 1) {
2340      LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2341      EXPECT_SIZE_EQ(gfx::Size(1, 1), root_layer->bounds());
2342    } else {
2343      LayerImpl* root_layer = host_impl->active_tree()->root_layer();
2344      EXPECT_SIZE_EQ(gfx::Size(2, 2), root_layer->bounds());
2345      EndTest();
2346    }
2347  }
2348
2349 private:
2350  SetBoundsClient client_;
2351  int num_commits_;
2352};
2353
2354SINGLE_THREAD_TEST_F(LayerTreeHostTestChangeLayerPropertiesInPaintContents);
2355
2356class MockIOSurfaceWebGraphicsContext3D : public FakeWebGraphicsContext3D {
2357 public:
2358  MockIOSurfaceWebGraphicsContext3D()
2359      : FakeWebGraphicsContext3D() {}
2360
2361  virtual WebKit::WebGLId createTexture() OVERRIDE {
2362    return 1;
2363  }
2364
2365  virtual WebKit::WebString getString(WebKit::WGC3Denum name) OVERRIDE {
2366    if (name == GL_EXTENSIONS) {
2367      return WebKit::WebString(
2368          "GL_CHROMIUM_iosurface GL_ARB_texture_rectangle");
2369    }
2370    return WebKit::WebString();
2371  }
2372
2373  MOCK_METHOD1(activeTexture, void(WebKit::WGC3Denum texture));
2374  MOCK_METHOD2(bindTexture, void(WebKit::WGC3Denum target,
2375                                WebKit::WebGLId texture_id));
2376  MOCK_METHOD3(texParameteri, void(WebKit::WGC3Denum target,
2377                                   WebKit::WGC3Denum pname,
2378                                   WebKit::WGC3Dint param));
2379  MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(WebKit::WGC3Denum target,
2380                                                 WebKit::WGC3Dint width,
2381                                                 WebKit::WGC3Dint height,
2382                                                 WebKit::WGC3Duint ioSurfaceId,
2383                                                 WebKit::WGC3Duint plane));
2384  MOCK_METHOD4(drawElements, void(WebKit::WGC3Denum mode,
2385                                  WebKit::WGC3Dsizei count,
2386                                  WebKit::WGC3Denum type,
2387                                  WebKit::WGC3Dintptr offset));
2388};
2389
2390
2391class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
2392 protected:
2393  virtual scoped_ptr<OutputSurface> CreateOutputSurface() OVERRIDE {
2394    scoped_ptr<MockIOSurfaceWebGraphicsContext3D> context(
2395        new MockIOSurfaceWebGraphicsContext3D);
2396    mock_context_ = context.get();
2397    scoped_ptr<OutputSurface> output_surface = FakeOutputSurface::Create3d(
2398        context.PassAs<WebKit::WebGraphicsContext3D>()).PassAs<OutputSurface>();
2399    return output_surface.Pass();
2400  }
2401
2402  virtual void SetupTree() OVERRIDE {
2403    LayerTreeHostTest::SetupTree();
2404
2405    layer_tree_host()->root_layer()->SetIsDrawable(false);
2406
2407    io_surface_id_ = 9;
2408    io_surface_size_ = gfx::Size(6, 7);
2409
2410    scoped_refptr<IOSurfaceLayer> io_surface_layer = IOSurfaceLayer::Create();
2411    io_surface_layer->SetBounds(gfx::Size(10, 10));
2412    io_surface_layer->SetAnchorPoint(gfx::PointF());
2413    io_surface_layer->SetIsDrawable(true);
2414    io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
2415    layer_tree_host()->root_layer()->AddChild(io_surface_layer);
2416  }
2417
2418  virtual void BeginTest() OVERRIDE {
2419    PostSetNeedsCommitToMainThread();
2420  }
2421
2422  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2423    // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
2424
2425    EXPECT_CALL(*mock_context_, activeTexture(_))
2426        .Times(0);
2427    EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2428        .Times(AtLeast(1));
2429    EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2430                                              GL_TEXTURE_MIN_FILTER,
2431                                              GL_LINEAR))
2432        .Times(1);
2433    EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2434                                              GL_TEXTURE_MAG_FILTER,
2435                                              GL_LINEAR))
2436        .Times(1);
2437    EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2438                                              GL_TEXTURE_WRAP_S,
2439                                              GL_CLAMP_TO_EDGE))
2440        .Times(1);
2441    EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
2442                                              GL_TEXTURE_WRAP_T,
2443                                              GL_CLAMP_TO_EDGE))
2444        .Times(1);
2445
2446    EXPECT_CALL(*mock_context_, texImageIOSurface2DCHROMIUM(
2447        GL_TEXTURE_RECTANGLE_ARB,
2448        io_surface_size_.width(),
2449        io_surface_size_.height(),
2450        io_surface_id_,
2451        0))
2452        .Times(1);
2453
2454    EXPECT_CALL(*mock_context_, bindTexture(_, 0))
2455        .Times(AnyNumber());
2456  }
2457
2458  virtual bool PrepareToDrawOnThread(
2459      LayerTreeHostImpl* host_impl,
2460      LayerTreeHostImpl::FrameData* frame,
2461      bool result) OVERRIDE {
2462    Mock::VerifyAndClearExpectations(&mock_context_);
2463
2464    // The io surface layer's texture is drawn.
2465    EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0))
2466        .Times(AtLeast(1));
2467    EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
2468        .Times(1);
2469    EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
2470        .Times(AtLeast(1));
2471
2472    return result;
2473  }
2474
2475  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2476    Mock::VerifyAndClearExpectations(&mock_context_);
2477    EndTest();
2478  }
2479
2480  virtual void AfterTest() OVERRIDE {}
2481
2482  int io_surface_id_;
2483  MockIOSurfaceWebGraphicsContext3D* mock_context_;
2484  gfx::Size io_surface_size_;
2485};
2486
2487// TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
2488SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2489    LayerTreeHostTestIOSurfaceDrawing);
2490
2491class LayerTreeHostTestAsyncReadback : public LayerTreeHostTest {
2492 protected:
2493  virtual void SetupTree() OVERRIDE {
2494    root = FakeContentLayer::Create(&client_);
2495    root->SetBounds(gfx::Size(20, 20));
2496
2497    child = FakeContentLayer::Create(&client_);
2498    child->SetBounds(gfx::Size(10, 10));
2499    root->AddChild(child);
2500
2501    layer_tree_host()->SetRootLayer(root);
2502    LayerTreeHostTest::SetupTree();
2503  }
2504
2505  virtual void BeginTest() OVERRIDE {
2506    PostSetNeedsCommitToMainThread();
2507  }
2508
2509  virtual void DidCommitAndDrawFrame() OVERRIDE {
2510    WaitForCallback();
2511  }
2512
2513  void WaitForCallback() {
2514    base::MessageLoop::current()->PostTask(
2515        FROM_HERE,
2516        base::Bind(
2517            &LayerTreeHostTestAsyncReadback::NextStep,
2518            base::Unretained(this)));
2519  }
2520
2521  void NextStep() {
2522    int frame = layer_tree_host()->commit_number();
2523    switch (frame) {
2524      case 1:
2525        child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2526            base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2527                       base::Unretained(this))));
2528        EXPECT_EQ(0u, callbacks_.size());
2529        break;
2530      case 2:
2531        if (callbacks_.size() < 1u) {
2532          WaitForCallback();
2533          return;
2534        }
2535        EXPECT_EQ(1u, callbacks_.size());
2536        EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[0].ToString());
2537
2538        child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2539            base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2540                       base::Unretained(this))));
2541        root->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2542            base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2543                       base::Unretained(this))));
2544        child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
2545            base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
2546                       base::Unretained(this))));
2547        EXPECT_EQ(1u, callbacks_.size());
2548        break;
2549      case 3:
2550        if (callbacks_.size() < 4u) {
2551          WaitForCallback();
2552          return;
2553        }
2554        EXPECT_EQ(4u, callbacks_.size());
2555        // The child was copied to a bitmap and passed back twice.
2556        EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[1].ToString());
2557        EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[2].ToString());
2558        // The root was copied to a bitmap and passed back also.
2559        EXPECT_EQ(gfx::Size(20, 20).ToString(), callbacks_[3].ToString());
2560        EndTest();
2561        break;
2562    }
2563  }
2564
2565  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
2566    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2567    EXPECT_TRUE(result->HasBitmap());
2568    scoped_ptr<SkBitmap> bitmap = result->TakeBitmap().Pass();
2569    EXPECT_EQ(result->size().ToString(),
2570              gfx::Size(bitmap->width(), bitmap->height()).ToString());
2571    callbacks_.push_back(result->size());
2572  }
2573
2574  virtual void AfterTest() OVERRIDE {
2575    EXPECT_EQ(4u, callbacks_.size());
2576  }
2577
2578  virtual scoped_ptr<OutputSurface> CreateOutputSurface() OVERRIDE {
2579    if (use_gl_renderer_)
2580      return FakeOutputSurface::Create3d().PassAs<OutputSurface>();
2581    return FakeOutputSurface::CreateSoftware(
2582        make_scoped_ptr(new SoftwareOutputDevice)).PassAs<OutputSurface>();
2583  }
2584
2585  bool use_gl_renderer_;
2586  std::vector<gfx::Size> callbacks_;
2587  FakeContentLayerClient client_;
2588  scoped_refptr<FakeContentLayer> root;
2589  scoped_refptr<FakeContentLayer> child;
2590};
2591
2592// Readback can't be done with a delegating renderer.
2593TEST_F(LayerTreeHostTestAsyncReadback, GLRenderer_RunSingleThread) {
2594  use_gl_renderer_ = true;
2595  RunTest(false, false, false);
2596}
2597
2598TEST_F(LayerTreeHostTestAsyncReadback,
2599       GLRenderer_RunMultiThread_MainThreadPainting) {
2600  use_gl_renderer_ = true;
2601  RunTest(true, false, false);
2602}
2603
2604TEST_F(LayerTreeHostTestAsyncReadback,
2605       GLRenderer_RunMultiThread_ImplSidePainting) {
2606  use_gl_renderer_ = true;
2607  RunTest(true, false, true);
2608}
2609
2610TEST_F(LayerTreeHostTestAsyncReadback, SoftwareRenderer_RunSingleThread) {
2611  use_gl_renderer_ = false;
2612  RunTest(false, false, false);
2613}
2614
2615TEST_F(LayerTreeHostTestAsyncReadback,
2616       SoftwareRenderer_RunMultiThread_MainThreadPainting) {
2617  use_gl_renderer_ = false;
2618  RunTest(true, false, false);
2619}
2620
2621TEST_F(LayerTreeHostTestAsyncReadback,
2622       SoftwareRenderer_RunMultiThread_ImplSidePainting) {
2623  use_gl_renderer_ = false;
2624  RunTest(true, false, true);
2625}
2626
2627class LayerTreeHostTestAsyncReadbackLayerDestroyed : public LayerTreeHostTest {
2628 protected:
2629  virtual void SetupTree() OVERRIDE {
2630    root_ = FakeContentLayer::Create(&client_);
2631    root_->SetBounds(gfx::Size(20, 20));
2632
2633    main_destroyed_ = FakeContentLayer::Create(&client_);
2634    main_destroyed_->SetBounds(gfx::Size(15, 15));
2635    root_->AddChild(main_destroyed_);
2636
2637    impl_destroyed_ = FakeContentLayer::Create(&client_);
2638    impl_destroyed_->SetBounds(gfx::Size(10, 10));
2639    root_->AddChild(impl_destroyed_);
2640
2641    layer_tree_host()->SetRootLayer(root_);
2642    LayerTreeHostTest::SetupTree();
2643  }
2644
2645  virtual void BeginTest() OVERRIDE {
2646    callback_count_ = 0;
2647    PostSetNeedsCommitToMainThread();
2648  }
2649
2650  virtual void DidCommit() OVERRIDE {
2651    int frame = layer_tree_host()->commit_number();
2652    switch (frame) {
2653      case 1:
2654        main_destroyed_->RequestCopyOfOutput(
2655            CopyOutputRequest::CreateBitmapRequest(base::Bind(
2656                &LayerTreeHostTestAsyncReadbackLayerDestroyed::
2657                    CopyOutputCallback,
2658                base::Unretained(this))));
2659        impl_destroyed_->RequestCopyOfOutput(
2660            CopyOutputRequest::CreateBitmapRequest(base::Bind(
2661                &LayerTreeHostTestAsyncReadbackLayerDestroyed::
2662                    CopyOutputCallback,
2663                base::Unretained(this))));
2664        EXPECT_EQ(0, callback_count_);
2665
2666        // Destroy the main thread layer right away.
2667        main_destroyed_->RemoveFromParent();
2668        main_destroyed_ = NULL;
2669
2670        // Should callback with a NULL bitmap.
2671        EXPECT_EQ(1, callback_count_);
2672
2673        // Prevent drawing so we can't make a copy of the impl_destroyed layer.
2674        layer_tree_host()->SetViewportSize(gfx::Size());
2675        break;
2676      case 2:
2677        // Flush the message loops and make sure the callbacks run.
2678        layer_tree_host()->SetNeedsCommit();
2679        break;
2680      case 3:
2681        // No drawing means no readback yet.
2682        EXPECT_EQ(1, callback_count_);
2683
2684        // Destroy the impl thread layer.
2685        impl_destroyed_->RemoveFromParent();
2686        impl_destroyed_ = NULL;
2687
2688        // No callback yet because it's on the impl side.
2689        EXPECT_EQ(1, callback_count_);
2690        break;
2691      case 4:
2692        // Flush the message loops and make sure the callbacks run.
2693        layer_tree_host()->SetNeedsCommit();
2694        break;
2695      case 5:
2696        // We should get another callback with a NULL bitmap.
2697        EXPECT_EQ(2, callback_count_);
2698        EndTest();
2699        break;
2700    }
2701  }
2702
2703  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
2704    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2705    EXPECT_TRUE(result->IsEmpty());
2706    ++callback_count_;
2707  }
2708
2709  virtual void AfterTest() OVERRIDE {}
2710
2711  int callback_count_;
2712  FakeContentLayerClient client_;
2713  scoped_refptr<FakeContentLayer> root_;
2714  scoped_refptr<FakeContentLayer> main_destroyed_;
2715  scoped_refptr<FakeContentLayer> impl_destroyed_;
2716};
2717
2718SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAsyncReadbackLayerDestroyed);
2719
2720class LayerTreeHostTestAsyncReadbackInHiddenSubtree : public LayerTreeHostTest {
2721 protected:
2722  virtual void SetupTree() OVERRIDE {
2723    root_ = FakeContentLayer::Create(&client_);
2724    root_->SetBounds(gfx::Size(20, 20));
2725
2726    grand_parent_layer_ = FakeContentLayer::Create(&client_);
2727    grand_parent_layer_->SetBounds(gfx::Size(15, 15));
2728    root_->AddChild(grand_parent_layer_);
2729
2730    // parent_layer_ owns a render surface.
2731    parent_layer_ = FakeContentLayer::Create(&client_);
2732    parent_layer_->SetBounds(gfx::Size(15, 15));
2733    parent_layer_->SetForceRenderSurface(true);
2734    grand_parent_layer_->AddChild(parent_layer_);
2735
2736    copy_layer_ = FakeContentLayer::Create(&client_);
2737    copy_layer_->SetBounds(gfx::Size(10, 10));
2738    parent_layer_->AddChild(copy_layer_);
2739
2740    layer_tree_host()->SetRootLayer(root_);
2741    LayerTreeHostTest::SetupTree();
2742  }
2743
2744  void AddCopyRequest(Layer* layer) {
2745    layer->RequestCopyOfOutput(
2746        CopyOutputRequest::CreateBitmapRequest(base::Bind(
2747            &LayerTreeHostTestAsyncReadbackInHiddenSubtree::CopyOutputCallback,
2748            base::Unretained(this))));
2749  }
2750
2751  virtual void BeginTest() OVERRIDE {
2752    callback_count_ = 0;
2753    PostSetNeedsCommitToMainThread();
2754
2755    AddCopyRequest(copy_layer_.get());
2756  }
2757
2758  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
2759    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2760    EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
2761    ++callback_count_;
2762
2763    switch (callback_count_) {
2764      case 1:
2765        // Hide the copy request layer.
2766        grand_parent_layer_->SetHideLayerAndSubtree(false);
2767        parent_layer_->SetHideLayerAndSubtree(false);
2768        copy_layer_->SetHideLayerAndSubtree(true);
2769        AddCopyRequest(copy_layer_.get());
2770        break;
2771      case 2:
2772        // Hide the copy request layer's parent only.
2773        grand_parent_layer_->SetHideLayerAndSubtree(false);
2774        parent_layer_->SetHideLayerAndSubtree(true);
2775        copy_layer_->SetHideLayerAndSubtree(false);
2776        AddCopyRequest(copy_layer_.get());
2777        break;
2778      case 3:
2779        // Hide the copy request layer's grand parent only.
2780        grand_parent_layer_->SetHideLayerAndSubtree(true);
2781        parent_layer_->SetHideLayerAndSubtree(false);
2782        copy_layer_->SetHideLayerAndSubtree(false);
2783        AddCopyRequest(copy_layer_.get());
2784        break;
2785      case 4:
2786        // Hide the copy request layer's parent and grandparent.
2787        grand_parent_layer_->SetHideLayerAndSubtree(true);
2788        parent_layer_->SetHideLayerAndSubtree(true);
2789        copy_layer_->SetHideLayerAndSubtree(false);
2790        AddCopyRequest(copy_layer_.get());
2791        break;
2792      case 5:
2793        // Hide the copy request layer as well as its parent and grandparent.
2794        grand_parent_layer_->SetHideLayerAndSubtree(true);
2795        parent_layer_->SetHideLayerAndSubtree(true);
2796        copy_layer_->SetHideLayerAndSubtree(true);
2797        AddCopyRequest(copy_layer_.get());
2798        break;
2799      case 6:
2800        EndTest();
2801        break;
2802    }
2803  }
2804
2805  virtual void AfterTest() OVERRIDE {}
2806
2807  int callback_count_;
2808  FakeContentLayerClient client_;
2809  scoped_refptr<FakeContentLayer> root_;
2810  scoped_refptr<FakeContentLayer> grand_parent_layer_;
2811  scoped_refptr<FakeContentLayer> parent_layer_;
2812  scoped_refptr<FakeContentLayer> copy_layer_;
2813};
2814
2815// No output to copy for delegated renderers.
2816SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2817    LayerTreeHostTestAsyncReadbackInHiddenSubtree);
2818
2819class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
2820    : public LayerTreeHostTest {
2821 protected:
2822  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
2823    settings->cache_render_pass_contents = true;
2824  }
2825
2826  virtual void SetupTree() OVERRIDE {
2827    root_ = FakeContentLayer::Create(&client_);
2828    root_->SetBounds(gfx::Size(20, 20));
2829
2830    grand_parent_layer_ = FakeContentLayer::Create(&client_);
2831    grand_parent_layer_->SetBounds(gfx::Size(15, 15));
2832    grand_parent_layer_->SetHideLayerAndSubtree(true);
2833    root_->AddChild(grand_parent_layer_);
2834
2835    // parent_layer_ owns a render surface.
2836    parent_layer_ = FakeContentLayer::Create(&client_);
2837    parent_layer_->SetBounds(gfx::Size(15, 15));
2838    parent_layer_->SetForceRenderSurface(true);
2839    grand_parent_layer_->AddChild(parent_layer_);
2840
2841    copy_layer_ = FakeContentLayer::Create(&client_);
2842    copy_layer_->SetBounds(gfx::Size(10, 10));
2843    parent_layer_->AddChild(copy_layer_);
2844
2845    layer_tree_host()->SetRootLayer(root_);
2846    LayerTreeHostTest::SetupTree();
2847  }
2848
2849  virtual void BeginTest() OVERRIDE {
2850    did_draw_ = false;
2851    PostSetNeedsCommitToMainThread();
2852
2853    copy_layer_->RequestCopyOfOutput(
2854        CopyOutputRequest::CreateBitmapRequest(base::Bind(
2855            &LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest::
2856                CopyOutputCallback,
2857            base::Unretained(this))));
2858  }
2859
2860  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
2861    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2862    EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
2863    EndTest();
2864  }
2865
2866  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
2867    Renderer* renderer = host_impl->renderer();
2868
2869    LayerImpl* root = host_impl->active_tree()->root_layer();
2870    LayerImpl* grand_parent = root->children()[0];
2871    LayerImpl* parent = grand_parent->children()[0];
2872    LayerImpl* copy_layer = parent->children()[0];
2873
2874    // |parent| owns a surface, but it was hidden and not part of the copy
2875    // request so it should not allocate any resource.
2876    EXPECT_FALSE(renderer->HaveCachedResourcesForRenderPassId(
2877        parent->render_surface()->RenderPassId()));
2878
2879    // |copy_layer| should have been rendered to a texture since it was needed
2880    // for a copy request.
2881    EXPECT_TRUE(renderer->HaveCachedResourcesForRenderPassId(
2882        copy_layer->render_surface()->RenderPassId()));
2883
2884    did_draw_ = true;
2885  }
2886
2887  virtual void AfterTest() OVERRIDE { EXPECT_TRUE(did_draw_); }
2888
2889  FakeContentLayerClient client_;
2890  bool did_draw_;
2891  scoped_refptr<FakeContentLayer> root_;
2892  scoped_refptr<FakeContentLayer> grand_parent_layer_;
2893  scoped_refptr<FakeContentLayer> parent_layer_;
2894  scoped_refptr<FakeContentLayer> copy_layer_;
2895};
2896
2897// No output to copy for delegated renderers.
2898SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2899      LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest);
2900
2901class LayerTreeHostTestAsyncReadbackClippedOut : public LayerTreeHostTest {
2902 protected:
2903  virtual void SetupTree() OVERRIDE {
2904    root_ = FakeContentLayer::Create(&client_);
2905    root_->SetBounds(gfx::Size(20, 20));
2906
2907    parent_layer_ = FakeContentLayer::Create(&client_);
2908    parent_layer_->SetBounds(gfx::Size(15, 15));
2909    parent_layer_->SetMasksToBounds(true);
2910    root_->AddChild(parent_layer_);
2911
2912    copy_layer_ = FakeContentLayer::Create(&client_);
2913    copy_layer_->SetPosition(gfx::Point(15, 15));
2914    copy_layer_->SetBounds(gfx::Size(10, 10));
2915    parent_layer_->AddChild(copy_layer_);
2916
2917    layer_tree_host()->SetRootLayer(root_);
2918    LayerTreeHostTest::SetupTree();
2919  }
2920
2921  virtual void BeginTest() OVERRIDE {
2922    PostSetNeedsCommitToMainThread();
2923
2924    copy_layer_->RequestCopyOfOutput(
2925        CopyOutputRequest::CreateBitmapRequest(base::Bind(
2926            &LayerTreeHostTestAsyncReadbackClippedOut::CopyOutputCallback,
2927            base::Unretained(this))));
2928  }
2929
2930  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
2931    // We should still get a callback with no output if the copy requested layer
2932    // was completely clipped away.
2933    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
2934    EXPECT_EQ(gfx::Size().ToString(), result->size().ToString());
2935    EndTest();
2936  }
2937
2938  virtual void AfterTest() OVERRIDE {}
2939
2940  FakeContentLayerClient client_;
2941  scoped_refptr<FakeContentLayer> root_;
2942  scoped_refptr<FakeContentLayer> parent_layer_;
2943  scoped_refptr<FakeContentLayer> copy_layer_;
2944};
2945
2946// No output to copy for delegated renderers.
2947SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
2948    LayerTreeHostTestAsyncReadbackClippedOut);
2949
2950class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw : public LayerTreeHostTest {
2951 protected:
2952  virtual void SetupTree() OVERRIDE {
2953    root_ = FakeContentLayer::Create(&client_);
2954    root_->SetBounds(gfx::Size(20, 20));
2955
2956    copy_layer_ = FakeContentLayer::Create(&client_);
2957    copy_layer_->SetBounds(gfx::Size(10, 10));
2958    root_->AddChild(copy_layer_);
2959
2960    layer_tree_host()->SetRootLayer(root_);
2961    LayerTreeHostTest::SetupTree();
2962  }
2963
2964  void AddCopyRequest(Layer* layer) {
2965    layer->RequestCopyOfOutput(
2966        CopyOutputRequest::CreateBitmapRequest(base::Bind(
2967            &LayerTreeHostTestAsyncTwoReadbacksWithoutDraw::CopyOutputCallback,
2968            base::Unretained(this))));
2969  }
2970
2971  virtual void BeginTest() OVERRIDE {
2972    saw_copy_request_ = false;
2973    callback_count_ = 0;
2974    PostSetNeedsCommitToMainThread();
2975
2976    // Prevent drawing.
2977    layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
2978
2979    AddCopyRequest(copy_layer_.get());
2980  }
2981
2982  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
2983    if (impl->active_tree()->source_frame_number() == 0) {
2984      LayerImpl* root = impl->active_tree()->root_layer();
2985      EXPECT_TRUE(root->children()[0]->HasCopyRequest());
2986      saw_copy_request_ = true;
2987    }
2988  }
2989
2990  virtual void DidCommit() OVERRIDE {
2991    if (layer_tree_host()->commit_number() == 1) {
2992      // Allow drawing.
2993      layer_tree_host()->SetViewportSize(gfx::Size(root_->bounds()));
2994
2995      AddCopyRequest(copy_layer_.get());
2996    }
2997  }
2998
2999  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
3000    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
3001    EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
3002    ++callback_count_;
3003
3004    if (callback_count_ == 2)
3005      EndTest();
3006  }
3007
3008  virtual void AfterTest() OVERRIDE { EXPECT_TRUE(saw_copy_request_); }
3009
3010  bool saw_copy_request_;
3011  int callback_count_;
3012  FakeContentLayerClient client_;
3013  scoped_refptr<FakeContentLayer> root_;
3014  scoped_refptr<FakeContentLayer> copy_layer_;
3015};
3016
3017// No output to copy for delegated renderers.
3018SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
3019    LayerTreeHostTestAsyncTwoReadbacksWithoutDraw);
3020
3021class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
3022 public:
3023  virtual void BeginTest() OVERRIDE {
3024    frame_ = 0;
3025    PostSetNeedsCommitToMainThread();
3026  }
3027
3028  // Round 1: commit + draw
3029  // Round 2: commit only (no draw/swap)
3030  // Round 3: draw only (no commit)
3031  // Round 4: composite & readback (2 commits, no draw/swap)
3032  // Round 5: commit + draw
3033
3034  virtual void DidCommit() OVERRIDE {
3035    int commit = layer_tree_host()->commit_number();
3036    switch (commit) {
3037      case 2:
3038        // Round 2 done.
3039        EXPECT_EQ(1, frame_);
3040        layer_tree_host()->SetNeedsRedraw();
3041        break;
3042      case 3:
3043        // CompositeAndReadback in Round 4, first commit.
3044        EXPECT_EQ(2, frame_);
3045        break;
3046      case 4:
3047        // Round 4 done.
3048        EXPECT_EQ(2, frame_);
3049        layer_tree_host()->SetNeedsCommit();
3050        layer_tree_host()->SetNeedsRedraw();
3051        break;
3052    }
3053  }
3054
3055  virtual void DidCompleteSwapBuffers() OVERRIDE {
3056    int commit = layer_tree_host()->commit_number();
3057    ++frame_;
3058    char pixels[4] = {0};
3059    switch (frame_) {
3060      case 1:
3061        // Round 1 done.
3062        EXPECT_EQ(1, commit);
3063        layer_tree_host()->SetNeedsCommit();
3064        break;
3065      case 2:
3066        // Round 3 done.
3067        EXPECT_EQ(2, commit);
3068        layer_tree_host()->CompositeAndReadback(pixels, gfx::Rect(0, 0, 1, 1));
3069        break;
3070      case 3:
3071        // Round 5 done.
3072        EXPECT_EQ(5, commit);
3073        EndTest();
3074        break;
3075    }
3076  }
3077
3078  virtual void AfterTest() OVERRIDE {}
3079
3080 protected:
3081  int frame_;
3082};
3083
3084TEST_F(LayerTreeHostTestNumFramesPending, DelegatingRenderer) {
3085  RunTest(true, true, true);
3086}
3087
3088TEST_F(LayerTreeHostTestNumFramesPending, GLRenderer) {
3089  RunTest(true, false, true);
3090}
3091
3092class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest {
3093 public:
3094  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
3095    // PictureLayer can only be used with impl side painting enabled.
3096    settings->impl_side_painting = true;
3097    settings->solid_color_scrollbars = true;
3098  }
3099
3100  virtual void SetupTree() OVERRIDE {
3101    layer_ = FakePictureLayer::Create(&client_);
3102    layer_tree_host()->SetRootLayer(layer_);
3103    LayerTreeHostTest::SetupTree();
3104  }
3105
3106  virtual void BeginTest() OVERRIDE {
3107    did_initialize_gl_ = false;
3108    did_release_gl_ = false;
3109    last_source_frame_number_drawn_ = -1;  // Never drawn.
3110    PostSetNeedsCommitToMainThread();
3111  }
3112
3113  virtual scoped_ptr<OutputSurface> CreateOutputSurface() OVERRIDE {
3114    scoped_ptr<TestWebGraphicsContext3D> context3d(
3115        TestWebGraphicsContext3D::Create());
3116    context3d->set_support_swapbuffers_complete_callback(false);
3117
3118    return FakeOutputSurface::CreateDeferredGL(
3119        scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice))
3120        .PassAs<OutputSurface>();
3121  }
3122
3123  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
3124    ASSERT_TRUE(host_impl->RootLayer());
3125    FakePictureLayerImpl* layer_impl =
3126        static_cast<FakePictureLayerImpl*>(host_impl->RootLayer());
3127
3128    // The same frame can be draw multiple times if new visible tiles are
3129    // rasterized. But we want to make sure we only post DeferredInitialize
3130    // and ReleaseGL once, so early out if the same frame is drawn again.
3131    if (last_source_frame_number_drawn_ ==
3132        host_impl->active_tree()->source_frame_number())
3133      return;
3134
3135    last_source_frame_number_drawn_ =
3136        host_impl->active_tree()->source_frame_number();
3137
3138    if (!did_initialize_gl_) {
3139      EXPECT_LE(1u, layer_impl->append_quads_count());
3140      ImplThreadTaskRunner()->PostTask(
3141          FROM_HERE,
3142          base::Bind(
3143              &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw,
3144              base::Unretained(this),
3145              base::Unretained(host_impl)));
3146    } else if (did_initialize_gl_ && !did_release_gl_) {
3147      EXPECT_LE(2u, layer_impl->append_quads_count());
3148      ImplThreadTaskRunner()->PostTask(
3149          FROM_HERE,
3150          base::Bind(
3151              &LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw,
3152              base::Unretained(this),
3153              base::Unretained(host_impl)));
3154    } else if (did_initialize_gl_ && did_release_gl_) {
3155      EXPECT_LE(3u, layer_impl->append_quads_count());
3156      EndTest();
3157    }
3158  }
3159
3160  void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) {
3161    EXPECT_FALSE(did_initialize_gl_);
3162    // SetAndInitializeContext3D calls SetNeedsCommit.
3163    EXPECT_TRUE(static_cast<FakeOutputSurface*>(host_impl->output_surface())
3164                    ->SetAndInitializeContext3D(
3165                          scoped_ptr<WebKit::WebGraphicsContext3D>(
3166                              TestWebGraphicsContext3D::Create())));
3167    did_initialize_gl_ = true;
3168  }
3169
3170  void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) {
3171    EXPECT_TRUE(did_initialize_gl_);
3172    EXPECT_FALSE(did_release_gl_);
3173    // ReleaseGL calls SetNeedsCommit.
3174    static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL();
3175    did_release_gl_ = true;
3176  }
3177
3178  virtual void AfterTest() OVERRIDE {
3179    EXPECT_TRUE(did_initialize_gl_);
3180    EXPECT_TRUE(did_release_gl_);
3181  }
3182
3183 private:
3184  FakeContentLayerClient client_;
3185  scoped_refptr<FakePictureLayer> layer_;
3186  bool did_initialize_gl_;
3187  bool did_release_gl_;
3188  int last_source_frame_number_drawn_;
3189};
3190
3191MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize);
3192
3193class PushPropertiesCountingLayer : public Layer {
3194 public:
3195  static scoped_refptr<PushPropertiesCountingLayer> Create() {
3196    return new PushPropertiesCountingLayer();
3197  }
3198
3199  virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE {
3200    Layer::PushPropertiesTo(layer);
3201    push_properties_count_++;
3202    if (persist_needs_push_properties_)
3203      needs_push_properties_ = true;
3204  }
3205
3206  size_t push_properties_count() const { return push_properties_count_; }
3207  void reset_push_properties_count() { push_properties_count_ = 0; }
3208
3209  void set_persist_needs_push_properties(bool persist) {
3210    persist_needs_push_properties_ = persist;
3211  }
3212
3213 private:
3214  PushPropertiesCountingLayer()
3215      : push_properties_count_(0),
3216        persist_needs_push_properties_(false) {
3217    SetAnchorPoint(gfx::PointF());
3218    SetBounds(gfx::Size(1, 1));
3219    SetIsDrawable(true);
3220  }
3221  virtual ~PushPropertiesCountingLayer() {}
3222
3223  size_t push_properties_count_;
3224  bool persist_needs_push_properties_;
3225};
3226
3227class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
3228 protected:
3229  virtual void BeginTest() OVERRIDE {
3230    num_commits_ = 0;
3231    expected_push_properties_root_ = 0;
3232    expected_push_properties_child_ = 0;
3233    expected_push_properties_grandchild_ = 0;
3234    expected_push_properties_child2_ = 0;
3235    expected_push_properties_other_root_ = 0;
3236    expected_push_properties_leaf_layer_ = 0;
3237    PostSetNeedsCommitToMainThread();
3238  }
3239
3240  virtual void SetupTree() OVERRIDE {
3241    root_ = PushPropertiesCountingLayer::Create();
3242    child_ = PushPropertiesCountingLayer::Create();
3243    child2_ = PushPropertiesCountingLayer::Create();
3244    grandchild_ = PushPropertiesCountingLayer::Create();
3245
3246    if (layer_tree_host()->settings().impl_side_painting)
3247      leaf_picture_layer_ = FakePictureLayer::Create(&client_);
3248    else
3249      leaf_content_layer_ = FakeContentLayer::Create(&client_);
3250
3251    root_->AddChild(child_);
3252    root_->AddChild(child2_);
3253    child_->AddChild(grandchild_);
3254    if (leaf_picture_layer_)
3255      child2_->AddChild(leaf_picture_layer_);
3256    if (leaf_content_layer_)
3257      child2_->AddChild(leaf_content_layer_);
3258
3259    other_root_ = PushPropertiesCountingLayer::Create();
3260
3261    // Don't set the root layer here.
3262    LayerTreeHostTest::SetupTree();
3263  }
3264
3265  virtual void DidCommitAndDrawFrame() OVERRIDE {
3266    ++num_commits_;
3267
3268    EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
3269    EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
3270    EXPECT_EQ(expected_push_properties_grandchild_,
3271              grandchild_->push_properties_count());
3272    EXPECT_EQ(expected_push_properties_child2_,
3273              child2_->push_properties_count());
3274    EXPECT_EQ(expected_push_properties_other_root_,
3275              other_root_->push_properties_count());
3276    if (leaf_content_layer_) {
3277      EXPECT_EQ(expected_push_properties_leaf_layer_,
3278                leaf_content_layer_->push_properties_count());
3279    }
3280    if (leaf_picture_layer_) {
3281      EXPECT_EQ(expected_push_properties_leaf_layer_,
3282                leaf_picture_layer_->push_properties_count());
3283    }
3284
3285    // The content/picture layer always needs to be pushed.
3286    if (root_->layer_tree_host()) {
3287      EXPECT_TRUE(root_->descendant_needs_push_properties());
3288      EXPECT_FALSE(root_->needs_push_properties());
3289    }
3290    if (child2_->layer_tree_host()) {
3291      EXPECT_TRUE(child2_->descendant_needs_push_properties());
3292      EXPECT_FALSE(child2_->needs_push_properties());
3293    }
3294    if (leaf_content_layer_.get() && leaf_content_layer_->layer_tree_host()) {
3295      EXPECT_FALSE(leaf_content_layer_->descendant_needs_push_properties());
3296      EXPECT_TRUE(leaf_content_layer_->needs_push_properties());
3297    }
3298    if (leaf_picture_layer_.get() && leaf_picture_layer_->layer_tree_host()) {
3299      EXPECT_FALSE(leaf_picture_layer_->descendant_needs_push_properties());
3300      EXPECT_TRUE(leaf_picture_layer_->needs_push_properties());
3301    }
3302
3303    // child_ and grandchild_ don't persist their need to push properties.
3304    if (child_->layer_tree_host()) {
3305      EXPECT_FALSE(child_->descendant_needs_push_properties());
3306      EXPECT_FALSE(child_->needs_push_properties());
3307    }
3308    if (grandchild_->layer_tree_host()) {
3309      EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
3310      EXPECT_FALSE(grandchild_->needs_push_properties());
3311    }
3312
3313    if (other_root_->layer_tree_host()) {
3314      EXPECT_FALSE(other_root_->descendant_needs_push_properties());
3315      EXPECT_FALSE(other_root_->needs_push_properties());
3316    }
3317
3318    switch (num_commits_) {
3319      case 1:
3320        layer_tree_host()->SetRootLayer(root_);
3321        // Layers added to the tree get committed.
3322        ++expected_push_properties_root_;
3323        ++expected_push_properties_child_;
3324        ++expected_push_properties_grandchild_;
3325        ++expected_push_properties_child2_;
3326        break;
3327      case 2:
3328        layer_tree_host()->SetNeedsCommit();
3329        // No layers need commit.
3330        break;
3331      case 3:
3332        layer_tree_host()->SetRootLayer(other_root_);
3333        // Layers added to the tree get committed.
3334        ++expected_push_properties_other_root_;
3335        break;
3336      case 4:
3337        layer_tree_host()->SetRootLayer(root_);
3338        // Layers added to the tree get committed.
3339        ++expected_push_properties_root_;
3340        ++expected_push_properties_child_;
3341        ++expected_push_properties_grandchild_;
3342        ++expected_push_properties_child2_;
3343        break;
3344      case 5:
3345        layer_tree_host()->SetNeedsCommit();
3346        // No layers need commit.
3347        break;
3348      case 6:
3349        child_->RemoveFromParent();
3350        // No layers need commit.
3351        break;
3352      case 7:
3353        root_->AddChild(child_);
3354        // Layers added to the tree get committed.
3355        ++expected_push_properties_child_;
3356        ++expected_push_properties_grandchild_;
3357        break;
3358      case 8:
3359        grandchild_->RemoveFromParent();
3360        // No layers need commit.
3361        break;
3362      case 9:
3363        child_->AddChild(grandchild_);
3364        // Layers added to the tree get committed.
3365        ++expected_push_properties_grandchild_;
3366        break;
3367      case 10:
3368        layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
3369        // No layers need commit.
3370        break;
3371      case 11:
3372        layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
3373        // No layers need commit.
3374        break;
3375      case 12:
3376        child_->SetPosition(gfx::Point(1, 1));
3377        // The modified layer needs commit
3378        ++expected_push_properties_child_;
3379        break;
3380      case 13:
3381        child2_->SetPosition(gfx::Point(1, 1));
3382        // The modified layer needs commit
3383        ++expected_push_properties_child2_;
3384        break;
3385      case 14:
3386        child_->RemoveFromParent();
3387        root_->AddChild(child_);
3388        // Layers added to the tree get committed.
3389        ++expected_push_properties_child_;
3390        ++expected_push_properties_grandchild_;
3391        break;
3392      case 15:
3393        grandchild_->SetPosition(gfx::Point(1, 1));
3394        // The modified layer needs commit
3395        ++expected_push_properties_grandchild_;
3396        break;
3397      case 16:
3398        child_->SetNeedsDisplay();
3399        // The modified layer needs commit
3400        ++expected_push_properties_child_;
3401        break;
3402      case 17:
3403        EndTest();
3404        break;
3405    }
3406
3407    // Content/Picture layers require PushProperties every commit that they are
3408    // in the tree.
3409    if ((leaf_content_layer_.get() && leaf_content_layer_->layer_tree_host()) ||
3410        (leaf_picture_layer_.get() && leaf_picture_layer_->layer_tree_host()))
3411      ++expected_push_properties_leaf_layer_;
3412  }
3413
3414  virtual void AfterTest() OVERRIDE {}
3415
3416  int num_commits_;
3417  FakeContentLayerClient client_;
3418  scoped_refptr<PushPropertiesCountingLayer> root_;
3419  scoped_refptr<PushPropertiesCountingLayer> child_;
3420  scoped_refptr<PushPropertiesCountingLayer> child2_;
3421  scoped_refptr<PushPropertiesCountingLayer> grandchild_;
3422  scoped_refptr<PushPropertiesCountingLayer> other_root_;
3423  scoped_refptr<FakeContentLayer> leaf_content_layer_;
3424  scoped_refptr<FakePictureLayer> leaf_picture_layer_;
3425  size_t expected_push_properties_root_;
3426  size_t expected_push_properties_child_;
3427  size_t expected_push_properties_child2_;
3428  size_t expected_push_properties_grandchild_;
3429  size_t expected_push_properties_other_root_;
3430  size_t expected_push_properties_leaf_layer_;
3431};
3432
3433MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
3434
3435class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
3436    : public LayerTreeHostTest {
3437 protected:
3438  virtual void BeginTest() OVERRIDE {
3439    PostSetNeedsCommitToMainThread();
3440  }
3441
3442  virtual void SetupTree() OVERRIDE {
3443    root_ = Layer::Create();
3444    root_->SetBounds(gfx::Size(1, 1));
3445
3446    bool paint_scrollbar = true;
3447    bool has_thumb = false;
3448    scrollbar_layer_ =
3449        FakeScrollbarLayer::Create(paint_scrollbar, has_thumb, root_->id());
3450
3451    root_->AddChild(scrollbar_layer_);
3452
3453    layer_tree_host()->SetRootLayer(root_);
3454    LayerTreeHostTest::SetupTree();
3455  }
3456
3457  virtual void DidCommitAndDrawFrame() OVERRIDE {
3458    switch (layer_tree_host()->commit_number()) {
3459      case 0:
3460        break;
3461      case 1: {
3462        // During update, the ignore_set_needs_commit_ bit is set to true to
3463        // avoid causing a second commit to be scheduled. If a property change
3464        // is made during this, however, it needs to be pushed in the upcoming
3465        // commit.
3466        scoped_ptr<base::AutoReset<bool> > ignore =
3467            scrollbar_layer_->IgnoreSetNeedsCommit();
3468
3469        scrollbar_layer_->SetBounds(gfx::Size(30, 30));
3470
3471        EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
3472        EXPECT_TRUE(root_->descendant_needs_push_properties());
3473        layer_tree_host()->SetNeedsCommit();
3474
3475        scrollbar_layer_->reset_push_properties_count();
3476        EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
3477        break;
3478      }
3479      case 2:
3480        EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
3481        EndTest();
3482        break;
3483    }
3484  }
3485
3486  virtual void AfterTest() OVERRIDE {}
3487
3488  scoped_refptr<Layer> root_;
3489  scoped_refptr<FakeScrollbarLayer> scrollbar_layer_;
3490};
3491
3492MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
3493
3494class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
3495    : public LayerTreeHostTest {
3496 protected:
3497  virtual void BeginTest() OVERRIDE {
3498    expected_push_properties_root_ = 0;
3499    expected_push_properties_child_ = 0;
3500    expected_push_properties_grandchild1_ = 0;
3501    expected_push_properties_grandchild2_ = 0;
3502    expected_push_properties_grandchild3_ = 0;
3503    PostSetNeedsCommitToMainThread();
3504  }
3505
3506  virtual void SetupTree() OVERRIDE {
3507    root_ = PushPropertiesCountingLayer::Create();
3508    child_ = PushPropertiesCountingLayer::Create();
3509    grandchild1_ = PushPropertiesCountingLayer::Create();
3510    grandchild2_ = PushPropertiesCountingLayer::Create();
3511    grandchild3_ = PushPropertiesCountingLayer::Create();
3512
3513    root_->AddChild(child_);
3514    child_->AddChild(grandchild1_);
3515    child_->AddChild(grandchild2_);
3516    child_->AddChild(grandchild3_);
3517
3518    // Don't set the root layer here.
3519    LayerTreeHostTest::SetupTree();
3520  }
3521
3522  virtual void AfterTest() OVERRIDE {}
3523
3524  FakeContentLayerClient client_;
3525  scoped_refptr<PushPropertiesCountingLayer> root_;
3526  scoped_refptr<PushPropertiesCountingLayer> child_;
3527  scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
3528  scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
3529  scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
3530  size_t expected_push_properties_root_;
3531  size_t expected_push_properties_child_;
3532  size_t expected_push_properties_grandchild1_;
3533  size_t expected_push_properties_grandchild2_;
3534  size_t expected_push_properties_grandchild3_;
3535};
3536
3537class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
3538    : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3539 protected:
3540  virtual void DidCommitAndDrawFrame() OVERRIDE {
3541    int last_source_frame_number = layer_tree_host()->commit_number() - 1;
3542    switch (last_source_frame_number) {
3543      case 0:
3544        EXPECT_FALSE(root_->needs_push_properties());
3545        EXPECT_FALSE(root_->descendant_needs_push_properties());
3546        EXPECT_FALSE(child_->needs_push_properties());
3547        EXPECT_FALSE(child_->descendant_needs_push_properties());
3548        EXPECT_FALSE(grandchild1_->needs_push_properties());
3549        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3550        EXPECT_FALSE(grandchild2_->needs_push_properties());
3551        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3552        EXPECT_FALSE(grandchild3_->needs_push_properties());
3553        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3554
3555        layer_tree_host()->SetRootLayer(root_);
3556
3557        EXPECT_TRUE(root_->needs_push_properties());
3558        EXPECT_TRUE(root_->descendant_needs_push_properties());
3559        EXPECT_TRUE(child_->needs_push_properties());
3560        EXPECT_TRUE(child_->descendant_needs_push_properties());
3561        EXPECT_TRUE(grandchild1_->needs_push_properties());
3562        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3563        EXPECT_TRUE(grandchild2_->needs_push_properties());
3564        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3565        EXPECT_TRUE(grandchild3_->needs_push_properties());
3566        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3567        break;
3568      case 1:
3569        EndTest();
3570        break;
3571    }
3572  }
3573};
3574
3575MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
3576
3577class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
3578    : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3579 protected:
3580  virtual void DidCommitAndDrawFrame() OVERRIDE {
3581    int last_source_frame_number = layer_tree_host()->commit_number() - 1;
3582    switch (last_source_frame_number) {
3583      case 0:
3584        layer_tree_host()->SetRootLayer(root_);
3585        break;
3586      case 1:
3587        EXPECT_FALSE(root_->needs_push_properties());
3588        EXPECT_FALSE(root_->descendant_needs_push_properties());
3589        EXPECT_FALSE(child_->needs_push_properties());
3590        EXPECT_FALSE(child_->descendant_needs_push_properties());
3591        EXPECT_FALSE(grandchild1_->needs_push_properties());
3592        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3593        EXPECT_FALSE(grandchild2_->needs_push_properties());
3594        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3595        EXPECT_FALSE(grandchild3_->needs_push_properties());
3596        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3597
3598        grandchild1_->RemoveFromParent();
3599        grandchild1_->SetPosition(gfx::Point(1, 1));
3600
3601        EXPECT_FALSE(root_->needs_push_properties());
3602        EXPECT_FALSE(root_->descendant_needs_push_properties());
3603        EXPECT_FALSE(child_->needs_push_properties());
3604        EXPECT_FALSE(child_->descendant_needs_push_properties());
3605        EXPECT_FALSE(grandchild2_->needs_push_properties());
3606        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3607        EXPECT_FALSE(grandchild3_->needs_push_properties());
3608        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3609
3610        child_->AddChild(grandchild1_);
3611
3612        EXPECT_FALSE(root_->needs_push_properties());
3613        EXPECT_TRUE(root_->descendant_needs_push_properties());
3614        EXPECT_FALSE(child_->needs_push_properties());
3615        EXPECT_TRUE(child_->descendant_needs_push_properties());
3616        EXPECT_TRUE(grandchild1_->needs_push_properties());
3617        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3618        EXPECT_FALSE(grandchild2_->needs_push_properties());
3619        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3620        EXPECT_FALSE(grandchild3_->needs_push_properties());
3621        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3622
3623        grandchild2_->SetPosition(gfx::Point(1, 1));
3624
3625        EXPECT_FALSE(root_->needs_push_properties());
3626        EXPECT_TRUE(root_->descendant_needs_push_properties());
3627        EXPECT_FALSE(child_->needs_push_properties());
3628        EXPECT_TRUE(child_->descendant_needs_push_properties());
3629        EXPECT_TRUE(grandchild1_->needs_push_properties());
3630        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3631        EXPECT_TRUE(grandchild2_->needs_push_properties());
3632        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3633        EXPECT_FALSE(grandchild3_->needs_push_properties());
3634        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3635
3636        // grandchild2_ will still need a push properties.
3637        grandchild1_->RemoveFromParent();
3638
3639        EXPECT_FALSE(root_->needs_push_properties());
3640        EXPECT_TRUE(root_->descendant_needs_push_properties());
3641        EXPECT_FALSE(child_->needs_push_properties());
3642        EXPECT_TRUE(child_->descendant_needs_push_properties());
3643
3644        // grandchild3_ does not need a push properties, so recursing should
3645        // no longer be needed.
3646        grandchild2_->RemoveFromParent();
3647
3648        EXPECT_FALSE(root_->needs_push_properties());
3649        EXPECT_FALSE(root_->descendant_needs_push_properties());
3650        EXPECT_FALSE(child_->needs_push_properties());
3651        EXPECT_FALSE(child_->descendant_needs_push_properties());
3652        EndTest();
3653        break;
3654    }
3655  }
3656};
3657
3658MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
3659
3660class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
3661    : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3662 protected:
3663  virtual void DidCommitAndDrawFrame() OVERRIDE {
3664    int last_source_frame_number = layer_tree_host()->commit_number() - 1;
3665    switch (last_source_frame_number) {
3666      case 0:
3667        layer_tree_host()->SetRootLayer(root_);
3668        grandchild1_->set_persist_needs_push_properties(true);
3669        grandchild2_->set_persist_needs_push_properties(true);
3670        break;
3671      case 1:
3672        EXPECT_FALSE(root_->needs_push_properties());
3673        EXPECT_TRUE(root_->descendant_needs_push_properties());
3674        EXPECT_FALSE(child_->needs_push_properties());
3675        EXPECT_TRUE(child_->descendant_needs_push_properties());
3676        EXPECT_TRUE(grandchild1_->needs_push_properties());
3677        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3678        EXPECT_TRUE(grandchild2_->needs_push_properties());
3679        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3680        EXPECT_FALSE(grandchild3_->needs_push_properties());
3681        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3682
3683        // grandchild2_ will still need a push properties.
3684        grandchild1_->RemoveFromParent();
3685
3686        EXPECT_FALSE(root_->needs_push_properties());
3687        EXPECT_TRUE(root_->descendant_needs_push_properties());
3688        EXPECT_FALSE(child_->needs_push_properties());
3689        EXPECT_TRUE(child_->descendant_needs_push_properties());
3690
3691        // grandchild3_ does not need a push properties, so recursing should
3692        // no longer be needed.
3693        grandchild2_->RemoveFromParent();
3694
3695        EXPECT_FALSE(root_->needs_push_properties());
3696        EXPECT_FALSE(root_->descendant_needs_push_properties());
3697        EXPECT_FALSE(child_->needs_push_properties());
3698        EXPECT_FALSE(child_->descendant_needs_push_properties());
3699        EndTest();
3700        break;
3701    }
3702  }
3703};
3704
3705MULTI_THREAD_TEST_F(
3706    LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
3707
3708class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
3709    : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3710 protected:
3711  virtual void DidCommitAndDrawFrame() OVERRIDE {
3712    int last_source_frame_number = layer_tree_host()->commit_number() - 1;
3713    switch (last_source_frame_number) {
3714      case 0:
3715        layer_tree_host()->SetRootLayer(root_);
3716        break;
3717      case 1:
3718        EXPECT_FALSE(root_->needs_push_properties());
3719        EXPECT_FALSE(root_->descendant_needs_push_properties());
3720        EXPECT_FALSE(child_->needs_push_properties());
3721        EXPECT_FALSE(child_->descendant_needs_push_properties());
3722        EXPECT_FALSE(grandchild1_->needs_push_properties());
3723        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3724        EXPECT_FALSE(grandchild2_->needs_push_properties());
3725        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3726        EXPECT_FALSE(grandchild3_->needs_push_properties());
3727        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3728
3729        // Change grandchildren while their parent is not in the tree.
3730        child_->RemoveFromParent();
3731        grandchild1_->SetPosition(gfx::Point(1, 1));
3732        grandchild2_->SetPosition(gfx::Point(1, 1));
3733        root_->AddChild(child_);
3734
3735        EXPECT_FALSE(root_->needs_push_properties());
3736        EXPECT_TRUE(root_->descendant_needs_push_properties());
3737        EXPECT_TRUE(child_->needs_push_properties());
3738        EXPECT_TRUE(child_->descendant_needs_push_properties());
3739        EXPECT_TRUE(grandchild1_->needs_push_properties());
3740        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3741        EXPECT_TRUE(grandchild2_->needs_push_properties());
3742        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3743        EXPECT_TRUE(grandchild3_->needs_push_properties());
3744        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3745
3746        grandchild1_->RemoveFromParent();
3747
3748        EXPECT_FALSE(root_->needs_push_properties());
3749        EXPECT_TRUE(root_->descendant_needs_push_properties());
3750        EXPECT_TRUE(child_->needs_push_properties());
3751        EXPECT_TRUE(child_->descendant_needs_push_properties());
3752
3753        grandchild2_->RemoveFromParent();
3754
3755        EXPECT_FALSE(root_->needs_push_properties());
3756        EXPECT_TRUE(root_->descendant_needs_push_properties());
3757        EXPECT_TRUE(child_->needs_push_properties());
3758        EXPECT_TRUE(child_->descendant_needs_push_properties());
3759
3760        grandchild3_->RemoveFromParent();
3761
3762        EXPECT_FALSE(root_->needs_push_properties());
3763        EXPECT_TRUE(root_->descendant_needs_push_properties());
3764        EXPECT_TRUE(child_->needs_push_properties());
3765        EXPECT_FALSE(child_->descendant_needs_push_properties());
3766
3767        EndTest();
3768        break;
3769    }
3770  }
3771};
3772
3773MULTI_THREAD_TEST_F(
3774    LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
3775
3776class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
3777    : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3778 protected:
3779  virtual void DidCommitAndDrawFrame() OVERRIDE {
3780    int last_source_frame_number = layer_tree_host()->commit_number() - 1;
3781    switch (last_source_frame_number) {
3782      case 0:
3783        layer_tree_host()->SetRootLayer(root_);
3784        break;
3785      case 1:
3786        EXPECT_FALSE(root_->needs_push_properties());
3787        EXPECT_FALSE(root_->descendant_needs_push_properties());
3788        EXPECT_FALSE(child_->needs_push_properties());
3789        EXPECT_FALSE(child_->descendant_needs_push_properties());
3790        EXPECT_FALSE(grandchild1_->needs_push_properties());
3791        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3792        EXPECT_FALSE(grandchild2_->needs_push_properties());
3793        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3794        EXPECT_FALSE(grandchild3_->needs_push_properties());
3795        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3796
3797        child_->SetPosition(gfx::Point(1, 1));
3798        grandchild1_->SetPosition(gfx::Point(1, 1));
3799        grandchild2_->SetPosition(gfx::Point(1, 1));
3800
3801        EXPECT_FALSE(root_->needs_push_properties());
3802        EXPECT_TRUE(root_->descendant_needs_push_properties());
3803        EXPECT_TRUE(child_->needs_push_properties());
3804        EXPECT_TRUE(child_->descendant_needs_push_properties());
3805        EXPECT_TRUE(grandchild1_->needs_push_properties());
3806        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3807        EXPECT_TRUE(grandchild2_->needs_push_properties());
3808        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3809        EXPECT_FALSE(grandchild3_->needs_push_properties());
3810        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3811
3812        grandchild1_->RemoveFromParent();
3813
3814        EXPECT_FALSE(root_->needs_push_properties());
3815        EXPECT_TRUE(root_->descendant_needs_push_properties());
3816        EXPECT_TRUE(child_->needs_push_properties());
3817        EXPECT_TRUE(child_->descendant_needs_push_properties());
3818
3819        grandchild2_->RemoveFromParent();
3820
3821        EXPECT_FALSE(root_->needs_push_properties());
3822        EXPECT_TRUE(root_->descendant_needs_push_properties());
3823        EXPECT_TRUE(child_->needs_push_properties());
3824        EXPECT_FALSE(child_->descendant_needs_push_properties());
3825
3826        child_->RemoveFromParent();
3827
3828        EXPECT_FALSE(root_->needs_push_properties());
3829        EXPECT_FALSE(root_->descendant_needs_push_properties());
3830
3831        EndTest();
3832        break;
3833    }
3834  }
3835};
3836
3837MULTI_THREAD_TEST_F(
3838    LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
3839
3840class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
3841    : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
3842 protected:
3843  virtual void DidCommitAndDrawFrame() OVERRIDE {
3844    int last_source_frame_number = layer_tree_host()->commit_number() - 1;
3845    switch (last_source_frame_number) {
3846      case 0:
3847        layer_tree_host()->SetRootLayer(root_);
3848        break;
3849      case 1:
3850        EXPECT_FALSE(root_->needs_push_properties());
3851        EXPECT_FALSE(root_->descendant_needs_push_properties());
3852        EXPECT_FALSE(child_->needs_push_properties());
3853        EXPECT_FALSE(child_->descendant_needs_push_properties());
3854        EXPECT_FALSE(grandchild1_->needs_push_properties());
3855        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3856        EXPECT_FALSE(grandchild2_->needs_push_properties());
3857        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3858        EXPECT_FALSE(grandchild3_->needs_push_properties());
3859        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3860
3861        grandchild1_->SetPosition(gfx::Point(1, 1));
3862        grandchild2_->SetPosition(gfx::Point(1, 1));
3863        child_->SetPosition(gfx::Point(1, 1));
3864
3865        EXPECT_FALSE(root_->needs_push_properties());
3866        EXPECT_TRUE(root_->descendant_needs_push_properties());
3867        EXPECT_TRUE(child_->needs_push_properties());
3868        EXPECT_TRUE(child_->descendant_needs_push_properties());
3869        EXPECT_TRUE(grandchild1_->needs_push_properties());
3870        EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
3871        EXPECT_TRUE(grandchild2_->needs_push_properties());
3872        EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
3873        EXPECT_FALSE(grandchild3_->needs_push_properties());
3874        EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
3875
3876        grandchild1_->RemoveFromParent();
3877
3878        EXPECT_FALSE(root_->needs_push_properties());
3879        EXPECT_TRUE(root_->descendant_needs_push_properties());
3880        EXPECT_TRUE(child_->needs_push_properties());
3881        EXPECT_TRUE(child_->descendant_needs_push_properties());
3882
3883        grandchild2_->RemoveFromParent();
3884
3885        EXPECT_FALSE(root_->needs_push_properties());
3886        EXPECT_TRUE(root_->descendant_needs_push_properties());
3887        EXPECT_TRUE(child_->needs_push_properties());
3888        EXPECT_FALSE(child_->descendant_needs_push_properties());
3889
3890        child_->RemoveFromParent();
3891
3892        EXPECT_FALSE(root_->needs_push_properties());
3893        EXPECT_FALSE(root_->descendant_needs_push_properties());
3894
3895        EndTest();
3896        break;
3897    }
3898  }
3899};
3900
3901MULTI_THREAD_TEST_F(
3902    LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
3903
3904// This test verifies that the tree activation callback is invoked correctly.
3905class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
3906 public:
3907  LayerTreeHostTestTreeActivationCallback()
3908      : num_commits_(0), callback_count_(0) {}
3909
3910  virtual void BeginTest() OVERRIDE {
3911    EXPECT_TRUE(HasImplThread());
3912    PostSetNeedsCommitToMainThread();
3913  }
3914
3915  virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
3916                                     LayerTreeHostImpl::FrameData* frame_data,
3917                                     bool result) OVERRIDE {
3918    ++num_commits_;
3919    switch (num_commits_) {
3920      case 1:
3921        EXPECT_EQ(0, callback_count_);
3922        callback_count_ = 0;
3923        SetCallback(true);
3924        PostSetNeedsCommitToMainThread();
3925        break;
3926      case 2:
3927        EXPECT_EQ(1, callback_count_);
3928        callback_count_ = 0;
3929        SetCallback(false);
3930        PostSetNeedsCommitToMainThread();
3931        break;
3932      case 3:
3933        EXPECT_EQ(0, callback_count_);
3934        callback_count_ = 0;
3935        EndTest();
3936        break;
3937      default:
3938        ADD_FAILURE() << num_commits_;
3939        EndTest();
3940        break;
3941    }
3942    return LayerTreeHostTest::PrepareToDrawOnThread(host_impl, frame_data,
3943                                                    result);
3944  }
3945
3946  virtual void AfterTest() OVERRIDE {
3947    EXPECT_EQ(3, num_commits_);
3948  }
3949
3950  void SetCallback(bool enable) {
3951    output_surface()->SetTreeActivationCallback(enable ?
3952        base::Bind(&LayerTreeHostTestTreeActivationCallback::ActivationCallback,
3953                   base::Unretained(this)) :
3954        base::Closure());
3955  }
3956
3957  void ActivationCallback() {
3958    ++callback_count_;
3959  }
3960
3961  int num_commits_;
3962  int callback_count_;
3963};
3964
3965TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
3966  RunTest(true, false, true);
3967}
3968
3969TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
3970  RunTest(true, true, true);
3971}
3972
3973}  // namespace
3974}  // namespace cc
3975