1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/message_loop/message_loop_proxy.h"
6 #include "base/threading/simple_thread.h"
7 #include "cc/layers/delegated_frame_provider.h"
8 #include "cc/layers/delegated_frame_resource_collection.h"
9 #include "cc/layers/delegated_renderer_layer.h"
10 #include "cc/layers/layer.h"
11 #include "cc/layers/solid_color_layer.h"
12 #include "cc/output/delegated_frame_data.h"
13 #include "cc/output/output_surface.h"
14 #include "cc/output/output_surface_client.h"
15 #include "cc/resources/resource_provider.h"
16 #include "cc/test/fake_delegated_renderer_layer.h"
17 #include "cc/test/test_context_provider.h"
18 #include "cc/trees/layer_tree_host.h"
19 #include "cc/trees/layer_tree_host_client.h"
20 #include "cc/trees/layer_tree_host_single_thread_client.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "third_party/skia/include/core/SkColor.h"
23 #include "ui/gfx/frame_time.h"
28 class NoMessageLoopOutputSurface
: public OutputSurface
{
30 NoMessageLoopOutputSurface() : OutputSurface(TestContextProvider::Create()) {}
31 virtual ~NoMessageLoopOutputSurface() {}
33 // OutputSurface overrides.
34 virtual void SwapBuffers(CompositorFrame
* frame
) OVERRIDE
{
36 client_
->DidSwapBuffers();
37 client_
->DidSwapBuffersComplete();
41 class LayerTreeHostNoMessageLoopTest
42 : public testing::Test
,
43 public base::DelegateSimpleThread::Delegate
,
44 public LayerTreeHostClient
,
45 public LayerTreeHostSingleThreadClient
{
47 LayerTreeHostNoMessageLoopTest()
48 : did_initialize_output_surface_(false),
50 did_commit_and_draw_frame_(false),
52 no_loop_thread_(this, "LayerTreeHostNoMessageLoopTest") {}
53 virtual ~LayerTreeHostNoMessageLoopTest() {}
55 // LayerTreeHostClient overrides.
56 virtual void WillBeginMainFrame(int frame_id
) OVERRIDE
{}
57 virtual void BeginMainFrame(const BeginFrameArgs
& args
) OVERRIDE
{}
58 virtual void DidBeginMainFrame() OVERRIDE
{}
59 virtual void Layout() OVERRIDE
{}
60 virtual void ApplyScrollAndScale(const gfx::Vector2d
& scroll_delta
,
61 float page_scale
) OVERRIDE
{}
62 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface(
63 bool fallback
) OVERRIDE
{
64 return make_scoped_ptr
<OutputSurface
>(new NoMessageLoopOutputSurface
);
66 virtual void DidInitializeOutputSurface() OVERRIDE
{
67 did_initialize_output_surface_
= true;
69 virtual void WillCommit() OVERRIDE
{}
70 virtual void DidCommit() OVERRIDE
{ did_commit_
= true; }
71 virtual void DidCommitAndDrawFrame() OVERRIDE
{
72 did_commit_and_draw_frame_
= true;
74 virtual void DidCompleteSwapBuffers() OVERRIDE
{}
76 // LayerTreeHostSingleThreadClient overrides.
77 virtual void ScheduleComposite() OVERRIDE
{}
78 virtual void ScheduleAnimation() OVERRIDE
{}
79 virtual void DidPostSwapBuffers() OVERRIDE
{}
80 virtual void DidAbortSwapBuffers() OVERRIDE
{}
83 no_loop_thread_
.Start();
84 no_loop_thread_
.Join();
87 // base::DelegateSimpleThread::Delegate override.
88 virtual void Run() OVERRIDE
{
89 ASSERT_FALSE(base::MessageLoopProxy::current());
90 RunTestWithoutMessageLoop();
91 EXPECT_FALSE(base::MessageLoopProxy::current());
95 virtual void RunTestWithoutMessageLoop() = 0;
97 void SetupLayerTreeHost() {
98 LayerTreeSettings settings
;
100 LayerTreeHost::CreateSingleThreaded(this, this, NULL
, settings
, NULL
);
101 layer_tree_host_
->SetViewportSize(size_
);
102 layer_tree_host_
->SetRootLayer(root_layer_
);
107 did_commit_and_draw_frame_
= false;
108 layer_tree_host_
->Composite(gfx::FrameTime::Now());
109 EXPECT_TRUE(did_initialize_output_surface_
);
110 EXPECT_TRUE(did_commit_
);
111 EXPECT_TRUE(did_commit_and_draw_frame_
);
114 void TearDownLayerTreeHost() {
115 // Explicit teardown to make failures easier to debug.
116 layer_tree_host_
.reset();
120 // All protected member variables are accessed only on |no_loop_thread_|.
121 scoped_ptr
<LayerTreeHost
> layer_tree_host_
;
122 scoped_refptr
<Layer
> root_layer_
;
124 bool did_initialize_output_surface_
;
126 bool did_commit_and_draw_frame_
;
130 base::DelegateSimpleThread no_loop_thread_
;
133 class LayerTreeHostNoMessageLoopSmokeTest
134 : public LayerTreeHostNoMessageLoopTest
{
136 virtual void RunTestWithoutMessageLoop() OVERRIDE
{
137 gfx::Size
size(100, 100);
139 // Set up root layer.
141 scoped_refptr
<SolidColorLayer
> solid_color_layer
=
142 SolidColorLayer::Create();
143 solid_color_layer
->SetBackgroundColor(SK_ColorRED
);
144 solid_color_layer
->SetBounds(size_
);
145 solid_color_layer
->SetIsDrawable(true);
146 root_layer_
= solid_color_layer
;
149 SetupLayerTreeHost();
151 TearDownLayerTreeHost();
155 TEST_F(LayerTreeHostNoMessageLoopSmokeTest
, SmokeTest
) {
159 class LayerTreeHostNoMessageLoopDelegatedLayer
160 : public LayerTreeHostNoMessageLoopTest
,
161 public DelegatedFrameResourceCollectionClient
{
163 virtual void RunTestWithoutMessageLoop() OVERRIDE
{
164 resource_collection_
= new DelegatedFrameResourceCollection
;
165 frame_provider_
= new DelegatedFrameProvider(
166 resource_collection_
.get(), CreateFrameDataWithResource(998));
168 root_layer_
= Layer::Create();
169 delegated_layer_
= FakeDelegatedRendererLayer::Create(frame_provider_
);
170 delegated_layer_
->SetBounds(size_
);
171 delegated_layer_
->SetIsDrawable(true);
172 root_layer_
->AddChild(delegated_layer_
);
174 SetupLayerTreeHost();
179 // Prepare and draw second frame.
180 frame_provider_
->SetFrameData(CreateFrameDataWithResource(999));
183 // Resource from first frame should be returned.
184 CheckReturnedResource(1u);
186 TearDownLayerTreeHost();
187 delegated_layer_
= NULL
;
188 frame_provider_
= NULL
;
190 // Resource from second frame should be returned.
191 CheckReturnedResource(1u);
192 resource_collection_
= NULL
;
195 // DelegatedFrameResourceCollectionClient overrides.
196 virtual void UnusedResourcesAreAvailable() OVERRIDE
{}
199 scoped_ptr
<DelegatedFrameData
> CreateFrameDataWithResource(
200 ResourceProvider::ResourceId resource_id
) {
201 scoped_ptr
<DelegatedFrameData
> frame(new DelegatedFrameData
);
202 gfx::Rect
frame_rect(size_
);
204 scoped_ptr
<RenderPass
> root_pass(RenderPass::Create());
206 RenderPass::Id(1, 1), frame_rect
, frame_rect
, gfx::Transform());
207 frame
->render_pass_list
.push_back(root_pass
.Pass());
209 TransferableResource resource
;
210 resource
.id
= resource_id
;
211 resource
.mailbox_holder
.texture_target
= GL_TEXTURE_2D
;
212 resource
.mailbox_holder
.mailbox
= gpu::Mailbox::Generate();
213 frame
->resource_list
.push_back(resource
);
218 void CheckReturnedResource(size_t expected_num
) {
219 ReturnedResourceArray returned_resources
;
220 resource_collection_
->TakeUnusedResourcesForChildCompositor(
221 &returned_resources
);
222 EXPECT_EQ(expected_num
, returned_resources
.size());
225 scoped_refptr
<DelegatedFrameResourceCollection
> resource_collection_
;
226 scoped_refptr
<DelegatedFrameProvider
> frame_provider_
;
227 scoped_refptr
<DelegatedRendererLayer
> delegated_layer_
;
230 TEST_F(LayerTreeHostNoMessageLoopDelegatedLayer
, SingleDelegatedLayer
) {