1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "cc/output/copy_output_request.h"
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "cc/output/copy_output_result.h"
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "cc/test/fake_content_layer.h"
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "cc/test/fake_content_layer_client.h"
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "cc/test/fake_output_surface.h"
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "cc/test/layer_tree_test.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "cc/trees/layer_tree_impl.h"
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "gpu/GLES2/gl2extchromium.h"
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace cc {
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace {
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// These tests only use direct rendering, as there is no output to copy for
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// delegated renderers.
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class LayerTreeHostCopyRequestTest : public LayerTreeTest {};
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class LayerTreeHostCopyRequestTestMultipleRequests
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : public LayerTreeHostCopyRequestTest {
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected:
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void SetupTree() OVERRIDE {
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root = FakeContentLayer::Create(&client_);
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root->SetBounds(gfx::Size(20, 20));
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    child = FakeContentLayer::Create(&client_);
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    child->SetBounds(gfx::Size(10, 10));
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root->AddChild(child);
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    layer_tree_host()->SetRootLayer(root);
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostCopyRequestTest::SetupTree();
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void DidCommitAndDrawFrame() OVERRIDE { WaitForCallback(); }
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void WaitForCallback() {
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        FROM_HERE,
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::NextStep,
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   base::Unretained(this)));
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void NextStep() {
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int frame = layer_tree_host()->source_frame_number();
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    switch (frame) {
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 1:
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            CopyOutputCallback,
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       base::Unretained(this))));
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_EQ(0u, callbacks_.size());
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 2:
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        if (callbacks_.size() < 1u) {
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          WaitForCallback();
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          return;
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        }
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_EQ(1u, callbacks_.size());
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[0].ToString());
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            CopyOutputCallback,
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       base::Unretained(this))));
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        root->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            CopyOutputCallback,
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       base::Unretained(this))));
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            base::Bind(&LayerTreeHostCopyRequestTestMultipleRequests::
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            CopyOutputCallback,
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       base::Unretained(this))));
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_EQ(1u, callbacks_.size());
78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 3:
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        if (callbacks_.size() < 4u) {
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          WaitForCallback();
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          return;
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        }
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_EQ(4u, callbacks_.size());
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // The child was copied to a bitmap and passed back twice.
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[1].ToString());
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[2].ToString());
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // The root was copied to a bitmap and passed back also.
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_EQ(gfx::Size(20, 20).ToString(), callbacks_[3].ToString());
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EndTest();
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(result->HasBitmap());
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_ptr<SkBitmap> bitmap = result->TakeBitmap().Pass();
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(result->size().ToString(),
100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              gfx::Size(bitmap->width(), bitmap->height()).ToString());
101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    callbacks_.push_back(result->size());
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void AfterTest() OVERRIDE { EXPECT_EQ(4u, callbacks_.size()); }
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      OVERRIDE {
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (use_gl_renderer_)
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return FakeOutputSurface::Create3d();
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return FakeOutputSurface::CreateSoftware(
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        make_scoped_ptr(new SoftwareOutputDevice));
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool use_gl_renderer_;
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<gfx::Size> callbacks_;
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FakeContentLayerClient client_;
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> root;
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> child;
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Readback can't be done with a delegating renderer.
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       GLRenderer_RunSingleThread) {
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  use_gl_renderer_ = true;
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RunTest(false, false, false);
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       GLRenderer_RunMultiThread_MainThreadPainting) {
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  use_gl_renderer_ = true;
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RunTest(true, false, false);
132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       SoftwareRenderer_RunSingleThread) {
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  use_gl_renderer_ = false;
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RunTest(false, false, false);
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LayerTreeHostCopyRequestTestMultipleRequests,
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       SoftwareRenderer_RunMultiThread_MainThreadPainting) {
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  use_gl_renderer_ = false;
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RunTest(true, false, false);
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class LayerTreeHostCopyRequestTestLayerDestroyed
147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : public LayerTreeHostCopyRequestTest {
148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected:
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void SetupTree() OVERRIDE {
150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_ = FakeContentLayer::Create(&client_);
151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_->SetBounds(gfx::Size(20, 20));
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    main_destroyed_ = FakeContentLayer::Create(&client_);
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    main_destroyed_->SetBounds(gfx::Size(15, 15));
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_->AddChild(main_destroyed_);
156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    impl_destroyed_ = FakeContentLayer::Create(&client_);
158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    impl_destroyed_->SetBounds(gfx::Size(10, 10));
159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_->AddChild(impl_destroyed_);
160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    layer_tree_host()->SetRootLayer(root_);
162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostCopyRequestTest::SetupTree();
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE {
166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    callback_count_ = 0;
167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PostSetNeedsCommitToMainThread();
168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void DidCommit() OVERRIDE {
171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int frame = layer_tree_host()->source_frame_number();
172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    switch (frame) {
173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 1:
174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        main_destroyed_->RequestCopyOfOutput(
175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            CopyOutputRequest::CreateBitmapRequest(base::Bind(
176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                &LayerTreeHostCopyRequestTestLayerDestroyed::CopyOutputCallback,
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                base::Unretained(this))));
178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        impl_destroyed_->RequestCopyOfOutput(
179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            CopyOutputRequest::CreateBitmapRequest(base::Bind(
180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                &LayerTreeHostCopyRequestTestLayerDestroyed::CopyOutputCallback,
181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                base::Unretained(this))));
182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_EQ(0, callback_count_);
183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Destroy the main thread layer right away.
185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        main_destroyed_->RemoveFromParent();
186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        main_destroyed_ = NULL;
187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Should callback with a NULL bitmap.
189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_EQ(1, callback_count_);
190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Prevent drawing so we can't make a copy of the impl_destroyed layer.
192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        layer_tree_host()->SetViewportSize(gfx::Size());
193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 2:
195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Flush the message loops and make sure the callbacks run.
196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        layer_tree_host()->SetNeedsCommit();
197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 3:
199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // No drawing means no readback yet.
200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_EQ(1, callback_count_);
201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Destroy the impl thread layer.
203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        impl_destroyed_->RemoveFromParent();
204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        impl_destroyed_ = NULL;
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // No callback yet because it's on the impl side.
207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_EQ(1, callback_count_);
208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 4:
210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Flush the message loops and make sure the callbacks run.
211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        layer_tree_host()->SetNeedsCommit();
212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 5:
214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // We should get another callback with a NULL bitmap.
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_EQ(2, callback_count_);
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EndTest();
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(result->IsEmpty());
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ++callback_count_;
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void AfterTest() OVERRIDE {}
228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int callback_count_;
230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FakeContentLayerClient client_;
231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> root_;
232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> main_destroyed_;
233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> impl_destroyed_;
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestLayerDestroyed);
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class LayerTreeHostCopyRequestTestInHiddenSubtree
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : public LayerTreeHostCopyRequestTest {
240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected:
241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void SetupTree() OVERRIDE {
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_ = FakeContentLayer::Create(&client_);
243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_->SetBounds(gfx::Size(20, 20));
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    grand_parent_layer_ = FakeContentLayer::Create(&client_);
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    grand_parent_layer_->SetBounds(gfx::Size(15, 15));
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_->AddChild(grand_parent_layer_);
248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // parent_layer_ owns a render surface.
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    parent_layer_ = FakeContentLayer::Create(&client_);
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    parent_layer_->SetBounds(gfx::Size(15, 15));
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    parent_layer_->SetForceRenderSurface(true);
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    grand_parent_layer_->AddChild(parent_layer_);
254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_ = FakeContentLayer::Create(&client_);
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_->SetBounds(gfx::Size(10, 10));
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    parent_layer_->AddChild(copy_layer_);
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    layer_tree_host()->SetRootLayer(root_);
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostCopyRequestTest::SetupTree();
261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void AddCopyRequest(Layer* layer) {
264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    layer->RequestCopyOfOutput(
265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        CopyOutputRequest::CreateBitmapRequest(base::Bind(
266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            &LayerTreeHostCopyRequestTestInHiddenSubtree::CopyOutputCallback,
267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            base::Unretained(this))));
268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE {
271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    callback_count_ = 0;
272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PostSetNeedsCommitToMainThread();
273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    AddCopyRequest(copy_layer_.get());
275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ++callback_count_;
279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString())
281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        << callback_count_;
282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    switch (callback_count_) {
283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 1:
284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Hide the copy request layer.
285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        grand_parent_layer_->SetHideLayerAndSubtree(false);
286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        parent_layer_->SetHideLayerAndSubtree(false);
287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        copy_layer_->SetHideLayerAndSubtree(true);
288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        AddCopyRequest(copy_layer_.get());
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 2:
291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Hide the copy request layer's parent only.
292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        grand_parent_layer_->SetHideLayerAndSubtree(false);
293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        parent_layer_->SetHideLayerAndSubtree(true);
294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        copy_layer_->SetHideLayerAndSubtree(false);
295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        AddCopyRequest(copy_layer_.get());
296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 3:
298a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Hide the copy request layer's grand parent only.
299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        grand_parent_layer_->SetHideLayerAndSubtree(true);
300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        parent_layer_->SetHideLayerAndSubtree(false);
301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        copy_layer_->SetHideLayerAndSubtree(false);
302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        AddCopyRequest(copy_layer_.get());
303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 4:
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Hide the copy request layer's parent and grandparent.
306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        grand_parent_layer_->SetHideLayerAndSubtree(true);
307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        parent_layer_->SetHideLayerAndSubtree(true);
308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        copy_layer_->SetHideLayerAndSubtree(false);
309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        AddCopyRequest(copy_layer_.get());
310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 5:
312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Hide the copy request layer as well as its parent and grandparent.
313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        grand_parent_layer_->SetHideLayerAndSubtree(true);
314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        parent_layer_->SetHideLayerAndSubtree(true);
315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        copy_layer_->SetHideLayerAndSubtree(true);
316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        AddCopyRequest(copy_layer_.get());
317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 6:
319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EndTest();
320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
321a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
322a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
324a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void AfterTest() OVERRIDE {}
325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
326a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int callback_count_;
327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FakeContentLayerClient client_;
328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> root_;
329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> grand_parent_layer_;
330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> parent_layer_;
331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> copy_layer_;
332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostCopyRequestTestInHiddenSubtree);
336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : public LayerTreeHostCopyRequestTest {
339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected:
340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void SetupTree() OVERRIDE {
341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_ = FakeContentLayer::Create(&client_);
342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_->SetBounds(gfx::Size(20, 20));
343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    grand_parent_layer_ = FakeContentLayer::Create(&client_);
345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    grand_parent_layer_->SetBounds(gfx::Size(15, 15));
346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    grand_parent_layer_->SetHideLayerAndSubtree(true);
347a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_->AddChild(grand_parent_layer_);
348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // parent_layer_ owns a render surface.
350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    parent_layer_ = FakeContentLayer::Create(&client_);
351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    parent_layer_->SetBounds(gfx::Size(15, 15));
352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    parent_layer_->SetForceRenderSurface(true);
353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    grand_parent_layer_->AddChild(parent_layer_);
354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_ = FakeContentLayer::Create(&client_);
356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_->SetBounds(gfx::Size(10, 10));
357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    parent_layer_->AddChild(copy_layer_);
358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    layer_tree_host()->SetRootLayer(root_);
360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostCopyRequestTest::SetupTree();
361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE {
364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    did_draw_ = false;
365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PostSetNeedsCommitToMainThread();
366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_->RequestCopyOfOutput(
368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        CopyOutputRequest::CreateBitmapRequest(base::Bind(
369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            &LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest::
370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 CopyOutputCallback,
371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            base::Unretained(this))));
372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EndTest();
378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    Renderer* renderer = host_impl->renderer();
382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerImpl* root = host_impl->active_tree()->root_layer();
384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerImpl* grand_parent = root->children()[0];
385a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerImpl* parent = grand_parent->children()[0];
386a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerImpl* copy_layer = parent->children()[0];
387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // |parent| owns a surface, but it was hidden and not part of the copy
389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // request so it should not allocate any resource.
390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_FALSE(renderer->HasAllocatedResourcesForTesting(
39103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        parent->render_surface()->GetRenderPassId()));
392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // |copy_layer| should have been rendered to a texture since it was needed
394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // for a copy request.
395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting(
39603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        copy_layer->render_surface()->GetRenderPassId()));
397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    did_draw_ = true;
399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
400a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
401a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void AfterTest() OVERRIDE { EXPECT_TRUE(did_draw_); }
402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FakeContentLayerClient client_;
404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool did_draw_;
405a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> root_;
406a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> grand_parent_layer_;
407a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> parent_layer_;
408a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> copy_layer_;
409a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
410a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
411a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// No output to copy for delegated renderers.
412a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
413a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest);
414a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
415a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class LayerTreeHostCopyRequestTestClippedOut
416a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : public LayerTreeHostCopyRequestTest {
417a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected:
418a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void SetupTree() OVERRIDE {
419a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_ = FakeContentLayer::Create(&client_);
420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_->SetBounds(gfx::Size(20, 20));
421a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    parent_layer_ = FakeContentLayer::Create(&client_);
423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    parent_layer_->SetBounds(gfx::Size(15, 15));
424a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    parent_layer_->SetMasksToBounds(true);
425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_->AddChild(parent_layer_);
426a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
427a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_ = FakeContentLayer::Create(&client_);
428a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_->SetPosition(gfx::Point(15, 15));
429a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_->SetBounds(gfx::Size(10, 10));
430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    parent_layer_->AddChild(copy_layer_);
431a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
432a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    layer_tree_host()->SetRootLayer(root_);
433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostCopyRequestTest::SetupTree();
434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE {
437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PostSetNeedsCommitToMainThread();
438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        base::Bind(&LayerTreeHostCopyRequestTestClippedOut::CopyOutputCallback,
441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   base::Unretained(this))));
442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // We should still get a callback with no output if the copy requested layer
446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // was completely clipped away.
447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(gfx::Size().ToString(), result->size().ToString());
449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EndTest();
450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
452a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void AfterTest() OVERRIDE {}
453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FakeContentLayerClient client_;
455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> root_;
456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> parent_layer_;
457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> copy_layer_;
458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostCopyRequestTestClippedOut);
462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw
464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : public LayerTreeHostCopyRequestTest {
465a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected:
466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void SetupTree() OVERRIDE {
467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_ = FakeContentLayer::Create(&client_);
468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_->SetBounds(gfx::Size(20, 20));
469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_ = FakeContentLayer::Create(&client_);
471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_->SetBounds(gfx::Size(10, 10));
472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_->AddChild(copy_layer_);
473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    layer_tree_host()->SetRootLayer(root_);
475a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostCopyRequestTest::SetupTree();
476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void AddCopyRequest(Layer* layer) {
479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    layer->RequestCopyOfOutput(
480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        CopyOutputRequest::CreateBitmapRequest(base::Bind(
481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            &LayerTreeHostTestAsyncTwoReadbacksWithoutDraw::CopyOutputCallback,
482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            base::Unretained(this))));
483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
484a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE {
486a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    saw_copy_request_ = false;
487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    callback_count_ = 0;
488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PostSetNeedsCommitToMainThread();
489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Prevent drawing.
491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
493a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    AddCopyRequest(copy_layer_.get());
494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
496a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
497a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (impl->active_tree()->source_frame_number() == 0) {
498a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      LayerImpl* root = impl->active_tree()->root_layer();
499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      EXPECT_TRUE(root->children()[0]->HasCopyRequest());
500a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      saw_copy_request_ = true;
501a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
502a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
503a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
504a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void DidCommit() OVERRIDE {
505a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (layer_tree_host()->source_frame_number() == 1) {
506a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // Allow drawing.
507a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      layer_tree_host()->SetViewportSize(gfx::Size(root_->bounds()));
508a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
509a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      AddCopyRequest(copy_layer_.get());
510a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
511a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
512a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
513a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
514a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
515a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
516a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ++callback_count_;
517a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
518a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (callback_count_ == 2)
519a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      EndTest();
520a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
521a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
522a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void AfterTest() OVERRIDE { EXPECT_TRUE(saw_copy_request_); }
523a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
524a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool saw_copy_request_;
525a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int callback_count_;
526a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FakeContentLayerClient client_;
527a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> root_;
528a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> copy_layer_;
529a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
530a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
531a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
532a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostTestAsyncTwoReadbacksWithoutDraw);
533a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
534a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class LayerTreeHostCopyRequestTestLostOutputSurface
535a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : public LayerTreeHostCopyRequestTest {
536a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected:
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
538a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      OVERRIDE {
539a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!first_context_provider_.get()) {
540a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      first_context_provider_ = TestContextProvider::Create();
5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return FakeOutputSurface::Create3d(first_context_provider_);
542a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
543a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
544a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_FALSE(second_context_provider_.get());
545a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    second_context_provider_ = TestContextProvider::Create();
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return FakeOutputSurface::Create3d(second_context_provider_);
547a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
548a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
549a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void SetupTree() OVERRIDE {
550a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_ = FakeContentLayer::Create(&client_);
551a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_->SetBounds(gfx::Size(20, 20));
552a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
553a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_ = FakeContentLayer::Create(&client_);
554a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_->SetBounds(gfx::Size(10, 10));
555a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_->AddChild(copy_layer_);
556a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
557a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    layer_tree_host()->SetRootLayer(root_);
558a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostCopyRequestTest::SetupTree();
559a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
560a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
561a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
562a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
563a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
564a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
565a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(gfx::Size(10, 10).ToString(), result->size().ToString());
566a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(result->HasTexture());
567a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
568a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Save the result for later.
569a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_FALSE(result_);
570a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    result_ = result.Pass();
571a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
572a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Post a commit to lose the output surface.
573a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    layer_tree_host()->SetNeedsCommit();
574a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
575a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
576a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void DidCommitAndDrawFrame() OVERRIDE {
577a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    switch (layer_tree_host()->source_frame_number()) {
578a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 1:
579a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // The layers have been pushed to the impl side. The layer textures have
580a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // been allocated.
581a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
582a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Request a copy of the layer. This will use another texture.
583a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        copy_layer_->RequestCopyOfOutput(CopyOutputRequest::CreateRequest(
584a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            base::Bind(&LayerTreeHostCopyRequestTestLostOutputSurface::
585a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            CopyOutputCallback,
586a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       base::Unretained(this))));
587a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
588a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 4:
589a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // With SingleThreadProxy it takes two commits to finally swap after a
590a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // context loss.
591a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 5:
592a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Now destroy the CopyOutputResult, releasing the texture inside back
593a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // to the compositor.
594a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_TRUE(result_);
595a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        result_.reset();
596a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
597a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Check that it is released.
598a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        ImplThreadTaskRunner()->PostTask(
599a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            FROM_HERE,
600a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            base::Bind(&LayerTreeHostCopyRequestTestLostOutputSurface::
601a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            CheckNumTextures,
602a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       base::Unretained(this),
603a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       num_textures_after_loss_ - 1));
604a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
605a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
606a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
607a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
608a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void SwapBuffersOnThread(LayerTreeHostImpl* impl,
609a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                   bool result) OVERRIDE {
610a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    switch (impl->active_tree()->source_frame_number()) {
611a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 0:
612a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // The layers have been drawn, so their textures have been allocated.
613a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_FALSE(result_);
614a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        num_textures_without_readback_ =
615a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            first_context_provider_->TestContext3d()->NumTextures();
616a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
617a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 1:
618a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // We did a readback, so there will be a readback texture around now.
619a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_LT(num_textures_without_readback_,
620a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  first_context_provider_->TestContext3d()->NumTextures());
621a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
622a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 2:
623a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // The readback texture is collected.
624a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_TRUE(result_);
625a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
626a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Lose the output surface.
627a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        first_context_provider_->TestContext3d()->loseContextCHROMIUM(
628a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
629a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
630a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 3:
631a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // With SingleThreadProxy it takes two commits to finally swap after a
632a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // context loss.
633a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 4:
634a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // The output surface has been recreated.
635a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_TRUE(second_context_provider_.get());
636a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
637a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        num_textures_after_loss_ =
638a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            first_context_provider_->TestContext3d()->NumTextures();
639a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
640a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
641a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
642a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
643a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void CheckNumTextures(size_t expected_num_textures) {
644a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(expected_num_textures,
645a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              first_context_provider_->TestContext3d()->NumTextures());
646a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EndTest();
647a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
648a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
649a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void AfterTest() OVERRIDE {}
650a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
651a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<TestContextProvider> first_context_provider_;
652a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<TestContextProvider> second_context_provider_;
653a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  size_t num_textures_without_readback_;
654a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  size_t num_textures_after_loss_;
655a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FakeContentLayerClient client_;
656a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> root_;
657a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> copy_layer_;
658a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<CopyOutputResult> result_;
659a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
660a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
661a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
662a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostCopyRequestTestLostOutputSurface);
663a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
664a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class LayerTreeHostCopyRequestTestCountTextures
665a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : public LayerTreeHostCopyRequestTest {
666a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected:
6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
668a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      OVERRIDE {
669a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    context_provider_ = TestContextProvider::Create();
6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return FakeOutputSurface::Create3d(context_provider_);
671a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
672a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
673a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void SetupTree() OVERRIDE {
674a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_ = FakeContentLayer::Create(&client_);
675a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_->SetBounds(gfx::Size(20, 20));
676a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
677a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_ = FakeContentLayer::Create(&client_);
678a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_->SetBounds(gfx::Size(10, 10));
679a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    root_->AddChild(copy_layer_);
680a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
681a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    layer_tree_host()->SetRootLayer(root_);
682a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostCopyRequestTest::SetupTree();
683a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
684a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
685a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE {
686a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    num_textures_without_readback_ = 0;
687a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    num_textures_with_readback_ = 0;
688a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    waited_sync_point_after_readback_ = 0;
689a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PostSetNeedsCommitToMainThread();
690a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
691a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
692a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void RequestCopy(Layer* layer) = 0;
693a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
694a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void DidCommitAndDrawFrame() OVERRIDE {
695a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    switch (layer_tree_host()->source_frame_number()) {
696a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 1:
697a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // The layers have been pushed to the impl side. The layer textures have
698a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // been allocated.
699a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        RequestCopy(copy_layer_.get());
700a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
701a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
702a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
703a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
704a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void SwapBuffersOnThread(LayerTreeHostImpl* impl,
705a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                   bool result) OVERRIDE {
706a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    switch (impl->active_tree()->source_frame_number()) {
707a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 0:
708a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // The layers have been drawn, so their textures have been allocated.
709a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        num_textures_without_readback_ =
710a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            context_provider_->TestContext3d()->NumTextures();
711a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
712a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case 1:
713a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // We did a readback, so there will be a readback texture around now.
714a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        num_textures_with_readback_ =
715a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            context_provider_->TestContext3d()->NumTextures();
716a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        waited_sync_point_after_readback_ =
717a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            context_provider_->TestContext3d()->last_waited_sync_point();
718a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
719a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MainThreadTaskRunner()->PostTask(
720a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            FROM_HERE,
721a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            base::Bind(&LayerTreeHostCopyRequestTestCountTextures::DoEndTest,
722a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       base::Unretained(this)));
723a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        break;
724a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
725a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
726a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
727a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void DoEndTest() { EndTest(); }
728a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
729a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<TestContextProvider> context_provider_;
730a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  size_t num_textures_without_readback_;
731a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  size_t num_textures_with_readback_;
732a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  unsigned waited_sync_point_after_readback_;
733a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FakeContentLayerClient client_;
734a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> root_;
735a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> copy_layer_;
736a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
737a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
738a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class LayerTreeHostCopyRequestTestCreatesTexture
739a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : public LayerTreeHostCopyRequestTestCountTextures {
740a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected:
741a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void RequestCopy(Layer* layer) OVERRIDE {
742a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Request a normal texture copy. This should create a new texture.
743a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_->RequestCopyOfOutput(
744a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        CopyOutputRequest::CreateRequest(base::Bind(
745a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            &LayerTreeHostCopyRequestTestCreatesTexture::CopyOutputCallback,
746a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            base::Unretained(this))));
747a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
748a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
749a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
750a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_FALSE(result->IsEmpty());
751a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(result->HasTexture());
752a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
753a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TextureMailbox mailbox;
754a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_ptr<SingleReleaseCallback> release;
755a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    result->TakeTexture(&mailbox, &release);
756a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(release);
757a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
758a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    release->Run(0, false);
759a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
760a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
761a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void AfterTest() OVERRIDE {
762a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // No sync point was needed.
763a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(0u, waited_sync_point_after_readback_);
764a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Except the copy to have made another texture.
765a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(num_textures_without_readback_ + 1, num_textures_with_readback_);
766a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
767a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
768a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
769a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
770a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostCopyRequestTestCreatesTexture);
771a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
772a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class LayerTreeHostCopyRequestTestProvideTexture
773a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : public LayerTreeHostCopyRequestTestCountTextures {
774a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected:
775a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE {
776a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    external_context_provider_ = TestContextProvider::Create();
777a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(external_context_provider_->BindToCurrentThread());
778a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostCopyRequestTestCountTextures::BeginTest();
779a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
780a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
781a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
782a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_FALSE(result->IsEmpty());
783a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(result->HasTexture());
784a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
785a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TextureMailbox mailbox;
786a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_ptr<SingleReleaseCallback> release;
787a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    result->TakeTexture(&mailbox, &release);
788a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_FALSE(release);
789a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
790a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
791a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void RequestCopy(Layer* layer) OVERRIDE {
792a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Request a copy to a provided texture. This should not create a new
793a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // texture.
794a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_ptr<CopyOutputRequest> request =
795a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        CopyOutputRequest::CreateRequest(base::Bind(
796a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            &LayerTreeHostCopyRequestTestProvideTexture::CopyOutputCallback,
797a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            base::Unretained(this)));
798a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gpu::gles2::GLES2Interface* gl = external_context_provider_->ContextGL();
800a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gpu::Mailbox mailbox;
8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gl->GenMailboxCHROMIUM(mailbox.name);
8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sync_point_ = gl->InsertSyncPointCHROMIUM();
8035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    request->SetTextureMailbox(
8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point_));
805a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(request->has_texture_mailbox());
806a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
807a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    copy_layer_->RequestCopyOfOutput(request.Pass());
808a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
809a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
810a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void AfterTest() OVERRIDE {
811a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Expect the compositor to have waited for the sync point in the provided
812a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // TextureMailbox.
813a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(sync_point_, waited_sync_point_after_readback_);
814a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Except the copy to have *not* made another texture.
815a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(num_textures_without_readback_, num_textures_with_readback_);
816a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
817a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
818a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_refptr<TestContextProvider> external_context_provider_;
819a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  unsigned sync_point_;
820a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
821a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
822a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
823a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LayerTreeHostCopyRequestTestProvideTexture);
824a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
8255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class LayerTreeHostCopyRequestTestDestroyBeforeCopy
8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : public LayerTreeHostCopyRequestTest {
8275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
8285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void SetupTree() OVERRIDE {
8295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    root_ = FakeContentLayer::Create(&client_);
8305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    root_->SetBounds(gfx::Size(20, 20));
8315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    copy_layer_ = FakeContentLayer::Create(&client_);
8335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    copy_layer_->SetBounds(gfx::Size(10, 10));
8345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    root_->AddChild(copy_layer_);
8355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    layer_tree_host()->SetRootLayer(root_);
8375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LayerTreeHostCopyRequestTest::SetupTree();
8385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
8395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE {
8415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback_count_ = 0;
8425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PostSetNeedsCommitToMainThread();
8435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
8445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
8465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(result->IsEmpty());
8475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ++callback_count_;
8485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
8495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
8515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MainThreadTaskRunner()->PostTask(
8525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE,
8535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&LayerTreeHostCopyRequestTestDestroyBeforeCopy::DidActivate,
8545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::Unretained(this)));
8555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
8565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void DidActivate() {
8585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    switch (layer_tree_host()->source_frame_number()) {
8595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case 1: {
8605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_EQ(0, callback_count_);
8615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // Put a copy request on the layer, but then don't allow any
8625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // drawing to take place.
8635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        scoped_ptr<CopyOutputRequest> request =
8645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            CopyOutputRequest::CreateRequest(
8655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                base::Bind(&LayerTreeHostCopyRequestTestDestroyBeforeCopy::
8665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                CopyOutputCallback,
8675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           base::Unretained(this)));
8685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        copy_layer_->RequestCopyOfOutput(request.Pass());
8695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        layer_tree_host()->SetViewportSize(gfx::Size());
8715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
8725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
8735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case 2:
8745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_EQ(0, callback_count_);
8755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // Remove the copy layer before we were able to draw.
8765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        copy_layer_->RemoveFromParent();
8775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
8785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case 3:
8795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_EQ(1, callback_count_);
8805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // Allow us to draw now.
8815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        layer_tree_host()->SetViewportSize(
8825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            layer_tree_host()->root_layer()->bounds());
8835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
8845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case 4:
8855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_EQ(1, callback_count_);
8865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // We should not have crashed.
8875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EndTest();
8885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
8895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
8905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void AfterTest() OVERRIDE {}
8925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int callback_count_;
8945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeContentLayerClient client_;
8955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> root_;
8965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> copy_layer_;
8975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
8985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
9005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LayerTreeHostCopyRequestTestDestroyBeforeCopy);
9015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class LayerTreeHostCopyRequestTestShutdownBeforeCopy
9035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : public LayerTreeHostCopyRequestTest {
9045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
9055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void SetupTree() OVERRIDE {
9065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    root_ = FakeContentLayer::Create(&client_);
9075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    root_->SetBounds(gfx::Size(20, 20));
9085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    copy_layer_ = FakeContentLayer::Create(&client_);
9105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    copy_layer_->SetBounds(gfx::Size(10, 10));
9115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    root_->AddChild(copy_layer_);
9125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    layer_tree_host()->SetRootLayer(root_);
9145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LayerTreeHostCopyRequestTest::SetupTree();
9155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
9165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void BeginTest() OVERRIDE {
9185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback_count_ = 0;
9195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PostSetNeedsCommitToMainThread();
9205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
9215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
9235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(result->IsEmpty());
9245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ++callback_count_;
9255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
9265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
9285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MainThreadTaskRunner()->PostTask(
9295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE,
9305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::DidActivate,
9315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::Unretained(this)));
9325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
9335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void DidActivate() {
9355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    switch (layer_tree_host()->source_frame_number()) {
9365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case 1: {
9375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_EQ(0, callback_count_);
9385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // Put a copy request on the layer, but then don't allow any
9395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // drawing to take place.
9405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        scoped_ptr<CopyOutputRequest> request =
9415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            CopyOutputRequest::CreateRequest(
9425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::
9435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                CopyOutputCallback,
9445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           base::Unretained(this)));
9455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        copy_layer_->RequestCopyOfOutput(request.Pass());
9465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        layer_tree_host()->SetViewportSize(gfx::Size());
9485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
9495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
9505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case 2:
9515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        DestroyLayerTreeHost();
9525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // End the test after the copy result has had a chance to get back to
9535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // the main thread.
9545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        MainThreadTaskRunner()->PostTask(
9555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            FROM_HERE,
9565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::EndTest,
9575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       base::Unretained(this)));
9585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
9595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
9605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
9615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, callback_count_); }
9635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int callback_count_;
9655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeContentLayerClient client_;
9665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> root_;
9675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<FakeContentLayer> copy_layer_;
9685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
9695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
9715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LayerTreeHostCopyRequestTestShutdownBeforeCopy);
9725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
973a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace
974a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace cc
975