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/thread_task_runner_handle.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/scheduler/begin_frame_source.h"
17 #include "cc/test/fake_delegated_renderer_layer.h"
18 #include "cc/test/test_context_provider.h"
19 #include "cc/trees/layer_tree_host.h"
20 #include "cc/trees/layer_tree_host_client.h"
21 #include "cc/trees/layer_tree_host_single_thread_client.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "third_party/skia/include/core/SkColor.h"
24 #include "ui/gfx/frame_time.h"
29 class NoMessageLoopOutputSurface
: public OutputSurface
{
31 NoMessageLoopOutputSurface() : OutputSurface(TestContextProvider::Create()) {}
32 ~NoMessageLoopOutputSurface() override
{}
34 // OutputSurface overrides.
35 void SwapBuffers(CompositorFrame
* frame
) override
{
37 client_
->DidSwapBuffers();
38 client_
->DidSwapBuffersComplete();
42 class LayerTreeHostNoMessageLoopTest
43 : public testing::Test
,
44 public base::DelegateSimpleThread::Delegate
,
45 public LayerTreeHostClient
,
46 public LayerTreeHostSingleThreadClient
{
48 LayerTreeHostNoMessageLoopTest()
49 : did_initialize_output_surface_(false),
51 did_commit_and_draw_frame_(false),
53 no_loop_thread_(this, "LayerTreeHostNoMessageLoopTest") {}
54 ~LayerTreeHostNoMessageLoopTest() override
{}
56 // LayerTreeHostClient overrides.
57 void WillBeginMainFrame() override
{}
58 void BeginMainFrame(const BeginFrameArgs
& args
) override
{}
59 void BeginMainFrameNotExpectedSoon() override
{}
60 void DidBeginMainFrame() override
{}
61 void Layout() override
{}
62 void ApplyViewportDeltas(const gfx::Vector2dF
& inner_delta
,
63 const gfx::Vector2dF
& outer_delta
,
64 const gfx::Vector2dF
& elastic_overscroll_delta
,
66 float top_controls_delta
) override
{}
67 void ApplyViewportDeltas(const gfx::Vector2d
& scroll_delta
,
69 float top_controls_delta
) override
{}
70 void RequestNewOutputSurface() override
{
71 layer_tree_host_
->SetOutputSurface(
72 make_scoped_ptr
<OutputSurface
>(new NoMessageLoopOutputSurface
));
74 void DidInitializeOutputSurface() override
{
75 did_initialize_output_surface_
= true;
77 void DidFailToInitializeOutputSurface() override
{}
78 void WillCommit() override
{}
79 void DidCommit() override
{ did_commit_
= true; }
80 void DidCommitAndDrawFrame() override
{ did_commit_and_draw_frame_
= true; }
81 void DidCompleteSwapBuffers() override
{}
82 void DidCompletePageScaleAnimation() override
{}
84 // LayerTreeHostSingleThreadClient overrides.
85 void DidPostSwapBuffers() override
{}
86 void DidAbortSwapBuffers() override
{}
89 no_loop_thread_
.Start();
90 no_loop_thread_
.Join();
93 // base::DelegateSimpleThread::Delegate override.
95 ASSERT_FALSE(base::ThreadTaskRunnerHandle::IsSet());
96 RunTestWithoutMessageLoop();
97 EXPECT_FALSE(base::ThreadTaskRunnerHandle::IsSet());
101 virtual void RunTestWithoutMessageLoop() = 0;
103 void SetupLayerTreeHost() {
104 LayerTreeSettings settings
;
105 settings
.single_thread_proxy_scheduler
= false;
106 settings
.verify_property_trees
= true;
107 settings
.raster_enabled
= false;
109 LayerTreeHost::InitParams params
;
110 params
.client
= this;
111 params
.settings
= &settings
;
112 layer_tree_host_
= LayerTreeHost::CreateSingleThreaded(this, ¶ms
);
113 layer_tree_host_
->SetViewportSize(size_
);
114 layer_tree_host_
->SetRootLayer(root_layer_
);
119 did_commit_and_draw_frame_
= false;
120 layer_tree_host_
->Composite(gfx::FrameTime::Now());
121 EXPECT_TRUE(did_initialize_output_surface_
);
122 EXPECT_TRUE(did_commit_
);
123 EXPECT_TRUE(did_commit_and_draw_frame_
);
126 void TearDownLayerTreeHost() {
127 // Explicit teardown to make failures easier to debug.
128 layer_tree_host_
= nullptr;
129 root_layer_
= nullptr;
132 // All protected member variables are accessed only on |no_loop_thread_|.
133 scoped_ptr
<LayerTreeHost
> layer_tree_host_
;
134 scoped_refptr
<Layer
> root_layer_
;
136 bool did_initialize_output_surface_
;
138 bool did_commit_and_draw_frame_
;
142 base::DelegateSimpleThread no_loop_thread_
;
145 class LayerTreeHostNoMessageLoopSmokeTest
146 : public LayerTreeHostNoMessageLoopTest
{
148 void RunTestWithoutMessageLoop() override
{
149 gfx::Size
size(100, 100);
151 // Set up root layer.
153 scoped_refptr
<SolidColorLayer
> solid_color_layer
=
154 SolidColorLayer::Create();
155 solid_color_layer
->SetBackgroundColor(SK_ColorRED
);
156 solid_color_layer
->SetBounds(size_
);
157 solid_color_layer
->SetIsDrawable(true);
158 root_layer_
= solid_color_layer
;
161 SetupLayerTreeHost();
163 TearDownLayerTreeHost();
167 TEST_F(LayerTreeHostNoMessageLoopSmokeTest
, SmokeTest
) {
171 class LayerTreeHostNoMessageLoopDelegatedLayer
172 : public LayerTreeHostNoMessageLoopTest
,
173 public DelegatedFrameResourceCollectionClient
{
175 void RunTestWithoutMessageLoop() override
{
176 resource_collection_
= new DelegatedFrameResourceCollection
;
177 frame_provider_
= new DelegatedFrameProvider(
178 resource_collection_
.get(), CreateFrameDataWithResource(998));
180 root_layer_
= Layer::Create();
182 FakeDelegatedRendererLayer::Create(frame_provider_
.get());
183 delegated_layer_
->SetBounds(size_
);
184 delegated_layer_
->SetIsDrawable(true);
185 root_layer_
->AddChild(delegated_layer_
);
187 SetupLayerTreeHost();
192 // Prepare and draw second frame.
193 frame_provider_
->SetFrameData(CreateFrameDataWithResource(999));
196 // Resource from first frame should be returned.
197 CheckReturnedResource(1u);
199 TearDownLayerTreeHost();
200 delegated_layer_
= NULL
;
201 frame_provider_
= NULL
;
203 // Resource from second frame should be returned.
204 CheckReturnedResource(1u);
205 resource_collection_
= NULL
;
208 // DelegatedFrameResourceCollectionClient overrides.
209 void UnusedResourcesAreAvailable() override
{}
212 scoped_ptr
<DelegatedFrameData
> CreateFrameDataWithResource(
213 ResourceProvider::ResourceId resource_id
) {
214 scoped_ptr
<DelegatedFrameData
> frame(new DelegatedFrameData
);
215 gfx::Rect
frame_rect(size_
);
217 scoped_ptr
<RenderPass
> root_pass(RenderPass::Create());
219 RenderPassId(1, 1), frame_rect
, frame_rect
, gfx::Transform());
220 frame
->render_pass_list
.push_back(root_pass
.Pass());
222 TransferableResource resource
;
223 resource
.id
= resource_id
;
224 resource
.mailbox_holder
.texture_target
= GL_TEXTURE_2D
;
225 resource
.mailbox_holder
.mailbox
= gpu::Mailbox::Generate();
226 frame
->resource_list
.push_back(resource
);
231 void CheckReturnedResource(size_t expected_num
) {
232 ReturnedResourceArray returned_resources
;
233 resource_collection_
->TakeUnusedResourcesForChildCompositor(
234 &returned_resources
);
235 EXPECT_EQ(expected_num
, returned_resources
.size());
238 scoped_refptr
<DelegatedFrameResourceCollection
> resource_collection_
;
239 scoped_refptr
<DelegatedFrameProvider
> frame_provider_
;
240 scoped_refptr
<DelegatedRendererLayer
> delegated_layer_
;
243 TEST_F(LayerTreeHostNoMessageLoopDelegatedLayer
, SingleDelegatedLayer
) {